diff options
Diffstat (limited to 'drivers/gpu/drm/i915/intel_ddi.c')
-rw-r--r-- | drivers/gpu/drm/i915/intel_ddi.c | 274 |
1 files changed, 150 insertions, 124 deletions
diff --git a/drivers/gpu/drm/i915/intel_ddi.c b/drivers/gpu/drm/i915/intel_ddi.c index 01e523df363b..dd1d6fe12297 100644 --- a/drivers/gpu/drm/i915/intel_ddi.c +++ b/drivers/gpu/drm/i915/intel_ddi.c @@ -318,7 +318,7 @@ static void ddi_get_encoder_port(struct intel_encoder *intel_encoder, default: WARN(1, "Invalid DDI encoder type %d\n", intel_encoder->type); /* fallthrough and treat as unknown */ - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_EDP: case INTEL_OUTPUT_HDMI: case INTEL_OUTPUT_UNKNOWN: @@ -482,7 +482,7 @@ void intel_prepare_ddi_buffer(struct intel_encoder *encoder) ddi_translations = ddi_translations_edp; size = n_edp_entries; break; - case INTEL_OUTPUT_DISPLAYPORT: + case INTEL_OUTPUT_DP: case INTEL_OUTPUT_HDMI: ddi_translations = ddi_translations_dp; size = n_dp_entries; @@ -543,7 +543,7 @@ static void intel_wait_ddi_buf_idle(struct drm_i915_private *dev_priv, void hsw_fdi_link_train(struct drm_crtc *crtc) { struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *encoder; u32 temp, i, rx_ctl_val; @@ -834,7 +834,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) if (pipe_config->has_pch_encoder) dotclock = intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->fdi_m_n); - else if (pipe_config->has_dp_encoder) + else if (intel_crtc_has_dp_encoder(pipe_config)) dotclock = intel_dotclock_calculate(pipe_config->port_clock, &pipe_config->dp_m_n); else if (pipe_config->has_hdmi_sink && pipe_config->pipe_bpp == 36) @@ -851,7 +851,7 @@ static void ddi_dotclock_get(struct intel_crtc_state *pipe_config) static void skl_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; uint32_t dpll_ctl1, dpll; @@ -899,7 +899,7 @@ static void skl_ddi_clock_get(struct intel_encoder *encoder, static void hsw_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int link_clock = 0; u32 val, pll; @@ -948,7 +948,7 @@ static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, { struct intel_shared_dpll *pll; struct intel_dpll_hw_state *state; - intel_clock_t clock; + struct dpll clock; /* For DDI ports we always use a shared PLL. */ if (WARN_ON(dpll == DPLL_ID_PRIVATE)) @@ -971,7 +971,7 @@ static int bxt_calc_pll_link(struct drm_i915_private *dev_priv, static void bxt_ddi_clock_get(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); enum port port = intel_ddi_get_encoder_port(encoder); uint32_t dpll = port; @@ -1061,14 +1061,14 @@ bool intel_ddi_pll_select(struct intel_crtc *intel_crtc, void intel_ddi_set_pipe_settings(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; int type = intel_encoder->type; uint32_t temp; - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP || type == INTEL_OUTPUT_DP_MST) { WARN_ON(transcoder_is_dsi(cpu_transcoder)); temp = TRANS_MSA_SYNC_CLK; @@ -1096,7 +1096,7 @@ void intel_ddi_set_vc_payload_alloc(struct drm_crtc *crtc, bool state) { struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; uint32_t temp; temp = I915_READ(TRANS_DDI_FUNC_CTL(cpu_transcoder)); @@ -1113,7 +1113,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum pipe pipe = intel_crtc->pipe; enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; enum port port = intel_ddi_get_encoder_port(intel_encoder); @@ -1182,7 +1182,7 @@ void intel_ddi_enable_transcoder_func(struct drm_crtc *crtc) temp |= TRANS_DDI_MODE_SELECT_FDI; temp |= (intel_crtc->config->fdi_lanes - 1) << 1; - } else if (type == INTEL_OUTPUT_DISPLAYPORT || + } else if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); @@ -1223,7 +1223,7 @@ void intel_ddi_disable_transcoder_func(struct drm_i915_private *dev_priv, bool intel_ddi_connector_get_hw_state(struct intel_connector *intel_connector) { struct drm_device *dev = intel_connector->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder = intel_connector->encoder; int type = intel_connector->base.connector_type; enum port port = intel_ddi_get_encoder_port(intel_encoder); @@ -1285,7 +1285,7 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, enum pipe *pipe) { struct drm_device *dev = encoder->base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(encoder); enum intel_display_power_domain power_domain; u32 tmp; @@ -1342,6 +1342,14 @@ bool intel_ddi_get_hw_state(struct intel_encoder *encoder, DRM_DEBUG_KMS("No pipe for ddi port %c found\n", port_name(port)); out: + if (ret && IS_BROXTON(dev_priv)) { + tmp = I915_READ(BXT_PHY_CTL(port)); + if ((tmp & (BXT_PHY_LANE_POWERDOWN_ACK | + BXT_PHY_LANE_ENABLED)) != BXT_PHY_LANE_ENABLED) + DRM_ERROR("Port %c enabled but PHY powered down? " + "(PHY_CTL %08x)\n", port_name(port), tmp); + } + intel_display_power_put(dev_priv, power_domain); return ret; @@ -1351,7 +1359,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) { struct drm_crtc *crtc = &intel_crtc->base; struct drm_device *dev = crtc->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); enum port port = intel_ddi_get_encoder_port(intel_encoder); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; @@ -1363,7 +1371,7 @@ void intel_ddi_enable_pipe_clock(struct intel_crtc *intel_crtc) void intel_ddi_disable_pipe_clock(struct intel_crtc *intel_crtc) { - struct drm_i915_private *dev_priv = intel_crtc->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(intel_crtc->base.dev); enum transcoder cpu_transcoder = intel_crtc->config->cpu_transcoder; if (cpu_transcoder != TRANSCODER_EDP) @@ -1384,7 +1392,7 @@ static void skl_ddi_set_iboost(struct drm_i915_private *dev_priv, 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) { + if (type == INTEL_OUTPUT_DP) { if (dp_iboost) { iboost = dp_iboost; } else { @@ -1442,7 +1450,7 @@ static void bxt_ddi_vswing_sequence(struct drm_i915_private *dev_priv, if (type == INTEL_OUTPUT_EDP && dev_priv->vbt.edp.low_vswing) { n_entries = ARRAY_SIZE(bxt_ddi_translations_edp); ddi_translations = bxt_ddi_translations_edp; - } else if (type == INTEL_OUTPUT_DISPLAYPORT + } else if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { n_entries = ARRAY_SIZE(bxt_ddi_translations_dp); ddi_translations = bxt_ddi_translations_dp; @@ -1616,7 +1624,7 @@ static void intel_ddi_pre_enable(struct intel_encoder *intel_encoder) intel_ddi_clk_select(intel_encoder, crtc->config); - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_dp_set_link_params(intel_dp, crtc->config); @@ -1640,7 +1648,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) { struct drm_encoder *encoder = &intel_encoder->base; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; uint32_t val; @@ -1661,7 +1669,7 @@ static void intel_ddi_post_disable(struct intel_encoder *intel_encoder) if (wait) intel_wait_ddi_buf_idle(dev_priv, port); - if (type == INTEL_OUTPUT_DISPLAYPORT || type == INTEL_OUTPUT_EDP) { + if (type == INTEL_OUTPUT_DP || type == INTEL_OUTPUT_EDP) { struct intel_dp *intel_dp = enc_to_intel_dp(encoder); intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_OFF); intel_edp_panel_vdd_on(intel_dp); @@ -1687,7 +1695,7 @@ static void intel_enable_ddi(struct intel_encoder *intel_encoder) struct drm_crtc *crtc = encoder->crtc; struct intel_crtc *intel_crtc = to_intel_crtc(crtc); struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); enum port port = intel_ddi_get_encoder_port(intel_encoder); int type = intel_encoder->type; @@ -1726,7 +1734,7 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) struct intel_crtc *intel_crtc = to_intel_crtc(crtc); int type = intel_encoder->type; struct drm_device *dev = encoder->dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); if (intel_crtc->config->has_audio) { intel_audio_codec_disable(intel_encoder); @@ -1742,9 +1750,11 @@ static void intel_disable_ddi(struct intel_encoder *intel_encoder) } } -static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv, - enum dpio_phy phy) +bool bxt_ddi_phy_is_enabled(struct drm_i915_private *dev_priv, + enum dpio_phy phy) { + enum port port; + if (!(I915_READ(BXT_P_CR_GT_DISP_PWRON) & GT_DISPLAY_POWER_ON(phy))) return false; @@ -1770,38 +1780,51 @@ static bool broxton_phy_is_enabled(struct drm_i915_private *dev_priv, return false; } + for_each_port_masked(port, + phy == DPIO_PHY0 ? BIT(PORT_B) | BIT(PORT_C) : + BIT(PORT_A)) { + u32 tmp = I915_READ(BXT_PHY_CTL(port)); + + if (tmp & BXT_PHY_CMNLANE_POWERDOWN_ACK) { + DRM_DEBUG_DRIVER("DDI PHY %d powered, but common lane " + "for port %c powered down " + "(PHY_CTL %08x)\n", + phy, port_name(port), tmp); + + return false; + } + } + return true; } -static u32 broxton_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy) +static u32 bxt_get_grc(struct drm_i915_private *dev_priv, enum dpio_phy phy) { u32 val = I915_READ(BXT_PORT_REF_DW6(phy)); return (val & GRC_CODE_MASK) >> GRC_CODE_SHIFT; } -static void broxton_phy_wait_grc_done(struct drm_i915_private *dev_priv, - enum dpio_phy phy) +static void bxt_phy_wait_grc_done(struct drm_i915_private *dev_priv, + enum dpio_phy phy) { - if (wait_for(I915_READ(BXT_PORT_REF_DW3(phy)) & GRC_DONE, 10)) + if (intel_wait_for_register(dev_priv, + BXT_PORT_REF_DW3(phy), + GRC_DONE, GRC_DONE, + 10)) DRM_ERROR("timeout waiting for PHY%d GRC\n", phy); } -static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, - enum dpio_phy phy); - -static void broxton_phy_init(struct drm_i915_private *dev_priv, - enum dpio_phy phy) +void bxt_ddi_phy_init(struct drm_i915_private *dev_priv, enum dpio_phy phy) { - enum port port; - u32 ports, val; + u32 val; - if (broxton_phy_is_enabled(dev_priv, phy)) { + if (bxt_ddi_phy_is_enabled(dev_priv, phy)) { /* Still read out the GRC value for state verification */ if (phy == DPIO_PHY0) - dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, phy); + dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, phy); - if (broxton_phy_verify_state(dev_priv, phy)) { + if (bxt_ddi_phy_verify_state(dev_priv, phy)) { DRM_DEBUG_DRIVER("DDI PHY %d already enabled, " "won't reprogram it\n", phy); @@ -1810,8 +1833,6 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, DRM_DEBUG_DRIVER("DDI PHY %d enabled with invalid state, " "force reprogramming it\n", phy); - } else { - DRM_DEBUG_DRIVER("DDI PHY %d not enabled, enabling it\n", phy); } val = I915_READ(BXT_P_CR_GT_DISP_PWRON); @@ -1831,28 +1852,6 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, DRM_ERROR("timeout during PHY%d power on\n", phy); } - if (phy == DPIO_PHY0) - ports = BIT(PORT_B) | BIT(PORT_C); - else - ports = BIT(PORT_A); - - for_each_port_masked(port, ports) { - int lane; - - for (lane = 0; lane < 4; lane++) { - val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane)); - /* - * Note that on CHV this flag is called UPAR, but has - * the same function. - */ - val &= ~LATENCY_OPTIM; - if (lane != 1) - val |= LATENCY_OPTIM; - - I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val); - } - } - /* Program PLL Rcomp code offset */ val = I915_READ(BXT_PORT_CL1CM_DW9(phy)); val &= ~IREF0RC_OFFSET_MASK; @@ -1899,10 +1898,7 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, * the corresponding calibrated value from PHY1, and disable * the automatic calibration on PHY0. */ - broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1); - - val = dev_priv->bxt_phy_grc = broxton_get_grc(dev_priv, - DPIO_PHY1); + val = dev_priv->bxt_phy_grc = bxt_get_grc(dev_priv, DPIO_PHY1); grc_code = val << GRC_CODE_FAST_SHIFT | val << GRC_CODE_SLOW_SHIFT | val; @@ -1912,31 +1908,16 @@ static void broxton_phy_init(struct drm_i915_private *dev_priv, val |= GRC_DIS | GRC_RDY_OVRD; I915_WRITE(BXT_PORT_REF_DW8(DPIO_PHY0), val); } - /* - * During PHY1 init delay waiting for GRC calibration to finish, since - * it can happen in parallel with the subsequent PHY0 init. - */ val = I915_READ(BXT_PHY_CTL_FAMILY(phy)); val |= COMMON_RESET_DIS; I915_WRITE(BXT_PHY_CTL_FAMILY(phy), val); -} - -void broxton_ddi_phy_init(struct drm_i915_private *dev_priv) -{ - /* Enable PHY1 first since it provides Rcomp for PHY0 */ - broxton_phy_init(dev_priv, DPIO_PHY1); - broxton_phy_init(dev_priv, DPIO_PHY0); - /* - * If BIOS enabled only PHY0 and not PHY1, we skipped waiting for the - * PHY1 GRC calibration to finish, so wait for it here. - */ - broxton_phy_wait_grc_done(dev_priv, DPIO_PHY1); + if (phy == DPIO_PHY1) + bxt_phy_wait_grc_done(dev_priv, DPIO_PHY1); } -static void broxton_phy_uninit(struct drm_i915_private *dev_priv, - enum dpio_phy phy) +void bxt_ddi_phy_uninit(struct drm_i915_private *dev_priv, enum dpio_phy phy) { uint32_t val; @@ -1949,12 +1930,6 @@ static void broxton_phy_uninit(struct drm_i915_private *dev_priv, I915_WRITE(BXT_P_CR_GT_DISP_PWRON, val); } -void broxton_ddi_phy_uninit(struct drm_i915_private *dev_priv) -{ - broxton_phy_uninit(dev_priv, DPIO_PHY1); - broxton_phy_uninit(dev_priv, DPIO_PHY0); -} - static bool __printf(6, 7) __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, i915_reg_t reg, u32 mask, u32 expected, @@ -1982,11 +1957,9 @@ __phy_reg_verify_state(struct drm_i915_private *dev_priv, enum dpio_phy phy, return false; } -static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, - enum dpio_phy phy) +bool bxt_ddi_phy_verify_state(struct drm_i915_private *dev_priv, + enum dpio_phy phy) { - enum port port; - u32 ports; uint32_t mask; bool ok; @@ -1994,27 +1967,11 @@ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, __phy_reg_verify_state(dev_priv, phy, reg, mask, exp, fmt, \ ## __VA_ARGS__) - /* We expect the PHY to be always enabled */ - if (!broxton_phy_is_enabled(dev_priv, phy)) + if (!bxt_ddi_phy_is_enabled(dev_priv, phy)) return false; ok = true; - if (phy == DPIO_PHY0) - ports = BIT(PORT_B) | BIT(PORT_C); - else - ports = BIT(PORT_A); - - for_each_port_masked(port, ports) { - int lane; - - for (lane = 0; lane < 4; lane++) - ok &= _CHK(BXT_PORT_TX_DW14_LN(port, lane), - LATENCY_OPTIM, - lane != 1 ? LATENCY_OPTIM : 0, - "BXT_PORT_TX_DW14_LN(%d, %d)", port, lane); - } - /* PLL Rcomp code offset */ ok &= _CHK(BXT_PORT_CL1CM_DW9(phy), IREF0RC_OFFSET_MASK, 0xe4 << IREF0RC_OFFSET_SHIFT, @@ -2058,11 +2015,65 @@ static bool broxton_phy_verify_state(struct drm_i915_private *dev_priv, #undef _CHK } -void broxton_ddi_phy_verify_state(struct drm_i915_private *dev_priv) +static uint8_t +bxt_ddi_phy_calc_lane_lat_optim_mask(struct intel_encoder *encoder, + struct intel_crtc_state *pipe_config) { - if (!broxton_phy_verify_state(dev_priv, DPIO_PHY0) || - !broxton_phy_verify_state(dev_priv, DPIO_PHY1)) - i915_report_error(dev_priv, "DDI PHY state mismatch\n"); + switch (pipe_config->lane_count) { + case 1: + return 0; + case 2: + return BIT(2) | BIT(0); + case 4: + return BIT(3) | BIT(2) | BIT(0); + default: + MISSING_CASE(pipe_config->lane_count); + + return 0; + } +} + +static void bxt_ddi_pre_pll_enable(struct intel_encoder *encoder) +{ + struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); + struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); + enum port port = dport->port; + struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); + int lane; + + for (lane = 0; lane < 4; lane++) { + u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane)); + + /* + * Note that on CHV this flag is called UPAR, but has + * the same function. + */ + val &= ~LATENCY_OPTIM; + if (intel_crtc->config->lane_lat_optim_mask & BIT(lane)) + val |= LATENCY_OPTIM; + + I915_WRITE(BXT_PORT_TX_DW14_LN(port, lane), val); + } +} + +static uint8_t +bxt_ddi_phy_get_lane_lat_optim_mask(struct intel_encoder *encoder) +{ + struct intel_digital_port *dport = enc_to_dig_port(&encoder->base); + struct drm_i915_private *dev_priv = to_i915(dport->base.base.dev); + enum port port = dport->port; + int lane; + uint8_t mask; + + mask = 0; + for (lane = 0; lane < 4; lane++) { + u32 val = I915_READ(BXT_PORT_TX_DW14_LN(port, lane)); + + if (val & LATENCY_OPTIM) + mask |= BIT(lane); + } + + return mask; } void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) @@ -2113,7 +2124,7 @@ void intel_ddi_prepare_link_retrain(struct intel_dp *intel_dp) void intel_ddi_fdi_disable(struct drm_crtc *crtc) { - struct drm_i915_private *dev_priv = crtc->dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(crtc->dev); struct intel_encoder *intel_encoder = intel_ddi_get_crtc_encoder(crtc); uint32_t val; @@ -2146,7 +2157,7 @@ void intel_ddi_fdi_disable(struct drm_crtc *crtc) void intel_ddi_get_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { - struct drm_i915_private *dev_priv = encoder->base.dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_crtc *intel_crtc = to_intel_crtc(encoder->base.crtc); enum transcoder cpu_transcoder = pipe_config->cpu_transcoder; struct intel_hdmi *intel_hdmi; @@ -2200,7 +2211,6 @@ void intel_ddi_get_config(struct intel_encoder *encoder, break; 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); @@ -2236,13 +2246,19 @@ void intel_ddi_get_config(struct intel_encoder *encoder, } intel_ddi_clock_get(encoder, pipe_config); + + if (IS_BROXTON(dev_priv)) + pipe_config->lane_lat_optim_mask = + bxt_ddi_phy_get_lane_lat_optim_mask(encoder); } static bool intel_ddi_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) { + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); int type = encoder->type; int port = intel_ddi_get_encoder_port(encoder); + int ret; WARN(type == INTEL_OUTPUT_UNKNOWN, "compute_config() on unknown output!\n"); @@ -2250,9 +2266,17 @@ static bool intel_ddi_compute_config(struct intel_encoder *encoder, pipe_config->cpu_transcoder = TRANSCODER_EDP; if (type == INTEL_OUTPUT_HDMI) - return intel_hdmi_compute_config(encoder, pipe_config); + ret = intel_hdmi_compute_config(encoder, pipe_config); else - return intel_dp_compute_config(encoder, pipe_config); + ret = intel_dp_compute_config(encoder, pipe_config); + + if (IS_BROXTON(dev_priv) && ret) + pipe_config->lane_lat_optim_mask = + bxt_ddi_phy_calc_lane_lat_optim_mask(encoder, + pipe_config); + + return ret; + } static const struct drm_encoder_funcs intel_ddi_funcs = { @@ -2297,7 +2321,7 @@ intel_ddi_init_hdmi_connector(struct intel_digital_port *intel_dig_port) void intel_ddi_init(struct drm_device *dev, enum port port) { - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = to_i915(dev); struct intel_digital_port *intel_dig_port; struct intel_encoder *intel_encoder; struct drm_encoder *encoder; @@ -2347,10 +2371,12 @@ void intel_ddi_init(struct drm_device *dev, enum port port) encoder = &intel_encoder->base; drm_encoder_init(dev, encoder, &intel_ddi_funcs, - DRM_MODE_ENCODER_TMDS, NULL); + DRM_MODE_ENCODER_TMDS, "DDI %c", port_name(port)); intel_encoder->compute_config = intel_ddi_compute_config; intel_encoder->enable = intel_enable_ddi; + if (IS_BROXTON(dev_priv)) + intel_encoder->pre_pll_enable = bxt_ddi_pre_pll_enable; intel_encoder->pre_enable = intel_ddi_pre_enable; intel_encoder->disable = intel_disable_ddi; intel_encoder->post_disable = intel_ddi_post_disable; |