summaryrefslogtreecommitdiff
path: root/drivers/media/i2c/ccs-pll.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/i2c/ccs-pll.c')
-rw-r--r--drivers/media/i2c/ccs-pll.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/drivers/media/i2c/ccs-pll.c b/drivers/media/i2c/ccs-pll.c
index cf8858cb13d4..611c9823be85 100644
--- a/drivers/media/i2c/ccs-pll.c
+++ b/drivers/media/i2c/ccs-pll.c
@@ -312,6 +312,11 @@ __ccs_pll_calculate_vt_tree(struct device *dev,
dev_dbg(dev, "more_mul2: %u\n", more_mul);
pll_fr->pll_multiplier = mul * more_mul;
+ if (pll_fr->pll_multiplier > lim_fr->max_pll_multiplier) {
+ dev_dbg(dev, "pll multiplier %u too high\n",
+ pll_fr->pll_multiplier);
+ return -EINVAL;
+ }
if (pll_fr->pll_multiplier * pll_fr->pll_ip_clk_freq_hz >
lim_fr->max_pll_op_clk_freq_hz)
@@ -397,6 +402,8 @@ static int ccs_pll_calculate_vt_tree(struct device *dev,
min_pre_pll_clk_div = max_t(u16, min_pre_pll_clk_div,
pll->ext_clk_freq_hz /
lim_fr->max_pll_ip_clk_freq_hz);
+ if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
+ min_pre_pll_clk_div = clk_div_even(min_pre_pll_clk_div);
dev_dbg(dev, "vt min/max_pre_pll_clk_div: %u,%u\n",
min_pre_pll_clk_div, max_pre_pll_clk_div);
@@ -792,7 +799,7 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
op_lim_fr->min_pre_pll_clk_div, op_lim_fr->max_pre_pll_clk_div);
max_op_pre_pll_clk_div =
min_t(u16, op_lim_fr->max_pre_pll_clk_div,
- clk_div_even(pll->ext_clk_freq_hz /
+ DIV_ROUND_UP(pll->ext_clk_freq_hz,
op_lim_fr->min_pll_ip_clk_freq_hz));
min_op_pre_pll_clk_div =
max_t(u16, op_lim_fr->min_pre_pll_clk_div,
@@ -815,6 +822,8 @@ int ccs_pll_calculate(struct device *dev, const struct ccs_pll_limits *lim,
one_or_more(
DIV_ROUND_UP(op_lim_fr->max_pll_op_clk_freq_hz,
pll->ext_clk_freq_hz))));
+ if (!(pll->flags & CCS_PLL_FLAG_EXT_IP_PLL_DIVIDER))
+ min_op_pre_pll_clk_div = clk_div_even(min_op_pre_pll_clk_div);
dev_dbg(dev, "pll_op check: min / max op_pre_pll_clk_div: %u / %u\n",
min_op_pre_pll_clk_div, max_op_pre_pll_clk_div);