1515#include "clk.h"
1616
1717#define PLL_CTRL 0x0
18+ #define HW_CTRL_SEL BIT(16)
1819#define CLKMUX_BYPASS BIT(2)
1920#define CLKMUX_EN BIT(1)
2021#define POWERUP_MASK BIT(0)
5253 .odiv = (_odiv), \
5354 }
5455
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+
5566struct clk_fracn_gppll {
5667 struct clk_hw hw ;
5768 void __iomem * base ;
5869 const struct imx_fracn_gppll_rate_table * rate_table ;
5970 int rate_count ;
71+ u32 flags ;
6072};
6173
6274/*
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
6579 */
6680static 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 ),
6882 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 ),
7185 PLL_FRACN_GP (484000000U , 121 , 0 , 1 , 0 , 6 ),
7286 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 )
7590};
7691
7792struct imx_fracn_gppll_clk imx_fracn_gppll = {
@@ -80,6 +95,24 @@ struct imx_fracn_gppll_clk imx_fracn_gppll = {
8095};
8196EXPORT_SYMBOL_GPL (imx_fracn_gppll );
8297
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+
83116static inline struct clk_fracn_gppll * to_clk_fracn_gppll (struct clk_hw * hw )
84117{
85118 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
166199 break ;
167200 }
168201
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+ }
172211
173212 return (unsigned long )fvco ;
174213}
@@ -191,6 +230,11 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
191230
192231 rate = imx_get_pll_settings (pll , drate );
193232
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+
194238 /* Disable output */
195239 tmp = readl_relaxed (pll -> base + PLL_CTRL );
196240 tmp &= ~CLKMUX_EN ;
@@ -207,8 +251,10 @@ static int clk_fracn_gppll_set_rate(struct clk_hw *hw, unsigned long drate,
207251 pll_div = FIELD_PREP (PLL_RDIV_MASK , rate -> rdiv ) | rate -> odiv |
208252 FIELD_PREP (PLL_MFI_MASK , rate -> mfi );
209253 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+ }
212258
213259 /* Wait for 5us according to fracn mode pll doc */
214260 udelay (5 );
@@ -292,8 +338,10 @@ static const struct clk_ops clk_fracn_gppll_ops = {
292338 .set_rate = clk_fracn_gppll_set_rate ,
293339};
294340
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 )
297345{
298346 struct clk_fracn_gppll * pll ;
299347 struct clk_hw * hw ;
@@ -314,6 +362,7 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
314362 pll -> hw .init = & init ;
315363 pll -> rate_table = pll_clk -> rate_table ;
316364 pll -> rate_count = pll_clk -> rate_count ;
365+ pll -> flags = pll_flags ;
317366
318367 hw = & pll -> hw ;
319368
@@ -326,4 +375,18 @@ struct clk_hw *imx_clk_fracn_gppll(const char *name, const char *parent_name, vo
326375
327376 return hw ;
328377}
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+ }
329384EXPORT_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