1414
1515#include "pmc.h"
1616
17+ #define PMC_PLL_CTRL0 0xc
18+ #define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
19+ #define PMC_PLL_CTRL0_ENPLL BIT(28)
20+ #define PMC_PLL_CTRL0_ENPLLCK BIT(29)
21+ #define PMC_PLL_CTRL0_ENLOCK BIT(31)
22+
23+ #define PMC_PLL_CTRL1 0x10
24+ #define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
25+ #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
26+
27+ #define PMC_PLL_ACR 0x18
28+ #define PMC_PLL_ACR_DEFAULT_UPLL 0x12020010UL
29+ #define PMC_PLL_ACR_DEFAULT_PLLA 0x00020010UL
30+ #define PMC_PLL_ACR_UTMIVR BIT(12)
31+ #define PMC_PLL_ACR_UTMIBG BIT(13)
32+ #define PMC_PLL_ACR_LOOP_FILTER_MSK GENMASK(31, 24)
33+
34+ #define PMC_PLL_UPDT 0x1c
35+ #define PMC_PLL_UPDT_UPDATE BIT(8)
36+
37+ #define PMC_PLL_ISR0 0xec
1738#define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0)
18- #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24)
39+ #define PMC_PLL_CTRL1_MUL_MSK GENMASK(31, 24)
40+ #define PMC_PLL_CTRL1_FRACR_MSK GENMASK(21, 0)
1941
2042#define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1)
2143#define UPLL_DIV 2
2244#define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1)
2345
46+ #define FCORE_MIN (600000000)
47+ #define FCORE_MAX (1200000000)
48+
2449#define PLL_MAX_ID 1
2550
2651struct sam9x60_pll {
@@ -52,7 +77,7 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
5277 unsigned long flags ;
5378 u8 div ;
5479 u16 mul ;
55- u32 val ;
80+ u32 val , frac ;
5681
5782 spin_lock_irqsave (pll -> lock , flags );
5883 regmap_write (regmap , AT91_PMC_PLL_UPDT , pll -> id );
@@ -62,9 +87,10 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
6287
6388 regmap_read (regmap , AT91_PMC_PLL_CTRL1 , & val );
6489 mul = FIELD_GET (PMC_PLL_CTRL1_MUL_MSK , val );
90+ frac = FIELD_GET (PMC_PLL_CTRL1_FRACR_MSK , val );
6591
6692 if (sam9x60_pll_ready (regmap , pll -> id ) &&
67- (div == pll -> div && mul == pll -> mul )) {
93+ (div == pll -> div && mul == pll -> mul && frac == pll -> frac )) {
6894 spin_unlock_irqrestore (pll -> lock , flags );
6995 return 0 ;
7096 }
@@ -77,7 +103,8 @@ static int sam9x60_pll_prepare(struct clk_hw *hw)
77103 regmap_write (regmap , AT91_PMC_PLL_ACR , val );
78104
79105 regmap_write (regmap , AT91_PMC_PLL_CTRL1 ,
80- FIELD_PREP (PMC_PLL_CTRL1_MUL_MSK , pll -> mul ));
106+ FIELD_PREP (PMC_PLL_CTRL1_MUL_MSK , pll -> mul ) |
107+ FIELD_PREP (PMC_PLL_CTRL1_FRACR_MSK , pll -> frac ));
81108
82109 if (pll -> characteristics -> upll ) {
83110 /* Enable the UTMI internal bandgap */
@@ -152,7 +179,8 @@ static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw,
152179{
153180 struct sam9x60_pll * pll = to_sam9x60_pll (hw );
154181
155- return (parent_rate * (pll -> mul + 1 )) / (pll -> div + 1 );
182+ return DIV_ROUND_CLOSEST_ULL ((parent_rate * (pll -> mul + 1 ) +
183+ ((u64 )parent_rate * pll -> frac >> 22 )), (pll -> div + 1 ));
156184}
157185
158186static long sam9x60_pll_get_best_div_mul (struct sam9x60_pll * pll ,
@@ -168,6 +196,7 @@ static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
168196 unsigned long bestdiv = 0 ;
169197 unsigned long bestmul = 0 ;
170198 unsigned long bestfrac = 0 ;
199+ u64 fcore = 0 ;
171200
172201 if (rate < characteristics -> output [0 ].min ||
173202 rate > characteristics -> output [0 ].max )
@@ -212,6 +241,11 @@ static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
212241 remainder = rate - tmprate ;
213242 }
214243
244+ fcore = parent_rate * (tmpmul + 1 ) +
245+ ((u64 )parent_rate * tmpfrac >> 22 );
246+ if (fcore < FCORE_MIN || fcore > FCORE_MAX )
247+ continue ;
248+
215249 /*
216250 * Compare the remainder with the best remainder found until
217251 * now and elect a new best multiplier/divider pair if the
@@ -231,7 +265,8 @@ static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll,
231265 }
232266
233267 /* Check if bestrate is a valid output rate */
234- if (bestrate < characteristics -> output [0 ].min &&
268+ if (fcore < FCORE_MIN || fcore > FCORE_MAX ||
269+ bestrate < characteristics -> output [0 ].min ||
235270 bestrate > characteristics -> output [0 ].max )
236271 return - ERANGE ;
237272
0 commit comments