Skip to content

Commit 84da489

Browse files
quic-varadaandersson
authored andcommitted
clk: qcom: clk-alpha-pll: introduce stromer plus ops
Stromer plus APSS PLL does not support dynamic frequency scaling. To switch between frequencies, we have to shut down the PLL, configure the L and ALPHA values and turn on again. So introduce the separate set of ops for Stromer Plus PLL. Reviewed-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Kathiravan T <[email protected]> Signed-off-by: Varadarajan Narayanan <[email protected]> Link: https://lore.kernel.org/r/2affa6c63ff0c4342230623a7d4eef02ec7c02d4.1697781921.git.quic_varada@quicinc.com Signed-off-by: Bjorn Andersson <[email protected]>
1 parent 6a15647 commit 84da489

File tree

2 files changed

+64
-0
lines changed

2 files changed

+64
-0
lines changed

drivers/clk/qcom/clk-alpha-pll.c

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2508,3 +2508,66 @@ const struct clk_ops clk_alpha_pll_stromer_ops = {
25082508
.set_rate = clk_alpha_pll_stromer_set_rate,
25092509
};
25102510
EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_ops);
2511+
2512+
static int clk_alpha_pll_stromer_plus_set_rate(struct clk_hw *hw,
2513+
unsigned long rate,
2514+
unsigned long prate)
2515+
{
2516+
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
2517+
u32 l, alpha_width = pll_alpha_width(pll);
2518+
int ret, pll_mode;
2519+
u64 a;
2520+
2521+
rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
2522+
2523+
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &pll_mode);
2524+
if (ret)
2525+
return ret;
2526+
2527+
regmap_write(pll->clkr.regmap, PLL_MODE(pll), 0);
2528+
2529+
/* Delay of 2 output clock ticks required until output is disabled */
2530+
udelay(1);
2531+
2532+
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
2533+
2534+
if (alpha_width > ALPHA_BITWIDTH)
2535+
a <<= alpha_width - ALPHA_BITWIDTH;
2536+
2537+
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
2538+
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
2539+
a >> ALPHA_BITWIDTH);
2540+
2541+
regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL);
2542+
2543+
/* Wait five micro seconds or more */
2544+
udelay(5);
2545+
regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N,
2546+
PLL_RESET_N);
2547+
2548+
/* The lock time should be less than 50 micro seconds worst case */
2549+
usleep_range(50, 60);
2550+
2551+
ret = wait_for_pll_enable_lock(pll);
2552+
if (ret) {
2553+
pr_err("Wait for PLL enable lock failed [%s] %d\n",
2554+
clk_hw_get_name(hw), ret);
2555+
return ret;
2556+
}
2557+
2558+
if (pll_mode & PLL_OUTCTRL)
2559+
regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL,
2560+
PLL_OUTCTRL);
2561+
2562+
return 0;
2563+
}
2564+
2565+
const struct clk_ops clk_alpha_pll_stromer_plus_ops = {
2566+
.prepare = clk_alpha_pll_enable,
2567+
.unprepare = clk_alpha_pll_disable,
2568+
.is_enabled = clk_alpha_pll_is_enabled,
2569+
.recalc_rate = clk_alpha_pll_recalc_rate,
2570+
.determine_rate = clk_alpha_pll_stromer_determine_rate,
2571+
.set_rate = clk_alpha_pll_stromer_plus_set_rate,
2572+
};
2573+
EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops);

drivers/clk/qcom/clk-alpha-pll.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_ops;
152152
extern const struct clk_ops clk_alpha_pll_huayra_ops;
153153
extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops;
154154
extern const struct clk_ops clk_alpha_pll_stromer_ops;
155+
extern const struct clk_ops clk_alpha_pll_stromer_plus_ops;
155156

156157
extern const struct clk_ops clk_alpha_pll_fabia_ops;
157158
extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops;

0 commit comments

Comments
 (0)