Intel-XE Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Suraj Kandpal <suraj.kandpal@intel.com>
To: intel-xe@lists.freedesktop.org, intel-gfx@lists.freedesktop.org
Cc: ankit.k.nautiyal@intel.com, arun.r.murthy@intel.com,
	uma.shankar@intel.com, gustavo.sousa@intel.com,
	lucas.demarchi@intel.com, Suraj Kandpal <suraj.kandpal@intel.com>
Subject: [PATCH v2 07/26] drm/i915/ltphy: Read PHY_VDR_0_CONFIG register
Date: Fri, 24 Oct 2025 15:36:53 +0530	[thread overview]
Message-ID: <20251024100712.3776261-8-suraj.kandpal@intel.com> (raw)
In-Reply-To: <20251024100712.3776261-1-suraj.kandpal@intel.com>

Read PHY_VDR_0_CONFIG to check if there is any change in the register and
decide based on that if P2P sequence to change the data rate of LT PHY
are required or not. This scenario only happens if the requested mode
uses 1.62Gbps with DP mode since LT PHY defaults to this mode if
any other mode is requested we need to follow the whole sequence.

Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Reviewed-by: Arun R Murthy <arun.r.murthy@intel.com>
---
V1 -> V2: Update the commit message (Arun)
---
 drivers/gpu/drm/i915/display/intel_cx0_phy.c |   4 +-
 drivers/gpu/drm/i915/display/intel_cx0_phy.h |   2 +
 drivers/gpu/drm/i915/display/intel_lt_phy.c  | 146 ++++++++++++++++---
 3 files changed, 127 insertions(+), 25 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
index 3d79f3be1ccd..c8848e8bfe8c 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c
@@ -271,8 +271,8 @@ static u8 __intel_cx0_read(struct intel_encoder *encoder,
 	return 0;
 }
 
-static u8 intel_cx0_read(struct intel_encoder *encoder,
-			 u8 lane_mask, u16 addr)
+u8 intel_cx0_read(struct intel_encoder *encoder,
+		  u8 lane_mask, u16 addr)
 {
 	int lane = lane_mask_to_lane(lane_mask);
 
diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
index 8c9b97f0922d..b448ce936c37 100644
--- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h
+++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h
@@ -46,6 +46,8 @@ void intel_cx0_powerdown_change_sequence(struct intel_encoder *encoder,
 int intel_cx0_phy_check_hdmi_link_rate(struct intel_hdmi *hdmi, int clock);
 void intel_cx0_setup_powerdown(struct intel_encoder *encoder);
 bool intel_cx0_is_hdmi_frl(u32 clock);
+u8 intel_cx0_read(struct intel_encoder *encoder,
+		  u8 lane_mask, u16 addr);
 int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder);
 void intel_cx0_pll_power_save_wa(struct intel_display *display);
 void intel_lnl_mac_transmit_lfps(struct intel_encoder *encoder,
diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c
index 239f7cdd373b..0fdc1ddbc5b1 100644
--- a/drivers/gpu/drm/i915/display/intel_lt_phy.c
+++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c
@@ -6,6 +6,7 @@
 #include <drm/drm_print.h>
 
 #include "i915_reg.h"
+#include "i915_utils.h"
 #include "intel_cx0_phy.h"
 #include "intel_cx0_phy_regs.h"
 #include "intel_de.h"
@@ -14,12 +15,14 @@
 #include "intel_hdmi.h"
 #include "intel_lt_phy.h"
 #include "intel_lt_phy_regs.h"
+#include "intel_psr.h"
 #include "intel_tc.h"
 
 #define INTEL_LT_PHY_LANE0		BIT(0)
 #define INTEL_LT_PHY_LANE1		BIT(1)
 #define INTEL_LT_PHY_BOTH_LANES		(INTEL_LT_PHY_LANE1 |\
 					 INTEL_LT_PHY_LANE0)
+#define MODE_DP				3
 
 static u8 intel_lt_phy_get_owned_lane_mask(struct intel_encoder *encoder)
 {
@@ -32,6 +35,12 @@ static u8 intel_lt_phy_get_owned_lane_mask(struct intel_encoder *encoder)
 		? INTEL_LT_PHY_BOTH_LANES : INTEL_LT_PHY_LANE0;
 }
 
+static u8 intel_lt_phy_read(struct intel_encoder *encoder,
+			    u8 lane_mask, u16 addr)
+{
+	return intel_cx0_read(encoder, lane_mask, addr);
+}
+
 static void
 intel_lt_phy_setup_powerdown(struct intel_encoder *encoder, u8 lane_count)
 {
@@ -149,12 +158,96 @@ intel_lt_phy_program_port_clock_ctl(struct intel_encoder *encoder,
 		     XELPDP_SSC_ENABLE_PLLB, val);
 }
 
+static u32
+intel_lt_phy_get_dp_clock(u8 rate)
+{
+	switch (rate) {
+	case 0:
+		return 162000;
+	case 1:
+		return 270000;
+	case 2:
+		return 540000;
+	case 3:
+		return 810000;
+	case 4:
+		return 216000;
+	case 5:
+		return 243000;
+	case 6:
+		return 324000;
+	case 7:
+		return 432000;
+	case 8:
+		return 1000000;
+	case 9:
+		return 1350000;
+	case 10:
+		return 2000000;
+	case 11:
+		return 675000;
+	default:
+		MISSING_CASE(rate);
+		return 0;
+	}
+}
+
+static bool
+intel_lt_phy_config_changed(struct intel_encoder *encoder,
+			    const struct intel_crtc_state *crtc_state)
+{
+	u8 val, rate;
+	u32 clock;
+
+	val = intel_lt_phy_read(encoder, INTEL_LT_PHY_LANE0,
+				LT_PHY_VDR_0_CONFIG);
+	rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, val);
+
+	/*
+	 * The only time we do not reconfigure the PLL is when we are
+	 * 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)) {
+		clock = intel_lt_phy_get_dp_clock(rate);
+		if (crtc_state->port_clock == 1620000 && crtc_state->port_clock == clock)
+			return false;
+	}
+
+	return true;
+}
+
+static intel_wakeref_t intel_lt_phy_transaction_begin(struct intel_encoder *encoder)
+{
+	struct intel_display *display = to_intel_display(encoder);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+	intel_wakeref_t wakeref;
+
+	intel_psr_pause(intel_dp);
+	wakeref = intel_display_power_get(display, POWER_DOMAIN_DC_OFF);
+
+	return wakeref;
+}
+
+static void intel_lt_phy_transaction_end(struct intel_encoder *encoder, intel_wakeref_t wakeref)
+{
+	struct intel_display *display = to_intel_display(encoder);
+	struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
+	intel_psr_resume(intel_dp);
+	intel_display_power_put(display, POWER_DOMAIN_DC_OFF, wakeref);
+}
+
 void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
 			     const struct intel_crtc_state *crtc_state)
 {
+	struct intel_display *display = to_intel_display(encoder);
 	struct intel_digital_port *dig_port = enc_to_dig_port(encoder);
 	bool lane_reversal = dig_port->lane_reversal;
 	u8 owned_lane_mask = intel_lt_phy_get_owned_lane_mask(encoder);
+	intel_wakeref_t wakeref = 0;
+
+	wakeref = intel_lt_phy_transaction_begin(encoder);
 
 	/* 1. Enable MacCLK at default 162 MHz frequency. */
 	intel_lt_phy_lane_reset(encoder, crtc_state->lane_count);
@@ -170,29 +263,34 @@ 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.
 	 */
-	/*
-	 * 5. Program the PHY internal PLL registers over PHY message bus for the desired
-	 * frequency and protocol type
-	 */
-	/* 6. Use the P2P transaction flow */
-	/*
-	 * 6.1. Set the PHY VDR register 0xCC4[Rate Control VDR Update] = 1 over PHY message
-	 * bus for Owned PHY Lanes.
-	 */
-	/*
-	 * 6.2. Poll for P2P Transaction Ready = "1" and read the MAC message bus VDR register
-	 * at offset 0xC00 for Owned PHY Lanes.
-	 */
-	/* 6.3. Clear P2P transaction Ready bit. */
-	/* 7. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */
-	/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
-	/*
-	 * 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency Change.
-	 * We handle this step in bxt_set_cdclk()
-	 */
-	/* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */
-	/* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */
-	/* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */
+	if (intel_lt_phy_config_changed(encoder, crtc_state)) {
+		/*
+		 * 5. Program the PHY internal PLL registers over PHY message bus for the desired
+		 * frequency and protocol type
+		 */
+		/* 6. Use the P2P transaction flow */
+		/*
+		 * 6.1. Set the PHY VDR register 0xCC4[Rate Control VDR Update] = 1 over PHY message
+		 * bus for Owned PHY Lanes.
+		 */
+		/*
+		 * 6.2. Poll for P2P Transaction Ready = "1" and read the MAC message bus VDR
+		 * register at offset 0xC00 for Owned PHY Lanes*.
+		 */
+		/* 6.3. Clear P2P transaction Ready bit. */
+		/* 7. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 0. */
+		/* 8. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 0. */
+		/*
+		 * 9. Follow the Display Voltage Frequency Switching - Sequence Before Frequency
+		 * Change. We handle this step in bxt_set_cdclk().
+		 */
+		/* 10. Program DDI_CLK_VALFREQ to match intended DDI clock frequency. */
+		/* 11. Program PORT_CLOCK_CTL[PCLK PLL Request LN0] = 1. */
+		/* 12. Poll for PORT_CLOCK_CTL[PCLK PLL Ack LN0]= 1. */
+	} else {
+		intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), crtc_state->port_clock);
+	}
+
 	/* 13. Ungate the forward clock by setting PORT_CLOCK_CTL[Forward Clock Ungate] = 1. */
 	/* 14. SW clears PORT_BUF_CTL2 [PHY Pulse Status]. */
 	/*
@@ -206,4 +304,6 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder,
 	 * We handle this step in bxt_set_cdclk()
 	 */
 	/* 19. Move the PHY powerdown state to Active and program to enable/disable transmitters */
