diff options
author | Dave Airlie <airlied@redhat.com> | 2022-05-11 11:00:14 +1000 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2022-05-11 11:00:15 +1000 |
commit | d53b8e19c24bab37f72a2fc4b61d6f4d77b84ab4 (patch) | |
tree | b81a44c03974f710ea2b3b912654d8a078f2b694 /drivers/gpu/drm/i915/display/intel_dpll.c | |
parent | 98bcaafd7fb06647529227561ee72e37d3f00ff0 (diff) | |
parent | 949665a6e237a6fd49ff207e3876d71b20b7e9f2 (diff) |
Merge tag 'drm-intel-next-2022-05-06' of git://anongit.freedesktop.org/drm/drm-intel into drm-next
drm/i915 feature pull #2 for v5.19:
Features and functionality:
- Add first set of DG2 PCI IDs for "motherboard down" designs (Matt Roper)
- Add initial RPL-P PCI IDs as ADL-P subplatform (Matt Atwood)
Refactoring and cleanups:
- Power well refactoring and cleanup (Imre)
- GVT-g refactor and mdev API cleanup (Christoph, Jason, Zhi)
- DPLL refactoring and cleanup (Ville)
- VBT panel specific data parsing cleanup (Ville)
- Use drm_mode_init() for on-stack modes (Ville)
Fixes:
- Fix PSR state pipe A/B confusion by clearing more state on disable (José)
- Fix FIFO underruns caused by not taking DRAM channel into account (Vinod)
- Fix FBC flicker on display 11+ by enabling a workaround (José)
- Fix VBT seamless DRRS min refresh rate check (Ville)
- Fix panel type assumption on bogus VBT data (Ville)
- Fix panel data parsing for VBT that misses panel data pointers block (Ville)
- Fix spurious AUX timeout/hotplug handling on LTTPR links (Imre)
Merges:
- Backmerge drm-next (Jani)
- GVT changes (Jani)
Signed-off-by: Dave Airlie <airlied@redhat.com>
From: Jani Nikula <jani.nikula@intel.com>
Link: https://patchwork.freedesktop.org/patch/msgid/87bkwbkkdo.fsf@intel.com
Diffstat (limited to 'drivers/gpu/drm/i915/display/intel_dpll.c')
-rw-r--r-- | drivers/gpu/drm/i915/display/intel_dpll.c | 196 |
1 files changed, 133 insertions, 63 deletions
diff --git a/drivers/gpu/drm/i915/display/intel_dpll.c b/drivers/gpu/drm/i915/display/intel_dpll.c index 95b9d327ed4d..6eef0b8a91eb 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll.c +++ b/drivers/gpu/drm/i915/display/intel_dpll.c @@ -18,7 +18,10 @@ #include "vlv_sideband.h" struct intel_dpll_funcs { - int (*crtc_compute_clock)(struct intel_crtc_state *crtc_state); + int (*crtc_compute_clock)(struct intel_atomic_state *state, + struct intel_crtc *crtc); + int (*crtc_get_shared_dpll)(struct intel_atomic_state *state, + struct intel_crtc *crtc); }; struct intel_limit { @@ -759,8 +762,8 @@ chv_find_best_dpll(const struct intel_limit *limit, bool bxt_find_best_dpll(struct intel_crtc_state *crtc_state, struct dpll *best_clock) { - int refclk = 100000; const struct intel_limit *limit = &intel_limits_bxt; + int refclk = 100000; return chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, refclk, @@ -927,32 +930,48 @@ static void i8xx_compute_dpll(struct intel_crtc_state *crtc_state, crtc_state->dpll_hw_state.dpll = dpll; } -static int hsw_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int hsw_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_atomic_state *state = - to_intel_atomic_state(crtc_state->uapi.state); + return 0; +} + +static int hsw_crtc_get_shared_dpll(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); struct intel_encoder *encoder = intel_get_crtc_new_encoder(state, crtc_state); - - if (IS_DG2(dev_priv)) - return intel_mpllb_calc_state(crtc_state, encoder); + int ret; if (DISPLAY_VER(dev_priv) < 11 && intel_crtc_has_type(crtc_state, INTEL_OUTPUT_DSI)) return 0; - if (!intel_reserve_shared_dplls(state, crtc, encoder)) { + ret = intel_reserve_shared_dplls(state, crtc, encoder); + if (ret) { drm_dbg_kms(&dev_priv->drm, "failed to find PLL for pipe %c\n", pipe_name(crtc->pipe)); - return -EINVAL; + return ret; } return 0; } +static int dg2_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + struct intel_encoder *encoder = + intel_get_crtc_new_encoder(state, crtc_state); + + return intel_mpllb_calc_state(crtc_state, encoder); +} + static bool ilk_needs_fb_cb_tune(const struct dpll *dpll, int factor) { return dpll->m < factor * dpll->n; @@ -1068,18 +1087,15 @@ static void ilk_compute_dpll(struct intel_crtc_state *crtc_state, crtc_state->dpll_hw_state.dpll = dpll; } -static int ilk_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int ilk_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); - struct intel_atomic_state *state = - to_intel_atomic_state(crtc_state->uapi.state); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; int refclk = 120000; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ if (!crtc_state->has_pch_encoder) return 0; @@ -1118,11 +1134,27 @@ static int ilk_crtc_compute_clock(struct intel_crtc_state *crtc_state) ilk_compute_dpll(crtc_state, &crtc_state->dpll, &crtc_state->dpll); - if (!intel_reserve_shared_dplls(state, crtc, NULL)) { + return 0; +} + +static int ilk_crtc_get_shared_dpll(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + int ret; + + /* CPU eDP is the only output that doesn't need a PCH PLL of its own. */ + if (!crtc_state->has_pch_encoder) + return 0; + + ret = intel_reserve_shared_dplls(state, crtc, NULL); + if (ret) { drm_dbg_kms(&dev_priv->drm, "failed to find PLL for pipe %c\n", pipe_name(crtc->pipe)); - return -EINVAL; + return ret; } return 0; @@ -1163,14 +1195,14 @@ void chv_compute_dpll(struct intel_crtc_state *crtc_state) (crtc_state->pixel_multiplier - 1) << DPLL_MD_UDI_MULTIPLIER_SHIFT; } -static int chv_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int chv_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - int refclk = 100000; + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit = &intel_limits_chv; - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); + int refclk = 100000; if (!crtc_state->clock_set && !chv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, @@ -1184,14 +1216,14 @@ static int chv_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -static int vlv_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int vlv_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - int refclk = 100000; + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit = &intel_limits_vlv; - struct drm_i915_private *i915 = to_i915(crtc_state->uapi.crtc->dev); - - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); + int refclk = 100000; if (!crtc_state->clock_set && !vlv_find_best_dpll(limit, crtc_state, crtc_state->port_clock, @@ -1205,16 +1237,15 @@ static int vlv_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -static int g4x_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int g4x_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; int refclk = 96000; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; @@ -1251,16 +1282,15 @@ static int g4x_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -static int pnv_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int pnv_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; int refclk = 96000; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; @@ -1288,16 +1318,15 @@ static int pnv_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -static int i9xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int i9xx_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; int refclk = 96000; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; @@ -1325,16 +1354,15 @@ static int i9xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } -static int i8xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) +static int i8xx_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + struct drm_i915_private *dev_priv = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); const struct intel_limit *limit; int refclk = 48000; - memset(&crtc_state->dpll_hw_state, 0, - sizeof(crtc_state->dpll_hw_state)); - if (intel_crtc_has_type(crtc_state, INTEL_OUTPUT_LVDS)) { if (intel_panel_use_ssc(dev_priv)) { refclk = dev_priv->vbt.lvds_ssc_freq; @@ -1364,12 +1392,18 @@ static int i8xx_crtc_compute_clock(struct intel_crtc_state *crtc_state) return 0; } +static const struct intel_dpll_funcs dg2_dpll_funcs = { + .crtc_compute_clock = dg2_crtc_compute_clock, +}; + static const struct intel_dpll_funcs hsw_dpll_funcs = { .crtc_compute_clock = hsw_crtc_compute_clock, + .crtc_get_shared_dpll = hsw_crtc_get_shared_dpll, }; static const struct intel_dpll_funcs ilk_dpll_funcs = { .crtc_compute_clock = ilk_crtc_compute_clock, + .crtc_get_shared_dpll = ilk_crtc_get_shared_dpll, }; static const struct intel_dpll_funcs chv_dpll_funcs = { @@ -1396,18 +1430,54 @@ static const struct intel_dpll_funcs i8xx_dpll_funcs = { .crtc_compute_clock = i8xx_crtc_compute_clock, }; -int intel_dpll_crtc_compute_clock(struct intel_crtc_state *crtc_state) +int intel_dpll_crtc_compute_clock(struct intel_atomic_state *state, + struct intel_crtc *crtc) { - struct intel_crtc *crtc = to_intel_crtc(crtc_state->uapi.crtc); - struct drm_i915_private *i915 = to_i915(crtc->base.dev); + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); + + if (drm_WARN_ON(&i915->drm, crtc_state->shared_dpll)) + return 0; - return i915->dpll_funcs->crtc_compute_clock(crtc_state); + memset(&crtc_state->dpll_hw_state, 0, + sizeof(crtc_state->dpll_hw_state)); + + if (!crtc_state->hw.enable) + return 0; + + return i915->dpll_funcs->crtc_compute_clock(state, crtc); +} + +int intel_dpll_crtc_get_shared_dpll(struct intel_atomic_state *state, + struct intel_crtc *crtc) +{ + struct drm_i915_private *i915 = to_i915(state->base.dev); + struct intel_crtc_state *crtc_state = + intel_atomic_get_new_crtc_state(state, crtc); + + drm_WARN_ON(&i915->drm, !intel_crtc_needs_modeset(crtc_state)); + + if (drm_WARN_ON(&i915->drm, crtc_state->shared_dpll)) + return 0; + + if (!crtc_state->hw.enable) + return 0; + + if (!i915->dpll_funcs->crtc_get_shared_dpll) + return 0; + + return i915->dpll_funcs->crtc_get_shared_dpll(state, crtc); } void intel_dpll_init_clock_hook(struct drm_i915_private *dev_priv) { - if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) + if (IS_DG2(dev_priv)) + dev_priv->dpll_funcs = &dg2_dpll_funcs; + else if (DISPLAY_VER(dev_priv) >= 9 || HAS_DDI(dev_priv)) dev_priv->dpll_funcs = &hsw_dpll_funcs; else if (HAS_PCH_SPLIT(dev_priv)) dev_priv->dpll_funcs = &ilk_dpll_funcs; |