[PATCH] drm/i915/dp: Cable type identification for DP2.1
Animesh Manna
animesh.manna at intel.com
Fri Jun 9 05:54:35 UTC 2023
For DP alt mode display driver get the information
about cable speed and cable type through TCSS_DDI_STATUS
register which will be updated by type-c platform driver.
Accodingly Update dpcd 0x110 with cable information before
link training start. This change came part of DP2.1 SCR.
Note: This patch is not tested due to unavailability of
cable. Sending as RFC for design review.
Signed-off-by: Animesh Manna <animesh.manna at intel.com>
---
drivers/gpu/drm/i915/display/intel_ddi.c | 57 ++++++++++++++++++++++++
drivers/gpu/drm/i915/display/intel_tc.c | 10 +++++
drivers/gpu/drm/i915/display/intel_tc.h | 1 +
drivers/gpu/drm/i915/i915_reg.h | 5 +++
include/drm/display/drm_dp.h | 9 ++++
5 files changed, 82 insertions(+)
diff --git a/drivers/gpu/drm/i915/display/intel_ddi.c b/drivers/gpu/drm/i915/display/intel_ddi.c
index 70d44edd8c6e..3a0f6a3c9f98 100644
--- a/drivers/gpu/drm/i915/display/intel_ddi.c
+++ b/drivers/gpu/drm/i915/display/intel_ddi.c
@@ -2208,6 +2208,55 @@ static void intel_dp_sink_set_msa_timing_par_ignore_state(struct intel_dp *intel
str_enable_disable(enable));
}
+#define CABLE_SPEED_SHIFT 4
+
+enum dp_cable_speed {
+ DP_CABLE_HBR3 = 1,
+ DP_CABLE_UHBR10,
+ DP_CABLE_GEN3_UHBR20,
+ DP_CABLE_GEN4_UHBR20
+};
+
+static void intel_dp_set_cable_attributes(struct intel_dp *intel_dp,
+ u8 cable_attributes)
+{
+ u8 cable_speed;
+ bool active_cable, retimer;
+ u8 cable_attr_dpcd;
+
+ cable_speed = cable_attributes >> CABLE_SPEED_SHIFT;
+
+ switch (cable_speed) {
+ case DP_CABLE_HBR3:
+ cable_attr_dpcd = 0;
+ break;
+ case DP_CABLE_UHBR10:
+ cable_attr_dpcd = 1;
+ break;
+ case DP_CABLE_GEN3_UHBR20:
+ case DP_CABLE_GEN4_UHBR20:
+ cable_attr_dpcd = 2;
+ break;
+ default:
+ cable_attr_dpcd = 0;
+ break;
+ }
+
+ active_cable = (cable_attributes << TCSS_DDI_STATUS_CABLE_ATTR_SHIFT) &
+ TCSS_DDI_STATUS_ACTIVE_CABLE;
+ retimer = (cable_attributes << TCSS_DDI_STATUS_CABLE_ATTR_SHIFT) &
+ TCSS_DDI_STATUS_RETIMER_REDRIVER;
+ if (retimer && active_cable)
+ cable_attr_dpcd |= DP_CABLE_TYPE_RETIMER_ACTIVE;
+ else if (active_cable)
+ cable_attr_dpcd |= DP_CABLE_TYPE_LRD_ACTIVE;
+ else
+ cable_attr_dpcd |= DP_CABLE_TYPE_PASSIVE;
+
+ drm_dp_dpcd_writeb(&intel_dp->aux, DP_CABLE_ATTRIBUTES_UPDATED_BY_TX,
+ cable_attr_dpcd);
+}
+
static void intel_dp_sink_set_fec_ready(struct intel_dp *intel_dp,
const struct intel_crtc_state *crtc_state)
{
@@ -2414,6 +2463,7 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
{
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
bool is_mst = intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DP_MST);
+ struct intel_digital_port *dig_port = dp_to_dig_port(intel_dp);
intel_dp_set_link_params(intel_dp,
crtc_state->port_clock,
@@ -2480,6 +2530,13 @@ static void mtl_ddi_pre_enable_dp(struct intel_atomic_state *state,
intel_dp_check_frl_training(intel_dp);
intel_dp_pcon_dsc_configure(intel_dp, crtc_state);
+ if (intel_tc_port_in_dp_alt_mode(dig_port)) {
+ u8 cable_attributes;
+
+ cable_attributes = intel_tc_get_cable_attributes(dig_port);
+ intel_dp_set_cable_attributes(intel_dp, cable_attributes);
+ }
+
/*
* 6. The rest of the below are substeps under the bspec's "Enable and
* Train Display Port" step. Note that steps that are specific to
diff --git a/drivers/gpu/drm/i915/display/intel_tc.c b/drivers/gpu/drm/i915/display/intel_tc.c
index 3ebf41859043..6b10a8839563 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -260,6 +260,16 @@ assert_tc_port_power_enabled(struct intel_tc_port *tc)
!intel_display_power_is_enabled(i915, tc_port_power_domain(tc)));
}
+u8 intel_tc_get_cable_attributes(struct intel_digital_port *dig_port)
+{
+ struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
+ enum tc_port tc_port = intel_port_to_tc(i915, dig_port->base.port);
+
+ return (intel_de_read(i915, TCSS_DDI_STATUS(tc_port)) &
+ TCSS_DDI_STATUS_CABLE_ATTR_MASK) >>
+ TCSS_DDI_STATUS_CABLE_ATTR_SHIFT;
+}
+
u32 intel_tc_port_get_lane_mask(struct intel_digital_port *dig_port)
{
struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
diff --git a/drivers/gpu/drm/i915/display/intel_tc.h b/drivers/gpu/drm/i915/display/intel_tc.h
index 3b16491925fa..edafe92844b4 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.h
+++ b/drivers/gpu/drm/i915/display/intel_tc.h
@@ -43,5 +43,6 @@ int intel_tc_port_init(struct intel_digital_port *dig_port, bool is_legacy);
void intel_tc_port_cleanup(struct intel_digital_port *dig_port);
bool intel_tc_cold_requires_aux_pw(struct intel_digital_port *dig_port);
+u8 intel_tc_get_cable_attributes(struct intel_digital_port *dig_port);
#endif /* __INTEL_TC_H__ */
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 0523418129c5..991ecf082b5c 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6576,6 +6576,11 @@ enum skl_power_gate {
#define TCSS_DDI_STATUS(tc) _MMIO(_PICK_EVEN(tc, \
_TCSS_DDI_STATUS_1, \
_TCSS_DDI_STATUS_2))
+#define TCSS_DDI_STATUS_CABLE_ATTR_SHIFT 9
+#define TCSS_DDI_STATUS_CABLE_ATTR_MASK REG_GENMASK(14, 9)
+#define TCSS_DDI_STATUS_ACTIVE_CABLE REG_BIT(11)
+#define TCSS_DDI_STATUS_CABLE_TYPE REG_BIT(10)
+#define TCSS_DDI_STATUS_RETIMER_REDRIVER REG_BIT(9)
#define TCSS_DDI_STATUS_READY REG_BIT(2)
#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_TBT REG_BIT(1)
#define TCSS_DDI_STATUS_HPD_LIVE_STATUS_ALT REG_BIT(0)
diff --git a/include/drm/display/drm_dp.h b/include/drm/display/drm_dp.h
index b046f79f4744..dde715d567c2 100644
--- a/include/drm/display/drm_dp.h
+++ b/include/drm/display/drm_dp.h
@@ -654,6 +654,13 @@
# define DP_LANE13_POST_CURSOR2_SET_MASK (3 << 4)
# define DP_LANE13_MAX_POST_CURSOR2_REACHED (1 << 6)
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_TX 0x110
+# define DP_CABLE_TYPE_MASK (0x7 << 3)
+# define DP_CABLE_TYPE_UNKNOWN (0x0 << 3)
+# define DP_CABLE_TYPE_PASSIVE (0x1 << 3)
+# define DP_CABLE_TYPE_LRD_ACTIVE (0x2 << 3)
+# define DP_CABLE_TYPE_RETIMER_ACTIVE (0x3 << 3)
+
#define DP_MSTM_CTRL 0x111 /* 1.2 */
# define DP_MST_EN (1 << 0)
# define DP_UP_REQ_EN (1 << 1)
@@ -1139,6 +1146,8 @@
# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_32_MS 0x05
# define DP_128B132B_TRAINING_AUX_RD_INTERVAL_64_MS 0x06
+#define DP_CABLE_ATTRIBUTES_UPDATED_BY_RX 0x2217 /* 2.1 */
+
#define DP_TEST_264BIT_CUSTOM_PATTERN_7_0 0x2230
#define DP_TEST_264BIT_CUSTOM_PATTERN_263_256 0x2250
--
2.29.0
More information about the dri-devel
mailing list