Quoting Taniya Das (2019-10-31 05:21:07) > diff --git a/drivers/clk/qcom/clk-alpha-pll.c b/drivers/clk/qcom/clk-alpha-pll.c > index 055318f..8cb77ca 100644 > --- a/drivers/clk/qcom/clk-alpha-pll.c > +++ b/drivers/clk/qcom/clk-alpha-pll.c > @@ -1141,15 +1160,11 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, > unsigned long prate) > { > struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); > - u32 val, l, alpha_width = pll_alpha_width(pll); > + u32 l, alpha_width = pll_alpha_width(pll); > u64 a; > unsigned long rrate; > int ret = 0; > > - ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &val); > - if (ret) > - return ret; > - > rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); > > /* How is this diff related? Looks like it should be split off into another patch to remove a useless register read. > @@ -1167,7 +1182,66 @@ static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, > return __clk_alpha_pll_update_latch(pll); > } > > +static int alpha_pll_fabia_prepare(struct clk_hw *hw) > +{ Why are we doing this in prepare vs. doing it at PLL configuration time? Does it need to be recalibrated each time the PLL is enabled? > + struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); > + const struct pll_vco *vco; > + struct clk_hw *parent_hw; > + unsigned long cal_freq, rrate; > + u32 cal_l, regval, alpha_width = pll_alpha_width(pll); > + u64 a; > + int ret; > + > + /* Check if calibration needs to be done i.e. PLL is in reset */ > + ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), ®val); Please use 'val' instead of 'regval' as regval almost never appears in this file already. > + if (ret) > + return ret; > + > + /* Return early if calibration is not needed. */ > + if (regval & PLL_RESET_N) > + return 0; > + > + vco = alpha_pll_find_vco(pll, clk_hw_get_rate(hw)); > + if (!vco) { > + pr_err("alpha pll: not in a valid vco range\n"); > + return -EINVAL; > + } > + > + cal_freq = DIV_ROUND_CLOSEST((pll->vco_table[0].min_freq + > + pll->vco_table[0].max_freq) * 54, 100); Do we need to cast the first argument to a u64 to avoid overflow? > + > + parent_hw = clk_hw_get_parent(hw); > + if (!parent_hw) > + return -EINVAL; > + > + rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw), > + &cal_l, &a, alpha_width); > + /* > + * Due to a limited number of bits for fractional rate programming, the > + * rounded up rate could be marginally higher than the requested rate. > + */ > + if (rrate > (cal_freq + FABIA_PLL_RATE_MARGIN) || rrate < cal_freq) { > + pr_err("Call set rate on the PLL with rounded rates!\n"); This message is weird. Drivers shouldn't need to call set rate with rounded rates. What is going on? > + return -EINVAL; > + } > + > + /* Setup PLL for calibration frequency */ > + regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); > + > + /* Bringup the pll at calibration frequency */ capitalize PLL. > + ret = clk_alpha_pll_enable(hw); > + if (ret) { > + pr_err("alpha pll calibration failed\n"); > + return ret; > + } > + > + clk_alpha_pll_disable(hw); > + > + return 0; > +} > +