From 1dd885d5098db040e5faa5f63b301129e9a04639 Mon Sep 17 00:00:00 2001 From: Suraj Kandpal Date: Sat, 1 Nov 2025 08:54:57 +0530 Subject: [PATCH] drm/i915/ltphy: Program the VDR PLL registers for LT PHY Fetch the tables which need to be used and program it in the specified VDR register space. Everything is done over the respective lanes. Bspec: 68862, 74500 Signed-off-by: Suraj Kandpal Reviewed-by: Arun R Murthy Link: https://patch.msgid.link/20251101032513.4171255-10-suraj.kandpal@intel.com --- drivers/gpu/drm/i915/display/intel_cx0_phy.c | 7 ++-- drivers/gpu/drm/i915/display/intel_cx0_phy.h | 5 +++ drivers/gpu/drm/i915/display/intel_lt_phy.c | 38 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.c b/drivers/gpu/drm/i915/display/intel_cx0_phy.c index bfa3b3eab8cbd..7d57f0d8d4d73 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.c +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.c @@ -23,9 +23,6 @@ #include "intel_snps_hdmi_pll.h" #include "intel_tc.h" -#define MB_WRITE_COMMITTED true -#define MB_WRITE_UNCOMMITTED false - #define for_each_cx0_lane_in_mask(__lane_mask, __lane) \ for ((__lane) = 0; (__lane) < 2; (__lane)++) \ for_each_if((__lane_mask) & BIT(__lane)) @@ -358,8 +355,8 @@ static void __intel_cx0_write(struct intel_encoder *encoder, "PHY %c Write %04x failed after %d retries.\n", phy_name(phy), addr, i); } -static void intel_cx0_write(struct intel_encoder *encoder, - u8 lane_mask, u16 addr, u8 data, bool committed) +void intel_cx0_write(struct intel_encoder *encoder, + u8 lane_mask, u16 addr, u8 data, bool committed) { int lane; diff --git a/drivers/gpu/drm/i915/display/intel_cx0_phy.h b/drivers/gpu/drm/i915/display/intel_cx0_phy.h index 948fd626846d3..c1e61d16fb68e 100644 --- a/drivers/gpu/drm/i915/display/intel_cx0_phy.h +++ b/drivers/gpu/drm/i915/display/intel_cx0_phy.h @@ -8,6 +8,9 @@ #include +#define MB_WRITE_COMMITTED true +#define MB_WRITE_UNCOMMITTED false + enum icl_port_dpll_id; struct intel_atomic_state; struct intel_c10pll_state; @@ -47,6 +50,8 @@ 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); +void intel_cx0_write(struct intel_encoder *encoder, + u8 lane_mask, u16 addr, u8 data, bool committed); 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 22686da809d0d..ece81e8d558dd 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -992,6 +992,12 @@ static u8 intel_lt_phy_read(struct intel_encoder *encoder, u8 lane_mask, u16 add return intel_cx0_read(encoder, lane_mask, addr); } +static void intel_lt_phy_write(struct intel_encoder *encoder, + u8 lane_mask, u16 addr, u8 data, bool committed) +{ + intel_cx0_write(encoder, lane_mask, addr, data, committed); +} + static void intel_lt_phy_setup_powerdown(struct intel_encoder *encoder, u8 lane_count) { @@ -1228,6 +1234,36 @@ intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state, return -EINVAL; } +static void +intel_lt_phy_program_pll(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + 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); + 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); + intel_lt_phy_write(encoder, owned_lane_mask, LT_PHY_VDR_2_CONFIG, + crtc_state->dpll_hw_state.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], + 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], + 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], + MB_WRITE_COMMITTED); + } +} + void intel_lt_phy_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state) { @@ -1258,6 +1294,8 @@ void intel_lt_phy_pll_enable(struct intel_encoder *encoder, * 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); + /* 6. Use the P2P transaction flow */ /* * 6.1. Set the PHY VDR register 0xCC4[Rate Control VDR Update] = 1 over PHY message -- 2.47.3