1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (C) 2019 Microchip Technology Inc. 4 */ 5 6 #include <io.h> 7 #include <kernel/misc.h> 8 #include <mm/core_memprot.h> 9 #include <types_ext.h> 10 #include <util.h> 11 #include "at91_clk.h" 12 13 #define PMC_PLL_CTRL0_DIV_MASK 0xf 14 #define PMC_PLL_CTRL0_DIV_POS 0 15 #define PMC_PLL_CTRL1_MUL_MASK 0xff 16 #define PMC_PLL_CTRL1_MUL_POS 24 17 #define PMC_PLL_CTRL1_FRACR_MASK 0x3fffff 18 #define PMC_PLL_CTRL1_FRACR_POS 0 19 20 #define PLL_STATUS_MASK(id) BIT(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) \ 26 ({ \ 27 typeof(layout) __layout = layout; \ 28 \ 29 (((reg) >> (__layout)->mul_shift) & (__layout)->mul_mask); \ 30 }) 31 #define PLL_MUL_MIN 2 32 #define PLL_MUL_MASK(layout) ((layout)->mul_mask) 33 #define PLL_MUL_MAX(layout) (PLL_MUL_MASK(layout) + 1) 34 #define PLL_ICPR_SHIFT(id) ((id) * 16) 35 #define PLL_ICPR_MASK(id) SHIFT_U64(0xffff, PLL_ICPR_SHIFT(id)) 36 #define PLL_MAX_COUNT 0x3f 37 #define PLL_COUNT_SHIFT 8 38 #define PLL_OUT_SHIFT 14 39 40 struct sam9x60_pll_core { 41 vaddr_t base; 42 const struct clk_pll_charac *charac; 43 const struct clk_pll_layout *layout; 44 struct clk *hw; 45 uint8_t id; 46 }; 47 48 struct sam9x60_frac { 49 struct sam9x60_pll_core core; 50 uint32_t frac; 51 uint16_t mul; 52 }; 53 54 struct sam9x60_div { 55 struct sam9x60_pll_core core; 56 uint8_t div; 57 uint8_t safe_div; 58 }; 59 60 #define WAIT_PLL_READY_TIMEOUT(_base, _id) \ 61 ({ \ 62 uint32_t __timeout = 0; \ 63 uint32_t _c = 0; \ 64 \ 65 while (__timeout++ < 500) { \ 66 _c = io_read32((_base) + AT91_PMC_PLL_ISR0) & \ 67 BIT(_id); \ 68 if (_c) \ 69 break; \ 70 wait_cycles(100); \ 71 } \ 72 !(_c); \ 73 }) 74 75 static bool sam9x60_pll_ready(vaddr_t base, int id) 76 { 77 return io_read32(base + AT91_PMC_PLL_ISR0) & BIT(id); 78 } 79 80 static bool sam9x60_frac_pll_ready(vaddr_t regmap, uint8_t id) 81 { 82 return sam9x60_pll_ready(regmap, id); 83 } 84 85 static unsigned long sam9x60_frac_pll_recalc_rate(struct clk *hw, 86 unsigned long parent_rate) 87 { 88 struct sam9x60_frac *frac = hw->priv; 89 90 return parent_rate * (frac->mul + 1) + 91 UDIV_ROUND_NEAREST((unsigned long long)parent_rate * frac->frac, 92 1 << 22); 93 } 94 95 static TEE_Result sam9x60_frac_pll_set(struct sam9x60_frac *frac) 96 { 97 struct sam9x60_pll_core *core = &frac->core; 98 vaddr_t regmap = frac->core.base; 99 unsigned int val = 0; 100 unsigned int cfrac = 0; 101 unsigned int cmul = 0; 102 103 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 104 AT91_PMC_PLL_UPDT_ID_MASK, core->id); 105 val = io_read32(regmap + AT91_PMC_PLL_CTRL1); 106 cmul = (val & core->layout->mul_mask) >> core->layout->mul_shift; 107 cfrac = (val & core->layout->frac_mask) >> core->layout->frac_shift; 108 109 if (sam9x60_frac_pll_ready(regmap, core->id) && 110 cmul == frac->mul && cfrac == frac->frac) 111 return TEE_SUCCESS; 112 113 /* Recommended value for PMC_PLL_ACR */ 114 if (core->charac->upll) 115 val = AT91_PMC_PLL_ACR_DEFAULT_UPLL; 116 else 117 val = AT91_PMC_PLL_ACR_DEFAULT_PLLA; 118 io_write32(regmap + AT91_PMC_PLL_ACR, val); 119 120 io_write32(regmap + AT91_PMC_PLL_CTRL1, 121 SHIFT_U32(frac->mul, core->layout->mul_shift) | 122 SHIFT_U32(frac->frac, core->layout->frac_shift)); 123 124 if (core->charac->upll) { 125 /* Enable the UTMI internal bandgap */ 126 val |= AT91_PMC_PLL_ACR_UTMIBG; 127 io_write32(regmap + AT91_PMC_PLL_ACR, val); 128 129 udelay(10); 130 131 /* Enable the UTMI internal regulator */ 132 val |= AT91_PMC_PLL_ACR_UTMIVR; 133 io_write32(regmap + AT91_PMC_PLL_ACR, val); 134 135 udelay(10); 136 } 137 138 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 139 AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MASK, 140 AT91_PMC_PLL_UPDT_UPDATE | core->id); 141 142 io_setbits32(regmap + AT91_PMC_PLL_CTRL0, 143 AT91_PMC_PLL_CTRL0_ENLOCK | AT91_PMC_PLL_CTRL0_ENPLL); 144 145 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 146 AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MASK, 147 AT91_PMC_PLL_UPDT_UPDATE | core->id); 148 149 if (WAIT_PLL_READY_TIMEOUT(regmap, core->id)) { 150 EMSG("PLL not ready"); 151 return TEE_ERROR_BUSY; 152 } 153 154 return TEE_SUCCESS; 155 } 156 157 static TEE_Result sam9x60_frac_pll_prepare(struct clk *hw) 158 { 159 struct sam9x60_frac *frac = hw->priv; 160 161 return sam9x60_frac_pll_set(frac); 162 } 163 164 static void sam9x60_frac_pll_unprepare(struct clk *hw) 165 { 166 struct sam9x60_frac *frac = hw->priv; 167 168 io_clrsetbits32(frac->core.base + AT91_PMC_PLL_UPDT, 169 AT91_PMC_PLL_UPDT_ID_MASK, frac->core.id); 170 171 io_clrbits32(frac->core.base + AT91_PMC_PLL_CTRL0, 172 AT91_PMC_PLL_CTRL0_ENPLL); 173 174 if (frac->core.charac->upll) 175 io_clrbits32(frac->core.base + AT91_PMC_PLL_ACR, 176 AT91_PMC_PLL_ACR_UTMIBG | 177 AT91_PMC_PLL_ACR_UTMIVR); 178 179 io_clrsetbits32(frac->core.base + AT91_PMC_PLL_UPDT, 180 AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MASK, 181 AT91_PMC_PLL_UPDT_UPDATE | frac->core.id); 182 } 183 184 static TEE_Result sam9x60_frac_pll_compute_mul_frac(struct sam9x60_frac *frac, 185 unsigned long rate, 186 unsigned long parent_rate, 187 bool update) 188 { 189 unsigned long tmprate = 0; 190 unsigned long remainder = 0; 191 unsigned long nmul = 0; 192 unsigned long nfrac = 0; 193 194 if (rate < frac->core.charac->output[0].min || 195 rate > frac->core.charac->output[0].max) 196 return TEE_ERROR_GENERIC; 197 198 /* 199 * Calculate the multiplier associated with the current 200 * divider that provide the closest rate to the requested one. 201 */ 202 nmul = rate / parent_rate; 203 tmprate = parent_rate * nmul; 204 remainder = rate - tmprate; 205 206 if (remainder) { 207 nfrac = UDIV_ROUND_NEAREST((uint64_t)remainder * (1 << 22), 208 parent_rate); 209 210 tmprate += UDIV_ROUND_NEAREST((uint64_t)nfrac * parent_rate, 211 1 << 22); 212 } 213 214 /* Check if resulted rate is a valid. */ 215 if (tmprate < frac->core.charac->output[0].min || 216 tmprate > frac->core.charac->output[0].max) 217 return TEE_ERROR_GENERIC; 218 219 if (update) { 220 frac->mul = nmul - 1; 221 frac->frac = nfrac; 222 } 223 224 return TEE_SUCCESS; 225 } 226 227 static TEE_Result sam9x60_frac_pll_set_rate_chg(struct clk *hw, 228 unsigned long rate, 229 unsigned long parent_rate) 230 { 231 TEE_Result ret = TEE_SUCCESS; 232 struct sam9x60_frac *frac = hw->priv; 233 struct sam9x60_pll_core *core = &frac->core; 234 vaddr_t regmap = core->base; 235 236 ret = sam9x60_frac_pll_compute_mul_frac(frac, rate, parent_rate, true); 237 if (ret == TEE_SUCCESS) { 238 io_write32(regmap + AT91_PMC_PLL_CTRL1, 239 SHIFT_U32(frac->mul, core->layout->mul_shift) | 240 SHIFT_U32(frac->frac, core->layout->frac_shift)); 241 242 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 243 AT91_PMC_PLL_UPDT_UPDATE | 244 AT91_PMC_PLL_UPDT_ID_MASK, 245 AT91_PMC_PLL_UPDT_UPDATE | core->id); 246 247 io_setbits32(regmap + AT91_PMC_PLL_CTRL0, 248 AT91_PMC_PLL_CTRL0_ENLOCK | 249 AT91_PMC_PLL_CTRL0_ENPLL); 250 251 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 252 AT91_PMC_PLL_UPDT_UPDATE | 253 AT91_PMC_PLL_UPDT_ID_MASK, 254 AT91_PMC_PLL_UPDT_UPDATE | core->id); 255 256 if (WAIT_PLL_READY_TIMEOUT(regmap, core->id)) { 257 EMSG("PLL not ready"); 258 return TEE_ERROR_BUSY; 259 } 260 } 261 262 return ret; 263 } 264 265 static const struct clk_ops sam9x60_frac_pll_ops_chg = { 266 .enable = sam9x60_frac_pll_prepare, 267 .disable = sam9x60_frac_pll_unprepare, 268 .get_rate = sam9x60_frac_pll_recalc_rate, 269 .set_rate = sam9x60_frac_pll_set_rate_chg, 270 }; 271 272 static TEE_Result sam9x60_div_pll_set_div(struct sam9x60_pll_core *core, 273 uint32_t div, 274 bool enable) 275 { 276 vaddr_t regmap = core->base; 277 uint32_t enable_mask = enable ? core->layout->endiv_mask : 0; 278 uint32_t ena_val = enable ? BIT(core->layout->endiv_shift) : 0; 279 280 io_clrsetbits32(regmap + AT91_PMC_PLL_CTRL0, 281 core->layout->div_mask | enable_mask, 282 SHIFT_U32(div, core->layout->div_shift) | ena_val); 283 284 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 285 AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MASK, 286 AT91_PMC_PLL_UPDT_UPDATE | core->id); 287 288 if (WAIT_PLL_READY_TIMEOUT(regmap, core->id)) { 289 EMSG("PLL not ready"); 290 return TEE_ERROR_BUSY; 291 } 292 293 return TEE_SUCCESS; 294 } 295 296 static TEE_Result sam9x60_div_pll_set(struct sam9x60_div *div) 297 { 298 struct sam9x60_pll_core *core = &div->core; 299 vaddr_t regmap = core->base; 300 unsigned int val = 0; 301 unsigned int cdiv = 0; 302 303 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 304 AT91_PMC_PLL_UPDT_ID_MASK, core->id); 305 val = io_read32(regmap + AT91_PMC_PLL_CTRL0); 306 cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; 307 308 /* Stop if enabled an nothing changed. */ 309 if ((val & core->layout->endiv_mask) && cdiv == div->div) 310 return TEE_SUCCESS; 311 312 return sam9x60_div_pll_set_div(core, div->div, 1); 313 } 314 315 static TEE_Result sam9x60_div_pll_prepare(struct clk *hw) 316 { 317 struct sam9x60_div *div = hw->priv; 318 319 return sam9x60_div_pll_set(div); 320 } 321 322 static void sam9x60_div_pll_unprepare(struct clk *hw) 323 { 324 struct sam9x60_div *div = hw->priv; 325 struct sam9x60_pll_core *core = &div->core; 326 vaddr_t regmap = core->base; 327 328 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 329 AT91_PMC_PLL_UPDT_ID_MASK, core->id); 330 331 io_clrbits32(regmap + AT91_PMC_PLL_CTRL0, core->layout->endiv_mask); 332 333 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 334 AT91_PMC_PLL_UPDT_UPDATE | AT91_PMC_PLL_UPDT_ID_MASK, 335 AT91_PMC_PLL_UPDT_UPDATE | core->id); 336 } 337 338 static unsigned long sam9x60_div_pll_recalc_rate(struct clk *hw, 339 unsigned long parent_rate) 340 { 341 struct sam9x60_div *div = hw->priv; 342 343 return UDIV_ROUND_NEAREST(parent_rate, div->div + 1); 344 } 345 346 static TEE_Result sam9x60_div_pll_set_rate(struct clk *hw, 347 unsigned long rate, 348 unsigned long parent_rate) 349 { 350 struct sam9x60_div *div = hw->priv; 351 352 div->div = UDIV_ROUND_NEAREST(parent_rate, rate) - 1; 353 354 return TEE_SUCCESS; 355 } 356 357 static TEE_Result sam9x60_div_pll_set_rate_chg(struct clk *hw, 358 unsigned long rate, 359 unsigned long parent_rate) 360 { 361 struct sam9x60_div *div = hw->priv; 362 struct sam9x60_pll_core *core = &div->core; 363 vaddr_t regmap = core->base; 364 unsigned int val = 0; 365 unsigned int cdiv = 0; 366 367 div->div = UDIV_ROUND_NEAREST(parent_rate, rate) - 1; 368 369 io_clrsetbits32(regmap + AT91_PMC_PLL_UPDT, 370 AT91_PMC_PLL_UPDT_ID_MASK, 371 core->id); 372 val = io_read32(regmap + AT91_PMC_PLL_CTRL0); 373 cdiv = (val & core->layout->div_mask) >> core->layout->div_shift; 374 375 /* Stop if nothing changed. */ 376 if (cdiv == div->div) 377 return TEE_SUCCESS; 378 379 return sam9x60_div_pll_set_div(core, div->div, 0); 380 } 381 382 static const struct clk_ops sam9x60_div_pll_ops = { 383 .enable = sam9x60_div_pll_prepare, 384 .disable = sam9x60_div_pll_unprepare, 385 .set_rate = sam9x60_div_pll_set_rate, 386 .get_rate = sam9x60_div_pll_recalc_rate, 387 }; 388 389 static const struct clk_ops sam9x60_div_pll_ops_chg = { 390 .enable = sam9x60_div_pll_prepare, 391 .disable = sam9x60_div_pll_unprepare, 392 .set_rate = sam9x60_div_pll_set_rate_chg, 393 .get_rate = sam9x60_div_pll_recalc_rate, 394 }; 395 396 struct clk *sam9x60_clk_register_frac_pll(struct pmc_data *pmc, 397 const char *name, 398 struct clk *parent, 399 uint8_t id, 400 const struct clk_pll_charac *charac, 401 const struct clk_pll_layout *layout, 402 uint32_t flags) 403 { 404 struct sam9x60_frac *frac = NULL; 405 struct clk *hw = NULL; 406 unsigned long parent_rate = 0; 407 unsigned int val = 0; 408 TEE_Result ret = TEE_SUCCESS; 409 410 frac = calloc(1, sizeof(*frac)); 411 if (!frac) 412 return NULL; 413 414 hw = clk_alloc(name, &sam9x60_frac_pll_ops_chg, &parent, 1); 415 if (!hw) { 416 free(frac); 417 return NULL; 418 } 419 420 hw->priv = frac; 421 hw->flags = flags; 422 frac->core.id = id; 423 frac->core.charac = charac; 424 frac->core.layout = layout; 425 frac->core.base = pmc->base; 426 427 if (sam9x60_pll_ready(pmc->base, id)) { 428 io_clrsetbits32(frac->core.base + AT91_PMC_PLL_UPDT, 429 AT91_PMC_PLL_UPDT_ID_MASK, id); 430 val = io_read32(pmc->base + AT91_PMC_PLL_CTRL1); 431 frac->mul = (val >> PMC_PLL_CTRL1_MUL_POS) & 432 PMC_PLL_CTRL1_MUL_MASK; 433 frac->frac = (val >> PMC_PLL_CTRL1_FRACR_POS) & 434 PMC_PLL_CTRL1_FRACR_MASK; 435 } else { 436 /* 437 * This means the PLL is not setup by bootloaders. In this 438 * case we need to set the minimum rate for it. Otherwise 439 * a clock child of this PLL may be enabled before setting 440 * its rate leading to enabling this PLL with unsupported 441 * rate. This will lead to PLL not being locked at all. 442 */ 443 parent_rate = clk_get_rate(parent); 444 if (!parent_rate) { 445 clk_free(hw); 446 free(frac); 447 return NULL; 448 } 449 450 ret = sam9x60_frac_pll_compute_mul_frac(frac, 451 charac->output[0].min, 452 parent_rate, true); 453 if (ret != TEE_SUCCESS) { 454 clk_free(hw); 455 free(frac); 456 return NULL; 457 } 458 } 459 460 frac->core.hw = hw; 461 if (clk_register(hw)) { 462 clk_free(hw); 463 free(frac); 464 return NULL; 465 } 466 467 return hw; 468 } 469 470 struct clk *sam9x60_clk_register_div_pll(struct pmc_data *pmc, 471 const char *name, 472 struct clk *parent, 473 uint8_t id, 474 const struct clk_pll_charac *charac, 475 const struct clk_pll_layout *layout, 476 uint32_t flags, 477 uint32_t safe_div) 478 { 479 struct sam9x60_div *div = NULL; 480 struct clk *hw = NULL; 481 unsigned int val = 0; 482 483 if (safe_div >= PLL_DIV_MAX) 484 safe_div = PLL_DIV_MAX - 1; 485 486 div = calloc(1, sizeof(*div)); 487 if (!div) 488 return NULL; 489 490 if (flags & CLK_SET_RATE_GATE) 491 hw = clk_alloc(name, &sam9x60_div_pll_ops, &parent, 1); 492 else 493 hw = clk_alloc(name, &sam9x60_div_pll_ops_chg, &parent, 1); 494 if (!hw) { 495 free(div); 496 return NULL; 497 } 498 499 hw->priv = div; 500 hw->flags = flags; 501 div->core.id = id; 502 div->core.charac = charac; 503 div->core.layout = layout; 504 div->core.base = pmc->base; 505 div->safe_div = safe_div; 506 507 io_clrsetbits32(pmc->base + AT91_PMC_PLL_UPDT, 508 AT91_PMC_PLL_UPDT_ID_MASK, id); 509 val = io_read32(pmc->base + AT91_PMC_PLL_CTRL0); 510 div->div = (val >> PMC_PLL_CTRL0_DIV_POS) & PMC_PLL_CTRL0_DIV_MASK; 511 512 div->core.hw = hw; 513 if (clk_register(hw)) { 514 clk_free(hw); 515 free(div); 516 return NULL; 517 } 518 519 return hw; 520 } 521