drm/i915: Move intel_dp->lane_count into pipe_config
[deliverable/linux.git] / drivers / gpu / drm / i915 / intel_ddi.c
index db22f017302779070c27061dba4211498a94e5e2..56d778f004603116f4fa07467a49eba1f0f77f6f 100644 (file)
@@ -440,6 +440,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
 {
        struct drm_i915_private *dev_priv = dev->dev_private;
        u32 reg;
+       u32 iboost_bit = 0;
        int i, n_hdmi_entries, n_dp_entries, n_edp_entries, hdmi_default_entry,
            size;
        int hdmi_level = dev_priv->vbt.ddi_port_info[port].hdmi_level_shift;
@@ -458,6 +459,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
                                        INTEL_OUTPUT_HDMI);
                return;
        } else if (IS_SKYLAKE(dev)) {
+               ddi_translations_fdi = NULL;
                ddi_translations_dp =
                                skl_get_buf_trans_dp(dev, &n_dp_entries);
                ddi_translations_edp =
@@ -465,6 +467,10 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
                ddi_translations_hdmi =
                                skl_get_buf_trans_hdmi(dev, &n_hdmi_entries);
                hdmi_default_entry = 8;
+               /* If we're boosting the current, set bit 31 of trans1 */
+               if (dev_priv->vbt.ddi_port_info[port].hdmi_boost_level ||
+                   dev_priv->vbt.ddi_port_info[port].dp_boost_level)
+                       iboost_bit = 1<<31;
        } else if (IS_BROADWELL(dev)) {
                ddi_translations_fdi = bdw_ddi_translations_fdi;
                ddi_translations_dp = bdw_ddi_translations_dp;
@@ -525,7 +531,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
        }
 
        for (i = 0, reg = DDI_BUF_TRANS(port); i < size; i++) {
-               I915_WRITE(reg, ddi_translations[i].trans1);
+               I915_WRITE(reg, ddi_translations[i].trans1 | iboost_bit);
                reg += 4;
                I915_WRITE(reg, ddi_translations[i].trans2);
                reg += 4;
@@ -540,7 +546,7 @@ static void intel_prepare_ddi_buffers(struct drm_device *dev, enum port port,
                hdmi_level = hdmi_default_entry;
 
        /* Entry 9 is for HDMI: */
-       I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1);
+       I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans1 | iboost_bit);
        reg += 4;
        I915_WRITE(reg, ddi_translations_hdmi[hdmi_level].trans2);
        reg += 4;
@@ -722,11 +728,11 @@ void intel_ddi_init_dp_buf_reg(struct intel_encoder *encoder)
        struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base);
        struct intel_digital_port *intel_dig_port =
                enc_to_dig_port(&encoder->base);
+       struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc);
 
        intel_dp->DP = intel_dig_port->saved_port_bits |
                DDI_BUF_CTL_ENABLE | DDI_BUF_TRANS_SELECT(0);
-       intel_dp->DP |= DDI_PORT_WIDTH(intel_dp->lane_count);
-
+       intel_dp->DP |= DDI_PORT_WIDTH(crtc->config->lane_count);
 }
 
 static struct intel_encoder *
