]> Pileus Git - ~andy/linux/blobdiff - drivers/gpu/drm/i915/intel_dp.c
drm/i915: don't touch the VDD when disabling the panel
[~andy/linux] / drivers / gpu / drm / i915 / intel_dp.c
index 0b2e842fef0151070b09af535d54fdcee2215602..948892d18ff716acf0a9832242fdb8f43b718674 100644 (file)
@@ -142,7 +142,7 @@ intel_dp_max_data_rate(int max_link_clock, int max_lanes)
        return (max_link_clock * max_lanes * 8) / 10;
 }
 
-static int
+static enum drm_mode_status
 intel_dp_mode_valid(struct drm_connector *connector,
                    struct drm_display_mode *mode)
 {
@@ -404,7 +404,7 @@ intel_dp_aux_ch(struct intel_dp *intel_dp,
        int i, ret, recv_bytes;
        uint32_t status;
        int try, precharge, clock = 0;
-       bool has_aux_irq = INTEL_INFO(dev)->gen >= 5 && !IS_VALLEYVIEW(dev);
+       bool has_aux_irq = true;
        uint32_t timeout;
 
        /* dp aux is extremely sensitive to irq latency, hence request the
@@ -1037,6 +1037,8 @@ static void ironlake_wait_panel_status(struct intel_dp *intel_dp,
                                I915_READ(pp_stat_reg),
                                I915_READ(pp_ctrl_reg));
        }
+
+       DRM_DEBUG_KMS("Wait complete\n");
 }
 
 static void ironlake_wait_panel_on(struct intel_dp *intel_dp)
@@ -1092,6 +1094,8 @@ void ironlake_edp_panel_vdd_on(struct intel_dp *intel_dp)
        if (ironlake_edp_have_panel_vdd(intel_dp))
                return;
 
+       intel_runtime_pm_get(dev_priv);
+
        DRM_DEBUG_KMS("Turning eDP VDD on\n");
 
        if (!ironlake_edp_have_panel_power(intel_dp))
@@ -1141,6 +1145,8 @@ static void ironlake_panel_vdd_off_sync(struct intel_dp *intel_dp)
                DRM_DEBUG_KMS("PP_STATUS: 0x%08x PP_CONTROL: 0x%08x\n",
                I915_READ(pp_stat_reg), I915_READ(pp_ctrl_reg));
                msleep(intel_dp->panel_power_down_delay);
+
+               intel_runtime_pm_put(dev_priv);
        }
 }
 
@@ -1233,20 +1239,16 @@ void ironlake_edp_panel_off(struct intel_dp *intel_dp)
 
        DRM_DEBUG_KMS("Turn eDP power off\n");
 
-       WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n");
-
        pp = ironlake_get_pp_control(intel_dp);
        /* We need to switch off panel power _and_ force vdd, for otherwise some
         * panels get very unhappy and cease to work. */
-       pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE);
+       pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE);
 
        pp_ctrl_reg = _pp_ctrl_reg(intel_dp);
 
        I915_WRITE(pp_ctrl_reg, pp);
        POSTING_READ(pp_ctrl_reg);
 
-       intel_dp->want_panel_vdd = false;
-
        ironlake_wait_panel_off(intel_dp);
 }
 
@@ -1772,7 +1774,6 @@ static void intel_disable_dp(struct intel_encoder *encoder)
 
        /* Make sure the panel is off before trying to change the mode. But also
         * ensure that we have vdd while we switch off the panel. */
-       ironlake_edp_panel_vdd_on(intel_dp);
        ironlake_edp_backlight_off(intel_dp);
        intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF);
        ironlake_edp_panel_off(intel_dp);
@@ -1845,23 +1846,23 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
        struct drm_device *dev = encoder->base.dev;
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
        struct edp_power_seq power_seq;
        u32 val;
 
        mutex_lock(&dev_priv->dpio_lock);
 
-       val = vlv_dpio_read(dev_priv, pipe, DPIO_DATA_LANE_A(port));
+       val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW8(port));
        val = 0;
        if (pipe)
                val |= (1<<21);
        else
                val &= ~(1<<21);
        val |= 0x001000c4;
-       vlv_dpio_write(dev_priv, pipe, DPIO_DATA_CHANNEL(port), val);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF0(port), 0x00760018);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLOCKBUF8(port), 0x00400888);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW8(port), val);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW14(port), 0x00760018);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW23(port), 0x00400888);
 
        mutex_unlock(&dev_priv->dpio_lock);
 
@@ -1872,7 +1873,7 @@ static void vlv_pre_enable_dp(struct intel_encoder *encoder)
 
        intel_enable_dp(encoder);
 
