drm/i915: Fix locking for intel_enable_pipe_a()
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_crt.c
index 5a045d3bd77e7c7f77c7e8fc55292d37714eab3a..e8abfce40976c74a2f9cff93c4d93c897eda112e 100644 (file)
@@ -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;
 }
 
@@ -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;
This page took 0.054783 seconds and 5 git commands to generate.