diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_crt.c')
| -rw-r--r-- | drivers/gpu/drm/i915/intel_crt.c | 47 | 
1 files changed, 39 insertions, 8 deletions
diff --git a/drivers/gpu/drm/i915/intel_crt.c b/drivers/gpu/drm/i915/intel_crt.c index 5a045d3bd77e..9212e6504e0f 100644 --- a/drivers/gpu/drm/i915/intel_crt.c +++ b/drivers/gpu/drm/i915/intel_crt.c @@ -137,6 +137,18 @@ static void hsw_crt_get_config(struct intel_encoder *encoder,  	pipe_config->adjusted_mode.flags |= intel_crt_get_flags(encoder);  } +static void hsw_crt_pre_enable(struct intel_encoder *encoder) +{ +	struct drm_device *dev = encoder->base.dev; +	struct drm_i915_private *dev_priv = dev->dev_private; + +	WARN(I915_READ(SPLL_CTL) & SPLL_PLL_ENABLE, "SPLL already enabled\n"); +	I915_WRITE(SPLL_CTL, +		   SPLL_PLL_ENABLE | SPLL_PLL_FREQ_1350MHz | SPLL_PLL_SSC); +	POSTING_READ(SPLL_CTL); +	udelay(20); +} +  /* Note: The caller is required to filter out dpms modes not supported by the   * platform. */  static void intel_crt_set_dpms(struct intel_encoder *encoder, int mode) @@ -194,6 +206,20 @@ static void intel_disable_crt(struct intel_encoder *encoder)  	intel_crt_set_dpms(encoder, DRM_MODE_DPMS_OFF);  } + +static void hsw_crt_post_disable(struct intel_encoder *encoder) +{ +	struct drm_device *dev = encoder->base.dev; +	struct drm_i915_private *dev_priv = dev->dev_private; +	uint32_t val; + +	DRM_DEBUG_KMS("Disabling SPLL\n"); +	val = I915_READ(SPLL_CTL); +	WARN_ON(!(val & SPLL_PLL_ENABLE)); +	I915_WRITE(SPLL_CTL, val & ~SPLL_PLL_ENABLE); +	POSTING_READ(SPLL_CTL); +} +  static void intel_enable_crt(struct intel_encoder *encoder)  {  	struct intel_crt *crt = intel_encoder_to_crt(encoder); @@ -289,8 +315,10 @@ static bool intel_crt_compute_config(struct intel_encoder *encoder,  		pipe_config->pipe_bpp = 24;  	/* FDI must always be 2.7 GHz */ -	if (HAS_DDI(dev)) +	if (HAS_DDI(dev)) { +		pipe_config->ddi_pll_sel = PORT_CLK_SEL_SPLL;  		pipe_config->port_clock = 135000 * 2; +	}  	return true;  } @@ -632,8 +660,6 @@ intel_crt_detect(struct drm_connector *connector, bool force)  	struct intel_load_detect_pipe tmp;  	struct drm_modeset_acquire_ctx ctx; -	intel_runtime_pm_get(dev_priv); -  	DRM_DEBUG_KMS("[CONNECTOR:%d:%s] force=%d\n",  		      connector->base.id, connector->name,  		      force); @@ -673,20 +699,23 @@ intel_crt_detect(struct drm_connector *connector, bool force)  		goto out;  	} +	drm_modeset_acquire_init(&ctx, 0); +  	/* for pre-945g platforms use load detect */  	if (intel_get_load_detect_pipe(connector, NULL, &tmp, &ctx)) {  		if (intel_crt_detect_ddc(connector))  			status = connector_status_connected;  		else  			status = intel_crt_load_detect(crt); -		intel_release_load_detect_pipe(connector, &tmp, &ctx); +		intel_release_load_detect_pipe(connector, &tmp);  	} else  		status = connector_status_unknown; +	drm_modeset_drop_locks(&ctx); +	drm_modeset_acquire_fini(&ctx); +  out:  	intel_display_power_put(dev_priv, power_domain); -	intel_runtime_pm_put(dev_priv); -  	return status;  } @@ -775,7 +804,7 @@ static const struct drm_encoder_funcs intel_crt_enc_funcs = {  	.destroy = intel_encoder_destroy,  }; -static int __init intel_no_crt_dmi_callback(const struct dmi_system_id *id) +static int intel_no_crt_dmi_callback(const struct dmi_system_id *id)  {  	DRM_INFO("Skipping CRT initialization for %s\n", id->ident);  	return 1; @@ -860,6 +889,8 @@ void intel_crt_init(struct drm_device *dev)  	if (HAS_DDI(dev)) {  		crt->base.get_config = hsw_crt_get_config;  		crt->base.get_hw_state = intel_ddi_get_hw_state; +		crt->base.pre_enable = hsw_crt_pre_enable; +		crt->base.post_disable = hsw_crt_post_disable;  	} else {  		crt->base.get_config = intel_crt_get_config;  		crt->base.get_hw_state = intel_crt_get_hw_state; @@ -869,7 +900,7 @@ void intel_crt_init(struct drm_device *dev)  	drm_connector_helper_add(connector, &intel_crt_connector_helper_funcs); -	drm_sysfs_connector_add(connector); +	drm_connector_register(connector);  	if (!I915_HAS_HOTPLUG(dev))  		intel_connector->polled = DRM_CONNECTOR_POLL_CONNECT;  |