drm/i915: Fix hpd live status bits for g4x
[firefly-linux-kernel-4.4.55.git] / drivers / gpu / drm / i915 / intel_display.c
index beb0374a19f199d23c73116dcfcd08c3d500dde0..3292495ee10f0b09ef37335572dfdb158f93a7bf 100644 (file)
@@ -4447,7 +4447,7 @@ int skl_update_scaler_crtc(struct intel_crtc_state *state)
                      intel_crtc->base.base.id, intel_crtc->pipe, SKL_CRTC_INDEX);
 
        return skl_update_scaler(state, !state->base.active, SKL_CRTC_INDEX,
-               &state->scaler_state.scaler_id, DRM_ROTATE_0,
+               &state->scaler_state.scaler_id, BIT(DRM_ROTATE_0),
                state->pipe_src_w, state->pipe_src_h,
                adjusted_mode->crtc_hdisplay, adjusted_mode->crtc_vdisplay);
 }
@@ -8228,12 +8228,14 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_encoder *encoder;
+       int i;
        u32 val, final;
        bool has_lvds = false;
        bool has_cpu_edp = false;
        bool has_panel = false;
        bool has_ck505 = false;
        bool can_ssc = false;
+       bool using_ssc_source = false;
 
        /* We need to take the global config into account */
        for_each_intel_encoder(dev, encoder) {
@@ -8260,8 +8262,22 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
                can_ssc = true;
        }
 
-       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d\n",
-                     has_panel, has_lvds, has_ck505);
+       /* Check if any DPLLs are using the SSC source */
+       for (i = 0; i < dev_priv->num_shared_dpll; i++) {
+               u32 temp = I915_READ(PCH_DPLL(i));
+
+               if (!(temp & DPLL_VCO_ENABLE))
+                       continue;
+
+               if ((temp & PLL_REF_INPUT_MASK) ==
+                   PLLB_REF_INPUT_SPREADSPECTRUMIN) {
+                       using_ssc_source = true;
+                       break;
+               }
+       }
+
+       DRM_DEBUG_KMS("has_panel %d has_lvds %d has_ck505 %d using_ssc_source %d\n",
+                     has_panel, has_lvds, has_ck505, using_ssc_source);
 
        /* Ironlake: try to setup display ref clock before DPLL
         * enabling. This is only under driver's control after
@@ -8298,9 +8314,9 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
                                final |= DREF_CPU_SOURCE_OUTPUT_NONSPREAD;
                } else
                        final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
-       } else {
-               final |= DREF_SSC_SOURCE_DISABLE;
-               final |= DREF_CPU_SOURCE_OUTPUT_DISABLE;
+       } else if (using_ssc_source) {
+               final |= DREF_SSC_SOURCE_ENABLE;
+               final |= DREF_SSC1_ENABLE;
        }
 
        if (final == val)
@@ -8346,7 +8362,7 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
                POSTING_READ(PCH_DREF_CONTROL);
                udelay(200);
        } else {
-               DRM_DEBUG_KMS("Disabling SSC entirely\n");
+               DRM_DEBUG_KMS("Disabling CPU source output\n");
 
                val &= ~DREF_CPU_SOURCE_OUTPUT_MASK;
 
@@ -8357,16 +8373,20 @@ static void ironlake_init_pch_refclk(struct drm_device *dev)
                POSTING_READ(PCH_DREF_CONTROL);
                udelay(200);
 
-               /* Turn off the SSC source */
-               val &= ~DREF_SSC_SOURCE_MASK;
-               val |= DREF_SSC_SOURCE_DISABLE;
+               if (!using_ssc_source) {
+                       DRM_DEBUG_KMS("Disabling SSC source\n");
 
-               /* Turn off SSC1 */
-               val &= ~DREF_SSC1_ENABLE;
+                       /* Turn off the SSC source */
+                       val &= ~DREF_SSC_SOURCE_MASK;
+                       val |= DREF_SSC_SOURCE_DISABLE;
 
-               I915_WRITE(PCH_DREF_CONTROL, val);
-               POSTING_READ(PCH_DREF_CONTROL);
-               udelay(200);
+                       /* Turn off SSC1 */
+                       val &= ~DREF_SSC1_ENABLE;
+
+                       I915_WRITE(PCH_DREF_CONTROL, val);
+                       POSTING_READ(PCH_DREF_CONTROL);
+                       udelay(200);
+               }
        }
 
        BUG_ON(val != final);
@@ -9669,6 +9689,8 @@ static void broadwell_set_cdclk(struct drm_device *dev, int cdclk)
        sandybridge_pcode_write(dev_priv, HSW_PCODE_DE_WRITE_FREQ_REQ, data);
        mutex_unlock(&dev_priv->rps.hw_lock);
 
+       I915_WRITE(CDCLK_FREQ, DIV_ROUND_CLOSEST(cdclk, 1000) - 1);
+
        intel_update_cdclk(dev);
 
        WARN(cdclk != dev_priv->cdclk_freq,
@@ -12123,18 +12145,22 @@ static void intel_dump_pipe_config(struct intel_crtc *crtc,
 static bool check_digital_port_conflicts(struct drm_atomic_state *state)
 {
        struct drm_device *dev = state->dev;
-       struct intel_encoder *encoder;
        struct drm_connector *connector;
-       struct drm_connector_state *connector_state;
        unsigned int used_ports = 0;
-       int i;
 
        /*
         * Walk the connector list instead of the encoder
         * list to detect the problem on ddi platforms
         * where there's just one encoder per digital port.
         */
-       for_each_connector_in_state(state, connector, connector_state, i) {
+       drm_for_each_connector(connector, dev) {
+               struct drm_connector_state *connector_state;
+               struct intel_encoder *encoder;
+
+               connector_state = drm_atomic_get_existing_connector_state(state, connector);
+               if (!connector_state)
+                       connector_state = connector->state;
+
                if (!connector_state->best_encoder)
                        continue;
 
@@ -13533,11 +13559,12 @@ intel_check_primary_plane(struct drm_plane *plane,
        int max_scale = DRM_PLANE_HELPER_NO_SCALING;
        bool can_position = false;
 
-       /* use scaler when colorkey is not required */
-       if (INTEL_INFO(plane->dev)->gen >= 9 &&
-           state->ckey.flags == I915_SET_COLORKEY_NONE) {
-               min_scale = 1;
-               max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+       if (INTEL_INFO(plane->dev)->gen >= 9) {
+               /* use scaler when colorkey is not required */
+               if (state->ckey.flags == I915_SET_COLORKEY_NONE) {
+                       min_scale = 1;
+                       max_scale = skl_max_scale(to_intel_crtc(crtc), crtc_state);
+               }
                can_position = true;
        }
 
@@ -15561,6 +15588,8 @@ void intel_modeset_cleanup(struct drm_device *dev)
        mutex_lock(&dev->struct_mutex);
        intel_cleanup_gt_powersave(dev);
        mutex_unlock(&dev->struct_mutex);
+
+       intel_teardown_gmbus(dev);
 }
 
 /*