uboot/arch/arm/mach-imx/mx7ulp/scg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2/*
   3 * Copyright (C) 2016 Freescale Semiconductor, Inc.
   4 */
   5
   6#include <common.h>
   7#include <div64.h>
   8#include <log.h>
   9#include <asm/io.h>
  10#include <errno.h>
  11#include <asm/arch/imx-regs.h>
  12#include <asm/arch/pcc.h>
  13#include <asm/arch/sys_proto.h>
  14#include <linux/delay.h>
  15
  16scg_p scg1_regs = (scg_p)SCG1_RBASE;
  17
  18static u32 scg_src_get_rate(enum scg_clk clksrc)
  19{
  20        u32 reg;
  21
  22        switch (clksrc) {
  23        case SCG_SOSC_CLK:
  24                reg = readl(&scg1_regs->sosccsr);
  25                if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
  26                        return 0;
  27
  28                return 24000000;
  29        case SCG_FIRC_CLK:
  30                reg = readl(&scg1_regs->firccsr);
  31                if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
  32                        return 0;
  33
  34                return 48000000;
  35        case SCG_SIRC_CLK:
  36                reg = readl(&scg1_regs->sirccsr);
  37                if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
  38                        return 0;
  39
  40                return 16000000;
  41        case SCG_ROSC_CLK:
  42                reg = readl(&scg1_regs->rtccsr);
  43                if (!(reg & SCG_ROSC_CSR_ROSCVLD_MASK))
  44                        return 0;
  45
  46                return 32768;
  47        default:
  48                break;
  49        }
  50
  51        return 0;
  52}
  53
  54static u32 scg_sircdiv_get_rate(enum scg_clk clk)
  55{
  56        u32 reg, val, rate;
  57        u32 shift, mask;
  58
  59        switch (clk) {
  60        case SCG_SIRC_DIV1_CLK:
  61                mask = SCG_SIRCDIV_DIV1_MASK;
  62                shift = SCG_SIRCDIV_DIV1_SHIFT;
  63                break;
  64        case SCG_SIRC_DIV2_CLK:
  65                mask = SCG_SIRCDIV_DIV2_MASK;
  66                shift = SCG_SIRCDIV_DIV2_SHIFT;
  67                break;
  68        case SCG_SIRC_DIV3_CLK:
  69                mask = SCG_SIRCDIV_DIV3_MASK;
  70                shift = SCG_SIRCDIV_DIV3_SHIFT;
  71                break;
  72        default:
  73                return 0;
  74        }
  75
  76        reg = readl(&scg1_regs->sirccsr);
  77        if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK))
  78                return 0;
  79
  80        reg = readl(&scg1_regs->sircdiv);
  81        val = (reg & mask) >> shift;
  82
  83        if (!val) /*clock disabled*/
  84                return 0;
  85
  86        rate = scg_src_get_rate(SCG_SIRC_CLK);
  87        rate = rate / (1 << (val - 1));
  88
  89        return rate;
  90}
  91
  92static u32 scg_fircdiv_get_rate(enum scg_clk clk)
  93{
  94        u32 reg, val, rate;
  95        u32 shift, mask;
  96
  97        switch (clk) {
  98        case SCG_FIRC_DIV1_CLK:
  99                mask = SCG_FIRCDIV_DIV1_MASK;
 100                shift = SCG_FIRCDIV_DIV1_SHIFT;
 101                break;
 102        case SCG_FIRC_DIV2_CLK:
 103                mask = SCG_FIRCDIV_DIV2_MASK;
 104                shift = SCG_FIRCDIV_DIV2_SHIFT;
 105                break;
 106        case SCG_FIRC_DIV3_CLK:
 107                mask = SCG_FIRCDIV_DIV3_MASK;
 108                shift = SCG_FIRCDIV_DIV3_SHIFT;
 109                break;
 110        default:
 111                return 0;
 112        }
 113
 114        reg = readl(&scg1_regs->firccsr);
 115        if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK))
 116                return 0;
 117
 118        reg = readl(&scg1_regs->fircdiv);
 119        val = (reg & mask) >> shift;
 120
 121        if (!val) /*clock disabled*/
 122                return 0;
 123
 124        rate = scg_src_get_rate(SCG_FIRC_CLK);
 125        rate = rate / (1 << (val - 1));
 126
 127        return rate;
 128}
 129
 130static u32 scg_soscdiv_get_rate(enum scg_clk clk)
 131{
 132        u32 reg, val, rate;
 133        u32 shift, mask;
 134
 135        switch (clk) {
 136        case SCG_SOSC_DIV1_CLK:
 137                mask = SCG_SOSCDIV_DIV1_MASK;
 138                shift = SCG_SOSCDIV_DIV1_SHIFT;
 139                break;
 140        case SCG_SOSC_DIV2_CLK:
 141                mask = SCG_SOSCDIV_DIV2_MASK;
 142                shift = SCG_SOSCDIV_DIV2_SHIFT;
 143                break;
 144        case SCG_SOSC_DIV3_CLK:
 145                mask = SCG_SOSCDIV_DIV3_MASK;
 146                shift = SCG_SOSCDIV_DIV3_SHIFT;
 147                break;
 148        default:
 149                return 0;
 150        }
 151
 152        reg = readl(&scg1_regs->sosccsr);
 153        if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK))
 154                return 0;
 155
 156        reg = readl(&scg1_regs->soscdiv);
 157        val = (reg & mask) >> shift;
 158
 159        if (!val) /*clock disabled*/
 160                return 0;
 161
 162        rate = scg_src_get_rate(SCG_SOSC_CLK);
 163        rate = rate / (1 << (val - 1));
 164
 165        return rate;
 166}
 167
 168static u32 scg_apll_pfd_get_rate(enum scg_clk clk)
 169{
 170        u32 reg, val, rate;
 171        u32 shift, mask, gate, valid;
 172
 173        switch (clk) {
 174        case SCG_APLL_PFD0_CLK:
 175                gate = SCG_PLL_PFD0_GATE_MASK;
 176                valid = SCG_PLL_PFD0_VALID_MASK;
 177                mask = SCG_PLL_PFD0_FRAC_MASK;
 178                shift = SCG_PLL_PFD0_FRAC_SHIFT;
 179                break;
 180        case SCG_APLL_PFD1_CLK:
 181                gate = SCG_PLL_PFD1_GATE_MASK;
 182                valid = SCG_PLL_PFD1_VALID_MASK;
 183                mask = SCG_PLL_PFD1_FRAC_MASK;
 184                shift = SCG_PLL_PFD1_FRAC_SHIFT;
 185                break;
 186        case SCG_APLL_PFD2_CLK:
 187                gate = SCG_PLL_PFD2_GATE_MASK;
 188                valid = SCG_PLL_PFD2_VALID_MASK;
 189                mask = SCG_PLL_PFD2_FRAC_MASK;
 190                shift = SCG_PLL_PFD2_FRAC_SHIFT;
 191                break;
 192        case SCG_APLL_PFD3_CLK:
 193                gate = SCG_PLL_PFD3_GATE_MASK;
 194                valid = SCG_PLL_PFD3_VALID_MASK;
 195                mask = SCG_PLL_PFD3_FRAC_MASK;
 196                shift = SCG_PLL_PFD3_FRAC_SHIFT;
 197                break;
 198        default:
 199                return 0;
 200        }
 201
 202        reg = readl(&scg1_regs->apllpfd);
 203        if (reg & gate || !(reg & valid))
 204                return 0;
 205
 206        clk_debug("scg_apll_pfd_get_rate reg 0x%x\n", reg);
 207
 208        val = (reg & mask) >> shift;
 209        rate = decode_pll(PLL_A7_APLL);
 210
 211        rate = rate / val * 18;
 212
 213        clk_debug("scg_apll_pfd_get_rate rate %u\n", rate);
 214
 215        return rate;
 216}
 217
 218static u32 scg_spll_pfd_get_rate(enum scg_clk clk)
 219{
 220        u32 reg, val, rate;
 221        u32 shift, mask, gate, valid;
 222
 223        switch (clk) {
 224        case SCG_SPLL_PFD0_CLK:
 225                gate = SCG_PLL_PFD0_GATE_MASK;
 226                valid = SCG_PLL_PFD0_VALID_MASK;
 227                mask = SCG_PLL_PFD0_FRAC_MASK;
 228                shift = SCG_PLL_PFD0_FRAC_SHIFT;
 229                break;
 230        case SCG_SPLL_PFD1_CLK:
 231                gate = SCG_PLL_PFD1_GATE_MASK;
 232                valid = SCG_PLL_PFD1_VALID_MASK;
 233                mask = SCG_PLL_PFD1_FRAC_MASK;
 234                shift = SCG_PLL_PFD1_FRAC_SHIFT;
 235                break;
 236        case SCG_SPLL_PFD2_CLK:
 237                gate = SCG_PLL_PFD2_GATE_MASK;
 238                valid = SCG_PLL_PFD2_VALID_MASK;
 239                mask = SCG_PLL_PFD2_FRAC_MASK;
 240                shift = SCG_PLL_PFD2_FRAC_SHIFT;
 241                break;
 242        case SCG_SPLL_PFD3_CLK:
 243                gate = SCG_PLL_PFD3_GATE_MASK;
 244                valid = SCG_PLL_PFD3_VALID_MASK;
 245                mask = SCG_PLL_PFD3_FRAC_MASK;
 246                shift = SCG_PLL_PFD3_FRAC_SHIFT;
 247                break;
 248        default:
 249                return 0;
 250        }
 251
 252        reg = readl(&scg1_regs->spllpfd);
 253        if (reg & gate || !(reg & valid))
 254                return 0;
 255
 256        clk_debug("scg_spll_pfd_get_rate reg 0x%x\n", reg);
 257
 258        val = (reg & mask) >> shift;
 259        rate = decode_pll(PLL_A7_SPLL);
 260
 261        rate = rate / val * 18;
 262
 263        clk_debug("scg_spll_pfd_get_rate rate %u\n", rate);
 264
 265        return rate;
 266}
 267
 268static u32 scg_apll_get_rate(void)
 269{
 270        u32 reg, val, rate;
 271
 272        reg = readl(&scg1_regs->apllcfg);
 273        val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
 274
 275        if (!val) {
 276                /* APLL clock after two dividers */
 277                rate = decode_pll(PLL_A7_APLL);
 278
 279                val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
 280                        SCG_PLL_CFG_POSTDIV1_SHIFT;
 281                rate = rate / (val + 1);
 282
 283                val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
 284                        SCG_PLL_CFG_POSTDIV2_SHIFT;
 285                rate = rate / (val + 1);
 286        } else {
 287                /* APLL PFD clock */
 288                val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
 289                        SCG_PLL_CFG_PFDSEL_SHIFT;
 290                rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
 291        }
 292
 293        return rate;
 294}
 295
 296static u32 scg_spll_get_rate(void)
 297{
 298        u32 reg, val, rate;
 299
 300        reg = readl(&scg1_regs->spllcfg);
 301        val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT;
 302
 303        clk_debug("scg_spll_get_rate reg 0x%x\n", reg);
 304
 305        if (!val) {
 306                /* APLL clock after two dividers */
 307                rate = decode_pll(PLL_A7_SPLL);
 308
 309                val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >>
 310                        SCG_PLL_CFG_POSTDIV1_SHIFT;
 311                rate = rate / (val + 1);
 312
 313                val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >>
 314                        SCG_PLL_CFG_POSTDIV2_SHIFT;
 315                rate = rate / (val + 1);
 316
 317                clk_debug("scg_spll_get_rate SPLL %u\n", rate);
 318
 319        } else {
 320                /* APLL PFD clock */
 321                val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
 322                        SCG_PLL_CFG_PFDSEL_SHIFT;
 323                rate = scg_spll_pfd_get_rate(SCG_SPLL_PFD0_CLK + val);
 324
 325                clk_debug("scg_spll_get_rate PFD %u\n", rate);
 326        }
 327
 328        return rate;
 329}
 330
 331static u32 scg_ddr_get_rate(void)
 332{
 333        u32 reg, val, rate, div;
 334
 335        reg = readl(&scg1_regs->ddrccr);
 336        val = (reg & SCG_DDRCCR_DDRCS_MASK) >> SCG_DDRCCR_DDRCS_SHIFT;
 337        div = (reg & SCG_DDRCCR_DDRDIV_MASK) >> SCG_DDRCCR_DDRDIV_SHIFT;
 338
 339        if (!div)
 340                return 0;
 341
 342        if (!val) {
 343                reg = readl(&scg1_regs->apllcfg);
 344                val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >>
 345                        SCG_PLL_CFG_PFDSEL_SHIFT;
 346                rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val);
 347        } else {
 348                rate = decode_pll(PLL_USB);
 349        }
 350
 351        rate = rate / (1 << (div - 1));
 352        return rate;
 353}
 354
 355static u32 scg_nic_get_rate(enum scg_clk clk)
 356{
 357        u32 reg, val, rate, nic0_rate;
 358        u32 shift, mask;
 359
 360        reg = readl(&scg1_regs->niccsr);
 361        val = (reg & SCG_NICCSR_NICCS_MASK) >> SCG_NICCSR_NICCS_SHIFT;
 362
 363        clk_debug("scg_nic_get_rate niccsr 0x%x\n", reg);
 364
 365        if (!val)
 366                rate = scg_src_get_rate(SCG_FIRC_CLK);
 367        else
 368                rate = scg_ddr_get_rate();
 369
 370        clk_debug("scg_nic_get_rate parent rate %u\n", rate);
 371
 372        val = (reg & SCG_NICCSR_NIC0DIV_MASK) >> SCG_NICCSR_NIC0DIV_SHIFT;
 373
 374        rate = rate / (val + 1);
 375        nic0_rate = rate;
 376
 377        clk_debug("scg_nic_get_rate NIC0 rate %u\n", rate);
 378
 379        switch (clk) {
 380        case SCG_NIC0_CLK:
 381                return rate;
 382        case SCG_GPU_CLK:
 383                mask = SCG_NICCSR_GPUDIV_MASK;
 384                shift = SCG_NICCSR_GPUDIV_SHIFT;
 385                break;
 386        case SCG_NIC1_EXT_CLK:
 387        case SCG_NIC1_BUS_CLK:
 388        case SCG_NIC1_CLK:
 389                mask = SCG_NICCSR_NIC1DIV_MASK;
 390                shift = SCG_NICCSR_NIC1DIV_SHIFT;
 391                break;
 392        default:
 393                return 0;
 394        }
 395
 396        val = (reg & mask) >> shift;
 397        rate = rate / (val + 1);
 398
 399        clk_debug("scg_nic_get_rate NIC1 rate %u\n", rate);
 400
 401        switch (clk) {
 402        case SCG_GPU_CLK:
 403        case SCG_NIC1_CLK:
 404                return rate;
 405        case SCG_NIC1_EXT_CLK:
 406                mask = SCG_NICCSR_NIC1EXTDIV_MASK;
 407                shift = SCG_NICCSR_NIC1EXTDIV_SHIFT;
 408                break;
 409        case SCG_NIC1_BUS_CLK:
 410                mask = SCG_NICCSR_NIC1BUSDIV_MASK;
 411                shift = SCG_NICCSR_NIC1BUSDIV_SHIFT;
 412                break;
 413        default:
 414                return 0;
 415        }
 416
 417        /*
 418         * On RevB, the nic_bus and nic_ext dividers are parallel
 419         * not chained with nic div
 420         */
 421        if (soc_rev() >= CHIP_REV_2_0)
 422                rate = nic0_rate;
 423
 424        val = (reg & mask) >> shift;
 425        rate = rate / (val + 1);
 426
 427        clk_debug("scg_nic_get_rate NIC1 bus rate %u\n", rate);
 428        return rate;
 429}
 430
 431
 432static enum scg_clk scg_scs_array[4] = {
 433        SCG_SOSC_CLK, SCG_SIRC_CLK, SCG_FIRC_CLK, SCG_ROSC_CLK,
 434};
 435
 436static u32 scg_sys_get_rate(enum scg_clk clk)
 437{
 438        u32 reg, val, rate;
 439
 440        if (clk != SCG_CORE_CLK && clk != SCG_BUS_CLK)
 441                return 0;
 442
 443        reg = readl(&scg1_regs->csr);
 444        val = (reg & SCG_CCR_SCS_MASK) >> SCG_CCR_SCS_SHIFT;
 445
 446        clk_debug("scg_sys_get_rate reg 0x%x\n", reg);
 447
 448        switch (val) {
 449        case SCG_SCS_SYS_OSC:
 450        case SCG_SCS_SLOW_IRC:
 451        case SCG_SCS_FAST_IRC:
 452        case SCG_SCS_RTC_OSC:
 453                rate = scg_src_get_rate(scg_scs_array[val - 1]);
 454                break;
 455        case 5:
 456                rate = scg_apll_get_rate();
 457                break;
 458        case 6:
 459                rate = scg_spll_get_rate();
 460                break;
 461        default:
 462                return 0;
 463        }
 464
 465        clk_debug("scg_sys_get_rate parent rate %u\n", rate);
 466
 467        val = (reg & SCG_CCR_DIVCORE_MASK) >> SCG_CCR_DIVCORE_SHIFT;
 468
 469        rate = rate / (val + 1);
 470
 471        if (clk == SCG_BUS_CLK) {
 472                val = (reg & SCG_CCR_DIVBUS_MASK) >> SCG_CCR_DIVBUS_SHIFT;
 473                rate = rate / (val + 1);
 474        }
 475
 476        return rate;
 477}
 478
 479u32 decode_pll(enum pll_clocks pll)
 480{
 481        u32 reg,  pre_div, infreq, mult;
 482        u32 num, denom;
 483
 484        /*
 485         * Alought there are four choices for the bypass src,
 486         * we choose OSC_24M which is the default set in ROM.
 487         */
 488        switch (pll) {
 489        case PLL_A7_SPLL:
 490                reg = readl(&scg1_regs->spllcsr);
 491
 492                if (!(reg & SCG_SPLL_CSR_SPLLVLD_MASK))
 493                        return 0;
 494
 495                reg = readl(&scg1_regs->spllcfg);
 496
 497                pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
 498                           SCG_PLL_CFG_PREDIV_SHIFT;
 499                pre_div += 1;
 500
 501                mult = (reg & SCG1_SPLL_CFG_MULT_MASK) >>
 502                           SCG_PLL_CFG_MULT_SHIFT;
 503
 504                infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
 505                           SCG_PLL_CFG_CLKSRC_SHIFT;
 506                if (!infreq)
 507                        infreq = scg_src_get_rate(SCG_SOSC_CLK);
 508                else
 509                        infreq = scg_src_get_rate(SCG_FIRC_CLK);
 510
 511                num = readl(&scg1_regs->spllnum);
 512                denom = readl(&scg1_regs->splldenom);
 513
 514                infreq = infreq / pre_div;
 515
 516                if (denom)
 517                        return infreq * mult + infreq * num / denom;
 518                else
 519                        return infreq * mult;
 520
 521        case PLL_A7_APLL:
 522                reg = readl(&scg1_regs->apllcsr);
 523
 524                if (!(reg & SCG_APLL_CSR_APLLVLD_MASK))
 525                        return 0;
 526
 527                reg = readl(&scg1_regs->apllcfg);
 528
 529                pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >>
 530                           SCG_PLL_CFG_PREDIV_SHIFT;
 531                pre_div += 1;
 532
 533                mult = (reg & SCG_APLL_CFG_MULT_MASK) >>
 534                           SCG_PLL_CFG_MULT_SHIFT;
 535
 536                infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >>
 537                           SCG_PLL_CFG_CLKSRC_SHIFT;
 538                if (!infreq)
 539                        infreq = scg_src_get_rate(SCG_SOSC_CLK);
 540                else
 541                        infreq = scg_src_get_rate(SCG_FIRC_CLK);
 542
 543                num = readl(&scg1_regs->apllnum);
 544                denom = readl(&scg1_regs->aplldenom);
 545
 546                infreq = infreq / pre_div;
 547
 548                if (denom)
 549                        return infreq * mult + infreq * num / denom;
 550                else
 551                        return infreq * mult;
 552
 553        case PLL_USB:
 554                reg = readl(&scg1_regs->upllcsr);
 555
 556                if (!(reg & SCG_UPLL_CSR_UPLLVLD_MASK))
 557                        return 0;
 558
 559                return 480000000u;
 560
 561        case PLL_MIPI:
 562                return 480000000u;
 563        default:
 564                printf("Unsupported pll clocks %d\n", pll);
 565                break;
 566        }
 567
 568        return 0;
 569}
 570
 571u32 scg_clk_get_rate(enum scg_clk clk)
 572{
 573        switch (clk) {
 574        case SCG_SIRC_DIV1_CLK:
 575        case SCG_SIRC_DIV2_CLK:
 576        case SCG_SIRC_DIV3_CLK:
 577                return scg_sircdiv_get_rate(clk);
 578
 579        case SCG_FIRC_DIV1_CLK:
 580        case SCG_FIRC_DIV2_CLK:
 581        case SCG_FIRC_DIV3_CLK:
 582                return scg_fircdiv_get_rate(clk);
 583
 584        case SCG_SOSC_DIV1_CLK:
 585        case SCG_SOSC_DIV2_CLK:
 586        case SCG_SOSC_DIV3_CLK:
 587                return scg_soscdiv_get_rate(clk);
 588
 589        case SCG_CORE_CLK:
 590        case SCG_BUS_CLK:
 591                return scg_sys_get_rate(clk);
 592
 593        case SCG_SPLL_PFD0_CLK:
 594        case SCG_SPLL_PFD1_CLK:
 595        case SCG_SPLL_PFD2_CLK:
 596        case SCG_SPLL_PFD3_CLK:
 597                return scg_spll_pfd_get_rate(clk);
 598
 599        case SCG_APLL_PFD0_CLK:
 600        case SCG_APLL_PFD1_CLK:
 601        case SCG_APLL_PFD2_CLK:
 602        case SCG_APLL_PFD3_CLK:
 603                return scg_apll_pfd_get_rate(clk);
 604
 605        case SCG_DDR_CLK:
 606                return scg_ddr_get_rate();
 607
 608        case SCG_NIC0_CLK:
 609        case SCG_GPU_CLK:
 610        case SCG_NIC1_CLK:
 611        case SCG_NIC1_BUS_CLK:
 612        case SCG_NIC1_EXT_CLK:
 613                return scg_nic_get_rate(clk);
 614
 615        case USB_PLL_OUT:
 616                return decode_pll(PLL_USB);
 617
 618        case MIPI_PLL_OUT:
 619                return decode_pll(PLL_MIPI);
 620
 621        case SCG_SOSC_CLK:
 622        case SCG_FIRC_CLK:
 623        case SCG_SIRC_CLK:
 624        case SCG_ROSC_CLK:
 625                return scg_src_get_rate(clk);
 626        default:
 627                return 0;
 628        }
 629}
 630
 631int scg_enable_pll_pfd(enum scg_clk clk, u32 frac)
 632{
 633        u32 reg;
 634        u32 shift, mask, gate, valid;
 635        u32 addr;
 636
 637        if (frac < 12 || frac > 35)
 638                return -EINVAL;
 639
 640        switch (clk) {
 641        case SCG_SPLL_PFD0_CLK:
 642        case SCG_APLL_PFD0_CLK:
 643                gate = SCG_PLL_PFD0_GATE_MASK;
 644                valid = SCG_PLL_PFD0_VALID_MASK;
 645                mask = SCG_PLL_PFD0_FRAC_MASK;
 646                shift = SCG_PLL_PFD0_FRAC_SHIFT;
 647
 648                if (clk == SCG_SPLL_PFD0_CLK)
 649                        addr = (u32)(&scg1_regs->spllpfd);
 650                else
 651                        addr = (u32)(&scg1_regs->apllpfd);
 652                break;
 653        case SCG_SPLL_PFD1_CLK:
 654        case SCG_APLL_PFD1_CLK:
 655                gate = SCG_PLL_PFD1_GATE_MASK;
 656                valid = SCG_PLL_PFD1_VALID_MASK;
 657                mask = SCG_PLL_PFD1_FRAC_MASK;
 658                shift = SCG_PLL_PFD1_FRAC_SHIFT;
 659
 660                if (clk == SCG_SPLL_PFD1_CLK)
 661                        addr = (u32)(&scg1_regs->spllpfd);
 662                else
 663                        addr = (u32)(&scg1_regs->apllpfd);
 664                break;
 665        case SCG_SPLL_PFD2_CLK:
 666        case SCG_APLL_PFD2_CLK:
 667                gate = SCG_PLL_PFD2_GATE_MASK;
 668                valid = SCG_PLL_PFD2_VALID_MASK;
 669                mask = SCG_PLL_PFD2_FRAC_MASK;
 670                shift = SCG_PLL_PFD2_FRAC_SHIFT;
 671
 672                if (clk == SCG_SPLL_PFD2_CLK)
 673                        addr = (u32)(&scg1_regs->spllpfd);
 674                else
 675                        addr = (u32)(&scg1_regs->apllpfd);
 676                break;
 677        case SCG_SPLL_PFD3_CLK:
 678        case SCG_APLL_PFD3_CLK:
 679                gate = SCG_PLL_PFD3_GATE_MASK;
 680                valid = SCG_PLL_PFD3_VALID_MASK;
 681                mask = SCG_PLL_PFD3_FRAC_MASK;
 682                shift = SCG_PLL_PFD3_FRAC_SHIFT;
 683
 684                if (clk == SCG_SPLL_PFD3_CLK)
 685                        addr = (u32)(&scg1_regs->spllpfd);
 686                else
 687                        addr = (u32)(&scg1_regs->apllpfd);
 688                break;
 689        default:
 690                return -EINVAL;
 691        }
 692
 693        /* Gate the PFD */
 694        reg = readl(addr);
 695        reg |= gate;
 696        writel(reg, addr);
 697
 698        /* Write Frac divider */
 699        reg &= ~mask;
 700        reg |= (frac << shift) & mask;
 701        writel(reg, addr);
 702
 703        /*
 704         * Un-gate the PFD
 705         * (Need un-gate before checking valid, not align with RM)
 706         */
 707        reg &= ~gate;
 708        writel(reg, addr);
 709
 710        /* Wait for PFD clock being valid */
 711        do {
 712                reg = readl(addr);
 713        } while (!(reg & valid));
 714
 715        return 0;
 716}
 717
 718#define SIM_MISC_CTRL0_USB_PLL_EN_MASK (0x1 << 2)
 719int scg_enable_usb_pll(bool usb_control)
 720{
 721        u32 sosc_rate;
 722        s32 timeout = 1000000;
 723        u32 reg;
 724
 725        struct usbphy_regs *usbphy =
 726                (struct usbphy_regs *)USBPHY_RBASE;
 727
 728        sosc_rate = scg_src_get_rate(SCG_SOSC_CLK);
 729        if (!sosc_rate)
 730                return -EPERM;
 731
 732        reg = readl(SIM0_RBASE + 0x3C);
 733        if (usb_control)
 734                reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
 735        else
 736                reg |= SIM_MISC_CTRL0_USB_PLL_EN_MASK;
 737        writel(reg, SIM0_RBASE + 0x3C);
 738
 739        if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) {
 740                writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr);
 741
 742                switch (sosc_rate) {
 743                case 24000000:
 744                        writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
 745                        break;
 746
 747                case 30000000:
 748                        writel(0x800000, &usbphy->usb1_pll_480_ctrl_set);
 749                        break;
 750
 751                case 19200000:
 752                        writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set);
 753                        break;
 754
 755                default:
 756                        writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set);
 757                        break;
 758                }
 759
 760                /* Enable the regulator first */
 761                writel(PLL_USB_REG_ENABLE_MASK,
 762                       &usbphy->usb1_pll_480_ctrl_set);
 763
 764                /* Wait at least 15us */
 765                udelay(15);
 766
 767                /* Enable the power */
 768                writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set);
 769
 770                /* Wait lock */
 771                while (timeout--) {
 772                        if (readl(&usbphy->usb1_pll_480_ctrl) &
 773                            PLL_USB_LOCK_MASK)
 774                                break;
 775                }
 776
 777                if (timeout <= 0) {
 778                        /* If timeout, we power down the pll */
 779                        writel(PLL_USB_PWR_MASK,
 780                               &usbphy->usb1_pll_480_ctrl_clr);
 781                        return -ETIME;
 782                }
 783        }
 784
 785        /* Clear the bypass */
 786        writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr);
 787
 788        /* Enable the PLL clock out to USB */
 789        writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK),
 790               &usbphy->usb1_pll_480_ctrl_set);
 791
 792        if (!usb_control) {
 793                while (timeout--) {
 794                        if (readl(&scg1_regs->upllcsr) &
 795                            SCG_UPLL_CSR_UPLLVLD_MASK)
 796                                break;
 797                }
 798
 799                if (timeout <= 0) {
 800                        reg = readl(SIM0_RBASE + 0x3C);
 801                        reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK;
 802                        writel(reg, SIM0_RBASE + 0x3C);
 803                        return -ETIME;
 804                }
 805        }
 806
 807        return 0;
 808}
 809
 810
 811/* A7 domain system clock source is SPLL */
 812#define SCG1_RCCR_SCS_NUM       ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT)
 813
 814/* A7 Core clck = SPLL PFD0 / 1 = 500MHz / 1 = 500MHz */
 815#define SCG1_RCCR_DIVCORE_NUM   ((0x0)  << SCG_CCR_DIVCORE_SHIFT)
 816#define SCG1_RCCR_CFG_MASK      (SCG_CCR_SCS_MASK | SCG_CCR_DIVBUS_MASK)
 817
 818/* A7 Plat clck = A7 Core Clock / 2 = 250MHz / 1 = 250MHz */
 819#define SCG1_RCCR_DIVBUS_NUM    ((0x1)  << SCG_CCR_DIVBUS_SHIFT)
 820#define SCG1_RCCR_CFG_NUM       (SCG1_RCCR_SCS_NUM | SCG1_RCCR_DIVBUS_NUM)
 821
 822void scg_a7_rccr_init(void)
 823{
 824        u32 rccr_reg_val = 0;
 825
 826        rccr_reg_val = readl(&scg1_regs->rccr);
 827
 828        rccr_reg_val &= (~SCG1_RCCR_CFG_MASK);
 829        rccr_reg_val |= (SCG1_RCCR_CFG_NUM);
 830
 831        writel(rccr_reg_val, &scg1_regs->rccr);
 832}
 833
 834/* POSTDIV2 = 1 */
 835#define SCG1_SPLL_CFG_POSTDIV2_NUM      ((0x0)  << SCG_PLL_CFG_POSTDIV2_SHIFT)
 836/* POSTDIV1 = 1 */
 837#define SCG1_SPLL_CFG_POSTDIV1_NUM      ((0x0)  << SCG_PLL_CFG_POSTDIV1_SHIFT)
 838
 839/* MULT = 22 */
 840#define SCG1_SPLL_CFG_MULT_NUM          ((22)   << SCG_PLL_CFG_MULT_SHIFT)
 841
 842/* PFD0 output clock selected */
 843#define SCG1_SPLL_CFG_PFDSEL_NUM        ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
 844/* PREDIV = 1 */
 845#define SCG1_SPLL_CFG_PREDIV_NUM        ((0x0)  << SCG_PLL_CFG_PREDIV_SHIFT)
 846/* SPLL output clocks (including PFD outputs) selected */
 847#define SCG1_SPLL_CFG_BYPASS_NUM        ((0x0)  << SCG_PLL_CFG_BYPASS_SHIFT)
 848/* SPLL PFD output clock selected */
 849#define SCG1_SPLL_CFG_PLLSEL_NUM        ((0x1)  << SCG_PLL_CFG_PLLSEL_SHIFT)
 850/* Clock source is System OSC */
 851#define SCG1_SPLL_CFG_CLKSRC_NUM        ((0x0)  << SCG_PLL_CFG_CLKSRC_SHIFT)
 852#define SCG1_SPLL_CFG_NUM_24M_OSC       (SCG1_SPLL_CFG_POSTDIV2_NUM     | \
 853                                         SCG1_SPLL_CFG_POSTDIV1_NUM     | \
 854                                         (22 << SCG_PLL_CFG_MULT_SHIFT) | \
 855                                         SCG1_SPLL_CFG_PFDSEL_NUM       | \
 856                                         SCG1_SPLL_CFG_PREDIV_NUM       | \
 857                                         SCG1_SPLL_CFG_BYPASS_NUM       | \
 858                                         SCG1_SPLL_CFG_PLLSEL_NUM       | \
 859                                         SCG1_SPLL_CFG_CLKSRC_NUM)
 860/*413Mhz = A7 SPLL(528MHz) * 18/23 */
 861#define SCG1_SPLL_PFD0_FRAC_NUM         ((23) << SCG_PLL_PFD0_FRAC_SHIFT)
 862
 863void scg_a7_spll_init(void)
 864{
 865        u32 val = 0;
 866
 867        /* Disable A7 System PLL */
 868        val = readl(&scg1_regs->spllcsr);
 869        val &= ~SCG_SPLL_CSR_SPLLEN_MASK;
 870        writel(val, &scg1_regs->spllcsr);
 871
 872        /*
 873         * Per block guide,
 874         * "When changing PFD values, it is recommneded PFDx clock
 875         * gets gated first by writing a value of 1 to PFDx_CLKGATE register,
 876         * then program the new PFD value, then poll the PFDx_VALID
 877         * flag to set before writing a value of 0 to PFDx_CLKGATE
 878         * to ungate the PFDx clock and allow PFDx clock to run"
 879         */
 880
 881        /* Gate off A7 SPLL PFD0 ~ PDF4  */
 882        val = readl(&scg1_regs->spllpfd);
 883        val |= (SCG_PLL_PFD3_GATE_MASK |
 884                        SCG_PLL_PFD2_GATE_MASK |
 885                        SCG_PLL_PFD1_GATE_MASK |
 886                        SCG_PLL_PFD0_GATE_MASK);
 887        writel(val, &scg1_regs->spllpfd);
 888
 889        /* ================ A7 SPLL Configuration Start ============== */
 890
 891        /* Configure A7 System PLL */
 892        writel(SCG1_SPLL_CFG_NUM_24M_OSC, &scg1_regs->spllcfg);
 893
 894        /* Enable A7 System PLL */
 895        val = readl(&scg1_regs->spllcsr);
 896        val |= SCG_SPLL_CSR_SPLLEN_MASK;
 897        writel(val, &scg1_regs->spllcsr);
 898
 899        /* Wait for A7 SPLL clock ready */
 900        while (!(readl(&scg1_regs->spllcsr) & SCG_SPLL_CSR_SPLLVLD_MASK))
 901                ;
 902
 903        /* Configure A7 SPLL PFD0 */
 904        val = readl(&scg1_regs->spllpfd);
 905        val &= ~SCG_PLL_PFD0_FRAC_MASK;
 906        val |= SCG1_SPLL_PFD0_FRAC_NUM;
 907        writel(val, &scg1_regs->spllpfd);
 908
 909        /* Un-gate A7 SPLL PFD0 */
 910        val = readl(&scg1_regs->spllpfd);
 911        val &= ~SCG_PLL_PFD0_GATE_MASK;
 912        writel(val, &scg1_regs->spllpfd);
 913
 914        /* Wait for A7 SPLL PFD0 clock being valid */
 915        while (!(readl(&scg1_regs->spllpfd) & SCG_PLL_PFD0_VALID_MASK))
 916                ;
 917
 918        /* ================ A7 SPLL Configuration End ============== */
 919}
 920
 921/* DDR clock source is APLL PFD0 (396MHz) */
 922#define SCG1_DDRCCR_DDRCS_NUM           ((0x0) << SCG_DDRCCR_DDRCS_SHIFT)
 923/* DDR clock = APLL PFD0 / 1 = 396MHz / 1 = 396MHz */
 924#define SCG1_DDRCCR_DDRDIV_NUM          ((0x1) << SCG_DDRCCR_DDRDIV_SHIFT)
 925/* DDR clock = APLL PFD0 / 2 = 396MHz / 2 = 198MHz */
 926#define SCG1_DDRCCR_DDRDIV_LF_NUM       ((0x2) << SCG_DDRCCR_DDRDIV_SHIFT)
 927#define SCG1_DDRCCR_CFG_NUM             (SCG1_DDRCCR_DDRCS_NUM  | \
 928                                         SCG1_DDRCCR_DDRDIV_NUM)
 929#define SCG1_DDRCCR_CFG_LF_NUM          (SCG1_DDRCCR_DDRCS_NUM  | \
 930                                         SCG1_DDRCCR_DDRDIV_LF_NUM)
 931void scg_a7_ddrclk_init(void)
 932{
 933        writel(SCG1_DDRCCR_CFG_NUM, &scg1_regs->ddrccr);
 934}
 935
 936/* SCG1(A7) APLLCFG configurations */
 937/* divide by 1 <<28 */
 938#define SCG1_APLL_CFG_POSTDIV2_NUM      ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT)
 939/* divide by 1 <<24 */
 940#define SCG1_APLL_CFG_POSTDIV1_NUM      ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT)
 941/* MULT is 22  <<16 */
 942#define SCG1_APLL_CFG_MULT_NUM          ((22)  << SCG_PLL_CFG_MULT_SHIFT)
 943/* PFD0 output clock selected  <<14 */
 944#define SCG1_APLL_CFG_PFDSEL_NUM        ((0) << SCG_PLL_CFG_PFDSEL_SHIFT)
 945/* PREDIV = 1   <<8 */
 946#define SCG1_APLL_CFG_PREDIV_NUM        ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT)
 947/* APLL output clocks (including PFD outputs) selected  <<2 */
 948#define SCG1_APLL_CFG_BYPASS_NUM        ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT)
 949/* APLL PFD output clock selected <<1 */
 950#define SCG1_APLL_CFG_PLLSEL_NUM        ((0x0) << SCG_PLL_CFG_PLLSEL_SHIFT)
 951/* Clock source is System OSC <<0 */
 952#define SCG1_APLL_CFG_CLKSRC_NUM        ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT)
 953
 954/* SCG1(A7) FIRC DIV configurations */
 955/* Disable FIRC DIV3 */
 956#define SCG1_FIRCDIV_DIV3_NUM           ((0x0) << SCG_FIRCDIV_DIV3_SHIFT)
 957/* FIRC DIV2 = 48MHz / 1 = 48MHz */
 958#define SCG1_FIRCDIV_DIV2_NUM           ((0x1) << SCG_FIRCDIV_DIV2_SHIFT)
 959/* Disable FIRC DIV1 */
 960#define SCG1_FIRCDIV_DIV1_NUM           ((0x0) << SCG_FIRCDIV_DIV1_SHIFT)
 961
 962void scg_a7_firc_init(void)
 963{
 964        /* Wait for FIRC clock ready */
 965        while (!(readl(&scg1_regs->firccsr) & SCG_FIRC_CSR_FIRCVLD_MASK))
 966                ;
 967
 968        /* Configure A7 FIRC DIV1 ~ DIV3 */
 969        writel((SCG1_FIRCDIV_DIV3_NUM |
 970                        SCG1_FIRCDIV_DIV2_NUM |
 971                        SCG1_FIRCDIV_DIV1_NUM), &scg1_regs->fircdiv);
 972}
 973
 974/* SCG1(A7) NICCCR configurations */
 975/* NIC clock source is DDR clock (396/198MHz) */
 976#define SCG1_NICCCR_NICCS_NUM           ((0x1) << SCG_NICCCR_NICCS_SHIFT)
 977
 978/* NIC0 clock = DDR Clock / 2 = 396MHz / 2 = 198MHz */
 979#define SCG1_NICCCR_NIC0_DIV_NUM        ((0x1) << SCG_NICCCR_NIC0_DIV_SHIFT)
 980/* NIC0 clock = DDR Clock / 1 = 198MHz / 1 = 198MHz */
 981#define SCG1_NICCCR_NIC0_DIV_LF_NUM     ((0x0) << SCG_NICCCR_NIC0_DIV_SHIFT)
 982/* NIC1 clock = NIC0 Clock / 1 = 198MHz / 2 = 198MHz */
 983#define SCG1_NICCCR_NIC1_DIV_NUM        ((0x0) << SCG_NICCCR_NIC1_DIV_SHIFT)
 984/* NIC1 bus clock = NIC1 Clock / 3 = 198MHz / 3 = 66MHz */
 985#define SCG1_NICCCR_NIC1_DIVBUS_NUM     ((0x2) << SCG_NICCCR_NIC1_DIVBUS_SHIFT)
 986#define SCG1_NICCCR_CFG_NUM             (SCG1_NICCCR_NICCS_NUM      | \
 987                                         SCG1_NICCCR_NIC0_DIV_NUM   | \
 988                                         SCG1_NICCCR_NIC1_DIV_NUM   | \
 989                                         SCG1_NICCCR_NIC1_DIVBUS_NUM)
 990
 991void scg_a7_nicclk_init(void)
 992{
 993        writel(SCG1_NICCCR_CFG_NUM, &scg1_regs->nicccr);
 994}
 995
 996/* SCG1(A7) FIRC DIV configurations */
 997/* Enable FIRC DIV3 */
 998#define SCG1_SOSCDIV_DIV3_NUM           ((0x1) << SCG_SOSCDIV_DIV3_SHIFT)
 999/* FIRC DIV2 = 48MHz / 1 = 48MHz */
