Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Mika Kahola <mika.kahola@intel.com>
To: intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org
Cc: Mika Kahola <mika.kahola@intel.com>
Subject: [PATCH v3 03/24] drm/i915/lt_phy: Refactor LT PHY PLL handling to use explicit PLL state
Date: Tue, 10 Mar 2026 13:36:00 +0000	[thread overview]
Message-ID: <20260310133600.1708066-1-mika.kahola@intel.com> (raw)
In-Reply-To: <20260304131423.1017821-5-mika.kahola@intel.com>

The LT PHY implementation currently pulls PLL and port_clock
information directly from the CRTC state. This ties the PHY
programming logic too tightly to the CRTC state and makes it
harder to clearly express the PHY’s own PLL configuration.

Introduce an explicit "struct intel_lt_phy_pll_state" argument
for the PHY functions and update callers accordingly.

No functional change is intended — this is a preparatory cleanup for
to bring LT PHY PLL handling as part of PLL framework.

v2:  DP, HDMI 2.0, and HDMI FRL modes are port of the VDR configuration 0
    register. These modes are defined by bits 2:0. Decode these to
    differentiate DP and HDMI modes when programming PLL's. (Imre, Suraj)

BSpec: 744921

Signed-off-by: Mika Kahola <mika.kahola@intel.com>
---
 drivers/gpu/drm/i915/display/intel_lt_phy.c | 67 ++++++++++++++-------
 1 file changed, 46 insertions(+), 21 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index f173d1788af8..06d83282c495 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -33,6 +33,7 @@
 #define PCLK_PLL_ACK_LN0		REG_BIT(30)
 #define MODE_DP				3
 #define MODE_HDMI_20			4
+#define MODE_HDMI_FRL			5
 #define Q32_TO_INT(x)	((x) >> 32)
 #define Q32_TO_FRAC(x)	((x) & 0xFFFFFFFF)
 #define DCO_MIN_FREQ_MHZ	11850
@@ -1177,9 +1178,30 @@ intel_lt_phy_lane_reset(struct intel_encoder *encoder,
 	intel_de_rmw(display, XELPDP_PORT_BUF_CTL2(display, port), lane_phy_pulse_status, 0);
 }
 
+static bool intel_lt_phy_is_hdmi(const struct intel_lt_phy_pll_state *ltpll)
+{
+	u8 mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, ltpll->config[0]);
+
+	if (mode == MODE_HDMI_20 || mode == MODE_HDMI_FRL)
+		return true;
+
+	return false;
+}
+
+static bool intel_lt_phy_is_dp(const struct intel_lt_phy_pll_state *ltpll)
+{
+	u8 mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, ltpll->config[0]);
+
+	if (mode == MODE_DP)
+		return true;
+
+	return false;
+}
+
 static void
 intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
-				    const struct intel_crtc_state *crtc_state,
+				    const struct intel_lt_phy_pll_state *ltpll,
+				    int port_clock,
 				    bool lane_reversal)
 {
 	struct intel_display *display = to_intel_display(encoder);
@@ -1196,17 +1218,16 @@ intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
 	 * but since the register bits still remain the same we use
 	 * the same definition
 	 */
-	if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
-	    intel_hdmi_is_frl(crtc_state->port_clock))
+	if (intel_lt_phy_is_hdmi(ltpll) && intel_hdmi_is_frl(port_clock))
 		val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
 	else
 		val |= XELPDP_DDI_CLOCK_SELECT_PREP(display, XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
 
 	 /* DP2.0 10G and 20G rates enable MPLLA*/
-	if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
+	if (port_clock == 1000000 || port_clock == 2000000)
 		val |= XELPDP_SSC_ENABLE_PLLA;
 	else
-		val |= crtc_state->dpll_hw_state.ltpll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
+		val |= ltpll->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
 
 	intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
 		     XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
@@ -1249,10 +1270,12 @@ static u32 intel_lt_phy_get_dp_clock(u8 rate)
 
 static bool
 intel_lt_phy_config_changed(struct intel_encoder *encoder,
-			    const struct intel_crtc_state *crtc_state)
+			    const struct intel_lt_phy_pll_state *ltpll)
 {
+	struct intel_display *display = to_intel_display(encoder);
 	u8 val, rate;
 	u32 clock;
+	u32 port_clock = intel_lt_phy_calc_port_clock(display, ltpll);
 
 	val = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0,
 				LT_PHY_VDR_0_CONFIG);
