Skip to content

Commit a4ed5f3

Browse files
committed
drm/i915/display: Drop crtc_state from C10/C20 pll programming
For PLL programming for C10 and C20 we don't need to carry crtc_state but instead use only necessary parts of the crtc_state i.e. pll_state. This change is needed to PTL wa 14023648281 where we would need to otherwise pass an artificial crtc_state with majority of the struct members initialized as NULL. v2: Use err instead of val for error handling (Imre) Unify parameter order (Imre) v3: Fix misplaced port_clock, and is_dp in intel_c20_pll_program() call (Imre) Signed-off-by: Mika Kahola <mika.kahola@intel.com> Reviewed-by: Imre Deak <imre.deak@intel.com> Link: https://patchwork.freedesktop.org/patch/msgid/20250218100019.740556-2-mika.kahola@intel.com
1 parent c19f5a0 commit a4ed5f3

File tree

1 file changed

+74
-57
lines changed

1 file changed

+74
-57
lines changed

drivers/gpu/drm/i915/display/intel_cx0_phy.c

Lines changed: 74 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -2020,13 +2020,12 @@ intel_c10pll_tables_get(struct intel_crtc_state *crtc_state,
20202020
return NULL;
20212021
}
20222022

2023-
static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
2024-
struct intel_encoder *encoder)
2023+
static void intel_cx0pll_update_ssc(struct intel_encoder *encoder,
2024+
struct intel_cx0pll_state *pll_state, bool is_dp)
20252025
{
20262026
struct intel_display *display = to_intel_display(encoder);
2027-
struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll;
20282027

2029-
if (intel_crtc_has_dp_encoder(crtc_state)) {
2028+
if (is_dp) {
20302029
if (intel_panel_use_ssc(display)) {
20312030
struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
20322031
pll_state->ssc_enabled =
@@ -2035,11 +2034,10 @@ static void intel_cx0pll_update_ssc(struct intel_crtc_state *crtc_state,
20352034
}
20362035
}
20372036

2038-
static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
2039-
struct intel_encoder *encoder)
2037+
static void intel_c10pll_update_pll(struct intel_encoder *encoder,
2038+
struct intel_cx0pll_state *pll_state)
20402039
{
20412040
struct intel_display *display = to_intel_display(encoder);
2042-
struct intel_cx0pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll;
20432041
int i;
20442042

20452043
if (pll_state->ssc_enabled)
@@ -2050,38 +2048,53 @@ static void intel_c10pll_update_pll(struct intel_crtc_state *crtc_state,
20502048
pll_state->c10.pll[i] = 0;
20512049
}
20522050

2051+
static int intel_c10pll_calc_state_from_table(struct intel_encoder *encoder,
2052+
const struct intel_c10pll_state * const *tables,
2053+
bool is_dp, int port_clock,
2054+
struct intel_cx0pll_state *pll_state)
2055+
{
2056+
int i;
2057+
2058+
for (i = 0; tables[i]; i++) {
2059+
if (port_clock == tables[i]->clock) {
2060+
pll_state->c10 = *tables[i];
2061+
intel_cx0pll_update_ssc(encoder, pll_state, is_dp);
2062+
intel_c10pll_update_pll(encoder, pll_state);
2063+
pll_state->use_c10 = true;
2064+
2065+
return 0;
2066+
}
2067+
}
2068+
2069+
return -EINVAL;
2070+
}
2071+
20532072
static int intel_c10pll_calc_state(struct intel_crtc_state *crtc_state,
20542073
struct intel_encoder *encoder)
20552074
{
20562075
const struct intel_c10pll_state * const *tables;
2057-
int i;
2076+
int err;
20582077

20592078
tables = intel_c10pll_tables_get(crtc_state, encoder);
20602079
if (!tables)
20612080
return -EINVAL;
20622081

2063-
for (i = 0; tables[i]; i++) {
2064-
if (crtc_state->port_clock == tables[i]->clock) {
2065-
crtc_state->dpll_hw_state.cx0pll.c10 = *tables[i];
2066-
intel_cx0pll_update_ssc(crtc_state, encoder);
2067-
intel_c10pll_update_pll(crtc_state, encoder);
2068-
crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
2082+
err = intel_c10pll_calc_state_from_table(encoder, tables,
2083+
intel_crtc_has_dp_encoder(crtc_state),
2084+
crtc_state->port_clock,
2085+
&crtc_state->dpll_hw_state.cx0pll);
20692086

2070-
return 0;
2071-
}
2072-
}
2087+
if (err == 0 || !intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI))
2088+
return err;
20732089

20742090
/* For HDMI PLLs try SNPS PHY algorithm, if there are no precomputed tables */
2075-
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI)) {
2076-
intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10,
2077-
crtc_state->port_clock);
2078-
intel_c10pll_update_pll(crtc_state, encoder);
2079-
crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
2080-
2081-
return 0;
2082-
}
2091+
intel_snps_hdmi_pll_compute_c10pll(&crtc_state->dpll_hw_state.cx0pll.c10,
2092+
crtc_state->port_clock);
2093+
intel_c10pll_update_pll(encoder,
2094+
&crtc_state->dpll_hw_state.cx0pll);
2095+
crtc_state->dpll_hw_state.cx0pll.use_c10 = true;
20832096

