1 /* 2 * Copyright 2024 NXP 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 #include <errno.h> 7 8 #include <s32cc-clk-regs.h> 9 10 #include <common/debug.h> 11 #include <drivers/clk.h> 12 #include <lib/mmio.h> 13 #include <s32cc-clk-ids.h> 14 #include <s32cc-clk-modules.h> 15 #include <s32cc-clk-utils.h> 16 17 #define MAX_STACK_DEPTH (15U) 18 19 /* This is used for floating-point precision calculations. */ 20 #define FP_PRECISION (100000000UL) 21 22 struct s32cc_clk_drv { 23 uintptr_t fxosc_base; 24 uintptr_t armpll_base; 25 uintptr_t periphpll_base; 26 uintptr_t armdfs_base; 27 uintptr_t cgm0_base; 28 uintptr_t cgm1_base; 29 }; 30 31 static int update_stack_depth(unsigned int *depth) 32 { 33 if (*depth == 0U) { 34 return -ENOMEM; 35 } 36 37 (*depth)--; 38 return 0; 39 } 40 41 static struct s32cc_clk_drv *get_drv(void) 42 { 43 static struct s32cc_clk_drv driver = { 44 .fxosc_base = FXOSC_BASE_ADDR, 45 .armpll_base = ARMPLL_BASE_ADDR, 46 .periphpll_base = PERIPHPLL_BASE_ADDR, 47 .armdfs_base = ARM_DFS_BASE_ADDR, 48 .cgm0_base = CGM0_BASE_ADDR, 49 .cgm1_base = CGM1_BASE_ADDR, 50 }; 51 52 return &driver; 53 } 54 55 static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth); 56 57 static int enable_clk_module(const struct s32cc_clk_obj *module, 58 const struct s32cc_clk_drv *drv, 59 unsigned int *depth) 60 { 61 const struct s32cc_clk *clk = s32cc_obj2clk(module); 62 int ret; 63 64 ret = update_stack_depth(depth); 65 if (ret != 0) { 66 return ret; 67 } 68 69 if (clk == NULL) { 70 return -EINVAL; 71 } 72 73 if (clk->module != NULL) { 74 return enable_module(clk->module, depth); 75 } 76 77 if (clk->pclock != NULL) { 78 return enable_clk_module(&clk->pclock->desc, drv, depth); 79 } 80 81 return -EINVAL; 82 } 83 84 static int get_base_addr(enum s32cc_clk_source id, const struct s32cc_clk_drv *drv, 85 uintptr_t *base) 86 { 87 int ret = 0; 88 89 switch (id) { 90 case S32CC_FXOSC: 91 *base = drv->fxosc_base; 92 break; 93 case S32CC_ARM_PLL: 94 *base = drv->armpll_base; 95 break; 96 case S32CC_PERIPH_PLL: 97 *base = drv->periphpll_base; 98 break; 99 case S32CC_ARM_DFS: 100 *base = drv->armdfs_base; 101 break; 102 case S32CC_CGM0: 103 *base = drv->cgm0_base; 104 break; 105 case S32CC_CGM1: 106 *base = drv->cgm1_base; 107 break; 108 case S32CC_FIRC: 109 break; 110 case S32CC_SIRC: 111 break; 112 default: 113 ret = -EINVAL; 114 break; 115 } 116 117 if (ret != 0) { 118 ERROR("Unknown clock source id: %u\n", id); 119 } 120 121 return ret; 122 } 123 124 static void enable_fxosc(const struct s32cc_clk_drv *drv) 125 { 126 uintptr_t fxosc_base = drv->fxosc_base; 127 uint32_t ctrl; 128 129 ctrl = mmio_read_32(FXOSC_CTRL(fxosc_base)); 130 if ((ctrl & FXOSC_CTRL_OSCON) != U(0)) { 131 return; 132 } 133 134 ctrl = FXOSC_CTRL_COMP_EN; 135 ctrl &= ~FXOSC_CTRL_OSC_BYP; 136 ctrl |= FXOSC_CTRL_EOCV(0x1); 137 ctrl |= FXOSC_CTRL_GM_SEL(0x7); 138 mmio_write_32(FXOSC_CTRL(fxosc_base), ctrl); 139 140 /* Switch ON the crystal oscillator. */ 141 mmio_setbits_32(FXOSC_CTRL(fxosc_base), FXOSC_CTRL_OSCON); 142 143 /* Wait until the clock is stable. */ 144 while ((mmio_read_32(FXOSC_STAT(fxosc_base)) & FXOSC_STAT_OSC_STAT) == U(0)) { 145 } 146 } 147 148 static int enable_osc(const struct s32cc_clk_obj *module, 149 const struct s32cc_clk_drv *drv, 150 unsigned int *depth) 151 { 152 const struct s32cc_osc *osc = s32cc_obj2osc(module); 153 int ret = 0; 154 155 ret = update_stack_depth(depth); 156 if (ret != 0) { 157 return ret; 158 } 159 160 switch (osc->source) { 161 case S32CC_FXOSC: 162 enable_fxosc(drv); 163 break; 164 /* FIRC and SIRC oscillators are enabled by default */ 165 case S32CC_FIRC: 166 break; 167 case S32CC_SIRC: 168 break; 169 default: 170 ERROR("Invalid oscillator %d\n", osc->source); 171 ret = -EINVAL; 172 break; 173 }; 174 175 return ret; 176 } 177 178 static int get_pll_mfi_mfn(unsigned long pll_vco, unsigned long ref_freq, 179 uint32_t *mfi, uint32_t *mfn) 180 181 { 182 unsigned long vco; 183 unsigned long mfn64; 184 185 /* FRAC-N mode */ 186 *mfi = (uint32_t)(pll_vco / ref_freq); 187 188 /* MFN formula : (double)(pll_vco % ref_freq) / ref_freq * 18432.0 */ 189 mfn64 = pll_vco % ref_freq; 190 mfn64 *= FP_PRECISION; 191 mfn64 /= ref_freq; 192 mfn64 *= 18432UL; 193 mfn64 /= FP_PRECISION; 194 195 if (mfn64 > UINT32_MAX) { 196 return -EINVAL; 197 } 198 199 *mfn = (uint32_t)mfn64; 200 201 vco = ((unsigned long)*mfn * FP_PRECISION) / 18432UL; 202 vco += (unsigned long)*mfi * FP_PRECISION; 203 vco *= ref_freq; 204 vco /= FP_PRECISION; 205 206 if (vco != pll_vco) { 207 ERROR("Failed to find MFI and MFN settings for PLL freq %lu. Nearest freq = %lu\n", 208 pll_vco, vco); 209 return -EINVAL; 210 } 211 212 return 0; 213 } 214 215 static struct s32cc_clkmux *get_pll_mux(const struct s32cc_pll *pll) 216 { 217 const struct s32cc_clk_obj *source = pll->source; 218 const struct s32cc_clk *clk; 219 220 if (source == NULL) { 221 ERROR("Failed to identify PLL's parent\n"); 222 return NULL; 223 } 224 225 if (source->type != s32cc_clk_t) { 226 ERROR("The parent of the PLL isn't a clock\n"); 227 return NULL; 228 } 229 230 clk = s32cc_obj2clk(source); 231 232 if (clk->module == NULL) { 233 ERROR("The clock isn't connected to a module\n"); 234 return NULL; 235 } 236 237 source = clk->module; 238 239 if ((source->type != s32cc_clkmux_t) && 240 (source->type != s32cc_shared_clkmux_t)) { 241 ERROR("The parent of the PLL isn't a MUX\n"); 242 return NULL; 243 } 244 245 return s32cc_obj2clkmux(source); 246 } 247 248 static void disable_odiv(uintptr_t pll_addr, uint32_t div_index) 249 { 250 mmio_clrbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE); 251 } 252 253 static void enable_odiv(uintptr_t pll_addr, uint32_t div_index) 254 { 255 mmio_setbits_32(PLLDIG_PLLODIV(pll_addr, div_index), PLLDIG_PLLODIV_DE); 256 } 257 258 static void disable_odivs(uintptr_t pll_addr, uint32_t ndivs) 259 { 260 uint32_t i; 261 262 for (i = 0; i < ndivs; i++) { 263 disable_odiv(pll_addr, i); 264 } 265 } 266 267 static void enable_pll_hw(uintptr_t pll_addr) 268 { 269 /* Enable the PLL. */ 270 mmio_write_32(PLLDIG_PLLCR(pll_addr), 0x0); 271 272 /* Poll until PLL acquires lock. */ 273 while ((mmio_read_32(PLLDIG_PLLSR(pll_addr)) & PLLDIG_PLLSR_LOCK) == 0U) { 274 } 275 } 276 277 static void disable_pll_hw(uintptr_t pll_addr) 278 { 279 mmio_write_32(PLLDIG_PLLCR(pll_addr), PLLDIG_PLLCR_PLLPD); 280 } 281 282 static int program_pll(const struct s32cc_pll *pll, uintptr_t pll_addr, 283 const struct s32cc_clk_drv *drv, uint32_t sclk_id, 284 unsigned long sclk_freq) 285 { 286 uint32_t rdiv = 1, mfi, mfn; 287 int ret; 288 289 ret = get_pll_mfi_mfn(pll->vco_freq, sclk_freq, &mfi, &mfn); 290 if (ret != 0) { 291 return -EINVAL; 292 } 293 294 /* Disable ODIVs*/ 295 disable_odivs(pll_addr, pll->ndividers); 296 297 /* Disable PLL */ 298 disable_pll_hw(pll_addr); 299 300 /* Program PLLCLKMUX */ 301 mmio_write_32(PLLDIG_PLLCLKMUX(pll_addr), sclk_id); 302 303 /* Program VCO */ 304 mmio_clrsetbits_32(PLLDIG_PLLDV(pll_addr), 305 PLLDIG_PLLDV_RDIV_MASK | PLLDIG_PLLDV_MFI_MASK, 306 PLLDIG_PLLDV_RDIV_SET(rdiv) | PLLDIG_PLLDV_MFI(mfi)); 307 308 mmio_write_32(PLLDIG_PLLFD(pll_addr), 309 PLLDIG_PLLFD_MFN_SET(mfn) | PLLDIG_PLLFD_SMDEN); 310 311 enable_pll_hw(pll_addr); 312 313 return ret; 314 } 315 316 static int enable_pll(const struct s32cc_clk_obj *module, 317 const struct s32cc_clk_drv *drv, 318 unsigned int *depth) 319 { 320 const struct s32cc_pll *pll = s32cc_obj2pll(module); 321 const struct s32cc_clkmux *mux; 322 uintptr_t pll_addr = UL(0x0); 323 unsigned long sclk_freq; 324 uint32_t sclk_id; 325 int ret; 326 327 ret = update_stack_depth(depth); 328 if (ret != 0) { 329 return ret; 330 } 331 332 mux = get_pll_mux(pll); 333 if (mux == NULL) { 334 return -EINVAL; 335 } 336 337 if (pll->instance != mux->module) { 338 ERROR("MUX type is not in sync with PLL ID\n"); 339 return -EINVAL; 340 } 341 342 ret = get_base_addr(pll->instance, drv, &pll_addr); 343 if (ret != 0) { 344 ERROR("Failed to detect PLL instance\n"); 345 return ret; 346 } 347 348 switch (mux->source_id) { 349 case S32CC_CLK_FIRC: 350 sclk_freq = 48U * MHZ; 351 sclk_id = 0; 352 break; 353 case S32CC_CLK_FXOSC: 354 sclk_freq = 40U * MHZ; 355 sclk_id = 1; 356 break; 357 default: 358 ERROR("Invalid source selection for PLL 0x%lx\n", 359 pll_addr); 360 return -EINVAL; 361 }; 362 363 return program_pll(pll, pll_addr, drv, sclk_id, sclk_freq); 364 } 365 366 static inline struct s32cc_pll *get_div_pll(const struct s32cc_pll_out_div *pdiv) 367 { 368 const struct s32cc_clk_obj *parent; 369 370 parent = pdiv->parent; 371 if (parent == NULL) { 372 ERROR("Failed to identify PLL divider's parent\n"); 373 return NULL; 374 } 375 376 if (parent->type != s32cc_pll_t) { 377 ERROR("The parent of the divider is not a PLL instance\n"); 378 return NULL; 379 } 380 381 return s32cc_obj2pll(parent); 382 } 383 384 static void config_pll_out_div(uintptr_t pll_addr, uint32_t div_index, uint32_t dc) 385 { 386 uint32_t pllodiv; 387 uint32_t pdiv; 388 389 pllodiv = mmio_read_32(PLLDIG_PLLODIV(pll_addr, div_index)); 390 pdiv = PLLDIG_PLLODIV_DIV(pllodiv); 391 392 if (((pdiv + 1U) == dc) && ((pllodiv & PLLDIG_PLLODIV_DE) != 0U)) { 393 return; 394 } 395 396 if ((pllodiv & PLLDIG_PLLODIV_DE) != 0U) { 397 disable_odiv(pll_addr, div_index); 398 } 399 400 pllodiv = PLLDIG_PLLODIV_DIV_SET(dc - 1U); 401 mmio_write_32(PLLDIG_PLLODIV(pll_addr, div_index), pllodiv); 402 403 enable_odiv(pll_addr, div_index); 404 } 405 406 static int enable_pll_div(const struct s32cc_clk_obj *module, 407 const struct s32cc_clk_drv *drv, 408 unsigned int *depth) 409 { 410 const struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module); 411 uintptr_t pll_addr = 0x0ULL; 412 const struct s32cc_pll *pll; 413 uint32_t dc; 414 int ret; 415 416 ret = update_stack_depth(depth); 417 if (ret != 0) { 418 return ret; 419 } 420 421 pll = get_div_pll(pdiv); 422 if (pll == NULL) { 423 ERROR("The parent of the PLL DIV is invalid\n"); 424 return 0; 425 } 426 427 ret = get_base_addr(pll->instance, drv, &pll_addr); 428 if (ret != 0) { 429 ERROR("Failed to detect PLL instance\n"); 430 return -EINVAL; 431 } 432 433 dc = (uint32_t)(pll->vco_freq / pdiv->freq); 434 435 config_pll_out_div(pll_addr, pdiv->index, dc); 436 437 return 0; 438 } 439 440 static int cgm_mux_clk_config(uintptr_t cgm_addr, uint32_t mux, uint32_t source, 441 bool safe_clk) 442 { 443 uint32_t css, csc; 444 445 css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)); 446 447 /* Already configured */ 448 if ((MC_CGM_MUXn_CSS_SELSTAT(css) == source) && 449 (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) && 450 ((css & MC_CGM_MUXn_CSS_SWIP) == 0U) && !safe_clk) { 451 return 0; 452 } 453 454 /* Ongoing clock switch? */ 455 while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) & 456 MC_CGM_MUXn_CSS_SWIP) != 0U) { 457 } 458 459 csc = mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux)); 460 461 /* Clear previous source. */ 462 csc &= ~(MC_CGM_MUXn_CSC_SELCTL_MASK); 463 464 if (!safe_clk) { 465 /* Select the clock source and trigger the clock switch. */ 466 csc |= MC_CGM_MUXn_CSC_SELCTL(source) | MC_CGM_MUXn_CSC_CLK_SW; 467 } else { 468 /* Switch to safe clock */ 469 csc |= MC_CGM_MUXn_CSC_SAFE_SW; 470 } 471 472 mmio_write_32(CGM_MUXn_CSC(cgm_addr, mux), csc); 473 474 /* Wait for configuration bit to auto-clear. */ 475 while ((mmio_read_32(CGM_MUXn_CSC(cgm_addr, mux)) & 476 MC_CGM_MUXn_CSC_CLK_SW) != 0U) { 477 } 478 479 /* Is the clock switch completed? */ 480 while ((mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)) & 481 MC_CGM_MUXn_CSS_SWIP) != 0U) { 482 } 483 484 /* 485 * Check if the switch succeeded. 486 * Check switch trigger cause and the source. 487 */ 488 css = mmio_read_32(CGM_MUXn_CSS(cgm_addr, mux)); 489 if (!safe_clk) { 490 if ((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SUCCESS) && 491 (MC_CGM_MUXn_CSS_SELSTAT(css) == source)) { 492 return 0; 493 } 494 495 ERROR("Failed to change the source of mux %" PRIu32 " to %" PRIu32 " (CGM=%lu)\n", 496 mux, source, cgm_addr); 497 } else { 498 if (((MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK) || 499 (MC_CGM_MUXn_CSS_SWTRG(css) == MC_CGM_MUXn_CSS_SWTRG_SAFE_CLK_INACTIVE)) && 500 ((MC_CGM_MUXn_CSS_SAFE_SW & css) != 0U)) { 501 return 0; 502 } 503 504 ERROR("The switch of mux %" PRIu32 " (CGM=%lu) to safe clock failed\n", 505 mux, cgm_addr); 506 } 507 508 return -EINVAL; 509 } 510 511 static int enable_cgm_mux(const struct s32cc_clkmux *mux, 512 const struct s32cc_clk_drv *drv) 513 { 514 uintptr_t cgm_addr = UL(0x0); 515 uint32_t mux_hw_clk; 516 int ret; 517 518 ret = get_base_addr(mux->module, drv, &cgm_addr); 519 if (ret != 0) { 520 return ret; 521 } 522 523 mux_hw_clk = (uint32_t)S32CC_CLK_ID(mux->source_id); 524 525 return cgm_mux_clk_config(cgm_addr, mux->index, 526 mux_hw_clk, false); 527 } 528 529 static int enable_mux(const struct s32cc_clk_obj *module, 530 const struct s32cc_clk_drv *drv, 531 unsigned int *depth) 532 { 533 const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module); 534 const struct s32cc_clk *clk; 535 int ret = 0; 536 537 ret = update_stack_depth(depth); 538 if (ret != 0) { 539 return ret; 540 } 541 542 if (mux == NULL) { 543 return -EINVAL; 544 } 545 546 clk = s32cc_get_arch_clk(mux->source_id); 547 if (clk == NULL) { 548 ERROR("Invalid parent (%lu) for mux %" PRIu8 "\n", 549 mux->source_id, mux->index); 550 return -EINVAL; 551 } 552 553 switch (mux->module) { 554 /* PLL mux will be enabled by PLL setup */ 555 case S32CC_ARM_PLL: 556 break; 557 case S32CC_CGM1: 558 ret = enable_cgm_mux(mux, drv); 559 break; 560 case S32CC_CGM0: 561 ret = enable_cgm_mux(mux, drv); 562 break; 563 default: 564 ERROR("Unknown mux parent type: %d\n", mux->module); 565 ret = -EINVAL; 566 break; 567 }; 568 569 return ret; 570 } 571 572 static int enable_dfs(const struct s32cc_clk_obj *module, 573 const struct s32cc_clk_drv *drv, 574 unsigned int *depth) 575 { 576 int ret = 0; 577 578 ret = update_stack_depth(depth); 579 if (ret != 0) { 580 return ret; 581 } 582 583 return 0; 584 } 585 586 static struct s32cc_dfs *get_div_dfs(const struct s32cc_dfs_div *dfs_div) 587 { 588 const struct s32cc_clk_obj *parent = dfs_div->parent; 589 590 if (parent->type != s32cc_dfs_t) { 591 ERROR("DFS DIV doesn't have a DFS as parent\n"); 592 return NULL; 593 } 594 595 return s32cc_obj2dfs(parent); 596 } 597 598 static struct s32cc_pll *dfsdiv2pll(const struct s32cc_dfs_div *dfs_div) 599 { 600 const struct s32cc_clk_obj *parent; 601 const struct s32cc_dfs *dfs; 602 603 dfs = get_div_dfs(dfs_div); 604 if (dfs == NULL) { 605 return NULL; 606 } 607 608 parent = dfs->parent; 609 if (parent->type != s32cc_pll_t) { 610 return NULL; 611 } 612 613 return s32cc_obj2pll(parent); 614 } 615 616 static int get_dfs_mfi_mfn(unsigned long dfs_freq, const struct s32cc_dfs_div *dfs_div, 617 uint32_t *mfi, uint32_t *mfn) 618 { 619 uint64_t factor64, tmp64, ofreq; 620 uint32_t factor32; 621 622 unsigned long in = dfs_freq; 623 unsigned long out = dfs_div->freq; 624 625 /** 626 * factor = (IN / OUT) / 2 627 * MFI = integer(factor) 628 * MFN = (factor - MFI) * 36 629 */ 630 factor64 = ((((uint64_t)in) * FP_PRECISION) / ((uint64_t)out)) / 2ULL; 631 tmp64 = factor64 / FP_PRECISION; 632 if (tmp64 > UINT32_MAX) { 633 return -EINVAL; 634 } 635 636 factor32 = (uint32_t)tmp64; 637 *mfi = factor32; 638 639 tmp64 = ((factor64 - ((uint64_t)*mfi * FP_PRECISION)) * 36UL) / FP_PRECISION; 640 if (tmp64 > UINT32_MAX) { 641 return -EINVAL; 642 } 643 644 *mfn = (uint32_t)tmp64; 645 646 /* div_freq = in / (2 * (*mfi + *mfn / 36.0)) */ 647 factor64 = (((uint64_t)*mfn) * FP_PRECISION) / 36ULL; 648 factor64 += ((uint64_t)*mfi) * FP_PRECISION; 649 factor64 *= 2ULL; 650 ofreq = (((uint64_t)in) * FP_PRECISION) / factor64; 651 652 if (ofreq != dfs_div->freq) { 653 ERROR("Failed to find MFI and MFN settings for DFS DIV freq %lu\n", 654 dfs_div->freq); 655 ERROR("Nearest freq = %" PRIx64 "\n", ofreq); 656 return -EINVAL; 657 } 658 659 return 0; 660 } 661 662 static int init_dfs_port(uintptr_t dfs_addr, uint32_t port, 663 uint32_t mfi, uint32_t mfn) 664 { 665 uint32_t portsr, portolsr; 666 uint32_t mask, old_mfi, old_mfn; 667 uint32_t dvport; 668 bool init_dfs; 669 670 dvport = mmio_read_32(DFS_DVPORTn(dfs_addr, port)); 671 672 old_mfi = DFS_DVPORTn_MFI(dvport); 673 old_mfn = DFS_DVPORTn_MFN(dvport); 674 675 portsr = mmio_read_32(DFS_PORTSR(dfs_addr)); 676 portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr)); 677 678 /* Skip configuration if it's not needed */ 679 if (((portsr & BIT_32(port)) != 0U) && 680 ((portolsr & BIT_32(port)) == 0U) && 681 (mfi == old_mfi) && (mfn == old_mfn)) { 682 return 0; 683 } 684 685 init_dfs = (portsr == 0U); 686 687 if (init_dfs) { 688 mask = DFS_PORTRESET_MASK; 689 } else { 690 mask = DFS_PORTRESET_SET(BIT_32(port)); 691 } 692 693 mmio_write_32(DFS_PORTOLSR(dfs_addr), mask); 694 mmio_write_32(DFS_PORTRESET(dfs_addr), mask); 695 696 while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & mask) != 0U) { 697 } 698 699 if (init_dfs) { 700 mmio_write_32(DFS_CTL(dfs_addr), DFS_CTL_RESET); 701 } 702 703 mmio_write_32(DFS_DVPORTn(dfs_addr, port), 704 DFS_DVPORTn_MFI_SET(mfi) | DFS_DVPORTn_MFN_SET(mfn)); 705 706 if (init_dfs) { 707 /* DFS clk enable programming */ 708 mmio_clrbits_32(DFS_CTL(dfs_addr), DFS_CTL_RESET); 709 } 710 711 mmio_clrbits_32(DFS_PORTRESET(dfs_addr), BIT_32(port)); 712 713 while ((mmio_read_32(DFS_PORTSR(dfs_addr)) & BIT_32(port)) != BIT_32(port)) { 714 } 715 716 portolsr = mmio_read_32(DFS_PORTOLSR(dfs_addr)); 717 if ((portolsr & DFS_PORTOLSR_LOL(port)) != 0U) { 718 ERROR("Failed to lock DFS divider\n"); 719 return -EINVAL; 720 } 721 722 return 0; 723 } 724 725 static int enable_dfs_div(const struct s32cc_clk_obj *module, 726 const struct s32cc_clk_drv *drv, 727 unsigned int *depth) 728 { 729 const struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module); 730 const struct s32cc_pll *pll; 731 const struct s32cc_dfs *dfs; 732 uintptr_t dfs_addr = 0UL; 733 uint32_t mfi, mfn; 734 int ret = 0; 735 736 ret = update_stack_depth(depth); 737 if (ret != 0) { 738 return ret; 739 } 740 741 dfs = get_div_dfs(dfs_div); 742 if (dfs == NULL) { 743 return -EINVAL; 744 } 745 746 pll = dfsdiv2pll(dfs_div); 747 if (pll == NULL) { 748 ERROR("Failed to identify DFS divider's parent\n"); 749 return -EINVAL; 750 } 751 752 ret = get_base_addr(dfs->instance, drv, &dfs_addr); 753 if ((ret != 0) || (dfs_addr == 0UL)) { 754 return -EINVAL; 755 } 756 757 ret = get_dfs_mfi_mfn(pll->vco_freq, dfs_div, &mfi, &mfn); 758 if (ret != 0) { 759 return -EINVAL; 760 } 761 762 return init_dfs_port(dfs_addr, dfs_div->index, mfi, mfn); 763 } 764 765 static int enable_module(const struct s32cc_clk_obj *module, unsigned int *depth) 766 { 767 const struct s32cc_clk_drv *drv = get_drv(); 768 int ret = 0; 769 770 ret = update_stack_depth(depth); 771 if (ret != 0) { 772 return ret; 773 } 774 775 if (drv == NULL) { 776 return -EINVAL; 777 } 778 779 switch (module->type) { 780 case s32cc_osc_t: 781 ret = enable_osc(module, drv, depth); 782 break; 783 case s32cc_clk_t: 784 ret = enable_clk_module(module, drv, depth); 785 break; 786 case s32cc_pll_t: 787 ret = enable_pll(module, drv, depth); 788 break; 789 case s32cc_pll_out_div_t: 790 ret = enable_pll_div(module, drv, depth); 791 break; 792 case s32cc_clkmux_t: 793 ret = enable_mux(module, drv, depth); 794 break; 795 case s32cc_shared_clkmux_t: 796 ret = enable_mux(module, drv, depth); 797 break; 798 case s32cc_fixed_div_t: 799 ret = -ENOTSUP; 800 break; 801 case s32cc_dfs_t: 802 ret = enable_dfs(module, drv, depth); 803 break; 804 case s32cc_dfs_div_t: 805 ret = enable_dfs_div(module, drv, depth); 806 break; 807 default: 808 ret = -EINVAL; 809 break; 810 } 811 812 return ret; 813 } 814 815 static int s32cc_clk_enable(unsigned long id) 816 { 817 unsigned int depth = MAX_STACK_DEPTH; 818 const struct s32cc_clk *clk; 819 820 clk = s32cc_get_arch_clk(id); 821 if (clk == NULL) { 822 return -EINVAL; 823 } 824 825 return enable_module(&clk->desc, &depth); 826 } 827 828 static void s32cc_clk_disable(unsigned long id) 829 { 830 } 831 832 static bool s32cc_clk_is_enabled(unsigned long id) 833 { 834 return false; 835 } 836 837 static unsigned long s32cc_clk_get_rate(unsigned long id) 838 { 839 return 0; 840 } 841 842 static int set_module_rate(const struct s32cc_clk_obj *module, 843 unsigned long rate, unsigned long *orate, 844 unsigned int *depth); 845 846 static int set_osc_freq(const struct s32cc_clk_obj *module, unsigned long rate, 847 unsigned long *orate, unsigned int *depth) 848 { 849 struct s32cc_osc *osc = s32cc_obj2osc(module); 850 int ret; 851 852 ret = update_stack_depth(depth); 853 if (ret != 0) { 854 return ret; 855 } 856 857 if ((osc->freq != 0UL) && (rate != osc->freq)) { 858 ERROR("Already initialized oscillator. freq = %lu\n", 859 osc->freq); 860 return -EINVAL; 861 } 862 863 osc->freq = rate; 864 *orate = osc->freq; 865 866 return 0; 867 } 868 869 static int set_clk_freq(const struct s32cc_clk_obj *module, unsigned long rate, 870 unsigned long *orate, unsigned int *depth) 871 { 872 const struct s32cc_clk *clk = s32cc_obj2clk(module); 873 int ret; 874 875 ret = update_stack_depth(depth); 876 if (ret != 0) { 877 return ret; 878 } 879 880 if ((clk->min_freq != 0UL) && (clk->max_freq != 0UL) && 881 ((rate < clk->min_freq) || (rate > clk->max_freq))) { 882 ERROR("%lu frequency is out of the allowed range: [%lu:%lu]\n", 883 rate, clk->min_freq, clk->max_freq); 884 return -EINVAL; 885 } 886 887 if (clk->module != NULL) { 888 return set_module_rate(clk->module, rate, orate, depth); 889 } 890 891 if (clk->pclock != NULL) { 892 return set_clk_freq(&clk->pclock->desc, rate, orate, depth); 893 } 894 895 return -EINVAL; 896 } 897 898 static int set_pll_freq(const struct s32cc_clk_obj *module, unsigned long rate, 899 unsigned long *orate, unsigned int *depth) 900 { 901 struct s32cc_pll *pll = s32cc_obj2pll(module); 902 int ret; 903 904 ret = update_stack_depth(depth); 905 if (ret != 0) { 906 return ret; 907 } 908 909 if ((pll->vco_freq != 0UL) && (pll->vco_freq != rate)) { 910 ERROR("PLL frequency was already set\n"); 911 return -EINVAL; 912 } 913 914 pll->vco_freq = rate; 915 *orate = pll->vco_freq; 916 917 return 0; 918 } 919 920 static int set_pll_div_freq(const struct s32cc_clk_obj *module, unsigned long rate, 921 unsigned long *orate, unsigned int *depth) 922 { 923 struct s32cc_pll_out_div *pdiv = s32cc_obj2plldiv(module); 924 const struct s32cc_pll *pll; 925 unsigned long prate, dc; 926 int ret; 927 928 ret = update_stack_depth(depth); 929 if (ret != 0) { 930 return ret; 931 } 932 933 if (pdiv->parent == NULL) { 934 ERROR("Failed to identify PLL divider's parent\n"); 935 return -EINVAL; 936 } 937 938 pll = s32cc_obj2pll(pdiv->parent); 939 if (pll == NULL) { 940 ERROR("The parent of the PLL DIV is invalid\n"); 941 return -EINVAL; 942 } 943 944 prate = pll->vco_freq; 945 946 /** 947 * The PLL is not initialized yet, so let's take a risk 948 * and accept the proposed rate. 949 */ 950 if (prate == 0UL) { 951 pdiv->freq = rate; 952 *orate = rate; 953 return 0; 954 } 955 956 /* Decline in case the rate cannot fit PLL's requirements. */ 957 dc = prate / rate; 958 if ((prate / dc) != rate) { 959 return -EINVAL; 960 } 961 962 pdiv->freq = rate; 963 *orate = pdiv->freq; 964 965 return 0; 966 } 967 968 static int set_fixed_div_freq(const struct s32cc_clk_obj *module, unsigned long rate, 969 unsigned long *orate, unsigned int *depth) 970 { 971 const struct s32cc_fixed_div *fdiv = s32cc_obj2fixeddiv(module); 972 int ret; 973 974 ret = update_stack_depth(depth); 975 if (ret != 0) { 976 return ret; 977 } 978 979 if (fdiv->parent == NULL) { 980 ERROR("The divider doesn't have a valid parent\b"); 981 return -EINVAL; 982 } 983 984 ret = set_module_rate(fdiv->parent, rate * fdiv->rate_div, orate, depth); 985 986 /* Update the output rate based on the parent's rate */ 987 *orate /= fdiv->rate_div; 988 989 return ret; 990 } 991 992 static int set_mux_freq(const struct s32cc_clk_obj *module, unsigned long rate, 993 unsigned long *orate, unsigned int *depth) 994 { 995 const struct s32cc_clkmux *mux = s32cc_obj2clkmux(module); 996 const struct s32cc_clk *clk = s32cc_get_arch_clk(mux->source_id); 997 int ret; 998 999 ret = update_stack_depth(depth); 1000 if (ret != 0) { 1001 return ret; 1002 } 1003 1004 if (clk == NULL) { 1005 ERROR("Mux (id:%" PRIu8 ") without a valid source (%lu)\n", 1006 mux->index, mux->source_id); 1007 return -EINVAL; 1008 } 1009 1010 return set_module_rate(&clk->desc, rate, orate, depth); 1011 } 1012 1013 static int set_dfs_div_freq(const struct s32cc_clk_obj *module, unsigned long rate, 1014 unsigned long *orate, unsigned int *depth) 1015 { 1016 struct s32cc_dfs_div *dfs_div = s32cc_obj2dfsdiv(module); 1017 const struct s32cc_dfs *dfs; 1018 int ret; 1019 1020 ret = update_stack_depth(depth); 1021 if (ret != 0) { 1022 return ret; 1023 } 1024 1025 if (dfs_div->parent == NULL) { 1026 ERROR("Failed to identify DFS divider's parent\n"); 1027 return -EINVAL; 1028 } 1029 1030 /* Sanity check */ 1031 dfs = s32cc_obj2dfs(dfs_div->parent); 1032 if (dfs->parent == NULL) { 1033 ERROR("Failed to identify DFS's parent\n"); 1034 return -EINVAL; 1035 } 1036 1037 if ((dfs_div->freq != 0U) && (dfs_div->freq != rate)) { 1038 ERROR("DFS DIV frequency was already set to %lu\n", 1039 dfs_div->freq); 1040 return -EINVAL; 1041 } 1042 1043 dfs_div->freq = rate; 1044 *orate = rate; 1045 1046 return ret; 1047 } 1048 1049 static int set_module_rate(const struct s32cc_clk_obj *module, 1050 unsigned long rate, unsigned long *orate, 1051 unsigned int *depth) 1052 { 1053 int ret = 0; 1054 1055 ret = update_stack_depth(depth); 1056 if (ret != 0) { 1057 return ret; 1058 } 1059 1060 ret = -EINVAL; 1061 1062 switch (module->type) { 1063 case s32cc_clk_t: 1064 ret = set_clk_freq(module, rate, orate, depth); 1065 break; 1066 case s32cc_osc_t: 1067 ret = set_osc_freq(module, rate, orate, depth); 1068 break; 1069 case s32cc_pll_t: 1070 ret = set_pll_freq(module, rate, orate, depth); 1071 break; 1072 case s32cc_pll_out_div_t: 1073 ret = set_pll_div_freq(module, rate, orate, depth); 1074 break; 1075 case s32cc_fixed_div_t: 1076 ret = set_fixed_div_freq(module, rate, orate, depth); 1077 break; 1078 case s32cc_clkmux_t: 1079 ret = set_mux_freq(module, rate, orate, depth); 1080 break; 1081 case s32cc_shared_clkmux_t: 1082 ret = set_mux_freq(module, rate, orate, depth); 1083 break; 1084 case s32cc_dfs_t: 1085 ERROR("Setting the frequency of a DFS is not allowed!"); 1086 break; 1087 case s32cc_dfs_div_t: 1088 ret = set_dfs_div_freq(module, rate, orate, depth); 1089 break; 1090 default: 1091 break; 1092 } 1093 1094 return ret; 1095 } 1096 1097 static int s32cc_clk_set_rate(unsigned long id, unsigned long rate, 1098 unsigned long *orate) 1099 { 1100 unsigned int depth = MAX_STACK_DEPTH; 1101 const struct s32cc_clk *clk; 1102 int ret; 1103 1104 clk = s32cc_get_arch_clk(id); 1105 if (clk == NULL) { 1106 return -EINVAL; 1107 } 1108 1109 ret = set_module_rate(&clk->desc, rate, orate, &depth); 1110 if (ret != 0) { 1111 ERROR("Failed to set frequency (%lu MHz) for clock %lu\n", 1112 rate, id); 1113 } 1114 1115 return ret; 1116 } 1117 1118 static int s32cc_clk_get_parent(unsigned long id) 1119 { 1120 return -ENOTSUP; 1121 } 1122 1123 static int s32cc_clk_set_parent(unsigned long id, unsigned long parent_id) 1124 { 1125 const struct s32cc_clk *parent; 1126 const struct s32cc_clk *clk; 1127 bool valid_source = false; 1128 struct s32cc_clkmux *mux; 1129 uint8_t i; 1130 1131 clk = s32cc_get_arch_clk(id); 1132 if (clk == NULL) { 1133 return -EINVAL; 1134 } 1135 1136 parent = s32cc_get_arch_clk(parent_id); 1137 if (parent == NULL) { 1138 return -EINVAL; 1139 } 1140 1141 if (!is_s32cc_clk_mux(clk)) { 1142 ERROR("Clock %lu is not a mux\n", id); 1143 return -EINVAL; 1144 } 1145 1146 mux = s32cc_clk2mux(clk); 1147 if (mux == NULL) { 1148 ERROR("Failed to cast clock %lu to clock mux\n", id); 1149 return -EINVAL; 1150 } 1151 1152 for (i = 0; i < mux->nclks; i++) { 1153 if (mux->clkids[i] == parent_id) { 1154 valid_source = true; 1155 break; 1156 } 1157 } 1158 1159 if (!valid_source) { 1160 ERROR("Clock %lu is not a valid clock for mux %lu\n", 1161 parent_id, id); 1162 return -EINVAL; 1163 } 1164 1165 mux->source_id = parent_id; 1166 1167 return 0; 1168 } 1169 1170 void s32cc_clk_register_drv(void) 1171 { 1172 static const struct clk_ops s32cc_clk_ops = { 1173 .enable = s32cc_clk_enable, 1174 .disable = s32cc_clk_disable, 1175 .is_enabled = s32cc_clk_is_enabled, 1176 .get_rate = s32cc_clk_get_rate, 1177 .set_rate = s32cc_clk_set_rate, 1178 .get_parent = s32cc_clk_get_parent, 1179 .set_parent = s32cc_clk_set_parent, 1180 }; 1181 1182 clk_register(&s32cc_clk_ops); 1183 } 1184 1185