diff options
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dp.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dp.c | 242 |
1 files changed, 141 insertions, 101 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c index 36ab58c25b64..1046e7fe310a 100644 --- a/drivers/gpu/drm/i915/display/intel_dp.c +++ b/drivers/gpu/drm/i915/display/intel_dp.c @@ -46,6 +46,7 @@ #include "intel_atomic.h" #include "intel_audio.h" #include "intel_backlight.h" +#include "intel_combo_phy_regs.h" #include "intel_connector.h" #include "intel_crtc.h" #include "intel_ddi.h" @@ -72,8 +73,6 @@ #include "intel_vdsc.h" #include "intel_vrr.h" -#define DP_DPRX_ESI_LEN 14 - /* DP DSC throughput values used for slice count calculations KPixels/s */ #define DP_DSC_PEAK_PIXEL_RATE 2720000 #define DP_DSC_MAX_ENC_THROUGHPUT_0 340000 @@ -705,7 +704,7 @@ static u16 intel_dp_dsc_get_output_bpp(struct drm_i915_private *i915, i915->max_cdclk_freq * 48 / intel_dp_mode_to_fec_clock(mode_clock); - DRM_DEBUG_KMS("Max big joiner bpp: %u\n", max_bpp_bigjoiner); + drm_dbg_kms(&i915->drm, "Max big joiner bpp: %u\n", max_bpp_bigjoiner); bits_per_pixel = min(bits_per_pixel, max_bpp_bigjoiner); } @@ -887,9 +886,8 @@ intel_dp_mode_valid_downstream(struct intel_connector *connector, return MODE_CLOCK_HIGH; /* Assume 8bpc for the DP++/HDMI/DVI TMDS clock check */ - tmds_clock = target_clock; - if (drm_mode_is_420_only(info, mode)) - tmds_clock /= 2; + tmds_clock = intel_hdmi_tmds_clock(target_clock, 8, + drm_mode_is_420_only(info, mode)); if (intel_dp->dfp.min_tmds_clock && tmds_clock < intel_dp->dfp.min_tmds_clock) @@ -1140,21 +1138,12 @@ static bool intel_dp_hdmi_ycbcr420(struct intel_dp *intel_dp, intel_dp->dfp.ycbcr_444_to_420); } -static int intel_dp_hdmi_tmds_clock(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, int bpc) -{ - int clock = crtc_state->hw.adjusted_mode.crtc_clock * bpc / 8; - - if (intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) - clock /= 2; - - return clock; -} - static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state, int bpc) { - int tmds_clock = intel_dp_hdmi_tmds_clock(intel_dp, crtc_state, bpc); + int clock = crtc_state->hw.adjusted_mode.crtc_clock; + int tmds_clock = intel_hdmi_tmds_clock(clock, bpc, + intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)); if (intel_dp->dfp.min_tmds_clock && tmds_clock < intel_dp->dfp.min_tmds_clock) @@ -1167,14 +1156,13 @@ static bool intel_dp_hdmi_tmds_clock_valid(struct intel_dp *intel_dp, return true; } -static bool intel_dp_hdmi_deep_color_possible(struct intel_dp *intel_dp, - const struct intel_crtc_state *crtc_state, - int bpc) +static bool intel_dp_hdmi_bpc_possible(struct intel_dp *intel_dp, + const struct intel_crtc_state *crtc_state, + int bpc) { - return intel_hdmi_deep_color_possible(crtc_state, bpc, - intel_dp->has_hdmi_sink, - intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) && + return intel_hdmi_bpc_possible(crtc_state, bpc, intel_dp->has_hdmi_sink, + intel_dp_hdmi_ycbcr420(intel_dp, crtc_state)) && intel_dp_hdmi_tmds_clock_valid(intel_dp, crtc_state, bpc); } @@ -1192,7 +1180,7 @@ static int intel_dp_max_bpp(struct intel_dp *intel_dp, if (intel_dp->dfp.min_tmds_clock) { for (; bpc >= 10; bpc -= 2) { - if (intel_dp_hdmi_deep_color_possible(intel_dp, crtc_state, bpc)) + if (intel_dp_hdmi_bpc_possible(intel_dp, crtc_state, bpc)) break; } } @@ -1897,7 +1885,7 @@ intel_dp_compute_config(struct intel_encoder *encoder, /* FIXME: abstract this better */ if (pipe_config->splitter.enable) - pipe_config->dp_m_n.gmch_m *= pipe_config->splitter.link_count; + pipe_config->dp_m_n.data_m *= pipe_config->splitter.link_count; if (!HAS_DDI(dev_priv)) g4x_dp_set_clock(encoder, pipe_config); @@ -2813,11 +2801,22 @@ intel_dp_configure_mst(struct intel_dp *intel_dp) } static bool -intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *sink_irq_vector) +intel_dp_get_sink_irq_esi(struct intel_dp *intel_dp, u8 *esi) +{ + return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, esi, 4) == 4; +} + +static bool intel_dp_ack_sink_irq_esi(struct intel_dp *intel_dp, u8 esi[4]) { - return drm_dp_dpcd_read(&intel_dp->aux, DP_SINK_COUNT_ESI, - sink_irq_vector, DP_DPRX_ESI_LEN) == - DP_DPRX_ESI_LEN; + int retry; + + for (retry = 0; retry < 3; retry++) { + if (drm_dp_dpcd_write(&intel_dp->aux, DP_SINK_COUNT_ESI + 1, + &esi[1], 3) == 3) + return true; + } + + return false; } bool @@ -2909,7 +2908,8 @@ out: } static ssize_t -intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_infoframe, +intel_dp_hdr_metadata_infoframe_sdp_pack(struct drm_i915_private *i915, + const struct hdmi_drm_infoframe *drm_infoframe, struct dp_sdp *sdp, size_t size) { @@ -2925,12 +2925,12 @@ intel_dp_hdr_metadata_infoframe_sdp_pack(const struct hdmi_drm_infoframe *drm_in len = hdmi_drm_infoframe_pack_only(drm_infoframe, buf, sizeof(buf)); if (len < 0) { - DRM_DEBUG_KMS("buffer size is smaller than hdr metadata infoframe\n"); + drm_dbg_kms(&i915->drm, "buffer size is smaller than hdr metadata infoframe\n"); return -ENOSPC; } if (len != infoframe_size) { - DRM_DEBUG_KMS("wrong static hdr metadata size\n"); + drm_dbg_kms(&i915->drm, "wrong static hdr metadata size\n"); return -ENOSPC; } @@ -3003,7 +3003,8 @@ static void intel_write_dp_sdp(struct intel_encoder *encoder, sizeof(sdp)); break; case HDMI_PACKET_TYPE_GAMUT_METADATA: - len = intel_dp_hdr_metadata_infoframe_sdp_pack(&crtc_state->infoframes.drm.drm, + len = intel_dp_hdr_metadata_infoframe_sdp_pack(dev_priv, + &crtc_state->infoframes.drm.drm, &sdp, sizeof(sdp)); break; default: @@ -3411,22 +3412,22 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, switch (data->phy_pattern) { case DP_PHY_TEST_PATTERN_NONE: - DRM_DEBUG_KMS("Disable Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Disable Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), 0x0); break; case DP_PHY_TEST_PATTERN_D10_2: - DRM_DEBUG_KMS("Set D10.2 Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set D10.2 Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_D10_2); break; case DP_PHY_TEST_PATTERN_ERROR_COUNT: - DRM_DEBUG_KMS("Set Error Count Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set Error Count Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_SCRAMBLED_0); break; case DP_PHY_TEST_PATTERN_PRBS7: - DRM_DEBUG_KMS("Set PRBS7 Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set PRBS7 Phy Test Pattern\n"); intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_PRBS7); break; @@ -3436,7 +3437,8 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - DRM_DEBUG_KMS("Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); + drm_dbg_kms(&dev_priv->drm, + "Set 80Bit Custom Phy Test Pattern 0x3e0f83e0 0x0f83e0f8 0x0000f83e\n"); pattern_val = 0x3e0f83e0; intel_de_write(dev_priv, DDI_DP_COMP_PAT(pipe, 0), pattern_val); pattern_val = 0x0f83e0f8; @@ -3453,7 +3455,7 @@ static void intel_dp_phy_pattern_update(struct intel_dp *intel_dp, * current firmware of DPR-100 could not set it, so hardcoding * now for complaince test. */ - DRM_DEBUG_KMS("Set HBR2 compliance Phy Test Pattern\n"); + drm_dbg_kms(&dev_priv->drm, "Set HBR2 compliance Phy Test Pattern\n"); pattern_val = 0xFB; intel_de_write(dev_priv, DDI_DP_COMP_CTL(pipe), DDI_DP_COMP_CTL_ENABLE | DDI_DP_COMP_CTL_HBR2 | @@ -3522,13 +3524,14 @@ intel_dp_autotest_phy_ddi_enable(struct intel_dp *intel_dp, static void intel_dp_process_phy_request(struct intel_dp *intel_dp, const struct intel_crtc_state *crtc_state) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; u8 link_status[DP_LINK_STATUS_SIZE]; if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, DP_PHY_DPRX, link_status) < 0) { - DRM_DEBUG_KMS("failed to get link status\n"); + drm_dbg_kms(&i915->drm, "failed to get link status\n"); return; } @@ -3553,11 +3556,12 @@ static void intel_dp_process_phy_request(struct intel_dp *intel_dp, static u8 intel_dp_autotest_phy_pattern(struct intel_dp *intel_dp) { + struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_dp_phy_test_params *data = &intel_dp->compliance.test_data.phytest; if (drm_dp_get_phy_test_pattern(&intel_dp->aux, data)) { - DRM_DEBUG_KMS("DP Phy Test pattern AUX read failure\n"); + drm_dbg_kms(&i915->drm, "DP Phy Test pattern AUX read failure\n"); return DP_TEST_NAK; } @@ -3614,15 +3618,63 @@ update_status: "Could not write test response to sink\n"); } +static bool intel_dp_link_ok(struct intel_dp *intel_dp, + u8 link_status[DP_LINK_STATUS_SIZE]) +{ + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + bool uhbr = intel_dp->link_rate >= 1000000; + bool ok; + + if (uhbr) + ok = drm_dp_128b132b_lane_channel_eq_done(link_status, + intel_dp->lane_count); + else + ok = drm_dp_channel_eq_ok(link_status, intel_dp->lane_count); + + if (ok) + return true; + + intel_dp_dump_link_status(intel_dp, DP_PHY_DPRX, link_status); + drm_dbg_kms(&i915->drm, + "[ENCODER:%d:%s] %s link not ok, retraining\n", + encoder->base.base.id, encoder->base.name, + uhbr ? "128b/132b" : "8b/10b"); + + return false; +} + static void -intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, bool *handled) +intel_dp_mst_hpd_irq(struct intel_dp *intel_dp, u8 *esi, u8 *ack) { - drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, handled); + bool handled = false; - if (esi[1] & DP_CP_IRQ) { - intel_hdcp_handle_cp_irq(intel_dp->attached_connector); - *handled = true; - } + drm_dp_mst_hpd_irq(&intel_dp->mst_mgr, esi, &handled); + if (handled) + ack[1] |= esi[1] & (DP_DOWN_REP_MSG_RDY | DP_UP_REQ_MSG_RDY); + + if (esi[1] & DP_CP_IRQ) { + intel_hdcp_handle_cp_irq(intel_dp->attached_connector); + ack[1] |= DP_CP_IRQ; + } +} + +static bool intel_dp_mst_link_status(struct intel_dp *intel_dp) +{ + struct intel_encoder *encoder = &dp_to_dig_port(intel_dp)->base; + struct drm_i915_private *i915 = to_i915(encoder->base.dev); + u8 link_status[DP_LINK_STATUS_SIZE] = {}; + const size_t esi_link_status_size = DP_LINK_STATUS_SIZE - 2; + + if (drm_dp_dpcd_read(&intel_dp->aux, DP_LANE0_1_STATUS_ESI, link_status, + esi_link_status_size) != esi_link_status_size) { + drm_err(&i915->drm, + "[ENCODER:%d:%s] Failed to read link status\n", + encoder->base.base.id, encoder->base.name); + return false; + } + + return intel_dp_link_ok(intel_dp, link_status); } /** @@ -3647,20 +3699,8 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) drm_WARN_ON_ONCE(&i915->drm, intel_dp->active_mst_links < 0); for (;;) { - /* - * The +2 is because DP_DPRX_ESI_LEN is 14, but we then - * pass in "esi+10" to drm_dp_channel_eq_ok(), which - * takes a 6-byte array. So we actually need 16 bytes - * here. - * - * Somebody who knows what the limits actually are - * should check this, but for now this is at least - * harmless and avoids a valid compiler warning about - * using more of the array than we have allocated. - */ - u8 esi[DP_DPRX_ESI_LEN+2] = {}; - bool handled; - int retry; + u8 esi[4] = {}; + u8 ack[4] = {}; if (!intel_dp_get_sink_irq_esi(intel_dp, esi)) { drm_dbg_kms(&i915->drm, @@ -3670,30 +3710,22 @@ intel_dp_check_mst_status(struct intel_dp *intel_dp) break; } - /* check link status - esi[10] = 0x200c */ + drm_dbg_kms(&i915->drm, "DPRX ESI: %4ph\n", esi); + if (intel_dp->active_mst_links > 0 && link_ok && - !drm_dp_channel_eq_ok(&esi[10], intel_dp->lane_count)) { - drm_dbg_kms(&i915->drm, - "channel EQ not ok, retraining\n"); - link_ok = false; + esi[3] & LINK_STATUS_CHANGED) { + if (!intel_dp_mst_link_status(intel_dp)) + link_ok = false; + ack[3] |= LINK_STATUS_CHANGED; } - drm_dbg_kms(&i915->drm, "got esi %3ph\n", esi); + intel_dp_mst_hpd_irq(intel_dp, esi, ack); - intel_dp_mst_hpd_irq(intel_dp, esi, &handled); - - if (!handled) + if (!memchr_inv(ack, 0, sizeof(ack))) break; - for (retry = 0; retry < 3; retry++) { - int wret; - - wret = drm_dp_dpcd_write(&intel_dp->aux, - DP_SINK_COUNT_ESI+1, - &esi[1], 3); - if (wret == 3) - break; - } + if (!intel_dp_ack_sink_irq_esi(intel_dp, ack)) + drm_dbg_kms(&i915->drm, "Failed to ack ESI\n"); } return link_ok; @@ -3756,8 +3788,8 @@ intel_dp_needs_link_retrain(struct intel_dp *intel_dp) intel_dp->lane_count)) return false; - /* Retrain if Channel EQ or CR not ok */ - return !drm_dp_channel_eq_ok(link_status, intel_dp->lane_count); + /* Retrain if link not ok */ + return !intel_dp_link_ok(intel_dp, link_status); } static bool intel_dp_has_connector(struct intel_dp *intel_dp, @@ -3787,14 +3819,14 @@ static bool intel_dp_has_connector(struct intel_dp *intel_dp, static int intel_dp_prep_link_retrain(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx, - u32 *crtc_mask) + u8 *pipe_mask) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; int ret = 0; - *crtc_mask = 0; + *pipe_mask = 0; if (!intel_dp_needs_link_retrain(intel_dp)) return 0; @@ -3828,12 +3860,12 @@ static int intel_dp_prep_link_retrain(struct intel_dp *intel_dp, !try_wait_for_completion(&conn_state->commit->hw_done)) continue; - *crtc_mask |= drm_crtc_mask(&crtc->base); + *pipe_mask |= BIT(crtc->pipe); } drm_connector_list_iter_end(&conn_iter); if (!intel_dp_needs_link_retrain(intel_dp)) - *crtc_mask = 0; + *pipe_mask = 0; return ret; } @@ -3852,7 +3884,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc; - u32 crtc_mask; + u8 pipe_mask; int ret; if (!intel_dp_is_connected(intel_dp)) @@ -3863,17 +3895,17 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, if (ret) return ret; - ret = intel_dp_prep_link_retrain(intel_dp, ctx, &crtc_mask); + ret = intel_dp_prep_link_retrain(intel_dp, ctx, &pipe_mask); if (ret) return ret; - if (crtc_mask == 0) + if (pipe_mask == 0) return 0; drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] retraining link\n", encoder->base.base.id, encoder->base.name); - for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -3884,7 +3916,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, intel_crtc_pch_transcoder(crtc), false); } - for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -3901,7 +3933,7 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, break; } - for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -3919,14 +3951,14 @@ int intel_dp_retrain_link(struct intel_encoder *encoder, static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, struct drm_modeset_acquire_ctx *ctx, - u32 *crtc_mask) + u8 *pipe_mask) { struct drm_i915_private *i915 = dp_to_i915(intel_dp); struct drm_connector_list_iter conn_iter; struct intel_connector *connector; int ret = 0; - *crtc_mask = 0; + *pipe_mask = 0; drm_connector_list_iter_begin(&i915->drm, &conn_iter); for_each_intel_connector_iter(connector, &conn_iter) { @@ -3957,7 +3989,7 @@ static int intel_dp_prep_phy_test(struct intel_dp *intel_dp, !try_wait_for_completion(&conn_state->commit->hw_done)) continue; - *crtc_mask |= drm_crtc_mask(&crtc->base); + *pipe_mask |= BIT(crtc->pipe); } drm_connector_list_iter_end(&conn_iter); @@ -3970,7 +4002,7 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, struct drm_i915_private *dev_priv = to_i915(encoder->base.dev); struct intel_dp *intel_dp = enc_to_intel_dp(encoder); struct intel_crtc *crtc; - u32 crtc_mask; + u8 pipe_mask; int ret; ret = drm_modeset_lock(&dev_priv->drm.mode_config.connection_mutex, @@ -3978,17 +4010,17 @@ static int intel_dp_do_phy_test(struct intel_encoder *encoder, if (ret) return ret; - ret = intel_dp_prep_phy_test(intel_dp, ctx, &crtc_mask); + ret = intel_dp_prep_phy_test(intel_dp, ctx, &pipe_mask); if (ret) return ret; - if (crtc_mask == 0) + if (pipe_mask == 0) return 0; drm_dbg_kms(&dev_priv->drm, "[ENCODER:%d:%s] PHY test\n", encoder->base.base.id, encoder->base.name); - for_each_intel_crtc_mask(&dev_priv->drm, crtc, crtc_mask) { + for_each_intel_crtc_in_pipe_mask(&dev_priv->drm, crtc, pipe_mask) { const struct intel_crtc_state *crtc_state = to_intel_crtc_state(crtc->base.state); @@ -4974,6 +5006,14 @@ static bool intel_edp_init_connector(struct intel_dp *intel_dp, mutex_lock(&dev->mode_config.mutex); edid = drm_get_edid(connector, &intel_dp->aux.ddc); + if (!edid) { + /* Fallback to EDID from ACPI OpRegion, if any */ + edid = intel_opregion_get_edid(intel_connector); + if (edid) + drm_dbg_kms(&dev_priv->drm, + "[CONNECTOR:%d:%s] Using OpRegion EDID\n", + connector->base.id, connector->name); + } if (edid) { if (drm_add_edid_modes(connector, edid)) { drm_connector_update_edid_property(connector, edid); @@ -5048,8 +5088,8 @@ static void intel_dp_modeset_retry_work_fn(struct work_struct *work) intel_connector = container_of(work, typeof(*intel_connector), modeset_retry_work); connector = &intel_connector->base; - DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, - connector->name); + drm_dbg_kms(connector->dev, "[CONNECTOR:%d:%s]\n", connector->base.id, + connector->name); /* Grab the locks before changing connector property*/ mutex_lock(&connector->dev->mode_config.mutex); |