diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_dp.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_dp.c | 47 | 
1 files changed, 32 insertions, 15 deletions
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 1b63d55318a..fb3715b4b09 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -2579,7 +2579,8 @@ intel_dp_add_properties(struct intel_dp *intel_dp, struct drm_connector *connect  static void  intel_dp_init_panel_power_sequencer(struct drm_device *dev, -				    struct intel_dp *intel_dp) +				    struct intel_dp *intel_dp, +				    struct edp_power_seq *out)  {  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct edp_power_seq cur, vbt, spec, final; @@ -2650,16 +2651,35 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,  	intel_dp->panel_power_cycle_delay = get_delay(t11_t12);  #undef get_delay +	DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n", +		      intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay, +		      intel_dp->panel_power_cycle_delay); + +	DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", +		      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); + +	if (out) +		*out = final; +} + +static void +intel_dp_init_panel_power_sequencer_registers(struct drm_device *dev, +					      struct intel_dp *intel_dp, +					      struct edp_power_seq *seq) +{ +	struct drm_i915_private *dev_priv = dev->dev_private; +	u32 pp_on, pp_off, pp_div; +  	/* And finally store the new values in the power sequencer. */ -	pp_on = (final.t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | -		(final.t8 << PANEL_LIGHT_ON_DELAY_SHIFT); -	pp_off = (final.t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | -		 (final.t10 << PANEL_POWER_DOWN_DELAY_SHIFT); +	pp_on = (seq->t1_t3 << PANEL_POWER_UP_DELAY_SHIFT) | +		(seq->t8 << PANEL_LIGHT_ON_DELAY_SHIFT); +	pp_off = (seq->t9 << PANEL_LIGHT_OFF_DELAY_SHIFT) | +		 (seq->t10 << PANEL_POWER_DOWN_DELAY_SHIFT);  	/* Compute the divisor for the pp clock, simply match the Bspec  	 * formula. */  	pp_div = ((100 * intel_pch_rawclk(dev))/2 - 1)  			<< PP_REFERENCE_DIVIDER_SHIFT; -	pp_div |= (DIV_ROUND_UP(final.t11_t12, 1000) +	pp_div |= (DIV_ROUND_UP(seq->t11_t12, 1000)  			<< PANEL_POWER_CYCLE_DELAY_SHIFT);  	/* Haswell doesn't have any port selection bits for the panel @@ -2675,14 +2695,6 @@ intel_dp_init_panel_power_sequencer(struct drm_device *dev,  	I915_WRITE(PCH_PP_OFF_DELAYS, pp_off);  	I915_WRITE(PCH_PP_DIVISOR, pp_div); - -	DRM_DEBUG_KMS("panel power up delay %d, power down delay %d, power cycle delay %d\n", -		      intel_dp->panel_power_up_delay, intel_dp->panel_power_down_delay, -		      intel_dp->panel_power_cycle_delay); - -	DRM_DEBUG_KMS("backlight on delay %d, off delay %d\n", -		      intel_dp->backlight_on_delay, intel_dp->backlight_off_delay); -  	DRM_DEBUG_KMS("panel power sequencer register settings: PP_ON %#x, PP_OFF %#x, PP_DIV %#x\n",  		      I915_READ(PCH_PP_ON_DELAYS),  		      I915_READ(PCH_PP_OFF_DELAYS), @@ -2699,6 +2711,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,  	struct drm_device *dev = intel_encoder->base.dev;  	struct drm_i915_private *dev_priv = dev->dev_private;  	struct drm_display_mode *fixed_mode = NULL; +	struct edp_power_seq power_seq = { 0 };  	enum port port = intel_dig_port->port;  	const char *name = NULL;  	int type; @@ -2771,7 +2784,7 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,  	}  	if (is_edp(intel_dp)) -		intel_dp_init_panel_power_sequencer(dev, intel_dp); +		intel_dp_init_panel_power_sequencer(dev, intel_dp, &power_seq);  	intel_dp_i2c_init(intel_dp, intel_connector, name); @@ -2798,6 +2811,10 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port,  			return;  		} +		/* We now know it's not a ghost, init power sequence regs. */ +		intel_dp_init_panel_power_sequencer_registers(dev, intel_dp, +							      &power_seq); +  		ironlake_edp_panel_vdd_on(intel_dp);  		edid = drm_get_edid(connector, &intel_dp->adapter);  		if (edid) {  |