1 /* 2 * Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 */ 10 11 #include <linux/clk-provider.h> 12 #include <linux/clkdev.h> 13 #include <linux/clk/at91_pmc.h> 14 #include <linux/of.h> 15 #include <linux/mfd/syscon.h> 16 #include <linux/regmap.h> 17 18 #include "pmc.h" 19 20 #define PLL_STATUS_MASK(id) (1 << (1 + (id))) 21 #define PLL_REG(id) (AT91_CKGR_PLLAR + ((id) * 4)) 22 #define PLL_DIV_MASK 0xff 23 #define PLL_DIV_MAX PLL_DIV_MASK 24 #define PLL_DIV(reg) ((reg) & PLL_DIV_MASK) 25 #define PLL_MUL(reg, layout) (((reg) >> (layout)->mul_shift) & \ 26 (layout)->mul_mask) 27 #define PLL_MUL_MIN 2 28 #define PLL_MUL_MASK(layout) ((layout)->mul_mask) 29 #define PLL_MUL_MAX(layout) (PLL_MUL_MASK(layout) + 1) 30 #define PLL_ICPR_SHIFT(id) ((id) * 16) 31 #define PLL_ICPR_MASK(id) (0xffff << PLL_ICPR_SHIFT(id)) 32 #define PLL_MAX_COUNT 0x3f 33 #define PLL_COUNT_SHIFT 8 34 #define PLL_OUT_SHIFT 14 35 #define PLL_MAX_ID 1 36 37 #define to_clk_pll(hw) container_of(hw, struct clk_pll, hw) 38 39 struct clk_pll { 40 struct clk_hw hw; 41 struct regmap *regmap; 42 u8 id; 43 u8 div; 44 u8 range; 45 u16 mul; 46 const struct clk_pll_layout *layout; 47 const struct clk_pll_characteristics *characteristics; 48 }; 49 50 static inline bool clk_pll_ready(struct regmap *regmap, int id) 51 { 52 unsigned int status; 53 54 regmap_read(regmap, AT91_PMC_SR, &status); 55 56 return status & PLL_STATUS_MASK(id) ? 1 : 0; 57 } 58 59 static int clk_pll_prepare(struct clk_hw *hw) 60 { 61 struct clk_pll *pll = to_clk_pll(hw); 62 struct regmap *regmap = pll->regmap; 63 const struct clk_pll_layout *layout = pll->layout; 64 const struct clk_pll_characteristics *characteristics = 65 pll->characteristics; 66 u8 id = pll->id; 67 u32 mask = PLL_STATUS_MASK(id); 68 int offset = PLL_REG(id); 69 u8 out = 0; 70 unsigned int pllr; 71 unsigned int status; 72 u8 div; 73 u16 mul; 74 75 regmap_read(regmap, offset, &pllr); 76 div = PLL_DIV(pllr); 77 mul = PLL_MUL(pllr, layout); 78 79 regmap_read(regmap, AT91_PMC_SR, &status); 80 if ((status & mask) && 81 (div == pll->div && mul == pll->mul)) 82 return 0; 83 84 if (characteristics->out) 85 out = characteristics->out[pll->range]; 86 87 if (characteristics->icpll) 88 regmap_update_bits(regmap, AT91_PMC_PLLICPR, PLL_ICPR_MASK(id), 89 characteristics->icpll[pll->range] << PLL_ICPR_SHIFT(id)); 90 91 regmap_update_bits(regmap, offset, layout->pllr_mask, 92 pll->div | (PLL_MAX_COUNT << PLL_COUNT_SHIFT) | 93 (out << PLL_OUT_SHIFT) | 94 ((pll->mul & layout->mul_mask) << layout->mul_shift)); 95 96 while (!clk_pll_ready(regmap, pll->id)) 97 cpu_relax(); 98 99 return 0; 100 } 101 102 static int clk_pll_is_prepared(struct clk_hw *hw) 103 { 104 struct clk_pll *pll = to_clk_pll(hw); 105 106 return clk_pll_ready(pll->regmap, pll->id); 107 } 108 109 static void clk_pll_unprepare(struct clk_hw *hw) 110 { 111 struct clk_pll *pll = to_clk_pll(hw); 112 unsigned int mask = pll->layout->pllr_mask; 113 114 regmap_update_bits(pll->regmap, PLL_REG(pll->id), mask, ~mask); 115 } 116 117 static unsigned long clk_pll_recalc_rate(struct clk_hw *hw, 118 unsigned long parent_rate) 119 { 120 struct clk_pll *pll = to_clk_pll(hw); 121 122 if (!pll->div || !pll->mul) 123 return 0; 124 125 return (parent_rate / pll->div) * (pll->mul + 1); 126 } 127 128 static long clk_pll_get_best_div_mul(struct clk_pll *pll, unsigned long rate, 129 unsigned long parent_rate, 130 u32 *div, u32 *mul, 131 u32 *index) { 132 const struct clk_pll_layout *layout = pll->layout; 133 const struct clk_pll_characteristics *characteristics = 134 pll->characteristics; 135 unsigned long bestremainder = ULONG_MAX; 136 unsigned long maxdiv, mindiv, tmpdiv; 137 long bestrate = -ERANGE; 138 unsigned long bestdiv; 139 unsigned long bestmul; 140 int i = 0; 141 142 /* Check if parent_rate is a valid input rate */ 143 if (parent_rate < characteristics->input.min) 144 return -ERANGE; 145 146 /* 147 * Calculate minimum divider based on the minimum multiplier, the 148 * parent_rate and the requested rate. 149 * Should always be 2 according to the input and output characteristics 150 * of the PLL blocks. 151 */ 152 mindiv = (parent_rate * PLL_MUL_MIN) / rate; 153 if (!mindiv) 154 mindiv = 1; 155 156 if (parent_rate > characteristics->input.max) { 157 tmpdiv = DIV_ROUND_UP(parent_rate, characteristics->input.max); 158 if (tmpdiv > PLL_DIV_MAX) 159 return -ERANGE; 160 161 if (tmpdiv > mindiv) 162 mindiv = tmpdiv; 163 } 164 165 /* 166 * Calculate the maximum divider which is limited by PLL register 167 * layout (limited by the MUL or DIV field size). 168 */ 169 maxdiv = DIV_ROUND_UP(parent_rate * PLL_MUL_MAX(layout), rate); 170 if (maxdiv > PLL_DIV_MAX) 171 maxdiv = PLL_DIV_MAX; 172 173 /* 174 * Iterate over the acceptable divider values to find the best 175 * divider/multiplier pair (the one that generates the closest 176 * rate to the requested one). 177 */ 178 for (tmpdiv = mindiv; tmpdiv <= maxdiv; tmpdiv++) { 179 unsigned long remainder; 180 unsigned long tmprate; 181 unsigned long tmpmul; 182 183 /* 184 * Calculate the multiplier associated with the current 185 * divider that provide the closest rate to the requested one. 186 */ 187 tmpmul = DIV_ROUND_CLOSEST(rate, parent_rate / tmpdiv); 188 tmprate = (parent_rate / tmpdiv) * tmpmul; 189 if (tmprate > rate) 190 remainder = tmprate - rate; 191 else 192 remainder = rate - tmprate; 193 194 /* 195 * Compare the remainder with the best remainder found until 196 * now and elect a new best multiplier/divider pair if the 197 * current remainder is smaller than the best one. 198 */ 199 if (remainder < bestremainder) { 200 bestremainder = remainder; 201 bestdiv = tmpdiv; 202 bestmul = tmpmul; 203 bestrate = tmprate; 204 } 205 206 /* 207 * We've found a perfect match! 208 * Stop searching now and use this multiplier/divider pair. 209 */ 210 if (!remainder) 211 break; 212 } 213 214 /* We haven't found any multiplier/divider pair => return -ERANGE */ 215 if (bestrate < 0) 216 return bestrate; 217 218 /* Check if bestrate is a valid output rate */ 219 for (i = 0; i < characteristics->num_output; i++) { 220 if (bestrate >= characteristics->output[i].min && 221 bestrate <= characteristics->output[i].max) 222 break; 223 } 224 225 if (i >= characteristics->num_output) 226 return -ERANGE; 227 228 if (div) 229 *div = bestdiv; 230 if (mul) 231 *mul = bestmul - 1; 232 if (index) 233 *index = i; 234 235 return bestrate; 236 } 237 238 static long clk_pll_round_rate(struct clk_hw *hw, unsigned long rate, 239 unsigned long *parent_rate) 240 { 241 struct clk_pll *pll = to_clk_pll(hw); 242 243 return clk_pll_get_best_div_mul(pll, rate, *parent_rate, 244 NULL, NULL, NULL); 245 } 246 247 static int clk_pll_set_rate(struct clk_hw *hw, unsigned long rate, 248 unsigned long parent_rate) 249 { 250 struct clk_pll *pll = to_clk_pll(hw); 251 long ret; 252 u32 div; 253 u32 mul; 254 u32 index; 255 256 ret = clk_pll_get_best_div_mul(pll, rate, parent_rate, 257 &div, &mul, &index); 258 if (ret < 0) 259 return ret; 260 261 pll->range = index; 262 pll->div = div; 263 pll->mul = mul; 264 265 return 0; 266 } 267 268 static const struct clk_ops pll_ops = { 269 .prepare = clk_pll_prepare, 270 .unprepare = clk_pll_unprepare, 271 .is_prepared = clk_pll_is_prepared, 272 .recalc_rate = clk_pll_recalc_rate, 273 .round_rate = clk_pll_round_rate, 274 .set_rate = clk_pll_set_rate, 275 }; 276 277 struct clk_hw * __init 278 at91_clk_register_pll(struct regmap *regmap, const char *name, 279 const char *parent_name, u8 id, 280 const struct clk_pll_layout *layout, 281 const struct clk_pll_characteristics *characteristics) 282 { 283 struct clk_pll *pll; 284 struct clk_hw *hw; 285 struct clk_init_data init; 286 int offset = PLL_REG(id); 287 unsigned int pllr; 288 int ret; 289 290 if (id > PLL_MAX_ID) 291 return ERR_PTR(-EINVAL); 292 293 pll = kzalloc(sizeof(*pll), GFP_KERNEL); 294 if (!pll) 295 return ERR_PTR(-ENOMEM); 296 297 init.name = name; 298 init.ops = &pll_ops; 299 init.parent_names = &parent_name; 300 init.num_parents = 1; 301 init.flags = CLK_SET_RATE_GATE; 302 303 pll->id = id; 304 pll->hw.init = &init; 305 pll->layout = layout; 306 pll->characteristics = characteristics; 307 pll->regmap = regmap; 308 regmap_read(regmap, offset, &pllr); 309 pll->div = PLL_DIV(pllr); 310 pll->mul = PLL_MUL(pllr, layout); 311 312 hw = &pll->hw; 313 ret = clk_hw_register(NULL, &pll->hw); 314 if (ret) { 315 kfree(pll); 316 hw = ERR_PTR(ret); 317 } 318 319 return hw; 320 } 321 322 323 const struct clk_pll_layout at91rm9200_pll_layout = { 324 .pllr_mask = 0x7FFFFFF, 325 .mul_shift = 16, 326 .mul_mask = 0x7FF, 327 }; 328 329 const struct clk_pll_layout at91sam9g45_pll_layout = { 330 .pllr_mask = 0xFFFFFF, 331 .mul_shift = 16, 332 .mul_mask = 0xFF, 333 }; 334 335 const struct clk_pll_layout at91sam9g20_pllb_layout = { 336 .pllr_mask = 0x3FFFFF, 337 .mul_shift = 16, 338 .mul_mask = 0x3F, 339 }; 340 341 const struct clk_pll_layout sama5d3_pll_layout = { 342 .pllr_mask = 0x1FFFFFF, 343 .mul_shift = 18, 344 .mul_mask = 0x7F, 345 }; 346