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 <suraj.kandpal@intel.com>
Reviewed-by: Arun R Murthy <arun.r.murthy@intel.com>
Link: https://patch.msgid.link/20251101032513.4171255-10-suraj.kandpal@intel.com
This commit is contained in:
Suraj Kandpal 2025-11-01 08:54:57 +05:30
parent dc5742b619
commit 1dd885d509
3 changed files with 45 additions and 5 deletions

View File

@ -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;

View File

@ -8,6 +8,9 @@
#include <linux/types.h>
#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,

View File

@ -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