diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 54 | 
1 files changed, 43 insertions, 11 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 70b0f1abf14..0976137ab79 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -55,18 +55,36 @@ static struct intel_crt *intel_attached_crt(struct drm_connector *connector)  			    struct intel_crt, base);  } -static void intel_crt_dpms(struct drm_encoder *encoder, int mode) +static void pch_crt_dpms(struct drm_encoder *encoder, int mode)  {  	struct drm_device *dev = encoder->dev;  	struct drm_i915_private *dev_priv = dev->dev_private; -	u32 temp, reg; +	u32 temp; -	if (HAS_PCH_SPLIT(dev)) -		reg = PCH_ADPA; -	else -		reg = ADPA; +	temp = I915_READ(PCH_ADPA); +	temp &= ~ADPA_DAC_ENABLE; + +	switch (mode) { +	case DRM_MODE_DPMS_ON: +		temp |= ADPA_DAC_ENABLE; +		break; +	case DRM_MODE_DPMS_STANDBY: +	case DRM_MODE_DPMS_SUSPEND: +	case DRM_MODE_DPMS_OFF: +		/* Just leave port enable cleared */ +		break; +	} + +	I915_WRITE(PCH_ADPA, temp); +} -	temp = I915_READ(reg); +static void gmch_crt_dpms(struct drm_encoder *encoder, int mode) +{ +	struct drm_device *dev = encoder->dev; +	struct drm_i915_private *dev_priv = dev->dev_private; +	u32 temp; + +	temp = I915_READ(ADPA);  	temp &= ~(ADPA_HSYNC_CNTL_DISABLE | ADPA_VSYNC_CNTL_DISABLE);  	temp &= ~ADPA_DAC_ENABLE; @@ -85,7 +103,7 @@ static void intel_crt_dpms(struct drm_encoder *encoder, int mode)  		break;  	} -	I915_WRITE(reg, temp); +	I915_WRITE(ADPA, temp);  }  static int intel_crt_mode_valid(struct drm_connector *connector, @@ -516,12 +534,20 @@ static void intel_crt_reset(struct drm_connector *connector)   * Routines for controlling stuff on the analog port   */ -static const struct drm_encoder_helper_funcs intel_crt_helper_funcs = { -	.dpms = intel_crt_dpms, +static const struct drm_encoder_helper_funcs pch_encoder_funcs = { +	.mode_fixup = intel_crt_mode_fixup, +	.prepare = intel_encoder_prepare, +	.commit = intel_encoder_commit, +	.mode_set = intel_crt_mode_set, +	.dpms = pch_crt_dpms, +}; + +static const struct drm_encoder_helper_funcs gmch_encoder_funcs = {  	.mode_fixup = intel_crt_mode_fixup,  	.prepare = intel_encoder_prepare,  	.commit = intel_encoder_commit,  	.mode_set = intel_crt_mode_set, +	.dpms = gmch_crt_dpms,  };  static const struct drm_connector_funcs intel_crt_connector_funcs = { @@ -567,6 +593,7 @@ void intel_crt_init(struct drm_device *dev)  	struct intel_crt *crt;  	struct intel_connector *intel_connector;  	struct drm_i915_private *dev_priv = dev->dev_private; +	const struct drm_encoder_helper_funcs *encoder_helper_funcs;  	/* Skip machines without VGA that falsely report hotplug events */  	if (dmi_check_system(intel_no_crt)) @@ -602,7 +629,12 @@ void intel_crt_init(struct drm_device *dev)  		connector->interlace_allowed = 1;  	connector->doublescan_allowed = 0; -	drm_encoder_helper_add(&crt->base.base, &intel_crt_helper_funcs); +	if (HAS_PCH_SPLIT(dev)) +		encoder_helper_funcs = &pch_encoder_funcs; +	else +		encoder_helper_funcs = &gmch_encoder_funcs; + +	drm_encoder_helper_add(&crt->base.base, encoder_helper_funcs);  	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs);  	drm_sysfs_connector_add(connector);  |