drm/i915/cx0: Add MTL+ Thunderbolt PLL hooks

Add the PLL hooks for the TBT PLL on MTL+. These are simple stubs
similarly to the TBT PLL on earlier platforms, since this PLL is always
on from the display POV - so no PLL enable/disable programming is
required as opposed to the non-TBT PLLs - and the clocks for different
link rates are enabled/disabled at a different level, via the
intel_encoder::enable_clock()/disable_clock() interface.

Signed-off-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Mika Kahola <mika.kahola@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://lore.kernel.org/r/20251117104602.2363671-32-mika.kahola@intel.com
This commit is contained in:
Imre Deak 2025-11-17 12:46:01 +02:00 committed by Mika Kahola
parent 6b566d066c
commit 2a6e417907
3 changed files with 59 additions and 2 deletions

View File

@ -3283,6 +3283,24 @@ static void intel_cx0pll_enable(struct intel_encoder *encoder,
intel_cx0_phy_transaction_end(encoder, wakeref);
}
void intel_mtl_tbt_pll_calc_state(struct intel_dpll_hw_state *hw_state)
{
memset(hw_state, 0, sizeof(*hw_state));
hw_state->cx0pll.tbt_mode = true;
}
bool intel_mtl_tbt_pll_readout_hw_state(struct intel_display *display,
struct intel_dpll *pll,
struct intel_dpll_hw_state *hw_state)
{
memset(hw_state, 0, sizeof(*hw_state));
hw_state->cx0pll.tbt_mode = true;
return true;
}
int intel_mtl_tbt_calc_port_clock(struct intel_encoder *encoder)
{
struct intel_display *display = to_intel_display(encoder);

View File

@ -70,7 +70,13 @@ void intel_cx0_write(struct intel_encoder *encoder,
int intel_cx0_wait_for_ack(struct intel_encoder *encoder,
int command, int lane, u32 *val);
void intel_cx0_bus_reset(struct intel_encoder *encoder, int lane);
void intel_mtl_tbt_pll_calc_state(struct intel_dpll_hw_state *hw_state);
bool intel_mtl_tbt_pll_readout_hw_state(struct intel_display *display,
struct intel_dpll *pll,
struct intel_dpll_hw_state *hw_state);
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,
const struct intel_crtc_state *crtc_state);

View File

@ -4421,10 +4421,42 @@ static const struct intel_dpll_funcs mtl_pll_funcs = {
.get_freq = mtl_pll_get_freq,
};
static void mtl_tbt_pll_enable(struct intel_display *display,
struct intel_dpll *pll,
const struct intel_dpll_hw_state *hw_state)
{
}
static void mtl_tbt_pll_disable(struct intel_display *display,
struct intel_dpll *pll)
{
}
static int mtl_tbt_pll_get_freq(struct intel_display *display,
const struct intel_dpll *pll,
const struct intel_dpll_hw_state *dpll_hw_state)
{
/*
* The PLL outputs multiple frequencies at the same time, selection is
* made at DDI clock mux level.
*/
drm_WARN_ON(display->drm, 1);
return 0;
}
static const struct intel_dpll_funcs mtl_tbt_pll_funcs = {
.enable = mtl_tbt_pll_enable,
.disable = mtl_tbt_pll_disable,
.get_hw_state = intel_mtl_tbt_pll_readout_hw_state,
.get_freq = mtl_tbt_pll_get_freq,
};
static const struct dpll_info mtl_plls[] = {
{ .name = "DPLL 0", .funcs = &mtl_pll_funcs, .id = DPLL_ID_ICL_DPLL0, },
{ .name = "DPLL 1", .funcs = &mtl_pll_funcs, .id = DPLL_ID_ICL_DPLL1, },
/* TODO: Add TBT PLL */
{ .name = "TBT PLL", .funcs = &mtl_tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL,
.is_alt_port_dpll = true, .always_on = true },
{ .name = "TC PLL 1", .funcs = &mtl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, },
{ .name = "TC PLL 2", .funcs = &mtl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, },
{ .name = "TC PLL 3", .funcs = &mtl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, },
@ -4470,7 +4502,8 @@ static int mtl_compute_tc_phy_dplls(struct intel_atomic_state *state,
struct icl_port_dpll *port_dpll;
int ret;
/* TODO: Add state calculation for TBT PLL */
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_DEFAULT];
intel_mtl_tbt_pll_calc_state(&port_dpll->hw_state);
port_dpll = &crtc_state->icl_port_dplls[ICL_PORT_DPLL_MG_PHY];
ret = intel_cx0pll_calc_state(crtc_state, encoder, &port_dpll->hw_state);