@@ -1263,9 +1286,9 @@ intel_lt_phy_config_changed(struct intel_encoder *encoder,
 	 * using 1.62 Gbps clock since PHY PLL defaults to that
 	 * otherwise we always need to reconfigure it.
 	 */
-	if (intel_crtc_has_dp_encoder(crtc_state)) {
+	if (intel_lt_phy_is_dp(ltpll)) {
 		clock = intel_lt_phy_get_dp_clock(rate);
-		if (crtc_state->port_clock == 1620000 && crtc_state->port_clock == clock)
+		if (port_clock == 1620000 && port_clock == clock)
 			return false;
 	}
 
@@ -1760,41 +1783,41 @@ intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state,
 
 static void
 intel_lt_phy_program_pll(struct intel_encoder *encoder,
-			 const struct intel_crtc_state *crtc_state)
+			 const struct intel_lt_phy_pll_state *ltpll)
 {
 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
 	int i, j, k;
 
 	intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_0_CONFIG,
-			   crtc_state->dpll_hw_state.ltpll.config[0], MB_WRITE_COMMITTED);
+			   ltpll->config[0], MB_WRITE_COMMITTED);
 	intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_1_CONFIG,
-			   crtc_state->dpll_hw_state.ltpll.config[1], MB_WRITE_COMMITTED);
+			   ltpll->config[1], MB_WRITE_COMMITTED);
 	intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_2_CONFIG,
-			   crtc_state->dpll_hw_state.ltpll.config[2], MB_WRITE_COMMITTED);
+			   ltpll->config[2], MB_WRITE_COMMITTED);
 
 	for (i = 0; i <= 12; i++) {
 		intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_MSB(i),
-				   crtc_state->dpll_hw_state.ltpll.addr_msb[i],
+				   ltpll->addr_msb[i],
 				   MB_WRITE_COMMITTED);
 		intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0, LT_PHY_VDR_X_ADDR_LSB(i),
