Commit 61a31292 authored by Taniya Das's avatar Taniya Das Committed by Stephen Boyd

clk: qcom: clk-alpha-pll: Add support for helper functions

Introduce clk_alpha_pll_write_config and alpha_pll_check_rate_margin
helper functions to be across PLL configure functions and PLL set rate
functions.
Signed-off-by: default avatarTaniya Das <tdas@codeaurora.org>
Link: https://lore.kernel.org/r/1602873815-1677-2-git-send-email-tdas@codeaurora.orgSigned-off-by: default avatarStephen Boyd <sboyd@kernel.org>
parent 3650b228
...@@ -207,6 +207,13 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse, ...@@ -207,6 +207,13 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
#define wait_for_pll_update_ack_clear(pll) \ #define wait_for_pll_update_ack_clear(pll) \
wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear") wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear")
static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg,
unsigned int val)
{
if (val)
regmap_write(regmap, reg, val);
}
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config) const struct alpha_pll_config *config)
{ {
...@@ -1004,33 +1011,19 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, ...@@ -1004,33 +1011,19 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
{ {
u32 val, mask; u32 val, mask;
if (config->l) clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
regmap_write(regmap, PLL_L_VAL(pll), config->l); clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
if (config->alpha)
regmap_write(regmap, PLL_FRAC(pll), config->alpha);
if (config->config_ctl_val)
regmap_write(regmap, PLL_CONFIG_CTL(pll),
config->config_ctl_val); config->config_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
if (config->config_ctl_hi_val)
regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
config->config_ctl_hi_val); config->config_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
if (config->user_ctl_val) config->user_ctl_val);
regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val); clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
if (config->user_ctl_hi_val)
regmap_write(regmap, PLL_USER_CTL_U(pll),
config->user_ctl_hi_val); config->user_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
if (config->test_ctl_val)
regmap_write(regmap, PLL_TEST_CTL(pll),
config->test_ctl_val); config->test_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
if (config->test_ctl_hi_val)
regmap_write(regmap, PLL_TEST_CTL_U(pll),
config->test_ctl_hi_val); config->test_ctl_hi_val);
if (config->post_div_mask) { if (config->post_div_mask) {
...@@ -1145,25 +1138,38 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw, ...@@ -1145,25 +1138,38 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw,
return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width); return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
} }
/*
* Due to limited number of bits for fractional rate programming, the
* rounded up rate could be marginally higher than the requested rate.
*/
static int alpha_pll_check_rate_margin(struct clk_hw *hw,
unsigned long rrate, unsigned long rate)
{
unsigned long rate_margin = rate + PLL_RATE_MARGIN;
if (rrate > rate_margin || rrate < rate) {
pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
clk_hw_get_name(hw), rrate, rate, rate_margin);
return -EINVAL;
}
return 0;
}
static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate, static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long prate) unsigned long prate)
{ {
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw); struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
u32 l, alpha_width = pll_alpha_width(pll); u32 l, alpha_width = pll_alpha_width(pll);
unsigned long rrate;
int ret;
u64 a; u64 a;
unsigned long rrate, max = rate + PLL_RATE_MARGIN;
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
/* ret = alpha_pll_check_rate_margin(hw, rrate, rate);
* Due to limited number of bits for fractional rate programming, the if (ret < 0)
* rounded up rate could be marginally higher than the requested rate. return ret;
*/
if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
clk_hw_get_name(hw), rrate, rate, max);
return -EINVAL;
}
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a); regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a);
...@@ -1206,12 +1212,10 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw) ...@@ -1206,12 +1212,10 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw)
rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw), rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
&cal_l, &a, alpha_width); &cal_l, &a, alpha_width);
/*
* Due to a limited number of bits for fractional rate programming, the ret = alpha_pll_check_rate_margin(hw, rrate, cal_freq);
* rounded up rate could be marginally higher than the requested rate. if (ret < 0)
*/ return ret;
if (rrate > (cal_freq + PLL_RATE_MARGIN) || rrate < cal_freq)
return -EINVAL;
/* Setup PLL for calibration frequency */ /* Setup PLL for calibration frequency */
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l); regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l);
...@@ -1388,49 +1392,27 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops); ...@@ -1388,49 +1392,27 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap, void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config) const struct alpha_pll_config *config)
{ {
if (config->l) clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
regmap_write(regmap, PLL_L_VAL(pll), config->l);
regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL); regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
if (config->alpha) clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha); config->config_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
if (config->config_ctl_val) config->config_ctl_hi_val);
regmap_write(regmap, PLL_CONFIG_CTL(pll), clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),
config->config_ctl_val); config->config_ctl_hi1_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
if (config->config_ctl_hi_val) config->user_ctl_val);
regmap_write(regmap, PLL_CONFIG_CTL_U(pll), clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
config->config_ctl_hi_val); config->user_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),
if (config->config_ctl_hi1_val) config->user_ctl_hi1_val);
regmap_write(regmap, PLL_CONFIG_CTL_U1(pll), clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
config->config_ctl_hi1_val); config->test_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
if (config->user_ctl_val) config->test_ctl_hi_val);
regmap_write(regmap, PLL_USER_CTL(pll), clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),
config->user_ctl_val); config->test_ctl_hi1_val);
if (config->user_ctl_hi_val)
regmap_write(regmap, PLL_USER_CTL_U(pll),
config->user_ctl_hi_val);
if (config->user_ctl_hi1_val)
regmap_write(regmap, PLL_USER_CTL_U1(pll),
config->user_ctl_hi1_val);
if (config->test_ctl_val)
regmap_write(regmap, PLL_TEST_CTL(pll),
config->test_ctl_val);
if (config->test_ctl_hi_val)
regmap_write(regmap, PLL_TEST_CTL_U(pll),
config->test_ctl_hi_val);
if (config->test_ctl_hi1_val)
regmap_write(regmap, PLL_TEST_CTL_U1(pll),
config->test_ctl_hi1_val);
regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS, regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
PLL_UPDATE_BYPASS); PLL_UPDATE_BYPASS);
...@@ -1490,14 +1472,9 @@ static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate, ...@@ -1490,14 +1472,9 @@ static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width); rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
/* ret = alpha_pll_check_rate_margin(hw, rrate, rate);
* Due to a limited number of bits for fractional rate programming, the if (ret < 0)
* rounded up rate could be marginally higher than the requested rate. return ret;
*/
if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
pr_err("Call set rate on the PLL with rounded rates!\n");
return -EINVAL;
}
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l); regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a); regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment