From b4b7ff4b08e691656c9d77c758fc355833128ac0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Fabian=20Silva=20Delgado?= Date: Wed, 20 Jan 2016 14:01:31 -0300 Subject: Linux-libre 4.4-gnu --- drivers/gpu/drm/i915/intel_dp.c | 889 +++++++++++++++++++++++++--------------- 1 file changed, 556 insertions(+), 333 deletions(-) (limited to 'drivers/gpu/drm/i915/intel_dp.c') diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a2e33fbf..78b8ec84d 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c @@ -130,6 +130,11 @@ static void vlv_init_panel_power_sequencer(struct intel_dp *intel_dp); static void vlv_steal_power_sequencer(struct drm_device *dev, enum pipe pipe); +static unsigned int intel_dp_unused_lane_mask(int lane_count) +{ + return ~((1 << lane_count) - 1) & 0xf; +} + static int intel_dp_max_link_bw(struct intel_dp *intel_dp) { @@ -253,40 +258,6 @@ static void intel_dp_unpack_aux(uint32_t src, uint8_t *dst, int dst_bytes) dst[i] = src >> ((3-i) * 8); } -/* hrawclock is 1/4 the FSB frequency */ -static int -intel_hrawclk(struct drm_device *dev) -{ - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t clkcfg; - - /* There is no CLKCFG reg in Valleyview. VLV hrawclk is 200 MHz */ - if (IS_VALLEYVIEW(dev)) - return 200; - - clkcfg = I915_READ(CLKCFG); - switch (clkcfg & CLKCFG_FSB_MASK) { - case CLKCFG_FSB_400: - return 100; - case CLKCFG_FSB_533: - return 133; - case CLKCFG_FSB_667: - return 166; - case CLKCFG_FSB_800: - return 200; - case CLKCFG_FSB_1067: - return 266; - case CLKCFG_FSB_1333: - return 333; - /* these two are just a guess; one of them might be right */ - case CLKCFG_FSB_1600: - case CLKCFG_FSB_1600_ALT: - return 400; - default: - return 133; - } -} - static void intel_dp_init_panel_power_sequencer(struct drm_device *dev, struct intel_dp *intel_dp); @@ -306,7 +277,7 @@ static void pps_lock(struct intel_dp *intel_dp) * See vlv_power_sequencer_reset() why we need * a power domain reference here. */ - power_domain = intel_display_port_power_domain(encoder); + power_domain = intel_display_port_aux_power_domain(encoder); intel_display_power_get(dev_priv, power_domain); mutex_lock(&dev_priv->pps_mutex); @@ -322,7 +293,7 @@ static void pps_unlock(struct intel_dp *intel_dp) mutex_unlock(&dev_priv->pps_mutex); - power_domain = intel_display_port_power_domain(encoder); + power_domain = intel_display_port_aux_power_domain(encoder); intel_display_power_put(dev_priv, power_domain); } @@ -333,7 +304,9 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) struct drm_device *dev = intel_dig_port->base.base.dev; struct drm_i915_private *dev_priv = dev->dev_private; enum pipe pipe = intel_dp->pps_pipe; - bool pll_enabled; + bool pll_enabled, release_cl_override = false; + enum dpio_phy phy = DPIO_PHY(pipe); + enum dpio_channel ch = vlv_pipe_to_channel(pipe); uint32_t DP; if (WARN(I915_READ(intel_dp->output_reg) & DP_PORT_EN, @@ -363,9 +336,13 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) * The DPLL for the pipe must be enabled for this to work. * So enable temporarily it if it's not already enabled. */ - if (!pll_enabled) + if (!pll_enabled) { + release_cl_override = IS_CHERRYVIEW(dev) && + !chv_phy_powergate_ch(dev_priv, phy, ch, true); + vlv_force_pll_on(dev, pipe, IS_CHERRYVIEW(dev) ? &chv_dpll[0].dpll : &vlv_dpll[0].dpll); + } /* * Similar magic as in intel_dp_enable_port(). @@ -382,8 +359,12 @@ vlv_power_sequencer_kick(struct intel_dp *intel_dp) I915_WRITE(intel_dp->output_reg, DP & ~DP_PORT_EN); POSTING_READ(intel_dp->output_reg); - if (!pll_enabled) + if (!pll_enabled) { vlv_force_pll_off(dev, pipe); + + if (release_cl_override) + chv_phy_powergate_ch(dev_priv, phy, ch, false); + } } static enum pipe @@ -593,8 +574,6 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, edp_notifier); struct drm_device *dev = intel_dp_to_dev(intel_dp); struct drm_i915_private *dev_priv = dev->dev_private; - u32 pp_div; - u32 pp_ctrl_reg, pp_div_reg; if (!is_edp(intel_dp) || code != SYS_RESTART) return 0; @@ -603,6 +582,8 @@ static int edp_notify_handler(struct notifier_block *this, unsigned long code, if (IS_VALLEYVIEW(dev)) { enum pipe pipe = vlv_power_sequencer_pipe(intel_dp); + u32 pp_ctrl_reg, pp_div_reg; + u32 pp_div; pp_ctrl_reg = VLV_PIPE_PP_CONTROL(pipe); pp_div_reg = VLV_PIPE_PP_DIVISOR(pipe); @@ -835,8 +816,6 @@ intel_dp_aux_ch(struct intel_dp *intel_dp, intel_dp_check_edp(intel_dp); - intel_aux_display_runtime_get(dev_priv); - /* Try to wait for any previous AUX channel activity */ for (try = 0; try < 3; try++) { status = I915_READ_NOTRACE(ch_ctl); @@ -945,7 +924,6 @@ done: ret = recv_bytes; out: pm_qos_update_request(&dev_priv->pm_qos, PM_QOS_DEFAULT_VALUE); - intel_aux_display_runtime_put(dev_priv); if (vdd) edp_panel_vdd_off(intel_dp, false); @@ -974,6 +952,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) switch (msg->request & ~DP_AUX_I2C_MOT) { case DP_AUX_NATIVE_WRITE: case DP_AUX_I2C_WRITE: + case DP_AUX_I2C_WRITE_STATUS_UPDATE: txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE; rxsize = 2; /* 0 or 1 data bytes */ @@ -1383,6 +1362,19 @@ int intel_dp_rate_select(struct intel_dp *intel_dp, int rate) return rate_to_index(rate, intel_dp->sink_rates); } +static void intel_dp_compute_rate(struct intel_dp *intel_dp, int port_clock, + uint8_t *link_bw, uint8_t *rate_select) +{ + if (intel_dp->num_sink_rates) { + *link_bw = 0; + *rate_select = + intel_dp_rate_select(intel_dp, port_clock); + } else { + *link_bw = drm_dp_link_rate_to_bw_code(port_clock); + *rate_select = 0; + } +} + bool intel_dp_compute_config(struct intel_encoder *encoder, struct intel_crtc_state *pipe_config) @@ -1404,6 +1396,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, int link_avail, link_clock; int common_rates[DP_MAX_SUPPORTED_RATES] = {}; int common_len; + uint8_t link_bw, rate_select; common_len = intel_dp_common_rates(intel_dp, common_rates); @@ -1499,32 +1492,23 @@ found: * CEA-861-E - 5.1 Default Encoding Parameters * VESA DisplayPort Ver.1.2a - 5.1.1.1 Video Colorimetry */ - if (bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1) - intel_dp->color_range = DP_COLOR_RANGE_16_235; - else - intel_dp->color_range = 0; - } - - if (intel_dp->color_range) - pipe_config->limited_color_range = true; - - intel_dp->lane_count = lane_count; - - if (intel_dp->num_sink_rates) { - intel_dp->link_bw = 0; - intel_dp->rate_select = - intel_dp_rate_select(intel_dp, common_rates[clock]); + pipe_config->limited_color_range = + bpp != 18 && drm_match_cea_mode(adjusted_mode) > 1; } else { - intel_dp->link_bw = - drm_dp_link_rate_to_bw_code(common_rates[clock]); - intel_dp->rate_select = 0; + pipe_config->limited_color_range = + intel_dp->limited_color_range; } + pipe_config->lane_count = lane_count; + pipe_config->pipe_bpp = bpp; pipe_config->port_clock = common_rates[clock]; - DRM_DEBUG_KMS("DP link bw %02x lane count %d clock %d bpp %d\n", - intel_dp->link_bw, intel_dp->lane_count, + intel_dp_compute_rate(intel_dp, pipe_config->port_clock, + &link_bw, &rate_select); + + DRM_DEBUG_KMS("DP link bw %02x rate select %02x lane count %d clock %d bpp %d\n", + link_bw, rate_select, pipe_config->lane_count, pipe_config->port_clock, bpp); DRM_DEBUG_KMS("DP link bw required %i available %i\n", mode_rate, link_avail); @@ -1586,6 +1570,13 @@ static void ironlake_set_pll_cpu_edp(struct intel_dp *intel_dp) udelay(500); } +void intel_dp_set_link_params(struct intel_dp *intel_dp, + const struct intel_crtc_state *pipe_config) +{ + intel_dp->link_rate = pipe_config->port_clock; + intel_dp->lane_count = pipe_config->lane_count; +} + static void intel_dp_prepare(struct intel_encoder *encoder) { struct drm_device *dev = encoder->base.dev; @@ -1593,7 +1584,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder) struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); enum port port = dp_to_dig_port(intel_dp)->port; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); - struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; + const struct drm_display_mode *adjusted_mode = &crtc->config->base.adjusted_mode; + + intel_dp_set_link_params(intel_dp, crtc->config); /* * There are four kinds of DP registers: @@ -1619,7 +1612,7 @@ static void intel_dp_prepare(struct intel_encoder *encoder) /* Handle DP bits in common between all three register formats */ intel_dp->DP |= DP_VOLTAGE_0_4 | DP_PRE_EMPHASIS_0; - intel_dp->DP |= DP_PORT_WIDTH(intel_dp->lane_count); + intel_dp->DP |= DP_PORT_WIDTH(crtc->config->lane_count); if (crtc->config->has_audio) intel_dp->DP |= DP_AUDIO_OUTPUT_ENABLE; @@ -1649,8 +1642,9 @@ static void intel_dp_prepare(struct intel_encoder *encoder) trans_dp &= ~TRANS_DP_ENH_FRAMING; I915_WRITE(TRANS_DP_CTL(crtc->pipe), trans_dp); } else { - if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev)) - intel_dp->DP |= intel_dp->color_range; + if (!HAS_PCH_SPLIT(dev) && !IS_VALLEYVIEW(dev) && + crtc->config->limited_color_range) + intel_dp->DP |= DP_COLOR_RANGE_16_235; if (adjusted_mode->flags & DRM_MODE_FLAG_PHSYNC) intel_dp->DP |= DP_SYNC_HS_HIGH; @@ -1787,7 +1781,7 @@ static bool edp_panel_vdd_on(struct intel_dp *intel_dp) if (edp_have_panel_vdd(intel_dp)) return need_to_disable; - power_domain = intel_display_port_power_domain(intel_encoder); + power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); DRM_DEBUG_KMS("Turning eDP port %c VDD on\n", @@ -1877,7 +1871,7 @@ static void edp_panel_vdd_off_sync(struct intel_dp *intel_dp) if ((pp & POWER_TARGET_ON) == 0) intel_dp->last_power_cycle = jiffies; - power_domain = intel_display_port_power_domain(intel_encoder); + power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_put(dev_priv, power_domain); } @@ -2028,7 +2022,7 @@ static void edp_panel_off(struct intel_dp *intel_dp) wait_panel_off(intel_dp); /* We got a reference when we enabled the VDD. */ - power_domain = intel_display_port_power_domain(intel_encoder); + power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_put(dev_priv, power_domain); } @@ -2290,13 +2284,14 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->has_audio = tmp & DP_AUDIO_OUTPUT_ENABLE && port != PORT_A; if (HAS_PCH_CPT(dev) && port != PORT_A) { - tmp = I915_READ(TRANS_DP_CTL(crtc->pipe)); - if (tmp & TRANS_DP_HSYNC_ACTIVE_HIGH) + u32 trans_dp = I915_READ(TRANS_DP_CTL(crtc->pipe)); + + if (trans_dp & TRANS_DP_HSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PHSYNC; else flags |= DRM_MODE_FLAG_NHSYNC; - if (tmp & TRANS_DP_VSYNC_ACTIVE_HIGH) + if (trans_dp & TRANS_DP_VSYNC_ACTIVE_HIGH) flags |= DRM_MODE_FLAG_PVSYNC; else flags |= DRM_MODE_FLAG_NVSYNC; @@ -2320,6 +2315,9 @@ static void intel_dp_get_config(struct intel_encoder *encoder, pipe_config->has_dp_encoder = true; + pipe_config->lane_count = + ((tmp & DP_PORT_WIDTH_MASK) >> DP_PORT_WIDTH_SHIFT) + 1; + intel_dp_get_m_n(crtc, pipe_config); if (port == PORT_A) { @@ -2399,38 +2397,62 @@ static void vlv_post_disable_dp(struct intel_encoder *encoder) intel_dp_link_down(intel_dp); } -static void chv_post_disable_dp(struct intel_encoder *encoder) +static void chv_data_lane_soft_reset(struct intel_encoder *encoder, + bool reset) { - struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); - struct intel_digital_port *dport = dp_to_dig_port(intel_dp); - 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); - enum dpio_channel ch = vlv_dport_to_channel(dport); - enum pipe pipe = intel_crtc->pipe; - u32 val; + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum dpio_channel ch = vlv_dport_to_channel(enc_to_dig_port(&encoder->base)); + struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); + enum pipe pipe = crtc->pipe; + uint32_t val; - intel_dp_link_down(intel_dp); + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch)); + if (reset) + val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); + else + val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET; + vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val); - mutex_lock(&dev_priv->sb_lock); + if (crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch)); + if (reset) + val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); + else + val |= DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val); + } - /* Propagate soft reset to data lane reset */ val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch)); val |= CHV_PCS_REQ_SOFTRESET_EN; + if (reset) + val &= ~DPIO_PCS_CLK_SOFT_RESET; + else + val |= DPIO_PCS_CLK_SOFT_RESET; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch)); - val |= CHV_PCS_REQ_SOFTRESET_EN; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val); + if (crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch)); + val |= CHV_PCS_REQ_SOFTRESET_EN; + if (reset) + val &= ~DPIO_PCS_CLK_SOFT_RESET; + else + val |= DPIO_PCS_CLK_SOFT_RESET; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val); + } +} - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch)); - val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); - vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val); +static void chv_post_disable_dp(struct intel_encoder *encoder) +{ + struct intel_dp *intel_dp = enc_to_intel_dp(&encoder->base); + struct drm_device *dev = encoder->base.dev; + struct drm_i915_private *dev_priv = dev->dev_private; + + intel_dp_link_down(intel_dp); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch)); - val &= ~(DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val); + mutex_lock(&dev_priv->sb_lock); + + /* Assert data lane reset */ + chv_data_lane_soft_reset(encoder, true); mutex_unlock(&dev_priv->sb_lock); } @@ -2550,7 +2572,6 @@ static void intel_enable_dp(struct intel_encoder *encoder) struct drm_i915_private *dev_priv = dev->dev_private; struct intel_crtc *crtc = to_intel_crtc(encoder->base.crtc); uint32_t dp_reg = I915_READ(intel_dp->output_reg); - unsigned int lane_mask = 0x0; if (WARN_ON(dp_reg & DP_PORT_EN)) return; @@ -2568,13 +2589,18 @@ static void intel_enable_dp(struct intel_encoder *encoder) pps_unlock(intel_dp); - if (IS_VALLEYVIEW(dev)) + if (IS_VALLEYVIEW(dev)) { + unsigned int lane_mask = 0x0; + + if (IS_CHERRYVIEW(dev)) + lane_mask = intel_dp_unused_lane_mask(crtc->config->lane_count); + vlv_wait_port_ready(dev_priv, dp_to_dig_port(intel_dp), lane_mask); + } intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); intel_dp_start_link_train(intel_dp); - intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); if (crtc->config->has_audio) { @@ -2797,31 +2823,19 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) val &= ~DPIO_LANEDESKEW_STRAP_OVRD; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); - val &= ~DPIO_LANEDESKEW_STRAP_OVRD; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); - - /* Deassert soft data lane reset*/ - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW1(ch)); - val |= CHV_PCS_REQ_SOFTRESET_EN; - vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW1(ch), val); - - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW1(ch)); - val |= CHV_PCS_REQ_SOFTRESET_EN; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW1(ch), val); - - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW0(ch)); - val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); - vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW0(ch), val); - - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW0(ch)); - val |= (DPIO_PCS_TX_LANE2_RESET | DPIO_PCS_TX_LANE1_RESET); - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW0(ch), val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); + val &= ~DPIO_LANEDESKEW_STRAP_OVRD; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); + } /* Program Tx lane latency optimal setting*/ - for (i = 0; i < 4; i++) { + for (i = 0; i < intel_crtc->config->lane_count; i++) { /* Set the upar bit */ - data = (i == 1) ? 0x0 : 0x1; + if (intel_crtc->config->lane_count == 1) + data = 0x0; + else + data = (i == 1) ? 0x0 : 0x1; vlv_dpio_write(dev_priv, pipe, CHV_TX_DW14(ch, i), data << DPIO_UPAR_SHIFT); } @@ -2842,9 +2856,11 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) val |= DPIO_TX2_STAGGER_MASK(0x1f); vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW11(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); - val |= DPIO_TX2_STAGGER_MASK(0x1f); - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW11(ch)); + val |= DPIO_TX2_STAGGER_MASK(0x1f); + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW11(ch), val); + } vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW12(ch), DPIO_LANESTAGGER_STRAP(stagger) | @@ -2853,16 +2869,27 @@ static void chv_pre_enable_dp(struct intel_encoder *encoder) DPIO_TX1_STAGGER_MULT(6) | DPIO_TX2_STAGGER_MULT(0)); - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch), - DPIO_LANESTAGGER_STRAP(stagger) | - DPIO_LANESTAGGER_STRAP_OVRD | - DPIO_TX1_STAGGER_MASK(0x1f) | - DPIO_TX1_STAGGER_MULT(7) | - DPIO_TX2_STAGGER_MULT(5)); + if (intel_crtc->config->lane_count > 2) { + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW12(ch), + DPIO_LANESTAGGER_STRAP(stagger) | + DPIO_LANESTAGGER_STRAP_OVRD | + DPIO_TX1_STAGGER_MASK(0x1f) | + DPIO_TX1_STAGGER_MULT(7) | + DPIO_TX2_STAGGER_MULT(5)); + } + + /* Deassert data lane reset */ + chv_data_lane_soft_reset(encoder, false); mutex_unlock(&dev_priv->sb_lock); intel_enable_dp(encoder); + + /* Second common lane will stay alive on its own now */ + if (dport->release_cl2_override) { + chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, false); + dport->release_cl2_override = false; + } } static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) @@ -2874,12 +2901,27 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) to_intel_crtc(encoder->base.crtc); enum dpio_channel ch = vlv_dport_to_channel(dport); enum pipe pipe = intel_crtc->pipe; + unsigned int lane_mask = + intel_dp_unused_lane_mask(intel_crtc->config->lane_count); u32 val; intel_dp_prepare(encoder); + /* + * Must trick the second common lane into life. + * Otherwise we can't even access the PLL. + */ + if (ch == DPIO_CH0 && pipe == PIPE_B) + dport->release_cl2_override = + !chv_phy_powergate_ch(dev_priv, DPIO_PHY0, DPIO_CH1, true); + + chv_phy_powergate_lanes(encoder, true, lane_mask); + mutex_lock(&dev_priv->sb_lock); + /* Assert data lane reset */ + chv_data_lane_soft_reset(encoder, true); + /* program left/right clock distribution */ if (pipe != PIPE_B) { val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0); @@ -2908,13 +2950,15 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) val |= CHV_PCS_USEDCLKCHANNEL; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW8(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); - val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; - if (pipe != PIPE_B) - val &= ~CHV_PCS_USEDCLKCHANNEL; - else - val |= CHV_PCS_USEDCLKCHANNEL; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW8(ch)); + val |= CHV_PCS_USEDCLKCHANNEL_OVRRIDE; + if (pipe != PIPE_B) + val &= ~CHV_PCS_USEDCLKCHANNEL; + else + val |= CHV_PCS_USEDCLKCHANNEL; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW8(ch), val); + } /* * This a a bit weird since generally CL @@ -2931,6 +2975,39 @@ static void chv_dp_pre_pll_enable(struct intel_encoder *encoder) mutex_unlock(&dev_priv->sb_lock); } +static void chv_dp_post_pll_disable(struct intel_encoder *encoder) +{ + struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); + enum pipe pipe = to_intel_crtc(encoder->base.crtc)->pipe; + u32 val; + + mutex_lock(&dev_priv->sb_lock); + + /* disable left/right clock distribution */ + if (pipe != PIPE_B) { + val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW5_CH0); + val &= ~(CHV_BUFLEFTENA1_MASK | CHV_BUFRIGHTENA1_MASK); + vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW5_CH0, val); + } else { + val = vlv_dpio_read(dev_priv, pipe, _CHV_CMN_DW1_CH1); + val &= ~(CHV_BUFLEFTENA2_MASK | CHV_BUFRIGHTENA2_MASK); + vlv_dpio_write(dev_priv, pipe, _CHV_CMN_DW1_CH1, val); + } + + mutex_unlock(&dev_priv->sb_lock); + + /* + * Leave the power down bit cleared for at least one + * lane so that chv_powergate_phy_ch() will power + * on something when the channel is otherwise unused. + * When the port is off and the override is removed + * the lanes power down anyway, so otherwise it doesn't + * really matter what the state of power down bits is + * after this. + */ + chv_phy_powergate_lanes(encoder, false, 0x0); +} + /* * Native read with retry for link status and receiver capability reads for * cases where the sink may still be asleep. @@ -3167,6 +3244,12 @@ static uint32_t vlv_signal_levels(struct intel_dp *intel_dp) return 0; } +static bool chv_need_uniq_trans_scale(uint8_t train_set) +{ + return (train_set & DP_TRAIN_PRE_EMPHASIS_MASK) == DP_TRAIN_PRE_EMPH_LEVEL_0 && + (train_set & DP_TRAIN_VOLTAGE_SWING_MASK) == DP_TRAIN_VOLTAGE_SWING_LEVEL_3; +} + static uint32_t chv_signal_levels(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); @@ -3258,24 +3341,28 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp) val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); - val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); - val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); - val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); + val &= ~(DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3); + val &= ~(DPIO_PCS_TX1DEEMP_MASK | DPIO_PCS_TX2DEEMP_MASK); + val |= DPIO_PCS_TX1DEEMP_9P5 | DPIO_PCS_TX2DEEMP_9P5; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); + } val = vlv_dpio_read(dev_priv, pipe, VLV_PCS01_DW9(ch)); val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW9(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); - val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); - val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW9(ch)); + val &= ~(DPIO_PCS_TX1MARGIN_MASK | DPIO_PCS_TX2MARGIN_MASK); + val |= DPIO_PCS_TX1MARGIN_000 | DPIO_PCS_TX2MARGIN_000; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW9(ch), val); + } /* Program swing deemph */ - for (i = 0; i < 4; i++) { + for (i = 0; i < intel_crtc->config->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW4(ch, i)); val &= ~DPIO_SWING_DEEMPH9P5_MASK; val |= deemph_reg_value << DPIO_SWING_DEEMPH9P5_SHIFT; @@ -3283,43 +3370,36 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp) } /* Program swing margin */ - for (i = 0; i < 4; i++) { + for (i = 0; i < intel_crtc->config->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); + val &= ~DPIO_SWING_MARGIN000_MASK; val |= margin_reg_value << DPIO_SWING_MARGIN000_SHIFT; + + /* + * Supposedly this value shouldn't matter when unique transition + * scale is disabled, but in fact it does matter. Let's just + * always program the same value and hope it's OK. + */ + val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT); + val |= 0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT; + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val); } - /* Disable unique transition scale */ - for (i = 0; i < 4; i++) { + /* + * The document said it needs to set bit 27 for ch0 and bit 26 + * for ch1. Might be a typo in the doc. + * For now, for this unique transition scale selection, set bit + * 27 for ch0 and ch1. + */ + for (i = 0; i < intel_crtc->config->lane_count; i++) { val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i)); - val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN; - vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val); - } - - if (((train_set & DP_TRAIN_PRE_EMPHASIS_MASK) - == DP_TRAIN_PRE_EMPH_LEVEL_0) && - ((train_set & DP_TRAIN_VOLTAGE_SWING_MASK) - == DP_TRAIN_VOLTAGE_SWING_LEVEL_3)) { - - /* - * The document said it needs to set bit 27 for ch0 and bit 26 - * for ch1. Might be a typo in the doc. - * For now, for this unique transition scale selection, set bit - * 27 for ch0 and ch1. - */ - for (i = 0; i < 4; i++) { - val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW3(ch, i)); + if (chv_need_uniq_trans_scale(train_set)) val |= DPIO_TX_UNIQ_TRANS_SCALE_EN; - vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val); - } - - for (i = 0; i < 4; i++) { - val = vlv_dpio_read(dev_priv, pipe, CHV_TX_DW2(ch, i)); - val &= ~(0xff << DPIO_UNIQ_TRANS_SCALE_SHIFT); - val |= (0x9a << DPIO_UNIQ_TRANS_SCALE_SHIFT); - vlv_dpio_write(dev_priv, pipe, CHV_TX_DW2(ch, i), val); - } + else + val &= ~DPIO_TX_UNIQ_TRANS_SCALE_EN; + vlv_dpio_write(dev_priv, pipe, CHV_TX_DW3(ch, i), val); } /* Start swing calculation */ @@ -3327,14 +3407,11 @@ static uint32_t chv_signal_levels(struct intel_dp *intel_dp) val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; vlv_dpio_write(dev_priv, pipe, VLV_PCS01_DW10(ch), val); - val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); - val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; - vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); - - /* LRC Bypass */ - val = vlv_dpio_read(dev_priv, pipe, CHV_CMN_DW30); - val |= DPIO_LRC_BYPASS; - vlv_dpio_write(dev_priv, pipe, CHV_CMN_DW30, val); + if (intel_crtc->config->lane_count > 2) { + val = vlv_dpio_read(dev_priv, pipe, VLV_PCS23_DW10(ch)); + val |= DPIO_PCS_SWING_CALC_TX0_TX2 | DPIO_PCS_SWING_CALC_TX1_TX3; + vlv_dpio_write(dev_priv, pipe, VLV_PCS23_DW10(ch), val); + } mutex_unlock(&dev_priv->sb_lock); @@ -3520,8 +3597,8 @@ intel_dp_set_link_train(struct intel_dp *intel_dp, uint8_t dp_train_pat) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = + to_i915(intel_dig_port->base.base.dev); uint8_t buf[sizeof(intel_dp->train_set) + 1]; int ret, len; @@ -3562,8 +3639,8 @@ intel_dp_update_link_train(struct intel_dp *intel_dp, uint32_t *DP, const uint8_t link_status[DP_LINK_STATUS_SIZE]) { struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - struct drm_device *dev = intel_dig_port->base.base.dev; - struct drm_i915_private *dev_priv = dev->dev_private; + struct drm_i915_private *dev_priv = + to_i915(intel_dig_port->base.base.dev); int ret; intel_get_adjust_train(intel_dp, link_status); @@ -3610,8 +3687,8 @@ static void intel_dp_set_idle_link_train(struct intel_dp *intel_dp) } /* Enable corresponding port and start training pattern 1 */ -void -intel_dp_start_link_train(struct intel_dp *intel_dp) +static void +intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp) { struct drm_encoder *encoder = &dp_to_dig_port(intel_dp)->base.base; struct drm_device *dev = encoder->dev; @@ -3620,19 +3697,23 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) int voltage_tries, loop_tries; uint32_t DP = intel_dp->DP; uint8_t link_config[2]; + uint8_t link_bw, rate_select; if (HAS_DDI(dev)) intel_ddi_prepare_link_retrain(encoder); + intel_dp_compute_rate(intel_dp, intel_dp->link_rate, + &link_bw, &rate_select); + /* Write the link configuration data */ - link_config[0] = intel_dp->link_bw; + link_config[0] = link_bw; link_config[1] = intel_dp->lane_count; if (drm_dp_enhanced_frame_cap(intel_dp->dpcd)) link_config[1] |= DP_LANE_COUNT_ENHANCED_FRAME_EN; drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_BW_SET, link_config, 2); if (intel_dp->num_sink_rates) drm_dp_dpcd_write(&intel_dp->aux, DP_LINK_RATE_SET, - &intel_dp->rate_select, 1); + &rate_select, 1); link_config[0] = 0; link_config[1] = DP_SET_ANSI_8B10B; @@ -3720,17 +3801,30 @@ intel_dp_start_link_train(struct intel_dp *intel_dp) intel_dp->DP = DP; } -void -intel_dp_complete_link_train(struct intel_dp *intel_dp) +static void +intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp) { + struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); + struct drm_device *dev = dig_port->base.base.dev; bool channel_eq = false; int tries, cr_tries; uint32_t DP = intel_dp->DP; uint32_t training_pattern = DP_TRAINING_PATTERN_2; - /* Training Pattern 3 for HBR2 ot 1.2 devices that support it*/ - if (intel_dp->link_bw == DP_LINK_BW_5_4 || intel_dp->use_tps3) + /* + * Training Pattern 3 for HBR2 or 1.2 devices that support it. + * + * Intel platforms that support HBR2 also support TPS3. TPS3 support is + * also mandatory for downstream devices that support HBR2. + * + * Due to WaDisableHBR2 SKL < B0 is the only exception where TPS3 is + * supported but still not enabled. + */ + if (intel_dp_source_supports_hbr2(dev) && + drm_dp_tps3_supported(intel_dp->dpcd)) training_pattern = DP_TRAINING_PATTERN_3; + else if (intel_dp->link_rate == 540000) + DRM_ERROR("5.4 Gbps link rate without HBR2/TPS3 support\n"); /* channel equalization */ if (!intel_dp_set_link_train(intel_dp, &DP, @@ -3758,9 +3852,10 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) } /* Make sure clock is still ok */ - if (!drm_dp_clock_recovery_ok(link_status, intel_dp->lane_count)) { + if (!drm_dp_clock_recovery_ok(link_status, + intel_dp->lane_count)) { intel_dp->train_set_valid = false; - intel_dp_start_link_train(intel_dp); + intel_dp_link_training_clock_recovery(intel_dp); intel_dp_set_link_train(intel_dp, &DP, training_pattern | DP_LINK_SCRAMBLING_DISABLE); @@ -3768,7 +3863,8 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) continue; } - if (drm_dp_channel_eq_ok(link_status, intel_dp->lane_count)) { + if (drm_dp_channel_eq_ok(link_status, + intel_dp->lane_count)) { channel_eq = true; break; } @@ -3776,7 +3872,7 @@ intel_dp_complete_link_train(struct intel_dp *intel_dp) /* Try 5 times, then try clock recovery if that fails */ if (tries > 5) { intel_dp->train_set_valid = false; - intel_dp_start_link_train(intel_dp); + intel_dp_link_training_clock_recovery(intel_dp); intel_dp_set_link_train(intel_dp, &DP, training_pattern | DP_LINK_SCRAMBLING_DISABLE); @@ -3809,6 +3905,13 @@ void intel_dp_stop_link_train(struct intel_dp *intel_dp) DP_TRAINING_PATTERN_DISABLE); } +void +intel_dp_start_link_train(struct intel_dp *intel_dp) +{ + intel_dp_link_training_clock_recovery(intel_dp); + intel_dp_link_training_channel_equalization(intel_dp); +} + static void intel_dp_link_down(struct intel_dp *intel_dp) { @@ -3909,19 +4012,9 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp) } } - /* Training Pattern 3 support, Intel platforms that support HBR2 alone - * have support for TP3 hence that check is used along with dpcd check - * to ensure TP3 can be enabled. - * SKL < B0: due it's WaDisableHBR2 is the only exception where TP3 is - * supported but still not enabled. - */ - if (intel_dp->dpcd[DP_DPCD_REV] >= 0x12 && - intel_dp->dpcd[DP_MAX_LANE_COUNT] & DP_TPS3_SUPPORTED && - intel_dp_source_supports_hbr2(dev)) { - intel_dp->use_tps3 = true; - DRM_DEBUG_KMS("Displayport TPS3 supported\n"); - } else - intel_dp->use_tps3 = false; + DRM_DEBUG_KMS("Display Port TPS3 support: source %s, sink %s\n", + yesno(intel_dp_source_supports_hbr2(dev)), + yesno(drm_dp_tps3_supported(intel_dp->dpcd))); /* Intermediate frequency support */ if (is_edp(intel_dp) && @@ -4007,22 +4100,30 @@ intel_dp_probe_mst(struct intel_dp *intel_dp) return intel_dp->is_mst; } -static void intel_dp_sink_crc_stop(struct intel_dp *intel_dp) +static int intel_dp_sink_crc_stop(struct intel_dp *intel_dp) { struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); u8 buf; + int ret = 0; if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) { DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n"); - return; + ret = -EIO; + goto out; } if (drm_dp_dpcd_writeb(&intel_dp->aux, DP_TEST_SINK, - buf & ~DP_TEST_SINK_START) < 0) + buf & ~DP_TEST_SINK_START) < 0) { DRM_DEBUG_KMS("Sink CRC couldn't be stopped properly\n"); + ret = -EIO; + goto out; + } + intel_dp->sink_crc.started = false; + out: hsw_enable_ips(intel_crtc); + return ret; } static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) @@ -4030,6 +4131,13 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp); struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); u8 buf; + int ret; + + if (intel_dp->sink_crc.started) { + ret = intel_dp_sink_crc_stop(intel_dp); + if (ret) + return ret; + } if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) return -EIO; @@ -4037,6 +4145,8 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) if (!(buf & DP_TEST_CRC_SUPPORTED)) return -ENOTTY; + intel_dp->sink_crc.last_count = buf & DP_TEST_COUNT_MASK; + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK, &buf) < 0) return -EIO; @@ -4048,6 +4158,7 @@ static int intel_dp_sink_crc_start(struct intel_dp *intel_dp) return -EIO; } + intel_dp->sink_crc.started = true; return 0; } @@ -4057,38 +4168,55 @@ int intel_dp_sink_crc(struct intel_dp *intel_dp, u8 *crc) struct drm_device *dev = dig_port->base.base.dev; struct intel_crtc *intel_crtc = to_intel_crtc(dig_port->base.base.crtc); u8 buf; - int test_crc_count; + int count, ret; int attempts = 6; - int ret; + bool old_equal_new; ret = intel_dp_sink_crc_start(intel_dp); if (ret) return ret; - if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { - ret = -EIO; - goto stop; - } - - test_crc_count = buf & DP_TEST_COUNT_MASK; - do { + intel_wait_for_vblank(dev, intel_crtc->pipe); + if (drm_dp_dpcd_readb(&intel_dp->aux, DP_TEST_SINK_MISC, &buf) < 0) { ret = -EIO; goto stop; } - intel_wait_for_vblank(dev, intel_crtc->pipe); - } while (--attempts && (buf & DP_TEST_COUNT_MASK) == test_crc_count); + count = buf & DP_TEST_COUNT_MASK; + + /* + * Count might be reset during the loop. In this case + * last known count needs to be reset as well. + */ + if (count == 0) + intel_dp->sink_crc.last_count = 0; + + if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) { + ret = -EIO; + goto stop; + } + + old_equal_new = (count == intel_dp->sink_crc.last_count && + !memcmp(intel_dp->sink_crc.last_crc, crc, + 6 * sizeof(u8))); + + } while (--attempts && (count == 0 || old_equal_new)); + + intel_dp->sink_crc.last_count = buf & DP_TEST_COUNT_MASK; + memcpy(intel_dp->sink_crc.last_crc, crc, 6 * sizeof(u8)); if (attempts == 0) { - DRM_DEBUG_KMS("Panel is unable to calculate CRC after 6 vblanks\n"); - ret = -ETIMEDOUT; - goto stop; + if (old_equal_new) { + DRM_DEBUG_KMS("Unreliable Sink CRC counter: Current returned CRC is identical to the previous one\n"); + } else { + DRM_ERROR("Panel is unable to calculate any CRC after 6 vblanks\n"); + ret = -ETIMEDOUT; + goto stop; + } } - if (drm_dp_dpcd_read(&intel_dp->aux, DP_TEST_CRC_R_CR, crc, 6) < 0) - ret = -EIO; stop: intel_dp_sink_crc_stop(intel_dp); return ret; @@ -4248,10 +4376,10 @@ go_again: if (bret == true) { /* check link status - esi[10] = 0x200c */ - if (intel_dp->active_mst_links && !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { + if (intel_dp->active_mst_links && + !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { DRM_DEBUG_KMS("channel EQ not ok, retraining\n"); intel_dp_start_link_train(intel_dp); - intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); } @@ -4342,7 +4470,6 @@ intel_dp_check_link_status(struct intel_dp *intel_dp) DRM_DEBUG_KMS("%s: channel EQ not ok, retraining\n", intel_encoder->base.name); intel_dp_start_link_train(intel_dp); - intel_dp_complete_link_train(intel_dp); intel_dp_stop_link_train(intel_dp); } } @@ -4410,58 +4537,164 @@ edp_detect(struct intel_dp *intel_dp) return status; } -static enum drm_connector_status -ironlake_dp_detect(struct intel_dp *intel_dp) +static bool ibx_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) { - struct drm_device *dev = intel_dp_to_dev(intel_dp); - struct drm_i915_private *dev_priv = dev->dev_private; - struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + u32 bit; - if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) - return connector_status_disconnected; + switch (port->port) { + case PORT_A: + return true; + case PORT_B: + bit = SDE_PORTB_HOTPLUG; + break; + case PORT_C: + bit = SDE_PORTC_HOTPLUG; + break; + case PORT_D: + bit = SDE_PORTD_HOTPLUG; + break; + default: + MISSING_CASE(port->port); + return false; + } - return intel_dp_detect_dpcd(intel_dp); + return I915_READ(SDEISR) & bit; +} + +static bool cpt_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 bit; + + switch (port->port) { + case PORT_A: + return true; + case PORT_B: + bit = SDE_PORTB_HOTPLUG_CPT; + break; + case PORT_C: + bit = SDE_PORTC_HOTPLUG_CPT; + break; + case PORT_D: + bit = SDE_PORTD_HOTPLUG_CPT; + break; + case PORT_E: + bit = SDE_PORTE_HOTPLUG_SPT; + break; + default: + MISSING_CASE(port->port); + return false; + } + + return I915_READ(SDEISR) & bit; +} + +static bool g4x_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 bit; + + switch (port->port) { + case PORT_B: + bit = PORTB_HOTPLUG_LIVE_STATUS_G4X; + break; + case PORT_C: + bit = PORTC_HOTPLUG_LIVE_STATUS_G4X; + break; + case PORT_D: + bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; + break; + default: + MISSING_CASE(port->port); + return false; + } + + return I915_READ(PORT_HOTPLUG_STAT) & bit; +} + +static bool vlv_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + u32 bit; + + switch (port->port) { + case PORT_B: + bit = PORTB_HOTPLUG_LIVE_STATUS_VLV; + break; + case PORT_C: + bit = PORTC_HOTPLUG_LIVE_STATUS_VLV; + break; + case PORT_D: + bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; + break; + default: + MISSING_CASE(port->port); + return false; + } + + return I915_READ(PORT_HOTPLUG_STAT) & bit; } -static int g4x_digital_port_connected(struct drm_device *dev, +static bool bxt_digital_port_connected(struct drm_i915_private *dev_priv, struct intel_digital_port *intel_dig_port) { - struct drm_i915_private *dev_priv = dev->dev_private; - uint32_t bit; + struct intel_encoder *intel_encoder = &intel_dig_port->base; + enum port port; + u32 bit; - if (IS_VALLEYVIEW(dev)) { - switch (intel_dig_port->port) { - case PORT_B: - bit = PORTB_HOTPLUG_LIVE_STATUS_VLV; - break; - case PORT_C: - bit = PORTC_HOTPLUG_LIVE_STATUS_VLV; - break; - case PORT_D: - bit = PORTD_HOTPLUG_LIVE_STATUS_VLV; - break; - default: - return -EINVAL; - } - } else { - switch (intel_dig_port->port) { - case PORT_B: - bit = PORTB_HOTPLUG_LIVE_STATUS_G4X; - break; - case PORT_C: - bit = PORTC_HOTPLUG_LIVE_STATUS_G4X; - break; - case PORT_D: - bit = PORTD_HOTPLUG_LIVE_STATUS_G4X; - break; - default: - return -EINVAL; - } + intel_hpd_pin_to_port(intel_encoder->hpd_pin, &port); + switch (port) { + case PORT_A: + bit = BXT_DE_PORT_HP_DDIA; + break; + case PORT_B: + bit = BXT_DE_PORT_HP_DDIB; + break; + case PORT_C: + bit = BXT_DE_PORT_HP_DDIC; + break; + default: + MISSING_CASE(port); + return false; } - if ((I915_READ(PORT_HOTPLUG_STAT) & bit) == 0) - return 0; - return 1; + return I915_READ(GEN8_DE_PORT_ISR) & bit; +} + +/* + * intel_digital_port_connected - is the specified port connected? + * @dev_priv: i915 private structure + * @port: the port to test + * + * Return %true if @port is connected, %false otherwise. + */ +bool intel_digital_port_connected(struct drm_i915_private *dev_priv, + struct intel_digital_port *port) +{ + if (HAS_PCH_IBX(dev_priv)) + return ibx_digital_port_connected(dev_priv, port); + if (HAS_PCH_SPLIT(dev_priv)) + return cpt_digital_port_connected(dev_priv, port); + else if (IS_BROXTON(dev_priv)) + return bxt_digital_port_connected(dev_priv, port); + else if (IS_VALLEYVIEW(dev_priv)) + return vlv_digital_port_connected(dev_priv, port); + else + return g4x_digital_port_connected(dev_priv, port); +} + +static enum drm_connector_status +ironlake_dp_detect(struct intel_dp *intel_dp) +{ + struct drm_device *dev = intel_dp_to_dev(intel_dp); + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); + + if (!intel_digital_port_connected(dev_priv, intel_dig_port)) + return connector_status_disconnected; + + return intel_dp_detect_dpcd(intel_dp); } static enum drm_connector_status @@ -4469,7 +4702,6 @@ g4x_dp_detect(struct intel_dp *intel_dp) { struct drm_device *dev = intel_dp_to_dev(intel_dp); struct intel_digital_port *intel_dig_port = dp_to_dig_port(intel_dp); - int ret; /* Can't disconnect eDP, but you can close the lid... */ if (is_edp(intel_dp)) { @@ -4481,10 +4713,7 @@ g4x_dp_detect(struct intel_dp *intel_dp) return status; } - ret = g4x_digital_port_connected(dev, intel_dig_port); - if (ret == -EINVAL) - return connector_status_unknown; - else if (ret == 0) + if (!intel_digital_port_connected(dev->dev_private, intel_dig_port)) return connector_status_disconnected; return intel_dp_detect_dpcd(intel_dp); @@ -4533,26 +4762,6 @@ intel_dp_unset_edid(struct intel_dp *intel_dp) intel_dp->has_audio = false; } -static enum intel_display_power_domain -intel_dp_power_get(struct intel_dp *dp) -{ - struct intel_encoder *encoder = &dp_to_dig_port(dp)->base; - enum intel_display_power_domain power_domain; - - power_domain = intel_display_port_power_domain(encoder); - intel_display_power_get(to_i915(encoder->base.dev), power_domain); - - return power_domain; -} - -static void -intel_dp_power_put(struct intel_dp *dp, - enum intel_display_power_domain power_domain) -{ - struct intel_encoder *encoder = &dp_to_dig_port(dp)->base; - intel_display_power_put(to_i915(encoder->base.dev), power_domain); -} - static enum drm_connector_status intel_dp_detect(struct drm_connector *connector, bool force) { @@ -4576,7 +4785,8 @@ intel_dp_detect(struct drm_connector *connector, bool force) return connector_status_disconnected; } - power_domain = intel_dp_power_get(intel_dp); + power_domain = intel_display_port_aux_power_domain(intel_encoder); + intel_display_power_get(to_i915(dev), power_domain); /* Can't disconnect eDP, but you can close the lid... */ if (is_edp(intel_dp)) @@ -4621,7 +4831,7 @@ intel_dp_detect(struct drm_connector *connector, bool force) } out: - intel_dp_power_put(intel_dp, power_domain); + intel_display_power_put(to_i915(dev), power_domain); return status; } @@ -4630,6 +4840,7 @@ intel_dp_force(struct drm_connector *connector) { struct intel_dp *intel_dp = intel_attached_dp(connector); struct intel_encoder *intel_encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_i915_private *dev_priv = to_i915(intel_encoder->base.dev); enum intel_display_power_domain power_domain; DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", @@ -4639,11 +4850,12 @@ intel_dp_force(struct drm_connector *connector) if (connector->status != connector_status_connected) return; - power_domain = intel_dp_power_get(intel_dp); + power_domain = intel_display_port_aux_power_domain(intel_encoder); + intel_display_power_get(dev_priv, power_domain); intel_dp_set_edid(intel_dp); - intel_dp_power_put(intel_dp, power_domain); + intel_display_power_put(dev_priv, power_domain); if (intel_encoder->type != INTEL_OUTPUT_EDP) intel_encoder->type = INTEL_OUTPUT_DISPLAYPORT; @@ -4728,7 +4940,7 @@ intel_dp_set_property(struct drm_connector *connector, if (property == dev_priv->broadcast_rgb_property) { bool old_auto = intel_dp->color_range_auto; - uint32_t old_range = intel_dp->color_range; + bool old_range = intel_dp->limited_color_range; switch (val) { case INTEL_BROADCAST_RGB_AUTO: @@ -4736,18 +4948,18 @@ intel_dp_set_property(struct drm_connector *connector, break; case INTEL_BROADCAST_RGB_FULL: intel_dp->color_range_auto = false; - intel_dp->color_range = 0; + intel_dp->limited_color_range = false; break; case INTEL_BROADCAST_RGB_LIMITED: intel_dp->color_range_auto = false; - intel_dp->color_range = DP_COLOR_RANGE_16_235; + intel_dp->limited_color_range = true; break; default: return -EINVAL; } if (old_auto == intel_dp->color_range_auto && - old_range == intel_dp->color_range) + old_range == intel_dp->limited_color_range) return 0; goto done; @@ -4859,7 +5071,7 @@ static void intel_edp_panel_vdd_sanitize(struct intel_dp *intel_dp) * indefinitely. */ DRM_DEBUG_KMS("VDD left on by BIOS, adjusting state tracking\n"); - power_domain = intel_display_port_power_domain(&intel_dig_port->base); + power_domain = intel_display_port_aux_power_domain(&intel_dig_port->base); intel_display_power_get(dev_priv, power_domain); edp_panel_vdd_schedule_off(intel_dp); @@ -4921,7 +5133,8 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) enum intel_display_power_domain power_domain; enum irqreturn ret = IRQ_NONE; - if (intel_dig_port->base.type != INTEL_OUTPUT_EDP) + if (intel_dig_port->base.type != INTEL_OUTPUT_EDP && + intel_dig_port->base.type != INTEL_OUTPUT_HDMI) intel_dig_port->base.type = INTEL_OUTPUT_DISPLAYPORT; if (long_hpd && intel_dig_port->base.type == INTEL_OUTPUT_EDP) { @@ -4940,20 +5153,15 @@ intel_dp_hpd_pulse(struct intel_digital_port *intel_dig_port, bool long_hpd) port_name(intel_dig_port->port), long_hpd ? "long" : "short"); - power_domain = intel_display_port_power_domain(intel_encoder); + power_domain = intel_display_port_aux_power_domain(intel_encoder); intel_display_power_get(dev_priv, power_domain); if (long_hpd) { /* indicate that we need to restart link training */ intel_dp->train_set_valid = false; - if (HAS_PCH_SPLIT(dev)) { - if (!ibx_digital_port_connected(dev_priv, intel_dig_port)) - goto mst_fail; - } else { - if (g4x_digital_port_connected(dev, intel_dig_port) != 1) - goto mst_fail; - } + if (!intel_digital_port_connected(dev_priv, intel_dig_port)) + goto mst_fail; if (!intel_dp_get_dpcd(intel_dp)) { goto mst_fail; @@ -5028,6 +5236,13 @@ bool intel_dp_is_edp(struct drm_device *dev, enum port port) [PORT_E] = DVO_PORT_DPE, }; + /* + * eDP not supported on g4x. so bail out early just + * for a bit extra safety in case the VBT is bonkers. + */ + if (INTEL_INFO(dev)->gen < 5) + return false; + if (port == PORT_A) return true; @@ -5302,7 +5517,6 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) struct intel_dp *intel_dp = dev_priv->drrs.dp; struct intel_crtc_state *config = NULL; struct intel_crtc *intel_crtc = NULL; - u32 reg, val; enum drrs_refresh_rate_type index = DRRS_HIGH_RR; if (refresh_rate <= 0) { @@ -5364,9 +5578,10 @@ static void intel_dp_set_drrs_state(struct drm_device *dev, int refresh_rate) DRM_ERROR("Unsupported refreshrate type\n"); } } else if (INTEL_INFO(dev)->gen > 6) { - reg = PIPECONF(intel_crtc->config->cpu_transcoder); - val = I915_READ(reg); + u32 reg = PIPECONF(intel_crtc->config->cpu_transcoder); + u32 val; + val = I915_READ(reg); if (index > DRRS_HIGH_RR) { if (IS_VALLEYVIEW(dev)) val |= PIPECONF_EDP_RR_MODE_SWITCH_VLV; @@ -5765,7 +5980,7 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, } intel_panel_init(&intel_connector->panel, fixed_mode, downclock_mode); - intel_connector->panel.backlight_power = intel_edp_backlight_power; + intel_connector->panel.backlight.power = intel_edp_backlight_power; intel_panel_setup_backlight(connector, pipe); return true; @@ -5853,6 +6068,8 @@ intel_dp_init_connector(struct intel_digital_port *intel_dig_port, break; case PORT_B: intel_encoder->hpd_pin = HPD_PORT_B; + if (IS_BROXTON(dev_priv) && (INTEL_REVID(dev) < BXT_REVID_B0)) + intel_encoder->hpd_pin = HPD_PORT_A; break; case PORT_C: intel_encoder->hpd_pin = HPD_PORT_C; @@ -5932,10 +6149,8 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) return; intel_connector = intel_connector_alloc(); - if (!intel_connector) { - kfree(intel_dig_port); - return; - } + if (!intel_connector) + goto err_connector_alloc; intel_encoder = &intel_dig_port->base; encoder = &intel_encoder->base; @@ -5953,6 +6168,7 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_encoder->pre_enable = chv_pre_enable_dp; intel_encoder->enable = vlv_enable_dp; intel_encoder->post_disable = chv_post_disable_dp; + intel_encoder->post_pll_disable = chv_dp_post_pll_disable; } else if (IS_VALLEYVIEW(dev)) { intel_encoder->pre_pll_enable = vlv_dp_pre_pll_enable; intel_encoder->pre_enable = vlv_pre_enable_dp; @@ -5982,11 +6198,18 @@ intel_dp_init(struct drm_device *dev, int output_reg, enum port port) intel_dig_port->hpd_pulse = intel_dp_hpd_pulse; dev_priv->hotplug.irq_port[port] = intel_dig_port; - if (!intel_dp_init_connector(intel_dig_port, intel_connector)) { - drm_encoder_cleanup(encoder); - kfree(intel_dig_port); - kfree(intel_connector); - } + if (!intel_dp_init_connector(intel_dig_port, intel_connector)) + goto err_init_connector; + + return; + +err_init_connector: + drm_encoder_cleanup(encoder); + kfree(intel_connector); +err_connector_alloc: + kfree(intel_dig_port); + + return; } void intel_dp_mst_suspend(struct drm_device *dev) -- cgit v1.2.3