2084-
return -EINVAL;
2097+
return 0;
20852098
}
20862099

20872100
static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
@@ -2111,10 +2124,9 @@ static void intel_c10pll_readout_hw_state(struct intel_encoder *encoder,
21112124
}
21122125

21132126
static void intel_c10_pll_program(struct intel_display *display,
2114-
const struct intel_crtc_state *crtc_state,
2115-
struct intel_encoder *encoder)
2127+
struct intel_encoder *encoder,
2128+
const struct intel_c10pll_state *pll_state)
21162129
{
2117-
const struct intel_c10pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c10;
21182130
int i;
21192131

21202132
intel_cx0_rmw(encoder, INTEL_CX0_BOTH_LANES, PHY_C10_VDR_CONTROL(1),
@@ -2333,7 +2345,9 @@ static int intel_c20pll_calc_state(struct intel_crtc_state *crtc_state,
23332345
for (i = 0; tables[i]; i++) {
23342346
if (crtc_state->port_clock == tables[i]->clock) {
23352347
crtc_state->dpll_hw_state.cx0pll.c20 = *tables[i];
2336-
intel_cx0pll_update_ssc(crtc_state, encoder);
2348+
intel_cx0pll_update_ssc(encoder,
2349+
&crtc_state->dpll_hw_state.cx0pll,
2350+
intel_crtc_has_dp_encoder(crtc_state));
23372351
crtc_state->dpll_hw_state.cx0pll.use_c10 = false;
23382352
return 0;
23392353
}
@@ -2599,19 +2613,14 @@ static int intel_get_c20_custom_width(u32 clock, bool dp)
25992613
}
26002614

26012615
static void intel_c20_pll_program(struct intel_display *display,
2602-
const struct intel_crtc_state *crtc_state,
2603-
struct intel_encoder *encoder)
2616+
struct intel_encoder *encoder,
2617+
const struct intel_c20pll_state *pll_state,
2618+
bool is_dp, int port_clock)
26042619
{
2605-
const struct intel_c20pll_state *pll_state = &crtc_state->dpll_hw_state.cx0pll.c20;
2606-
bool dp = false;
26072620
u8 owned_lane_mask = intel_cx0_get_owned_lane_mask(encoder);
2608-
u32 clock = crtc_state->port_clock;
26092621
bool cntx;
26102622
int i;
26112623

2612-
if (intel_crtc_has_dp_encoder(crtc_state))
2613-
dp = true;
2614-
26152624
/* 1. Read current context selection */
26162625
cntx = intel_cx0_read(encoder, INTEL_CX0_LANE0, PHY_C20_VDR_CUSTOM_SERDES_RATE) & BIT(0);
26172626

@@ -2679,23 +2688,23 @@ static void intel_c20_pll_program(struct intel_display *display,
26792688
/* 4. Program custom width to match the link protocol */
26802689
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_WIDTH,
26812690
PHY_C20_CUSTOM_WIDTH_MASK,
2682-
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(clock, dp)),
2691+
PHY_C20_CUSTOM_WIDTH(intel_get_c20_custom_width(port_clock, is_dp)),
26832692
MB_WRITE_COMMITTED);
26842693

26852694
/* 5. For DP or 6. For HDMI */
2686-
if (dp) {
2695+
if (is_dp) {
26872696
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
26882697
BIT(6) | PHY_C20_CUSTOM_SERDES_MASK,
2689-
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(clock)),
2698+
BIT(6) | PHY_C20_CUSTOM_SERDES(intel_c20_get_dp_rate(port_clock)),
26902699
MB_WRITE_COMMITTED);
26912700
} else {
26922701
intel_cx0_rmw(encoder, owned_lane_mask, PHY_C20_VDR_CUSTOM_SERDES_RATE,
26932702
BIT(7) | PHY_C20_CUSTOM_SERDES_MASK,
2694-
is_hdmi_frl(clock) ? BIT(7) : 0,
2703+
is_hdmi_frl(port_clock) ? BIT(7) : 0,
26952704
MB_WRITE_COMMITTED);
26962705

26972706
intel_cx0_write(encoder, INTEL_CX0_BOTH_LANES, PHY_C20_VDR_HDMI_RATE,
2698-
intel_c20_get_hdmi_rate(clock),
2707+
intel_c20_get_hdmi_rate(port_clock),
26992708
MB_WRITE_COMMITTED);
27002709
}
27012710

@@ -2735,7 +2744,8 @@ static int intel_c10pll_calc_port_clock(struct intel_encoder *encoder,
27352744
}
27362745

27372746
static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
2738-
const struct intel_crtc_state *crtc_state,
2747+
const struct intel_cx0pll_state *pll_state,
2748+
bool is_dp, int port_clock,
27392749
bool lane_reversal)
27402750
{
27412751
struct intel_display *display = to_intel_display(encoder);
@@ -2750,18 +2760,17 @@ static void intel_program_port_clock_ctl(struct intel_encoder *encoder,
27502760

27512761
val |= XELPDP_FORWARD_CLOCK_UNGATE;
27522762

2753-
if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_HDMI) &&
2754-
is_hdmi_frl(crtc_state->port_clock))
2763+
if (!is_dp && is_hdmi_frl(port_clock))
27552764
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_DIV18CLK);
27562765
else
27572766
val |= XELPDP_DDI_CLOCK_SELECT(XELPDP_DDI_CLOCK_SELECT_MAXPCLK);
27582767

