summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/i915/display/intel_dpll_mgr.c26
1 files changed, 24 insertions, 2 deletions
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 @@ out:
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;
}