15
15
#include "clk.h"
16
16
17
17
#define PLL_CTRL 0x0
18
+ #define HW_CTRL_SEL BIT(16)
18
19
#define CLKMUX_BYPASS BIT(2)
19
20
#define CLKMUX_EN BIT(1)
20
21
#define POWERUP_MASK BIT(0)
52
53
.odiv = (_odiv), \
53
54
}
54
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
+
55
66
struct clk_fracn_gppll {
56
67
struct clk_hw hw ;
57
68
void __iomem * base ;
58
69
const struct imx_fracn_gppll_rate_table * rate_table ;
59
70
int rate_count ;
71
+ u32 flags ;
60
72
};
61
73
62
74
/*
63
- * Fvco = Fref * (MFI + MFN / MFD)
64
- * Fout = Fvco / (rdiv * odiv)
75
+ * Fvco = (Fref / rdiv) * (MFI + MFN / MFD)
76
+ * Fout = Fvco / odiv
77
+ * The (Fref / rdiv) should be in range 20MHz to 40MHz
78
+ * The Fvco should be in range 2.5Ghz to 5Ghz
65
79
*/
66
80
static const struct imx_fracn_gppll_rate_table fracn_tbl [] = {
67
- PLL_FRACN_GP (650000000U , 81 , 0 , 1 , 0 , 3 ),
81
+ PLL_FRACN_GP (650000000U , 162 , 50 , 100 , 0 , 6 ),
68
82
PLL_FRACN_GP (594000000U , 198 , 0 , 1 , 0 , 8 ),
69
- PLL_FRACN_GP (560000000U , 70 , 0 , 1 , 0 , 3 ),
70
- PLL_FRACN_GP (498000000U , 83 , 0 , 1 , 0 , 4 ),
83
+ PLL_FRACN_GP (560000000U , 140 , 0 , 1 , 0 , 6 ),
84
+ PLL_FRACN_GP (498000000U , 166 , 0 , 1 , 0 , 8 ),
71
85
PLL_FRACN_GP (484000000U , 121 , 0 , 1 , 0 , 6 ),
72
86
PLL_FRACN_GP (445333333U , 167 , 0 , 1 , 0 , 9 ),
73
- PLL_FRACN_GP (400000000U , 50 , 0 , 1 , 0 , 3 ),
74
- PLL_FRACN_GP (393216000U , 81 , 92 , 100 , 0 , 5 )
87
+ PLL_FRACN_GP (400000000U , 200 , 0 , 1 , 0 , 12 ),
88
+ PLL_FRACN_GP (393216000U , 163 , 84 , 100 , 0 , 10 ),
89
+ PLL_FRACN_GP (300000000U , 150 , 0 , 1 , 0 , 12 )
75
90
};
76
91
77
92
struct imx_fracn_gppll_clk imx_fracn_gppll = {
@@ -80,6 +95,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
80
95
};
81
96
EXPORT_SYMBOL_GPL (imx_fracn_gppll );
82
97
98
+ /*
99
+ * Fvco = (Fref / rdiv) * MFI
100
+ * Fout = Fvco / odiv
101
+ * The (Fref / rdiv) should be in range 20MHz to 40MHz
102
+ * The Fvco should be in range 2.5Ghz to 5Ghz
103
+ */
104
+ static const struct imx_fracn_gppll_rate_table int_tbl [] = {
105
+ PLL_FRACN_GP_INTEGER (1700000000U , 141 , 1 , 2 ),
106
+ PLL_FRACN_GP_INTEGER (1400000000U , 175 , 1 , 3 ),
107
+ PLL_FRACN_GP_INTEGER (900000000U , 150 , 1 , 4 ),
108
+ };
109
+
110
+ struct imx_fracn_gppll_clk imx_fracn_gppll_integer = {
111
+ .rate_table = int_tbl ,
112
+ .rate_count = ARRAY_SIZE (int_tbl ),
113
+ };
114
+ EXPORT_SYMBOL_GPL (imx_fracn_gppll_integer );
115
+
83
116
static inline struct clk_fracn_gppll * to_clk_fracn_gppll (struct clk_hw * hw )
84
117
{
85
118
return container_of (hw , struct clk_fracn_gppll , hw );
@@ -166,9 +199,15 @@ static unsigned long clk_fracn_gppll_recalc_rate(struct clk_hw *hw, unsigned lon
166
199
break ;
167
200
}
168
201
169
- /* Fvco = Fref * (MFI + MFN / MFD) */
170
- fvco = fvco * mfi * mfd + fvco * mfn ;
171
- do_div (fvco , mfd * rdiv * odiv );
202
+ if (pll -> flags & CLK_FRACN_GPPLL_INTEGER ) {
203
+ /* Fvco = (Fref / rdiv) * MFI */
204
+ fvco = fvco * mfi ;
205
+ do_div (fvco , rdiv * odiv );
206
+ } else {
207
+ /* Fvco = (Fref / rdiv) * (MFI + MFN / MFD) */
208
+ fvco = fvco * mfi * mfd + fvco * mfn ;
209
+ do_div (fvco , mfd * rdiv * odiv );
210
+ }
172
211
173
212
return (unsigned long )fvco ;
174
213
}
@@ -191,6 +230,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
191
230
192
231
rate = imx_get_pll_settings (pll , drate );
193
232
233
+ /* Hardware control select disable. PLL is control by register */
234
+ tmp = readl_relaxed (pll -> base + PLL_CTRL );
235
+ tmp &= ~HW_CTRL_SEL ;
236
+ writel_relaxed (tmp , pll -> base + PLL_CTRL );
237
+
194
238
/* Disable output */
195
239
tmp = readl_relaxed (pll -> base + PLL_CTRL );
196
240
tmp &= ~CLKMUX_EN ;
@@ -207,8 +251,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
207
251
pll_div = FIELD_PREP (PLL_RDIV_MASK , rate -> rdiv ) | rate -> odiv |
208
252
FIELD_PREP (PLL_MFI_MASK , rate -> mfi );
209
253
writel_relaxed (pll_div , pll -> base + PLL_DIV );
210
- writel_relaxed (rate -> mfd , pll -> base + PLL_DENOMINATOR );
211
- writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate -> mfn ), pll -> base + PLL_NUMERATOR );
254
+ if (pll -> flags & CLK_FRACN_GPPLL_FRACN ) {
255
+ writel_relaxed (rate -> mfd , pll -> base + PLL_DENOMINATOR );
256
+ writel_relaxed (FIELD_PREP (PLL_MFN_MASK , rate -> mfn ), pll -> base + PLL_NUMERATOR );
257
+ }
212
258
213
259
/* Wait for 5us according to fracn mode pll doc */
214
260
udelay (5 );
@@ -292,8 +338,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
292
338
.set_rate = clk_fracn_gppll_set_rate ,
293
339
};
294
340
295
- struct clk_hw * imx_clk_fracn_gppll (const char * name , const char * parent_name , void __iomem * base ,
296
- const struct imx_fracn_gppll_clk * pll_clk )
341
+ static struct clk_hw * _imx_clk_fracn_gppll (const char * name , const char * parent_name ,
342
+ void __iomem * base ,
343
+ const struct imx_fracn_gppll_clk * pll_clk ,
344
+ u32 pll_flags )
297
345
{
298
346
struct clk_fracn_gppll * pll ;
299
347
struct clk_hw * hw ;
@@ -314,6 +362,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
314
362
pll -> hw .init = & init ;
315
363
pll -> rate_table = pll_clk -> rate_table ;
316
364
pll -> rate_count = pll_clk -> rate_count ;
365
+ pll -> flags = pll_flags ;
317
366
318
367
hw = & pll -> hw ;
319
368
@@ -326,4 +375,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
326
375
327
376
return hw ;
328
377
}
378
+
379
+ struct clk_hw * imx_clk_fracn_gppll (const char * name , const char * parent_name , void __iomem * base ,
380
+ const struct imx_fracn_gppll_clk * pll_clk )
381
+ {
382
+ return _imx_clk_fracn_gppll (name , parent_name , base , pll_clk , CLK_FRACN_GPPLL_FRACN );
383
+ }
329
384
EXPORT_SYMBOL_GPL (imx_clk_fracn_gppll );
385
+
386
+ struct clk_hw * imx_clk_fracn_gppll_integer (const char * name , const char * parent_name ,
387
+ void __iomem * base ,
388
+ const struct imx_fracn_gppll_clk * pll_clk )
389
+ {
390
+ return _imx_clk_fracn_gppll (name , parent_name , base , pll_clk , CLK_FRACN_GPPLL_INTEGER );
391
+ }
392
+ EXPORT_SYMBOL_GPL (imx_clk_fracn_gppll_integer );
0 commit comments