27592768
/* TODO: HDMI FRL */
27602769
/* DP2.0 10G and 20G rates enable MPLLA*/
2761-
if (crtc_state->port_clock == 1000000 || crtc_state->port_clock == 2000000)
2762-
val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
2770+
if (port_clock == 1000000 || port_clock == 2000000)
2771+
val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLA : 0;
27632772
else
2764-
val |= crtc_state->dpll_hw_state.cx0pll.ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
2773+
val |= pll_state->ssc_enabled ? XELPDP_SSC_ENABLE_PLLB : 0;
27652774

27662775
intel_de_rmw(display, XELPDP_PORT_CLOCK_CTL(display, encoder->port),
27672776
XELPDP_LANE1_PHY_CLOCK_SELECT | XELPDP_FORWARD_CLOCK_UNGATE |
@@ -2991,8 +3000,9 @@ static u32 intel_cx0_get_pclk_pll_ack(u8 lane_mask)
29913000
return val;
29923001
}
29933002

2994-
static void intel_cx0pll_enable(struct intel_encoder *encoder,
2995-
const struct intel_crtc_state *crtc_state)
3003+
static void __intel_cx0pll_enable(struct intel_encoder *encoder,
3004+
const struct intel_cx0pll_state *pll_state,
3005+
bool is_dp, int port_clock, int lane_count)
29963006
{
29973007
struct intel_display *display = to_intel_display(encoder);
29983008
enum phy phy = intel_encoder_to_phy(encoder);
@@ -3006,7 +3016,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30063016
* 1. Program PORT_CLOCK_CTL REGISTER to configure
30073017
* clock muxes, gating and SSC
30083018
*/
3009-
intel_program_port_clock_ctl(encoder, crtc_state, lane_reversal);
3019+
intel_program_port_clock_ctl(encoder, pll_state, is_dp, port_clock, lane_reversal);
30103020

30113021
/* 2. Bring PHY out of reset. */
30123022
intel_cx0_phy_lane_reset(encoder, lane_reversal);
@@ -3026,15 +3036,15 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30263036

30273037
/* 5. Program PHY internal PLL internal registers. */
30283038
if (intel_encoder_is_c10phy(encoder))
3029-
intel_c10_pll_program(display, crtc_state, encoder);
3039+
intel_c10_pll_program(display, encoder, &pll_state->c10);
30303040
else
3031-
intel_c20_pll_program(display, crtc_state, encoder);
3041+
intel_c20_pll_program(display, encoder, &pll_state->c20, is_dp, port_clock);
30323042

30333043
/*
30343044
* 6. Program the enabled and disabled owned PHY lane
30353045
* transmitters over message bus
30363046
*/
3037-
intel_cx0_program_phy_lane(encoder, crtc_state->lane_count, lane_reversal);
3047+
intel_cx0_program_phy_lane(encoder, lane_count, lane_reversal);
30383048

30393049
/*
30403050
* 7. Follow the Display Voltage Frequency Switching - Sequence
@@ -3045,8 +3055,7 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30453055
* 8. Program DDI_CLK_VALFREQ to match intended DDI
30463056
* clock frequency.
30473057
*/
3048-
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port),
3049-
crtc_state->port_clock);
3058+
intel_de_write(display, DDI_CLK_VALFREQ(encoder->port), port_clock);
30503059

30513060
/*
30523061
* 9. Set PORT_CLOCK_CTL register PCLK PLL Request
@@ -3073,6 +3082,14 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
30733082
intel_cx0_phy_transaction_end(encoder, wakeref);
30743083
}
30753084

3085+
static void intel_cx0pll_enable(struct intel_encoder *encoder,
3086+
const struct intel_crtc_state *crtc_state)
3087+
{
3088+
__intel_cx0pll_enable(encoder, &crtc_state->dpll_hw_state.cx0pll,
3089+
intel_crtc_has_dp_encoder(crtc_state),
3090+
crtc_state->port_clock, crtc_state->lane_count);
3091+
}
3092+
30763093
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
30773094
{
30783095
struct intel_display *display = to_intel_display(encoder);

0 commit comments

Comments
 (0)