1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Copyright (C) 2019 Microchip Technology Inc. 4 * 5 */ 6 7 #include <linux/bitfield.h> 8 #include <linux/clk-provider.h> 9 #include <linux/clkdev.h> 10 #include <linux/clk/at91_pmc.h> 11 #include <linux/of.h> 12 #include <linux/mfd/syscon.h> 13 #include <linux/regmap.h> 14 15 #include "pmc.h" 16 17 #define PMC_PLL_CTRL0_DIV_MSK GENMASK(7, 0) 18 #define PMC_PLL_CTRL1_MUL_MSK GENMASK(30, 24) 19 20 #define PLL_DIV_MAX (FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, UINT_MAX) + 1) 21 #define UPLL_DIV 2 22 #define PLL_MUL_MAX (FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, UINT_MAX) + 1) 23 24 #define PLL_MAX_ID 1 25 26 struct sam9x60_pll { 27 struct clk_hw hw; 28 struct regmap *regmap; 29 spinlock_t *lock; 30 const struct clk_pll_characteristics *characteristics; 31 u32 frac; 32 u8 id; 33 u8 div; 34 u16 mul; 35 }; 36 37 #define to_sam9x60_pll(hw) container_of(hw, struct sam9x60_pll, hw) 38 39 static inline bool sam9x60_pll_ready(struct regmap *regmap, int id) 40 { 41 unsigned int status; 42 43 regmap_read(regmap, AT91_PMC_PLL_ISR0, &status); 44 45 return !!(status & BIT(id)); 46 } 47 48 static int sam9x60_pll_prepare(struct clk_hw *hw) 49 { 50 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 51 struct regmap *regmap = pll->regmap; 52 unsigned long flags; 53 u8 div; 54 u16 mul; 55 u32 val; 56 57 spin_lock_irqsave(pll->lock, flags); 58 regmap_write(regmap, AT91_PMC_PLL_UPDT, pll->id); 59 60 regmap_read(regmap, AT91_PMC_PLL_CTRL0, &val); 61 div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, val); 62 63 regmap_read(regmap, AT91_PMC_PLL_CTRL1, &val); 64 mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, val); 65 66 if (sam9x60_pll_ready(regmap, pll->id) && 67 (div == pll->div && mul == pll->mul)) { 68 spin_unlock_irqrestore(pll->lock, flags); 69 return 0; 70 } 71 72 /* Recommended value for AT91_PMC_PLL_ACR */ 73 if (pll->characteristics->upll) 74 val = AT91_PMC_PLL_ACR_DEFAULT_UPLL; 75 else 76 val = AT91_PMC_PLL_ACR_DEFAULT_PLLA; 77 regmap_write(regmap, AT91_PMC_PLL_ACR, val); 78 79 regmap_write(regmap, AT91_PMC_PLL_CTRL1, 80 FIELD_PREP(PMC_PLL_CTRL1_MUL_MSK, pll->mul)); 81 82 if (pll->characteristics->upll) { 83 /* Enable the UTMI internal bandgap */ 84 val |= AT91_PMC_PLL_ACR_UTMIBG; 85 regmap_write(regmap, AT91_PMC_PLL_ACR, val); 86 87 udelay(10); 88 89 /* Enable the UTMI internal regulator */ 90 val |= AT91_PMC_PLL_ACR_UTMIVR; 91 regmap_write(regmap, AT91_PMC_PLL_ACR, val); 92 93 udelay(10); 94 } 95 96 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 97 AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 98 99 regmap_write(regmap, AT91_PMC_PLL_CTRL0, 100 AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL | 101 AT91_PMC_PLL_CTRL0_ENPLLCK | pll->div); 102 103 regmap_update_bits(regmap, AT91_PMC_PLL_UPDT, 104 AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 105 106 while (!sam9x60_pll_ready(regmap, pll->id)) 107 cpu_relax(); 108 109 spin_unlock_irqrestore(pll->lock, flags); 110 111 return 0; 112 } 113 114 static int sam9x60_pll_is_prepared(struct clk_hw *hw) 115 { 116 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 117 118 return sam9x60_pll_ready(pll->regmap, pll->id); 119 } 120 121 static void sam9x60_pll_unprepare(struct clk_hw *hw) 122 { 123 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 124 unsigned long flags; 125 126 spin_lock_irqsave(pll->lock, flags); 127 128 regmap_write(pll->regmap, AT91_PMC_PLL_UPDT, pll->id); 129 130 regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0, 131 AT91_PMC_PLL_CTRL0_ENPLLCK, 0); 132 133 regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT, 134 AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 135 136 regmap_update_bits(pll->regmap, AT91_PMC_PLL_CTRL0, 137 AT91_PMC_PLL_CTRL0_ENPLL, 0); 138 139 if (pll->characteristics->upll) 140 regmap_update_bits(pll->regmap, AT91_PMC_PLL_ACR, 141 AT91_PMC_PLL_ACR_UTMIBG | 142 AT91_PMC_PLL_ACR_UTMIVR, 0); 143 144 regmap_update_bits(pll->regmap, AT91_PMC_PLL_UPDT, 145 AT91_PMC_PLL_UPDT_UPDATE, AT91_PMC_PLL_UPDT_UPDATE); 146 147 spin_unlock_irqrestore(pll->lock, flags); 148 } 149 150 static unsigned long sam9x60_pll_recalc_rate(struct clk_hw *hw, 151 unsigned long parent_rate) 152 { 153 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 154 155 return (parent_rate * (pll->mul + 1)) / (pll->div + 1); 156 } 157 158 static long sam9x60_pll_get_best_div_mul(struct sam9x60_pll *pll, 159 unsigned long rate, 160 unsigned long parent_rate, 161 bool update) 162 { 163 const struct clk_pll_characteristics *characteristics = 164 pll->characteristics; 165 unsigned long bestremainder = ULONG_MAX; 166 unsigned long maxdiv, mindiv, tmpdiv; 167 long bestrate = -ERANGE; 168 unsigned long bestdiv = 0; 169 unsigned long bestmul = 0; 170 unsigned long bestfrac = 0; 171 172 if (rate < characteristics->output[0].min || 173 rate > characteristics->output[0].max) 174 return -ERANGE; 175 176 if (!pll->characteristics->upll) { 177 mindiv = parent_rate / rate; 178 if (mindiv < 2) 179 mindiv = 2; 180 181 maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX, rate); 182 if (maxdiv > PLL_DIV_MAX) 183 maxdiv = PLL_DIV_MAX; 184 } else { 185 mindiv = maxdiv = UPLL_DIV; 186 } 187 188 for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) { 189 unsigned long remainder; 190 unsigned long tmprate; 191 unsigned long tmpmul; 192 unsigned long tmpfrac = 0; 193 194 /* 195 * Calculate the multiplier associated with the current 196 * divider that provide the closest rate to the requested one. 197 */ 198 tmpmul = mult_frac(rate, tmpdiv, parent_rate); 199 tmprate = mult_frac(parent_rate, tmpmul, tmpdiv); 200 remainder = rate - tmprate; 201 202 if (remainder) { 203 tmpfrac = DIV_ROUND_CLOSEST_ULL((u64)remainder * tmpdiv * (1 << 22), 204 parent_rate); 205 206 tmprate += DIV_ROUND_CLOSEST_ULL((u64)tmpfrac * parent_rate, 207 tmpdiv * (1 << 22)); 208 209 if (tmprate > rate) 210 remainder = tmprate - rate; 211 else 212 remainder = rate - tmprate; 213 } 214 215 /* 216 * Compare the remainder with the best remainder found until 217 * now and elect a new best multiplier/divider pair if the 218 * current remainder is smaller than the best one. 219 */ 220 if (remainder < bestremainder) { 221 bestremainder = remainder; 222 bestdiv = tmpdiv; 223 bestmul = tmpmul; 224 bestrate = tmprate; 225 bestfrac = tmpfrac; 226 } 227 228 /* We've found a perfect match! */ 229 if (!remainder) 230 break; 231 } 232 233 /* Check if bestrate is a valid output rate */ 234 if (bestrate < characteristics->output[0].min && 235 bestrate > characteristics->output[0].max) 236 return -ERANGE; 237 238 if (update) { 239 pll->div = bestdiv - 1; 240 pll->mul = bestmul - 1; 241 pll->frac = bestfrac; 242 } 243 244 return bestrate; 245 } 246 247 static long sam9x60_pll_round_rate(struct clk_hw *hw, unsigned long rate, 248 unsigned long *parent_rate) 249 { 250 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 251 252 return sam9x60_pll_get_best_div_mul(pll, rate, *parent_rate, false); 253 } 254 255 static int sam9x60_pll_set_rate(struct clk_hw *hw, unsigned long rate, 256 unsigned long parent_rate) 257 { 258 struct sam9x60_pll *pll = to_sam9x60_pll(hw); 259 260 return sam9x60_pll_get_best_div_mul(pll, rate, parent_rate, true); 261 } 262 263 static const struct clk_ops pll_ops = { 264 .prepare = sam9x60_pll_prepare, 265 .unprepare = sam9x60_pll_unprepare, 266 .is_prepared = sam9x60_pll_is_prepared, 267 .recalc_rate = sam9x60_pll_recalc_rate, 268 .round_rate = sam9x60_pll_round_rate, 269 .set_rate = sam9x60_pll_set_rate, 270 }; 271 272 struct clk_hw * __init 273 sam9x60_clk_register_pll(struct regmap *regmap, spinlock_t *lock, 274 const char *name, const char *parent_name, u8 id, 275 const struct clk_pll_characteristics *characteristics) 276 { 277 struct sam9x60_pll *pll; 278 struct clk_hw *hw; 279 struct clk_init_data init; 280 unsigned int pllr; 281 int ret; 282 283 if (id > PLL_MAX_ID) 284 return ERR_PTR(-EINVAL); 285 286 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 287 if (!pll) 288 return ERR_PTR(-ENOMEM); 289 290 init.name = name; 291 init.ops = &pll_ops; 292 init.parent_names = &parent_name; 293 init.num_parents = 1; 294 init.flags = CLK_SET_RATE_GATE; 295 296 pll->id = id; 297 pll->hw.init = &init; 298 pll->characteristics = characteristics; 299 pll->regmap = regmap; 300 pll->lock = lock; 301 302 regmap_write(regmap, AT91_PMC_PLL_UPDT, id); 303 regmap_read(regmap, AT91_PMC_PLL_CTRL0, &pllr); 304 pll->div = FIELD_GET(PMC_PLL_CTRL0_DIV_MSK, pllr); 305 regmap_read(regmap, AT91_PMC_PLL_CTRL1, &pllr); 306 pll->mul = FIELD_GET(PMC_PLL_CTRL1_MUL_MSK, pllr); 307 308 hw = &pll->hw; 309 ret = clk_hw_register(NULL, hw); 310 if (ret) { 311 kfree(pll); 312 hw = ERR_PTR(ret); 313 } 314 315 return hw; 316 } 317 318