@@ -1261,9 +1267,10 @@ hsw_ddi_calculate_wrpll(int clock /* in Hz */,
 static bool
 hsw_ddi_pll_select(struct intel_crtc *intel_crtc,
                   struct intel_crtc_state *crtc_state,
-                  struct intel_encoder *intel_encoder,
-                  int clock)
+                  struct intel_encoder *intel_encoder)
 {
+       int clock = crtc_state->port_clock;
+
        if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
                struct intel_shared_dpll *pll;
                uint32_t val;
@@ -1542,11 +1549,11 @@ skip_remaining_dividers:
 static bool
 skl_ddi_pll_select(struct intel_crtc *intel_crtc,
                   struct intel_crtc_state *crtc_state,
-                  struct intel_encoder *intel_encoder,
-                  int clock)
+                  struct intel_encoder *intel_encoder)
 {
        struct intel_shared_dpll *pll;
        uint32_t ctrl1, cfgcr1, cfgcr2;
+       int clock = crtc_state->port_clock;
 
        /*
         * See comment in intel_dpll_hw_state to understand why we always use 0
@@ -1573,17 +1580,14 @@ skl_ddi_pll_select(struct intel_crtc *intel_crtc,
                         DPLL_CFGCR2_PDIV(wrpll_params.pdiv) |
                         wrpll_params.central_freq;
        } else if (intel_encoder->type == INTEL_OUTPUT_DISPLAYPORT) {
-               struct drm_encoder *encoder = &intel_encoder->base;
-               struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
-
-               switch (intel_dp->link_bw) {
-               case DP_LINK_BW_1_62:
+               switch (crtc_state->port_clock / 2) {
+               case 81000:
                        ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_810, 0);
                        break;
-               case DP_LINK_BW_2_7:
+               case 135000:
                        ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_1350, 0);
                        break;
-               case DP_LINK_BW_5_4:
+               case 270000:
                        ctrl1 |= DPLL_CTRL1_LINK_RATE(DPLL_CTRL1_LINK_RATE_2700, 0);
                        break;
                }
@@ -1637,14 +1641,14 @@ static const struct bxt_clk_div bxt_dp_clk_val[] = {
 static bool
 bxt_ddi_pll_select(struct intel_crtc *intel_crtc,
                   struct intel_crtc_state *crtc_state,
-                  struct intel_encoder *intel_encoder,
-                  int clock)
+                  struct intel_encoder *intel_encoder)
 {
        struct intel_shared_dpll *pll;
        struct bxt_clk_div clk_div = {0};
        int vco = 0;
        uint32_t prop_coef, int_coef, gain_ctl, targ_cnt;
        uint32_t lanestagger;
+       int clock = crtc_state->port_clock;
 
        if (intel_encoder->type == INTEL_OUTPUT_HDMI) {
                intel_clock_t best_clock;
@@ -1772,17 +1776,16 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc,
        struct drm_device *dev = intel_crtc->base.dev;
        struct intel_encoder *intel_encoder =
                intel_ddi_get_crtc_new_encoder(crtc_state);
-       int clock = crtc_state->port_clock;
 
        if (IS_SKYLAKE(dev))
                return skl_ddi_pll_select(intel_crtc, crtc_state,
-                                         intel_encoder, clock);
+                                         intel_encoder);
        else if (IS_BROXTON(dev))
                return bxt_ddi_pll_select(intel_crtc, crtc_state,
-                                         intel_encoder, clock);
+                                         intel_encoder);
        else
                return hsw_ddi_pll_select(intel_crtc, crtc_state,
-                                         intel_encoder, clock);
+                                         intel_encoder);
 }
 
 void intel_ddi_set_pipe_settings(struct drm_crtc *crtc)
@@ -1915,7 +1918,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
                } else
                        temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 
-               temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
+               temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
        } else if (type == INTEL_OUTPUT_DP_MST) {
                struct intel_dp *intel_dp = &enc_to_mst(encoder)->primary->dp;
 
@@ -1924,7 +1927,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc)
                } else
                        temp |= TRANS_DDI_MODE_SELECT_DP_SST;
 
-               temp |= DDI_PORT_WIDTH(intel_dp->lane_count);
+               temp |= DDI_PORT_WIDTH(intel_crtc->config->lane_count);
        } else {
                WARN(1, "Invalid encoder type %d for pipe %c\n",
                     intel_encoder->type, pipe_name(pipe));
@@ -2077,18 +2080,35 @@ static void skl_ddi_set_iboost(struct drm_device *dev, u32 level,
        struct drm_i915_private *dev_priv = dev->dev_private;
        const struct ddi_buf_trans *ddi_translations;
        uint8_t iboost;
+       uint8_t dp_iboost, hdmi_iboost;
        int n_entries;
        u32 reg;
 
+       /* VBT may override standard boost values */
+       dp_iboost = dev_priv->vbt.ddi_port_info[port].dp_boost_level;
+       hdmi_iboost = dev_priv->vbt.ddi_port_info[port].hdmi_boost_level;
+
        if (type == INTEL_OUTPUT_DISPLAYPORT) {
-               ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
-               iboost = ddi_translations[port].i_boost;
+               if (dp_iboost) {
+                       iboost = dp_iboost;
+               } else {
+                       ddi_translations = skl_get_buf_trans_dp(dev, &n_entries);
+                       iboost = ddi_translations[port].i_boost;
+               }
        } else if (type == INTEL_OUTPUT_EDP) {
-               ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
-               iboost = ddi_translations[port].i_boost;
+               if (dp_iboost) {
+                       iboost = dp_iboost;
+               } else {
+                       ddi_translations = skl_get_buf_trans_edp(dev, &n_entries);
+                       iboost = ddi_translations[port].i_boost;
+               }
        } else if (type == INTEL_OUTPUT_HDMI) {
-               ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
-               iboost = ddi_translations[port].i_boost;
+               if (hdmi_iboost) {
+                       iboost = hdmi_iboost;
+               } else {
+                       ddi_translations = skl_get_buf_trans_hdmi(dev, &n_entries);
+                       iboost = ddi_translations[port].i_boost;
+               }
        } else {
                return;
        }
@@ -3074,6 +3094,8 @@ void intel_ddi_get_config(struct intel_encoder *encoder,
        case TRANS_DDI_MODE_SELECT_DP_SST:
        case TRANS_DDI_MODE_SELECT_DP_MST:
                pipe_config->has_dp_encoder = true;
+               pipe_config->lane_count =
+                       ((temp & DDI_PORT_WIDTH_MASK) >> DDI_PORT_WIDTH_SHIFT) + 1;
                intel_dp_get_m_n(intel_crtc, pipe_config);
                break;
        default:
@@ -3183,10 +3205,9 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                     dev_priv->vbt.ddi_port_info[port].supports_hdmi);
        init_dp = dev_priv->vbt.ddi_port_info[port].supports_dp;
        if (!init_dp && !init_hdmi) {
-               DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, assuming it is\n",
+               DRM_DEBUG_KMS("VBT says port %c is not DVI/HDMI/DP compatible, respect it\n",
                              port_name(port));
-               init_hdmi = true;
-               init_dp = true;
+               return;
        }
 
        intel_dig_port = kzalloc(sizeof(*intel_dig_port), GFP_KERNEL);
@@ -3221,7 +3242,15 @@ void intel_ddi_init(struct drm_device *dev, enum port port)
                        goto err;
 
                intel_dig_port->hpd_pulse = intel_dp_hpd_pulse;
-               dev_priv->hotplug.irq_port[port] = intel_dig_port;
+               /*
+                * On BXT A0/A1, sw needs to activate DDIA HPD logic and
+                * interrupts to check the external panel connection.
+                */
+               if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)
+                                        && port == PORT_B)
+                       dev_priv->hotplug.irq_port[PORT_A] = intel_dig_port;
+               else
+                       dev_priv->hotplug.irq_port[port] = intel_dig_port;
        }
 
        /* In theory we don't need the encoder->type check, but leave it just in
This page took 0.028954 seconds and 5 git commands to generate.