diff --git a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c index 614fdc21bde0..5b0ad34132c6 100644 --- a/drivers/gpu/drm/i915/display/intel_dpll_mgr.c +++ b/drivers/gpu/drm/i915/display/intel_dpll_mgr.c @@ -314,6 +314,23 @@ void intel_disable_shared_dpll(const struct intel_crtc_state *crtc_state) mutex_unlock(&dev_priv->display.dpll.lock); } +static unsigned long +intel_dpll_mask_all(struct drm_i915_private *i915) +{ + unsigned long dpll_mask = 0; + int i; + + for (i = 0; i < i915->display.dpll.num_shared_dpll; i++) { + struct intel_shared_dpll *pll = &i915->display.dpll.shared_dplls[i]; + + drm_WARN_ON(&i915->drm, dpll_mask & BIT(pll->info->id)); + + dpll_mask |= BIT(pll->info->id); + } + + return dpll_mask; +} + static struct intel_shared_dpll * intel_find_shared_dpll(struct intel_atomic_state *state, const struct intel_crtc *crtc, @@ -321,15 +338,16 @@ intel_find_shared_dpll(struct intel_atomic_state *state, unsigned long dpll_mask) { struct drm_i915_private *dev_priv = to_i915(crtc->base.dev); + unsigned long dpll_mask_all = intel_dpll_mask_all(dev_priv); struct intel_shared_dpll_state *shared_dpll; struct intel_shared_dpll *unused_pll = NULL; enum intel_dpll_id id; shared_dpll = intel_atomic_get_shared_dpll_state(&state->base); - drm_WARN_ON(&dev_priv->drm, dpll_mask & ~(BIT(I915_NUM_PLLS) - 1)); + drm_WARN_ON(&dev_priv->drm, dpll_mask & ~dpll_mask_all); - for_each_set_bit(id, &dpll_mask, I915_NUM_PLLS) { + for_each_set_bit(id, &dpll_mask, fls(dpll_mask_all)) { struct intel_shared_dpll *pll; pll = intel_get_shared_dpll_by_id(dev_priv, id); @@ -4189,6 +4207,10 @@ void intel_shared_dpll_init(struct drm_i915_private *dev_priv) i >= ARRAY_SIZE(dev_priv->display.dpll.shared_dplls))) break; + /* must fit into unsigned long bitmask on 32bit */ + if (drm_WARN_ON(&dev_priv->drm, dpll_info[i].id >= 32)) + break; + dev_priv->display.dpll.shared_dplls[i].info = &dpll_info[i]; dev_priv->display.dpll.shared_dplls[i].index = i; }