Skip to content

Commit b60b0b5

Browse files
pcercueibebarino
authored andcommitted
clk: ingenic: Support overriding PLLs M/N/OD calc algorithm
SoC-specific code can now provide a callback if they need to compute the M/N/OD values in a specific way. Signed-off-by: Paul Cercueil <[email protected]> Tested-by: 周琰杰 (Zhou Yanjie)<[email protected]> # on CU1000-neo/X1000E Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Stephen Boyd <[email protected]>
1 parent 037f1ff commit b60b0b5

File tree

2 files changed

+30
-13
lines changed

2 files changed

+30
-13
lines changed

drivers/clk/ingenic/cgu.c

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -119,28 +119,42 @@ ingenic_pll_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
119119
n * od);
120120
}
121121

122-
static unsigned long
123-
ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
124-
unsigned long rate, unsigned long parent_rate,
125-
unsigned *pm, unsigned *pn, unsigned *pod)
122+
static void
123+
ingenic_pll_calc_m_n_od(const struct ingenic_cgu_pll_info *pll_info,
124+
unsigned long rate, unsigned long parent_rate,
125+
unsigned int *pm, unsigned int *pn, unsigned int *pod)
126126
{
127-
const struct ingenic_cgu_pll_info *pll_info;
128-
unsigned m, n, od;
129-
130-
pll_info = &clk_info->pll;
131-
od = 1;
127+
unsigned int m, n, od = 1;
132128

133129
/*
134130
* The frequency after the input divider must be between 10 and 50 MHz.
135131
* The highest divider yields the best resolution.
136132
*/
137133
n = parent_rate / (10 * MHZ);
138-
n = min_t(unsigned, n, 1 << clk_info->pll.n_bits);
139-
n = max_t(unsigned, n, pll_info->n_offset);
134+
n = min_t(unsigned int, n, 1 << pll_info->n_bits);
135+
n = max_t(unsigned int, n, pll_info->n_offset);
140136

141137
m = (rate / MHZ) * od * n / (parent_rate / MHZ);
142-
m = min_t(unsigned, m, 1 << clk_info->pll.m_bits);
143-
m = max_t(unsigned, m, pll_info->m_offset);
138+
m = min_t(unsigned int, m, 1 << pll_info->m_bits);
139+
m = max_t(unsigned int, m, pll_info->m_offset);
140+
141+
*pm = m;
142+
*pn = n;
143+
*pod = od;
144+
}
145+
146+
static unsigned long
147+
ingenic_pll_calc(const struct ingenic_cgu_clk_info *clk_info,
148+
unsigned long rate, unsigned long parent_rate,
149+
unsigned int *pm, unsigned int *pn, unsigned int *pod)
150+
{
151+
const struct ingenic_cgu_pll_info *pll_info = &clk_info->pll;
152+
unsigned int m, n, od;
153+
154+
if (pll_info->calc_m_n_od)
155+
(*pll_info->calc_m_n_od)(pll_info, rate, parent_rate, &m, &n, &od);
156+
else
157+
ingenic_pll_calc_m_n_od(pll_info, rate, parent_rate, &m, &n, &od);
144158

145159
if (pm)
146160
*pm = m;

drivers/clk/ingenic/cgu.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ struct ingenic_cgu_pll_info {
5555
s8 bypass_bit;
5656
u8 enable_bit;
5757
u8 stable_bit;
58+
void (*calc_m_n_od)(const struct ingenic_cgu_pll_info *pll_info,
59+
unsigned long rate, unsigned long parent_rate,
60+
unsigned int *m, unsigned int *n, unsigned int *od);
5861
};
5962

6063
/**

0 commit comments

Comments
 (0)