From: Luca Coelho <luciano.coe...@intel.com>

Starting from display version 20, we need to read the pin assignment
from the IOM TCSS_DDI_STATUS register instead of reading it from the
FIA.

We use the pin assignment to decide the maximum lane count.  So, to
support this change, add a new lnl_tc_port_get_max_lane_count() function
that reads from the TCSS_DDI_STATUS register and decides the maximum
lane count based on that.

BSpec: 69594
Cc: Mika Kahola <mika.kah...@intel.com>
Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
Reviewed-by: Matt Roper <matthew.d.ro...@intel.com>
Reviewed-by: Mika Kahola <mika.kah...@intel.com>
Signed-off-by: Lucas De Marchi <lucas.demar...@intel.com>
---
 drivers/gpu/drm/i915/display/intel_tc.c | 28 +++++++++++++++++++++++++
 drivers/gpu/drm/i915/i915_reg.h         |  1 +
 2 files changed, 29 insertions(+)

diff --git a/drivers/gpu/drm/i915/display/intel_tc.c 
b/drivers/gpu/drm/i915/display/intel_tc.c
index 3c94bbcb5497..37b0f8529b4f 100644
--- a/drivers/gpu/drm/i915/display/intel_tc.c
+++ b/drivers/gpu/drm/i915/display/intel_tc.c
@@ -290,6 +290,31 @@ u32 intel_tc_port_get_pin_assignment_mask(struct 
intel_digital_port *dig_port)
               DP_PIN_ASSIGNMENT_SHIFT(tc->phy_fia_idx);
 }
 
+static int lnl_tc_port_get_max_lane_count(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);
+       intel_wakeref_t wakeref;
+       u32 val, pin_assignment;
+
+       with_intel_display_power(i915, POWER_DOMAIN_DISPLAY_CORE, wakeref)
+               val = intel_de_read(i915, TCSS_DDI_STATUS(tc_port));
+
+       pin_assignment =
+               REG_FIELD_GET(TCSS_DDI_STATUS_PIN_ASSIGNMENT_MASK, val);
+
+       switch (pin_assignment) {
+       default:
+               MISSING_CASE(pin_assignment);
+               fallthrough;
+       case DP_PIN_ASSIGNMENT_D:
+               return 2;
+       case DP_PIN_ASSIGNMENT_C:
+       case DP_PIN_ASSIGNMENT_E:
+               return 4;
+       }
+}
+
 static int mtl_tc_port_get_max_lane_count(struct intel_digital_port *dig_port)
 {
        struct drm_i915_private *i915 = to_i915(dig_port->base.base.dev);
@@ -348,6 +373,9 @@ int intel_tc_port_max_lane_count(struct intel_digital_port 
*dig_port)
 
        assert_tc_cold_blocked(tc);
 
+       if (DISPLAY_VER(i915) >= 20)
+               return lnl_tc_port_get_max_lane_count(dig_port);
+
        if (DISPLAY_VER(i915) >= 14)
                return mtl_tc_port_get_max_lane_count(dig_port);
 
diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h
index 467edc6f9e39..d67f381050dc 100644
--- a/drivers/gpu/drm/i915/i915_reg.h
+++ b/drivers/gpu/drm/i915/i915_reg.h
@@ -6349,6 +6349,7 @@ 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_PIN_ASSIGNMENT_MASK   REG_GENMASK(28, 25)
 #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)
-- 
2.40.1

Reply via email to