The current algorithm is very wrong and was made wrose with changes in algorithm that were done. It needs to be rewritten to be able to extract the correct values and get the right port clock.
Bspec: 74667 Signed-off-by: Nemesa Garg <[email protected]> Signed-off-by: Suraj Kandpal <[email protected]> --- drivers/gpu/drm/i915/display/intel_dpll.c | 2 + drivers/gpu/drm/i915/display/intel_lt_phy.c | 80 +++++++++++++++++++++ drivers/gpu/drm/i915/display/intel_lt_phy.h | 3 + 3 files changed, 85 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 8c3ef5867a12..2e1f67be8eda 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -1247,6 +1247,8 @@ static int xe3plpd_crtc_compute_clock(struct intel_atomic_state *state, return ret; /* TODO: Do the readback via intel_compute_shared_dplls() */ + crtc_state->port_clock = + intel_lt_phy_calc_port_clock(encoder, crtc_state); crtc_state->hw.adjusted_mode.crtc_clock = intel_crtc_dotclock(crtc_state); diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.c b/drivers/gpu/drm/i915/display/intel_lt_phy.c index 6ee785fbcad2..3aa8b3b345d3 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.c +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.c @@ -1236,6 +1236,86 @@ intel_lt_phy_pll_is_ssc_enabled(struct intel_crtc_state *crtc_state, return false; } +static int +intel_lt_phy_calc_hdmi_port_clock(const struct intel_lt_phy_pll_state *lt_state) +{ +#define DIV_CONST 10000000 +#define REF_CLK 38400 +#define REGVAL(i) ( \ + (lt_state->data[i][3]) | \ + (lt_state->data[i][2] << 8) | \ + (lt_state->data[i][1] << 16) | \ + (lt_state->data[i][0] << 24) \ +) + + int clk = 0; + u32 d8, pll_reg_5, pll_reg_3, pll_reg_57, m2div_frac, m2div_int; + u64 temp0, temp1; + + /* + * d7 max val can be 10 so 4 bits + * postdiv can be max 9 hence needs 4 bits + * d8 since loop_cnt / 2 and loop count can be max 255 + * henc we needs only 7 bits to represent but 8 bits is given. + * d8 since loop_cnt / 2 and loop count can be max 255 + * hence we needs only 7 bits to represent but 8 bits is given + * PLL_reg57 = ((D7 << 24) + (postdiv << 15) + (D8 << 7) + D6_new); + * PLL_reg57 = ((D7 << 24) + (postdiv << 15) + (D8 << 7) + D6_new); + * d4 max val can be 256 so 9 bits + * d3 can be max 9 hence needs 4 bits + * d1 can be max 2 hence needs 2 bits + * m2div can never be > 511 hence m2div_int + * usees up to 9 bits but since it is shifted + * by 5 in forward algo and then d1 is shifted to 15th bit + * it has 10 bits. + * PLL_reg3 = (uint32_t)((D4 << 21) + (D3 << 18) + (D1 << 15)+ (m2div_int << 5)); + */ + + pll_reg_5 = REGVAL(2); + pll_reg_3 = REGVAL(1); + pll_reg_57 = REGVAL(3); + m2div_frac = pll_reg_5; + + d8 = (pll_reg_57 & REG_GENMASK(14, 7)) >> 7; + m2div_int = (pll_reg_3 & REG_GENMASK(14, 5)) >> 5; + temp0 = ((u64)m2div_frac * REF_CLK) >> 32; + temp1 = (u64)m2div_int * REF_CLK; + if (d8 == 0) + return 0; + + clk = div_u64((temp1 + temp0), d8 * 10); + + return clk; +} + +int +intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state) +{ + int clk; + const struct intel_lt_phy_pll_state *lt_state = + &crtc_state->dpll_hw_state.ltpll; + u8 mode, rate; + + mode = REG_FIELD_GET8(LT_PHY_VDR_MODE_ENCODING_MASK, + lt_state->config[0]); + /* + * For edp/dp read the clock value from the tables + * and return the clock as the algorithm used for + * calculating the port clock does not exactly matches + * with edp/dp clock. + */ + if (mode == MODE_DP) { + rate = REG_FIELD_GET8(LT_PHY_VDR_RATE_ENCODING_MASK, + lt_state->config[0]); + clk = intel_lt_phy_get_dp_clock(rate); + } else { + clk = intel_lt_phy_calc_hdmi_port_clock(lt_state); + } + + return clk; +} + int intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder) diff --git a/drivers/gpu/drm/i915/display/intel_lt_phy.h b/drivers/gpu/drm/i915/display/intel_lt_phy.h index 3f255c9b0f96..5b4e0d9c940f 100644 --- a/drivers/gpu/drm/i915/display/intel_lt_phy.h +++ b/drivers/gpu/drm/i915/display/intel_lt_phy.h @@ -10,12 +10,15 @@ struct intel_encoder; struct intel_crtc_state; +struct intel_lt_phy_pll_state; void intel_lt_phy_pll_enable(struct intel_encoder *encoder, const struct intel_crtc_state *crtc_state); int intel_lt_phy_pll_calc_state(struct intel_crtc_state *crtc_state, struct intel_encoder *encoder); +int intel_lt_phy_calc_port_clock(struct intel_encoder *encoder, + const struct intel_crtc_state *crtc_state); #define HAS_LT_PHY(display) (DISPLAY_VER(display) >= 35) -- 2.34.1
