summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSuraj Kandpal <suraj.kandpal@intel.com>2025-11-01 08:55:08 +0530
committerSuraj Kandpal <suraj.kandpal@intel.com>2025-11-01 09:04:17 +0530
commita54bdcb7142d41a28831c1eaab2b3b64d1d34649 (patch)
tree666f56400466bfadf1ff9bda3d97425c1fe62f5e
parent13ba213f921ff264fa4e473c8c49d115231ec628 (diff)
drm/i915/ltphy: Enable/Disable Tx after Non TBT Enable sequence
We need to enable and disable the Tx for each active lane after the Non-TBT enable sequence is done. Bspec: 74500, 74497, 74701 Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com> Reviewed-by: Arun R Murthy <arun.r.murthy@intel.com> Link: https://patch.msgid.link/20251101032513.4171255-21-suraj.kandpal@intel.com
-rw-r--r--drivers/gpu/drm/i915/display/intel_lt_phy.c87
-rw-r--r--drivers/gpu/drm/i915/display/intel_lt_phy_regs.h4
2 files changed, 91 insertions, 0 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index eb6ec4de8045..5f75e72abd34 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -1507,6 +1507,92 @@ intel_lt_phy_program_pll(struct intel_encoder *encoder,
}
}
+static void
+intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder,
+ const struct intel_crtc_state *crtc_state)
+{
+ struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
+ bool lane_reversal = dig_port->lane_reversal;
+ u8 lane_count = crtc_state->lane_count;
+ bool is_dp_alt =
+ intel_tc_port_in_dp_alt_mode(dig_port);
+ enum intel_tc_pin_assignment tc_pin =
+ intel_tc_port_get_pin_assignment(dig_port);
+ u8 transmitter_mask = 0;
+
+ /*
+ * We have a two transmitters per lane and total of 2 PHY lanes so a total
+ * of 4 transmitters. We prepare a mask of the lanes that need to be activated
+ * and the transmitter which need to be activated for each lane. TX 0,1 correspond
+ * to LANE0 and TX 2, 3 correspond to LANE1.
+ */
+
+ switch (lane_count) {
+ case 1:
+ transmitter_mask = lane_reversal ? REG_BIT8(3) : REG_BIT8(0);
+ if (is_dp_alt) {
+ if (tc_pin == INTEL_TC_PIN_ASSIGNMENT_D)
+ transmitter_mask = REG_BIT8(0);
+ else
+ transmitter_mask = REG_BIT8(1);
+ }
+ break;
+ case 2:
+ transmitter_mask = lane_reversal ? REG_GENMASK8(3, 2) : REG_GENMASK8(1, 0);
+ if (is_dp_alt)
+ transmitter_mask = REG_GENMASK8(1, 0);
+ break;
+ case 3:
+ transmitter_mask = lane_reversal ? REG_GENMASK8(3, 1) : REG_GENMASK8(2, 0);
+ if (is_dp_alt)
+ transmitter_mask = REG_GENMASK8(2, 0);
+ break;
+ case 4:
+ transmitter_mask = REG_GENMASK8(3, 0);
+ break;
+ default:
+ MISSING_CASE(lane_count);
+ transmitter_mask = REG_GENMASK8(3, 0);
+ break;
+ }
+
+ if (transmitter_mask & BIT(0)) {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0),
+ LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0),
+ LT_PHY_TX_LANE_ENABLE);
+ } else {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(0),
+ 0, LT_PHY_TXY_CTL10_MAC(0), 0);
+ }
+
+ if (transmitter_mask & BIT(1)) {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1),
+ LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1),
+ LT_PHY_TX_LANE_ENABLE);
+ } else {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_TXY_CTL10(1),
+ 0, LT_PHY_TXY_CTL10_MAC(1), 0);
+ }
+
+ if (transmitter_mask & BIT(2)) {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0),
+ LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(0),
+ LT_PHY_TX_LANE_ENABLE);
+ } else {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(0),
+ 0, LT_PHY_TXY_CTL10_MAC(0), 0);
+ }
+
+ if (transmitter_mask & BIT(3)) {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1),
+ LT_PHY_TX_LANE_ENABLE, LT_PHY_TXY_CTL10_MAC(1),
+ LT_PHY_TX_LANE_ENABLE);
+ } else {
+ intel_lt_phy_p2p_write(encoder, INTEL_LT_PHY_LANE1, LT_PHY_TXY_CTL10(1),
+ 0, LT_PHY_TXY_CTL10_MAC(1), 0);
+ }
+}
+
void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
const struct intel_crtc_state *crtc_state)
{
@@ -1633,6 +1719,7 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
XELPDP_P0_STATE_ACTIVE);
+ intel_lt_phy_enable_disable_tx(encoder, crtc_state);
intel_lt_phy_transaction_end(encoder, wakeref);
}
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h b/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h
index da83a7c5faa3..9223487d764e 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy_regs.h
@@ -32,6 +32,10 @@
#define LT_PHY_TX_CURSOR_MASK REG_GENMASK8(5, 0)
#define LT_PHY_TX_CURSOR(val) REG_FIELD_PREP8(LT_PHY_TX_CURSOR_MASK, val)
+#define LT_PHY_TXY_CTL10(idx) (0x40A + (0x200 * (idx)))
+#define LT_PHY_TXY_CTL10_MAC(idx) _MMIO(LT_PHY_TXY_CTL10(idx))
+#define LT_PHY_TX_LANE_ENABLE REG_BIT8(0)
+
/* LT Phy Vendor Register */
#define LT_PHY_VDR_0_CONFIG 0xC02
#define LT_PHY_VDR_DP_PLL_ENABLE REG_BIT(7)