1000#define SCG1_SOSCDIV_DIV2_NUM           ((0x1) << SCG_SOSCDIV_DIV2_SHIFT)
1001/* Enable FIRC DIV1 */
1002#define SCG1_SOSCDIV_DIV1_NUM           ((0x1) << SCG_SOSCDIV_DIV1_SHIFT)
1003
1004void scg_a7_soscdiv_init(void)
1005{
1006        /* Wait for FIRC clock ready */
1007        while (!(readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK))
1008                ;
1009
1010        /* Configure A7 FIRC DIV1 ~ DIV3 */
1011        writel((SCG1_SOSCDIV_DIV3_NUM | SCG1_SOSCDIV_DIV2_NUM |
1012               SCG1_SOSCDIV_DIV1_NUM), &scg1_regs->soscdiv);
1013}
1014
1015void scg_a7_sys_clk_sel(enum scg_sys_src clk)
1016{
1017        u32 rccr_reg_val = 0;
1018
1019        clk_debug("%s: system clock selected as %s\n", "[SCG]",
1020                  clk == SCG_SCS_SYS_OSC ? "SYS_OSC" :
1021                  clk == SCG_SCS_SLOW_IRC  ? "SLOW_IRC" :
1022                  clk == SCG_SCS_FAST_IRC  ? "FAST_IRC" :
1023                  clk == SCG_SCS_RTC_OSC   ? "RTC_OSC" :
1024                  clk == SCG_SCS_AUX_PLL   ? "AUX_PLL" :
1025                  clk == SCG_SCS_SYS_PLL   ? "SYS_PLL" :
1026                  clk == SCG_SCS_USBPHY_PLL ? "USBPHY_PLL" :
1027                  "Invalid source"
1028        );
1029
1030        rccr_reg_val = readl(&scg1_regs->rccr);
1031        rccr_reg_val &= ~SCG_CCR_SCS_MASK;
1032        rccr_reg_val |= (clk << SCG_CCR_SCS_SHIFT);
1033        writel(rccr_reg_val, &scg1_regs->rccr);
1034}
1035
1036void scg_a7_info(void)
1037{
1038        debug("SCG Version: 0x%x\n", readl(&scg1_regs->verid));
1039        debug("SCG Parameter: 0x%x\n", readl(&scg1_regs->param));
1040        debug("SCG RCCR Value: 0x%x\n", readl(&scg1_regs->rccr));
1041        debug("SCG Clock Status: 0x%x\n", readl(&scg1_regs->csr));
1042}
1043
1044void scg_a7_init_core_clk(void)
1045{
1046        u32 val = 0;
1047
1048        /*
1049         * The normal target frequency for ULP B0 is 500Mhz,
1050         * but ROM set it to 413Mhz, need to change SPLL PFD0 FRAC
1051         */
1052        if (soc_rev() >= CHIP_REV_2_0) {
1053                /* Switch RCCR SCG to SOSC, firstly check the SOSC is valid */
1054                if ((readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK)) {
1055                        val = readl(&scg1_regs->rccr);
1056                        val &= (~SCG_CCR_SCS_MASK);
1057                        val |= ((SCG_SCS_SYS_OSC) << SCG_CCR_SCS_SHIFT);
1058                        writel(val, &scg1_regs->rccr);
1059
1060                        /* Switch the PLLS to SPLL clk */
1061                        val = readl(&scg1_regs->spllcfg);
1062                        val &= ~SCG_PLL_CFG_PLLSEL_MASK;
1063                        writel(val, &scg1_regs->spllcfg);
1064
1065                        /*
1066                         * Re-configure PFD0 to 19,
1067                         * A7 SPLL(528MHz) * 18 / 19 = 500MHz
1068                         */
1069                        scg_enable_pll_pfd(SCG_SPLL_PFD0_CLK, 19);
1070
1071                        /* Switch the PLLS to SPLL PFD0 */
1072                        val = readl(&scg1_regs->spllcfg);
1073                        val |= SCG_PLL_CFG_PLLSEL_MASK;
1074                        writel(val, &scg1_regs->spllcfg);
1075
1076                        /* Set RCCR SCG to SPLL clk out */
1077                        val = readl(&scg1_regs->rccr);
1078                        val &= (~SCG_CCR_SCS_MASK);
1079                        val |= ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT);
1080                        writel(val, &scg1_regs->rccr);
1081                }
1082        }
1083}
1084