6.7-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä ville.syrjala@linux.intel.com
commit 33c7760226c79ee8de6c0646640963a8a7ee794a upstream.
TC ports have both the MG/TC and TBT PLLs selected simultanously (so that we can switch from MG/TC to TBT as a fallback). This doesn't play well with the state checker that assumes that the old PLL shouldn't have the pipe in its pipe_mask anymore. Suppress that check for these PLLs to avoid spurious WARNs when you disconnect a TC port and a non-disabling modeset happens before actually disabling the port.
v2: Only suppress when one of the PLLs is the TBT PLL and the other one is not
Closes: https://gitlab.freedesktop.org/drm/intel/-/issues/9816 Signed-off-by: Ville Syrjälä ville.syrjala@linux.intel.com Link: https://patchwork.freedesktop.org/patch/msgid/20240123093137.9133-2-ville.sy... Reviewed-by: Jani Nikula jani.nikula@intel.com Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org --- drivers/gpu/drm/i915/display/intel_dpll_mgr.c | 23 +++++++++++++++++++---- drivers/gpu/drm/i915/display/intel_dpll_mgr.h | 4 ++++ 2 files changed, 23 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -4026,7 +4026,8 @@ static const struct intel_shared_dpll_fu static const struct dpll_info icl_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "MG PLL 1", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "MG PLL 2", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "MG PLL 3", .funcs = &mg_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4070,7 +4071,8 @@ static const struct intel_shared_dpll_fu static const struct dpll_info tgl_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4143,7 +4145,8 @@ static const struct intel_dpll_mgr adls_ static const struct dpll_info adlp_plls[] = { { .name = "DPLL 0", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL0, }, { .name = "DPLL 1", .funcs = &combo_pll_funcs, .id = DPLL_ID_ICL_DPLL1, }, - { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, }, + { .name = "TBT PLL", .funcs = &tbt_pll_funcs, .id = DPLL_ID_ICL_TBTPLL, + .flags = INTEL_DPLL_IS_ALT_PORT_DPLL, }, { .name = "TC PLL 1", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL1, }, { .name = "TC PLL 2", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL2, }, { .name = "TC PLL 3", .funcs = &dkl_pll_funcs, .id = DPLL_ID_ICL_MGPLL3, }, @@ -4521,6 +4524,14 @@ verify_single_dpll_state(struct drm_i915 pll->info->name); }
+static bool has_alt_port_dpll(const struct intel_shared_dpll *old_pll, + const struct intel_shared_dpll *new_pll) +{ + return old_pll && new_pll && old_pll != new_pll && + (old_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL || + new_pll->info->flags & INTEL_DPLL_IS_ALT_PORT_DPLL); +} + void intel_shared_dpll_state_verify(struct intel_atomic_state *state, struct intel_crtc *crtc) { @@ -4542,7 +4553,11 @@ void intel_shared_dpll_state_verify(stru I915_STATE_WARN(i915, pll->active_mask & pipe_mask, "%s: pll active mismatch (didn't expect pipe %c in active mask (0x%x))\n", pll->info->name, pipe_name(crtc->pipe), pll->active_mask); - I915_STATE_WARN(i915, pll->state.pipe_mask & pipe_mask, + + /* TC ports have both MG/TC and TBT PLL referenced simultaneously */ + I915_STATE_WARN(i915, !has_alt_port_dpll(old_crtc_state->shared_dpll, + new_crtc_state->shared_dpll) && + pll->state.pipe_mask & pipe_mask, "%s: pll enabled crtcs mismatch (found pipe %c in enabled mask (0x%x))\n", pll->info->name, pipe_name(crtc->pipe), pll->state.pipe_mask); } --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.h +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.h @@ -271,12 +271,16 @@ struct dpll_info { enum intel_dpll_id id;
#define INTEL_DPLL_ALWAYS_ON (1 << 0) +#define INTEL_DPLL_IS_ALT_PORT_DPLL (1 << 1) /** * @flags: * * INTEL_DPLL_ALWAYS_ON * Inform the state checker that the DPLL is kept enabled even if * not in use by any CRTC. + * INTEL_DPLL_IS_ALT_PORT_DPLL + * Inform the state checker that the DPLL can be used as a fallback + * (for TC->TBT fallback). */ u32 flags; };