-				   crtc_state->dpll_hw_state.ltpll.addr_lsb[i],
+				   ltpll->addr_lsb[i],
 				   MB_WRITE_COMMITTED);
 
 		for (j = 3, k = 0; j >= 0; j--, k++)
 			intel_lt_phy_write(encoder, INTEL_LT_PHY_LANE0,
 					   LT_PHY_VDR_X_DATAY(i, j),
-					   crtc_state->dpll_hw_state.ltpll.data[i][k],
+					   ltpll->data[i][k],
 					   MB_WRITE_COMMITTED);
 	}
 }
 
 static void
 intel_lt_phy_enable_disable_tx(struct intel_encoder *encoder,
-			       const struct intel_crtc_state *crtc_state)
+			       const struct intel_lt_phy_pll_state *ltpll,
+			       u8 lane_count)
 {
 	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 =
@@ -1896,7 +1919,8 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
 	intel_lt_phy_lane_reset(encoder, crtc_state->lane_count);
 
 	/* 2. Program PORT_CLOCK_CTL register to configure clock muxes, gating, and SSC. */
-	intel_lt_phy_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
+	intel_lt_phy_program_port_clock_ctl(encoder, &crtc_state->dpll_hw_state.ltpll,
+					    crtc_state->port_clock, lane_reversal);
 
 	/* 3. Change owned PHY lanes power to Ready state. */
 	intel_lt_phy_powerdown_change_sequence(encoder, owned_lane_mask,
@@ -1906,12 +1930,12 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
 	 * 4. Read the PHY message bus VDR register PHY_VDR_0_Config check enabled PLL type,
 	 * encoded rate and encoded mode.
 	 */
-	if (intel_lt_phy_config_changed(encoder, crtc_state)) {
+	if (intel_lt_phy_config_changed(encoder, &crtc_state->dpll_hw_state.ltpll)) {
 		/*
 		 * 5. Program the PHY internal PLL registers over PHY message bus for the desired
 		 * frequency and protocol type
 		 */
-		intel_lt_phy_program_pll(encoder, crtc_state);
+		intel_lt_phy_program_pll(encoder, &crtc_state->dpll_hw_state.ltpll);
 
 		/* 6. Use the P2P transaction flow */
 		/*
@@ -2002,7 +2026,8 @@ 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_enable_disable_tx(encoder, &crtc_state->dpll_hw_state.ltpll,
+				       crtc_state->lane_count);
 	intel_lt_phy_transaction_end(encoder, wakeref);
 }
 
-- 
2.43.0


  parent reply	other threads:[~2026-03-10 13:36 UTC|newest]

Thread overview: 67+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-03-04 13:13 [PATCH v2 00/24] Refactor LT PHY PLL handling to use DPLL framework Mika Kahola
2026-03-04 13:14 ` [PATCH v2 01/24] drm/i915/lt_phy: Dump missing PLL state parameters Mika Kahola
2026-03-10  2:57   ` Kandpal, Suraj
2026-03-10  3:10     ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 02/24] drm/i915/lt_phy: Add check if PLL is enabled Mika Kahola
2026-03-10  3:09   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 03/24] drm/i915/lt_phy: Add PLL information for xe3plpd Mika Kahola
2026-03-10  3:54   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 04/24] drm/i915/lt_phy: Refactor LT PHY PLL handling to use explicit PLL state Mika Kahola
2026-03-04 14:04   ` Imre Deak
2026-03-05  8:19     ` Kahola, Mika
2026-03-10  4:02       ` Kandpal, Suraj
2026-03-10  7:36         ` Kahola, Mika
2026-03-10  8:33           ` Kandpal, Suraj
2026-03-10 13:36   ` Mika Kahola [this message]
2026-03-10 15:38     ` [PATCH v3 " Mika Kahola
2026-03-11  4:18       ` Kandpal, Suraj
2026-03-11  6:15         ` Kandpal, Suraj
2026-03-11  8:12           ` Kahola, Mika
2026-03-04 13:14 ` [PATCH v2 05/24] drm/i915/lt_phy: Add lane_count to " Mika Kahola
2026-03-10  4:05   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 06/24] drm/i915/lt_phy: Add xe3plpd .compute_dplls hook Mika Kahola
2026-03-10  5:02   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 07/24] drm/i915/lt_phy: Add xe3plpd .get_dplls hook Mika Kahola
2026-03-04 13:14 ` [PATCH v2 08/24] drm/i915/lt_phy: Add xe3plpd .put_dplls hook Mika Kahola
2026-03-04 13:14 ` [PATCH v2 09/24] drm/i915/lt_phy: Add xe3plpd .update_active_dpll hook Mika Kahola
2026-03-04 13:14 ` [PATCH v2 10/24] drm/i915/lt_phy: Add xe3plpd .update_dpll_ref_clks hook Mika Kahola
2026-03-04 13:14 ` [PATCH v2 11/24] drm/i915/lt_phy: Add xe3plpd .dump_hw_state hook Mika Kahola
2026-03-10  6:19   ` Kandpal, Suraj
2026-03-10  6:32     ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 12/24] drm/i915/lt_phy: Add xe3plpd .compare_hw_state hook Mika Kahola
2026-03-10  6:23   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 13/24] drm/i915/lt_phy: Add xe3plpd .get_hw_state hook Mika Kahola
2026-03-04 13:14 ` [PATCH v2 14/24] drm/i915/lt_phy: Add xe3plpd .get_freq hook Mika Kahola
2026-03-11  4:24   ` Kandpal, Suraj
2026-03-11 13:32     ` Kahola, Mika
2026-03-04 13:14 ` [PATCH v2 15/24] drm/i915/lt_phy: Add xe3plpd .crtc_get_dpll Mika Kahola
2026-03-04 13:14 ` [PATCH v2 16/24] drm/i915/lt_phy: Replace crtc compute clock Mika Kahola
2026-03-11  4:30   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 17/24] drm/i915/lt_phy: Add .enable_clock hook on DDI Mika Kahola
2026-03-11  4:48   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 18/24] drm/i915/lt_phy: Add .disable_clock " Mika Kahola
2026-03-11  5:31   ` Kandpal, Suraj
2026-03-11  5:59     ` Kandpal, Suraj
2026-03-11 11:34       ` Kahola, Mika
2026-03-04 13:14 ` [PATCH v2 19/24] drm/i915/lt_phy: Dump lane count for HW state Mika Kahola
2026-03-11  5:46   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 20/24] drm/i915/lt_phy: Readout lane count Mika Kahola
2026-03-04 13:14 ` [PATCH v2 21/24] drm/i915/lt_phy: Get encoder configuration for xe3plpd platform Mika Kahola
2026-03-11  5:55   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 22/24] drm/i915/lt_phy: Add xe3plpd Thunderbolt pll hooks Mika Kahola
2026-03-11  6:05   ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 23/24] drm/i915/lt_phy: Remove LT PHY specific state verification Mika Kahola
2026-03-06 11:43   ` [PATCH v3 " Mika Kahola
2026-03-10  8:40     ` Kandpal, Suraj
2026-03-04 13:14 ` [PATCH v2 24/24] drm/i915/lt_phy: Enable dpll framework for xe3plpd Mika Kahola
2026-03-11  6:12   ` Kandpal, Suraj
2026-03-05 17:15 ` ✗ CI.checkpatch: warning for Refactor LT PHY PLL handling to use DPLL framework (rev2) Patchwork
2026-03-05 17:16 ` ✓ CI.KUnit: success " Patchwork
2026-03-05 18:32 ` ✗ Xe.CI.BAT: failure " Patchwork
2026-03-06  7:59 ` ✗ Xe.CI.FULL: " Patchwork
2026-03-06 20:27 ` ✗ CI.checkpatch: warning for Refactor LT PHY PLL handling to use DPLL framework (rev3) Patchwork
2026-03-06 20:28 ` ✓ CI.KUnit: success " Patchwork
2026-03-06 21:14 ` ✓ Xe.CI.BAT: " Patchwork
2026-03-07 23:48 ` ✗ Xe.CI.FULL: failure " Patchwork
2026-03-10 16:09 ` ✗ CI.checkpatch: warning for Refactor LT PHY PLL handling to use DPLL framework (rev5) Patchwork
2026-03-10 16:09 ` ✗ CI.KUnit: failure " Patchwork

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260310133600.1708066-1-mika.kahola@intel.com \
    --to=mika.kahola@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox