53
53
.odiv = (_odiv), \
54
54
}
55
55
56
+ #define PLL_FRACN_GP_INTEGER (_rate , _mfi , _rdiv , _odiv ) \
57
+ { \
58
+ .rate = (_rate), \
59
+ .mfi = (_mfi), \
60
+ .mfn = 0, \
61
+ .mfd = 0, \
62
+ .rdiv = (_rdiv), \
63
+ .odiv = (_odiv), \
64
+ }
65
+
56
66
struct clk_fracn_gppll {
57
67
struct clk_hw hw ;
58
68
void __iomem * base ;
59
69
const struct imx_fracn_gppll_rate_table * rate_table ;
60
70
int rate_count ;
71
+ u32 flags ;
61
72
};
62
73
63
74
/*
@@ -83,6 +94,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
83
94
};
84
95
EXPORT_SYMBOL_GPL (imx_fracn_gppll );
85
96
97
+ /*
98
+ * Fvco = (Fref / rdiv) * MFI
99
+ * Fout = Fvco / odiv
100
+ * The (Fref / rdiv) should be in range 20MHz to 40MHz
101
+ * The Fvco should be in range 2.5Ghz to 5Ghz
102
+ */
103
+ static const struct imx_fracn_gppll_rate_table int_tbl [] = {
104
+ PLL_FRACN_GP_INTEGER (1700000000U , 141 , 1 , 2 ),
105
+ PLL_FRACN_GP_INTEGER (1400000000U , 175 , 1 , 3 ),
106
+ PLL_FRACN_GP_INTEGER (900000000U , 150 , 1 , 4 ),
107
+ };
108
+
109
+ struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
110
+ .rate_table = int_tbl ,
111
+ .rate_count = ARRAY_SIZE (int_tbl ),
112
+ };
113
+ EXPORT_SYMBOL_GPL (imx_fracn_gppll_integer );
114
+
86
115
static inline struct clk_fracn_gppll * to_clk_fracn_gppll (struct clk_hw * hw )
87
116
{
88
117
return container_of (hw , struct clk_fracn_gppll , hw );
@@ -169,9 +198,15 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
169
198
break ;
170
199
}
171
200
172
- /* Fvco = Fref * (MFI + MFN / MFD) */
173
- fvco = fvco * mfi * mfd + fvco * mfn ;
174
- do_div (fvco , mfd * rdiv * odiv );
201
+ if (pll -> flags & CLK_FRACN_GPPLL_INTEGER ) {
202
+ /* Fvco = (Fref / rdiv) * MFI */
203
+ fvco = fvco * mfi ;
204
+ do_div (fvco , rdiv * odiv );
205
+ } else {
206
+ /* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */
207
+ fvco = fvco * mfi * mfd + fvco * mfn ;
208
+ do_div (fvco , mfd * rdiv * odiv );
209
+ }
175
210
176
211
return (unsigned long )fvco ;
177
212
}
@@ -215,8 +250,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
215
250
pll_div = FIELD_PREP (PLL_RDIV_MASK , rate -> rdiv ) | rate -> odiv |
216
251
FIELD_PREP (PLL_MFI_MASK , rate -> mfi );
217
252
writel_relaxed (pll_div , pll -> base + PLL_DIV );
218
- writel_relaxed (rate -> mfd , pll -> base + PLL_DENOMINATOR );
219
- writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate -> mfn ), pll -> base + PLL_NUMERATOR );
253
+ if (pll -> flags & CLK_FRACN_GPPLL_FRACN ) {
254
+ writel_relaxed (rate -> mfd , pll -> base + PLL_DENOMINATOR );
255
+ writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate -> mfn ), pll -> base + PLL_NUMERATOR );
256
+ }
220
257
221
258
/* Wait for 5us according to fracn mode pll doc */
222
259
udelay (5 );
@@ -300,8 +337,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
300
337
.set_rate = clk_fracn_gppll_set_rate ,
301
338
};
302
339
303
- struct clk_hw * imx_clk_fracn_gppll (const char * name , const char * parent_name , void __iomem * base ,
304
- const struct imx_fracn_gppll_clk * pll_clk )
340
+ static struct clk_hw * _imx_clk_fracn_gppll (const char * name , const char * parent_name ,
341
+ void __iomem * base ,
342
+ const struct imx_fracn_gppll_clk * pll_clk ,
343
+ u32 pll_flags )
305
344
{
306
345
struct clk_fracn_gppll * pll ;
307
346
struct clk_hw * hw ;
@@ -322,6 +361,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
322
361
pll -> hw .init = & init ;
323
362
pll -> rate_table = pll_clk -> rate_table ;
324
363
pll -> rate_count = pll_clk -> rate_count ;
364
+ pll -> flags = pll_flags ;
325
365
326
366
hw = & pll -> hw ;
327
367
@@ -334,4 +374,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
334
374
335
375
return hw ;
336
376
}
377
+
378
+ struct clk_hw * imx_clk_fracn_gppll (const char * name , const char * parent_name , void __iomem * base ,
379
+ const struct imx_fracn_gppll_clk * pll_clk )
380
+ {
381
+ return _imx_clk_fracn_gppll (name , parent_name , base , pll_clk , CLK_FRACN_GPPLL_FRACN );
382
+ }
337
383
EXPORT_SYMBOL_GPL (imx_clk_fracn_gppll );
384
+
385
+ struct clk_hw * imx_clk_fracn_gppll_integer (const char * name , const char * parent_name ,
386
+ void __iomem * base ,
387
+ const struct imx_fracn_gppll_clk * pll_clk )
388
+ {
389
+ return _imx_clk_fracn_gppll (name , parent_name , base , pll_clk , CLK_FRACN_GPPLL_INTEGER );
390
+ }
391
+ EXPORT_SYMBOL_GPL (imx_clk_fracn_gppll_integer );
0 commit comments