From: Suraj Kandpal Date: Sat, 1 Nov 2025 03:25:08 +0000 (+0530) Subject: drm/i915/ltphy: Enable/Disable Tx after Non TBT Enable sequence X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=a54bdcb7142d41a28831c1eaab2b3b64d1d34649;p=thirdparty%2Fkernel%2Flinux.git 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 Reviewed-by: Arun R Murthy Link: https://patch.msgid.link/20251101032513.4171255-21-suraj.kandpal@intel.com --- diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index eb6ec4de8045a..5f75e72abd343 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 da83a7c5faa3e..9223487d764e2 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)