-       vlv_wait_port_ready(dev_priv, port);
+       vlv_wait_port_ready(dev_priv, dport);
 }
 
 static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
@@ -1882,24 +1883,24 @@ static void vlv_dp_pre_pll_enable(struct intel_encoder *encoder)
        struct drm_i915_private *dev_priv = dev->dev_private;
        struct intel_crtc *intel_crtc =
                to_intel_crtc(encoder->base.crtc);
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        /* Program Tx lane resets to default */
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_TX(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW0(port),
                         DPIO_PCS_TX_LANE2_RESET |
                         DPIO_PCS_TX_LANE1_RESET);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CLK(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW1(port),
                         DPIO_PCS_CLK_CRI_RXEB_EIOS_EN |
                         DPIO_PCS_CLK_CRI_RXDIGFILTSG_EN |
                         (1<<DPIO_PCS_CLK_DATAWIDTH_SHIFT) |
                                 DPIO_PCS_CLK_SOFT_RESET);
 
        /* Fix up inter-pair skew failure */
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER1(port), 0x00750f00);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_CTL(port), 0x00001500);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_LANE(port), 0x40400000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW12(port), 0x00750f00);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW11(port), 0x00001500);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW14(port), 0x40400000);
        mutex_unlock(&dev_priv->dpio_lock);
 }
 
@@ -1941,18 +1942,6 @@ intel_dp_get_link_status(struct intel_dp *intel_dp, uint8_t link_status[DP_LINK_
                                              DP_LINK_STATUS_SIZE);
 }
 
-#if 0
-static char    *voltage_names[] = {
-       "0.4V", "0.6V", "0.8V", "1.2V"
-};
-static char    *pre_emph_names[] = {
-       "0dB", "3.5dB", "6dB", "9.5dB"
-};
-static char    *link_train_names[] = {
-       "pattern 1", "pattern 2", "idle", "off"
-};
-#endif
-
 /*
  * These are source-specific values; current Intel hardware supports
  * a maximum voltage of 800mV and a maximum pre-emphasis of 6dB
@@ -2050,7 +2039,7 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
        unsigned long demph_reg_value, preemph_reg_value,
                uniqtranscale_reg_value;
        uint8_t train_set = intel_dp->train_set[0];
-       int port = vlv_dport_to_channel(dport);
+       enum dpio_channel port = vlv_dport_to_channel(dport);
        int pipe = intel_crtc->pipe;
 
        switch (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) {
@@ -2127,14 +2116,14 @@ static uint32_t intel_vlv_signal_levels(struct intel_dp *intel_dp)
        }
 
        mutex_lock(&dev_priv->dpio_lock);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x00000000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL4(port), demph_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL2(port),
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x00000000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW4(port), demph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW2(port),
                         uniqtranscale_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_SWING_CTL3(port), 0x0C782040);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_STAGGER0(port), 0x00030000);
-       vlv_dpio_write(dev_priv, pipe, DPIO_PCS_CTL_OVER1(port), preemph_reg_value);
-       vlv_dpio_write(dev_priv, pipe, DPIO_TX_OCALINIT(port), 0x80000000);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW3(port), 0x0C782040);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW11(port), 0x00030000);
+       vlv_dpio_write(dev_priv, pipe, VLV_PCS_DW9(port), preemph_reg_value);
+       vlv_dpio_write(dev_priv, pipe, VLV_TX_DW5(port), 0x80000000);
        mutex_unlock(&dev_priv->dpio_lock);
 
        return 0;
@@ -3082,9 +3071,12 @@ intel_dp_detect(struct drm_connector *connector, bool force)
        struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp);
        struct intel_encoder *intel_encoder = &intel_dig_port->base;
        struct drm_device *dev = connector->dev;
+       struct drm_i915_private *dev_priv = dev->dev_private;
        enum drm_connector_status status;
        struct edid *edid = NULL;
 
+       intel_runtime_pm_get(dev_priv);
+
        DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n",
                      connector->base.id, drm_get_connector_name(connector));
 
@@ -3096,7 +3088,7 @@ intel_dp_detect(struct drm_connector *connector, bool force)
                status = g4x_dp_detect(intel_dp);
 
        if (status != connector_status_connected)
-               return status;
+               goto out;
 
        intel_dp_probe_oui(intel_dp);
 
@@ -3112,7 +3104,11 @@ intel_dp_detect(struct drm_connector *connector, bool force)
 
        if (intel_encoder->type != INTEL_OUTPUT_EDP)
                intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT;
-       return connector_status_connected;
+       status = connector_status_connected;
+
+out:
+       intel_runtime_pm_put(dev_priv);
+       return status;
 }
 
 static int intel_dp_get_modes(struct drm_connector *connector)