+
+	intel_lt_phy_transaction_end(encoder, wakeref);
 }
-- 
2.34.1


  parent reply	other threads:[~2025-10-24 10:07 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-24 10:06 [PATCH v2 00/26] Enable LT PHY Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 01/26] drm/i915/ltphy: Add LT Phy related VDR and Pipe Registers Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 02/26] drm/i915/cx0: Change register bit naming for powerdown values Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 03/26] drm/i915/ltphy: Phy lane reset for LT Phy Suraj Kandpal
2025-10-28  7:47   ` Murthy, Arun R
2025-10-24 10:06 ` [PATCH v2 04/26] drm/i915/cx0: Move the HDMI FRL function to intel_hdmi Suraj Kandpal
2025-10-28  7:48   ` Murthy, Arun R
2025-10-24 10:06 ` [PATCH v2 05/26] drm/i915/ltphy: Program sequence for PORT_CLOCK_CTL for LT Phy Suraj Kandpal
2025-10-28  7:51   ` Murthy, Arun R
2025-10-24 10:06 ` [PATCH v2 06/26] drm/i915/ltphy: Add a wrapper for LT Phy powerdown change sequence Suraj Kandpal
2025-10-24 10:06 ` Suraj Kandpal [this message]
2025-10-28  9:17   ` [PATCH v2 07/26] drm/i915/ltphy: Read PHY_VDR_0_CONFIG register Jani Nikula
2025-10-24 10:06 ` [PATCH v2 08/26] drm/i915/ltphy: Add LT Phy Programming recipe tables Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 09/26] drm/i915/ltphy: Program the VDR PLL registers for LT PHY Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 10/26] drm/i915/ltphy: Update the ltpll config table value for eDP Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 11/26] drm/i915/ltphy: Enable SSC during port clock programming Suraj Kandpal
2025-10-24 10:06 ` [PATCH v2 12/26] drm/i915/ltphy: Add function to calculate LT PHY port clock Suraj Kandpal
2025-10-31  5:15   ` Nautiyal, Ankit K
2025-10-24 10:06 ` [PATCH v2 13/26] drm/i915/ltphy: Program the P2P Transaction flow for LT Phy Suraj Kandpal
2025-10-28  7:55   ` Murthy, Arun R
2025-10-24 10:07 ` [PATCH v2 14/26] drm/i915/ltphy: Program the rest of the PORT_CLOCK_CTL steps Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 15/26] drm/i915/ltphy: Program the rest of the LT Phy Enable sequence Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 16/26] drm/i915/ltphy: Program LT Phy Non-TBT PLL disable sequence Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 17/26] drm/i915/ltphy: Hook up LT Phy Enable & Disable sequences Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 18/26] drm/i915/ddi: Define LT Phy Swing tables Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 19/26] drm/i915/ltphy: Program LT Phy Voltage Swing Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 20/26] drm/i915/ltphy: Enable/Disable Tx after Non TBT Enable sequence Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 21/26] drm/i915/ltphy: Define the LT Phy state compare function Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 22/26] drm/i915/ltphy: Define function to readout LT Phy PLL state Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 23/26] drm/i915/ltphy: Define LT PHY PLL state verify function Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 24/26] drm/i915/display: Aux Enable and Display powerwell timeouts Suraj Kandpal
2025-10-28  7:58   ` Murthy, Arun R
2025-10-24 10:07 ` [PATCH v2 25/26] drm/i915/ltphy: Modify the step that need to be skipped Suraj Kandpal
2025-10-24 10:07 ` [PATCH v2 26/26] drm/i915/ltphy: Implement HDMI Algo for Pll state Suraj Kandpal
2025-10-31  6:24   ` Nautiyal, Ankit K
2025-10-24 10:27 ` ✗ CI.checkpatch: warning for Enable LT PHY (rev2) Patchwork
2025-10-24 10:28 ` ✓ CI.KUnit: success " Patchwork
2025-10-24 10:43 ` ✗ CI.checksparse: warning " Patchwork
2025-10-24 11:20 ` ✓ Xe.CI.BAT: success " Patchwork
2025-10-24 21:07 ` ✗ Xe.CI.Full: 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=20251024100712.3776261-8-suraj.kandpal@intel.com \
    --to=suraj.kandpal@intel.com \
    --cc=ankit.k.nautiyal@intel.com \
    --cc=arun.r.murthy@intel.com \
    --cc=gustavo.sousa@intel.com \
    --cc=intel-gfx@lists.freedesktop.org \
    --cc=intel-xe@lists.freedesktop.org \
    --cc=lucas.demarchi@intel.com \
    --cc=uma.shankar@intel.com \
    /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