1*41793000SKever Yang /* 2*41793000SKever Yang * (C) Copyright 2017 Rockchip Electronics Co., Ltd 3*41793000SKever Yang * 4*41793000SKever Yang * SPDX-License-Identifier: GPL-2.0 5*41793000SKever Yang */ 6*41793000SKever Yang 7*41793000SKever Yang #include <common.h> 8*41793000SKever Yang #include <clk-uclass.h> 9*41793000SKever Yang #include <dm.h> 10*41793000SKever Yang #include <errno.h> 11*41793000SKever Yang #include <syscon.h> 12*41793000SKever Yang #include <asm/arch/clock.h> 13*41793000SKever Yang #include <asm/arch/cru_rk3328.h> 14*41793000SKever Yang #include <asm/arch/hardware.h> 15*41793000SKever Yang #include <asm/io.h> 16*41793000SKever Yang #include <dm/lists.h> 17*41793000SKever Yang #include <dt-bindings/clock/rk3328-cru.h> 18*41793000SKever Yang 19*41793000SKever Yang DECLARE_GLOBAL_DATA_PTR; 20*41793000SKever Yang 21*41793000SKever Yang struct pll_div { 22*41793000SKever Yang u32 refdiv; 23*41793000SKever Yang u32 fbdiv; 24*41793000SKever Yang u32 postdiv1; 25*41793000SKever Yang u32 postdiv2; 26*41793000SKever Yang u32 frac; 27*41793000SKever Yang }; 28*41793000SKever Yang 29*41793000SKever Yang #define RATE_TO_DIV(input_rate, output_rate) \ 30*41793000SKever Yang ((input_rate) / (output_rate) - 1); 31*41793000SKever Yang #define DIV_TO_RATE(input_rate, div) ((input_rate) / ((div) + 1)) 32*41793000SKever Yang 33*41793000SKever Yang #define PLL_DIVISORS(hz, _refdiv, _postdiv1, _postdiv2) {\ 34*41793000SKever Yang .refdiv = _refdiv,\ 35*41793000SKever Yang .fbdiv = (u32)((u64)hz * _refdiv * _postdiv1 * _postdiv2 / OSC_HZ),\ 36*41793000SKever Yang .postdiv1 = _postdiv1, .postdiv2 = _postdiv2}; 37*41793000SKever Yang 38*41793000SKever Yang static const struct pll_div gpll_init_cfg = PLL_DIVISORS(GPLL_HZ, 1, 4, 1); 39*41793000SKever Yang static const struct pll_div cpll_init_cfg = PLL_DIVISORS(CPLL_HZ, 2, 2, 1); 40*41793000SKever Yang 41*41793000SKever Yang static const struct pll_div apll_816_cfg = PLL_DIVISORS(816 * MHz, 1, 2, 1); 42*41793000SKever Yang static const struct pll_div apll_600_cfg = PLL_DIVISORS(600 * MHz, 1, 3, 1); 43*41793000SKever Yang 44*41793000SKever Yang static const struct pll_div *apll_cfgs[] = { 45*41793000SKever Yang [APLL_816_MHZ] = &apll_816_cfg, 46*41793000SKever Yang [APLL_600_MHZ] = &apll_600_cfg, 47*41793000SKever Yang }; 48*41793000SKever Yang 49*41793000SKever Yang enum { 50*41793000SKever Yang /* PLL_CON0 */ 51*41793000SKever Yang PLL_POSTDIV1_SHIFT = 12, 52*41793000SKever Yang PLL_POSTDIV1_MASK = 0x7 << PLL_POSTDIV1_SHIFT, 53*41793000SKever Yang PLL_FBDIV_SHIFT = 0, 54*41793000SKever Yang PLL_FBDIV_MASK = 0xfff, 55*41793000SKever Yang 56*41793000SKever Yang /* PLL_CON1 */ 57*41793000SKever Yang PLL_DSMPD_SHIFT = 12, 58*41793000SKever Yang PLL_DSMPD_MASK = 1 << PLL_DSMPD_SHIFT, 59*41793000SKever Yang PLL_INTEGER_MODE = 1, 60*41793000SKever Yang PLL_LOCK_STATUS_SHIFT = 10, 61*41793000SKever Yang PLL_LOCK_STATUS_MASK = 1 << PLL_LOCK_STATUS_SHIFT, 62*41793000SKever Yang PLL_POSTDIV2_SHIFT = 6, 63*41793000SKever Yang PLL_POSTDIV2_MASK = 0x7 << PLL_POSTDIV2_SHIFT, 64*41793000SKever Yang PLL_REFDIV_SHIFT = 0, 65*41793000SKever Yang PLL_REFDIV_MASK = 0x3f, 66*41793000SKever Yang 67*41793000SKever Yang /* PLL_CON2 */ 68*41793000SKever Yang PLL_FRACDIV_SHIFT = 0, 69*41793000SKever Yang PLL_FRACDIV_MASK = 0xffffff, 70*41793000SKever Yang 71*41793000SKever Yang /* MODE_CON */ 72*41793000SKever Yang APLL_MODE_SHIFT = 0, 73*41793000SKever Yang NPLL_MODE_SHIFT = 1, 74*41793000SKever Yang DPLL_MODE_SHIFT = 4, 75*41793000SKever Yang CPLL_MODE_SHIFT = 8, 76*41793000SKever Yang GPLL_MODE_SHIFT = 12, 77*41793000SKever Yang PLL_MODE_SLOW = 0, 78*41793000SKever Yang PLL_MODE_NORM, 79*41793000SKever Yang 80*41793000SKever Yang /* CLKSEL_CON0 */ 81*41793000SKever Yang CLK_CORE_PLL_SEL_APLL = 0, 82*41793000SKever Yang CLK_CORE_PLL_SEL_GPLL, 83*41793000SKever Yang CLK_CORE_PLL_SEL_DPLL, 84*41793000SKever Yang CLK_CORE_PLL_SEL_NPLL, 85*41793000SKever Yang CLK_CORE_PLL_SEL_SHIFT = 6, 86*41793000SKever Yang CLK_CORE_PLL_SEL_MASK = 3 << CLK_CORE_PLL_SEL_SHIFT, 87*41793000SKever Yang CLK_CORE_DIV_SHIFT = 0, 88*41793000SKever Yang CLK_CORE_DIV_MASK = 0x1f, 89*41793000SKever Yang 90*41793000SKever Yang /* CLKSEL_CON1 */ 91*41793000SKever Yang ACLKM_CORE_DIV_SHIFT = 4, 92*41793000SKever Yang ACLKM_CORE_DIV_MASK = 0x7 << ACLKM_CORE_DIV_SHIFT, 93*41793000SKever Yang PCLK_DBG_DIV_SHIFT = 0, 94*41793000SKever Yang PCLK_DBG_DIV_MASK = 0xF << PCLK_DBG_DIV_SHIFT, 95*41793000SKever Yang 96*41793000SKever Yang /* CLKSEL_CON28 */ 97*41793000SKever Yang ACLK_PERIHP_PLL_SEL_CPLL = 0, 98*41793000SKever Yang ACLK_PERIHP_PLL_SEL_GPLL, 99*41793000SKever Yang ACLK_PERIHP_PLL_SEL_HDMIPHY, 100*41793000SKever Yang ACLK_PERIHP_PLL_SEL_SHIFT = 6, 101*41793000SKever Yang ACLK_PERIHP_PLL_SEL_MASK = 3 << ACLK_PERIHP_PLL_SEL_SHIFT, 102*41793000SKever Yang ACLK_PERIHP_DIV_CON_SHIFT = 0, 103*41793000SKever Yang ACLK_PERIHP_DIV_CON_MASK = 0x1f, 104*41793000SKever Yang 105*41793000SKever Yang /* CLKSEL_CON29 */ 106*41793000SKever Yang PCLK_PERIHP_DIV_CON_SHIFT = 4, 107*41793000SKever Yang PCLK_PERIHP_DIV_CON_MASK = 0x7 << PCLK_PERIHP_DIV_CON_SHIFT, 108*41793000SKever Yang HCLK_PERIHP_DIV_CON_SHIFT = 0, 109*41793000SKever Yang HCLK_PERIHP_DIV_CON_MASK = 3 << HCLK_PERIHP_DIV_CON_SHIFT, 110*41793000SKever Yang 111*41793000SKever Yang /* CLKSEL_CON22 */ 112*41793000SKever Yang CLK_TSADC_DIV_CON_SHIFT = 0, 113*41793000SKever Yang CLK_TSADC_DIV_CON_MASK = 0x3ff, 114*41793000SKever Yang 115*41793000SKever Yang /* CLKSEL_CON23 */ 116*41793000SKever Yang CLK_SARADC_DIV_CON_SHIFT = 0, 117*41793000SKever Yang CLK_SARADC_DIV_CON_MASK = 0x3ff << CLK_SARADC_DIV_CON_SHIFT, 118*41793000SKever Yang 119*41793000SKever Yang /* CLKSEL_CON24 */ 120*41793000SKever Yang CLK_PWM_PLL_SEL_CPLL = 0, 121*41793000SKever Yang CLK_PWM_PLL_SEL_GPLL, 122*41793000SKever Yang CLK_PWM_PLL_SEL_SHIFT = 15, 123*41793000SKever Yang CLK_PWM_PLL_SEL_MASK = 1 << CLK_PWM_PLL_SEL_SHIFT, 124*41793000SKever Yang CLK_PWM_DIV_CON_SHIFT = 8, 125*41793000SKever Yang CLK_PWM_DIV_CON_MASK = 0x7f << CLK_PWM_DIV_CON_SHIFT, 126*41793000SKever Yang 127*41793000SKever Yang CLK_SPI_PLL_SEL_CPLL = 0, 128*41793000SKever Yang CLK_SPI_PLL_SEL_GPLL, 129*41793000SKever Yang CLK_SPI_PLL_SEL_SHIFT = 7, 130*41793000SKever Yang CLK_SPI_PLL_SEL_MASK = 1 << CLK_SPI_PLL_SEL_SHIFT, 131*41793000SKever Yang CLK_SPI_DIV_CON_SHIFT = 0, 132*41793000SKever Yang CLK_SPI_DIV_CON_MASK = 0x7f << CLK_SPI_DIV_CON_SHIFT, 133*41793000SKever Yang 134*41793000SKever Yang /* CLKSEL_CON30 */ 135*41793000SKever Yang CLK_SDMMC_PLL_SEL_CPLL = 0, 136*41793000SKever Yang CLK_SDMMC_PLL_SEL_GPLL, 137*41793000SKever Yang CLK_SDMMC_PLL_SEL_24M, 138*41793000SKever Yang CLK_SDMMC_PLL_SEL_USBPHY, 139*41793000SKever Yang CLK_SDMMC_PLL_SHIFT = 8, 140*41793000SKever Yang CLK_SDMMC_PLL_MASK = 0x3 << CLK_SDMMC_PLL_SHIFT, 141*41793000SKever Yang CLK_SDMMC_DIV_CON_SHIFT = 0, 142*41793000SKever Yang CLK_SDMMC_DIV_CON_MASK = 0xff << CLK_SDMMC_DIV_CON_SHIFT, 143*41793000SKever Yang 144*41793000SKever Yang /* CLKSEL_CON32 */ 145*41793000SKever Yang CLK_EMMC_PLL_SEL_CPLL = 0, 146*41793000SKever Yang CLK_EMMC_PLL_SEL_GPLL, 147*41793000SKever Yang CLK_EMMC_PLL_SEL_24M, 148*41793000SKever Yang CLK_EMMC_PLL_SEL_USBPHY, 149*41793000SKever Yang CLK_EMMC_PLL_SHIFT = 8, 150*41793000SKever Yang CLK_EMMC_PLL_MASK = 0x3 << CLK_EMMC_PLL_SHIFT, 151*41793000SKever Yang CLK_EMMC_DIV_CON_SHIFT = 0, 152*41793000SKever Yang CLK_EMMC_DIV_CON_MASK = 0xff << CLK_EMMC_DIV_CON_SHIFT, 153*41793000SKever Yang 154*41793000SKever Yang /* CLKSEL_CON34 */ 155*41793000SKever Yang CLK_I2C_PLL_SEL_CPLL = 0, 156*41793000SKever Yang CLK_I2C_PLL_SEL_GPLL, 157*41793000SKever Yang CLK_I2C_DIV_CON_MASK = 0x7f, 158*41793000SKever Yang CLK_I2C_PLL_SEL_MASK = 1, 159*41793000SKever Yang CLK_I2C1_PLL_SEL_SHIFT = 15, 160*41793000SKever Yang CLK_I2C1_DIV_CON_SHIFT = 8, 161*41793000SKever Yang CLK_I2C0_PLL_SEL_SHIFT = 7, 162*41793000SKever Yang CLK_I2C0_DIV_CON_SHIFT = 0, 163*41793000SKever Yang 164*41793000SKever Yang /* CLKSEL_CON35 */ 165*41793000SKever Yang CLK_I2C3_PLL_SEL_SHIFT = 15, 166*41793000SKever Yang CLK_I2C3_DIV_CON_SHIFT = 8, 167*41793000SKever Yang CLK_I2C2_PLL_SEL_SHIFT = 7, 168*41793000SKever Yang CLK_I2C2_DIV_CON_SHIFT = 0, 169*41793000SKever Yang }; 170*41793000SKever Yang 171*41793000SKever Yang #define VCO_MAX_KHZ (3200 * (MHz / KHz)) 172*41793000SKever Yang #define VCO_MIN_KHZ (800 * (MHz / KHz)) 173*41793000SKever Yang #define OUTPUT_MAX_KHZ (3200 * (MHz / KHz)) 174*41793000SKever Yang #define OUTPUT_MIN_KHZ (16 * (MHz / KHz)) 175*41793000SKever Yang 176*41793000SKever Yang /* 177*41793000SKever Yang * the div restructions of pll in integer mode, these are defined in 178*41793000SKever Yang * * CRU_*PLL_CON0 or PMUCRU_*PLL_CON0 179*41793000SKever Yang */ 180*41793000SKever Yang #define PLL_DIV_MIN 16 181*41793000SKever Yang #define PLL_DIV_MAX 3200 182*41793000SKever Yang 183*41793000SKever Yang /* 184*41793000SKever Yang * How to calculate the PLL(from TRM V0.3 Part 1 Page 63): 185*41793000SKever Yang * Formulas also embedded within the Fractional PLL Verilog model: 186*41793000SKever Yang * If DSMPD = 1 (DSM is disabled, "integer mode") 187*41793000SKever Yang * FOUTVCO = FREF / REFDIV * FBDIV 188*41793000SKever Yang * FOUTPOSTDIV = FOUTVCO / POSTDIV1 / POSTDIV2 189*41793000SKever Yang * Where: 190*41793000SKever Yang * FOUTVCO = Fractional PLL non-divided output frequency 191*41793000SKever Yang * FOUTPOSTDIV = Fractional PLL divided output frequency 192*41793000SKever Yang * (output of second post divider) 193*41793000SKever Yang * FREF = Fractional PLL input reference frequency, (the OSC_HZ 24MHz input) 194*41793000SKever Yang * REFDIV = Fractional PLL input reference clock divider 195*41793000SKever Yang * FBDIV = Integer value programmed into feedback divide 196*41793000SKever Yang * 197*41793000SKever Yang */ 198*41793000SKever Yang static void rkclk_set_pll(struct rk3328_cru *cru, enum rk_clk_id clk_id, 199*41793000SKever Yang const struct pll_div *div) 200*41793000SKever Yang { 201*41793000SKever Yang u32 *pll_con; 202*41793000SKever Yang u32 mode_shift, mode_mask; 203*41793000SKever Yang 204*41793000SKever Yang pll_con = NULL; 205*41793000SKever Yang mode_shift = 0; 206*41793000SKever Yang switch (clk_id) { 207*41793000SKever Yang case CLK_ARM: 208*41793000SKever Yang pll_con = cru->apll_con; 209*41793000SKever Yang mode_shift = APLL_MODE_SHIFT; 210*41793000SKever Yang break; 211*41793000SKever Yang case CLK_DDR: 212*41793000SKever Yang pll_con = cru->dpll_con; 213*41793000SKever Yang mode_shift = DPLL_MODE_SHIFT; 214*41793000SKever Yang break; 215*41793000SKever Yang case CLK_CODEC: 216*41793000SKever Yang pll_con = cru->cpll_con; 217*41793000SKever Yang mode_shift = CPLL_MODE_SHIFT; 218*41793000SKever Yang break; 219*41793000SKever Yang case CLK_GENERAL: 220*41793000SKever Yang pll_con = cru->gpll_con; 221*41793000SKever Yang mode_shift = GPLL_MODE_SHIFT; 222*41793000SKever Yang break; 223*41793000SKever Yang case CLK_NEW: 224*41793000SKever Yang pll_con = cru->npll_con; 225*41793000SKever Yang mode_shift = NPLL_MODE_SHIFT; 226*41793000SKever Yang break; 227*41793000SKever Yang default: 228*41793000SKever Yang break; 229*41793000SKever Yang } 230*41793000SKever Yang mode_mask = 1 << mode_shift; 231*41793000SKever Yang 232*41793000SKever Yang /* All 8 PLLs have same VCO and output frequency range restrictions. */ 233*41793000SKever Yang u32 vco_khz = OSC_HZ / 1000 * div->fbdiv / div->refdiv; 234*41793000SKever Yang u32 output_khz = vco_khz / div->postdiv1 / div->postdiv2; 235*41793000SKever Yang 236*41793000SKever Yang debug("PLL at %p: fbdiv=%d, refdiv=%d, postdiv1=%d, \ 237*41793000SKever Yang postdiv2=%d, vco=%u khz, output=%u khz\n", 238*41793000SKever Yang pll_con, div->fbdiv, div->refdiv, div->postdiv1, 239*41793000SKever Yang div->postdiv2, vco_khz, output_khz); 240*41793000SKever Yang assert(vco_khz >= VCO_MIN_KHZ && vco_khz <= VCO_MAX_KHZ && 241*41793000SKever Yang output_khz >= OUTPUT_MIN_KHZ && output_khz <= OUTPUT_MAX_KHZ && 242*41793000SKever Yang div->fbdiv >= PLL_DIV_MIN && div->fbdiv <= PLL_DIV_MAX); 243*41793000SKever Yang 244*41793000SKever Yang /* 245*41793000SKever Yang * When power on or changing PLL setting, 246*41793000SKever Yang * we must force PLL into slow mode to ensure output stable clock. 247*41793000SKever Yang */ 248*41793000SKever Yang rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_SLOW << mode_shift); 249*41793000SKever Yang 250*41793000SKever Yang /* use integer mode */ 251*41793000SKever Yang rk_clrsetreg(&pll_con[1], PLL_DSMPD_MASK, 252*41793000SKever Yang PLL_INTEGER_MODE << PLL_DSMPD_SHIFT); 253*41793000SKever Yang 254*41793000SKever Yang rk_clrsetreg(&pll_con[0], 255*41793000SKever Yang PLL_FBDIV_MASK | PLL_POSTDIV1_MASK, 256*41793000SKever Yang (div->fbdiv << PLL_FBDIV_SHIFT) | 257*41793000SKever Yang (div->postdiv1 << PLL_POSTDIV1_SHIFT)); 258*41793000SKever Yang rk_clrsetreg(&pll_con[1], 259*41793000SKever Yang PLL_POSTDIV2_MASK | PLL_REFDIV_MASK, 260*41793000SKever Yang (div->postdiv2 << PLL_POSTDIV2_SHIFT) | 261*41793000SKever Yang (div->refdiv << PLL_REFDIV_SHIFT)); 262*41793000SKever Yang 263*41793000SKever Yang /* waiting for pll lock */ 264*41793000SKever Yang while (!(readl(&pll_con[1]) & (1 << PLL_LOCK_STATUS_SHIFT))) 265*41793000SKever Yang udelay(1); 266*41793000SKever Yang 267*41793000SKever Yang /* pll enter normal mode */ 268*41793000SKever Yang rk_clrsetreg(&cru->mode_con, mode_mask, PLL_MODE_NORM << mode_shift); 269*41793000SKever Yang } 270*41793000SKever Yang 271*41793000SKever Yang static void rkclk_init(struct rk3328_cru *cru) 272*41793000SKever Yang { 273*41793000SKever Yang u32 aclk_div; 274*41793000SKever Yang u32 hclk_div; 275*41793000SKever Yang u32 pclk_div; 276*41793000SKever Yang 277*41793000SKever Yang /* configure gpll cpll */ 278*41793000SKever Yang rkclk_set_pll(cru, CLK_GENERAL, &gpll_init_cfg); 279*41793000SKever Yang rkclk_set_pll(cru, CLK_CODEC, &cpll_init_cfg); 280*41793000SKever Yang 281*41793000SKever Yang /* configure perihp aclk, hclk, pclk */ 282*41793000SKever Yang aclk_div = GPLL_HZ / PERIHP_ACLK_HZ - 1; 283*41793000SKever Yang hclk_div = PERIHP_ACLK_HZ / PERIHP_HCLK_HZ - 1; 284*41793000SKever Yang pclk_div = PERIHP_ACLK_HZ / PERIHP_PCLK_HZ - 1; 285*41793000SKever Yang 286*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[28], 287*41793000SKever Yang ACLK_PERIHP_PLL_SEL_MASK | ACLK_PERIHP_DIV_CON_MASK, 288*41793000SKever Yang ACLK_PERIHP_PLL_SEL_GPLL << ACLK_PERIHP_PLL_SEL_SHIFT | 289*41793000SKever Yang aclk_div << ACLK_PERIHP_DIV_CON_SHIFT); 290*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[29], 291*41793000SKever Yang PCLK_PERIHP_DIV_CON_MASK | HCLK_PERIHP_DIV_CON_MASK, 292*41793000SKever Yang pclk_div << PCLK_PERIHP_DIV_CON_SHIFT | 293*41793000SKever Yang hclk_div << HCLK_PERIHP_DIV_CON_SHIFT); 294*41793000SKever Yang } 295*41793000SKever Yang 296*41793000SKever Yang void rk3328_configure_cpu(struct rk3328_cru *cru, 297*41793000SKever Yang enum apll_frequencies apll_freq) 298*41793000SKever Yang { 299*41793000SKever Yang u32 clk_core_div; 300*41793000SKever Yang u32 aclkm_div; 301*41793000SKever Yang u32 pclk_dbg_div; 302*41793000SKever Yang 303*41793000SKever Yang rkclk_set_pll(cru, CLK_ARM, apll_cfgs[apll_freq]); 304*41793000SKever Yang 305*41793000SKever Yang clk_core_div = APLL_HZ / CLK_CORE_HZ - 1; 306*41793000SKever Yang aclkm_div = APLL_HZ / ACLKM_CORE_HZ / (clk_core_div + 1) - 1; 307*41793000SKever Yang pclk_dbg_div = APLL_HZ / PCLK_DBG_HZ / (clk_core_div + 1) - 1; 308*41793000SKever Yang 309*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[0], 310*41793000SKever Yang CLK_CORE_PLL_SEL_MASK | CLK_CORE_DIV_MASK, 311*41793000SKever Yang CLK_CORE_PLL_SEL_APLL << CLK_CORE_PLL_SEL_SHIFT | 312*41793000SKever Yang clk_core_div << CLK_CORE_DIV_SHIFT); 313*41793000SKever Yang 314*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[1], 315*41793000SKever Yang PCLK_DBG_DIV_MASK | ACLKM_CORE_DIV_MASK, 316*41793000SKever Yang pclk_dbg_div << PCLK_DBG_DIV_SHIFT | 317*41793000SKever Yang aclkm_div << ACLKM_CORE_DIV_SHIFT); 318*41793000SKever Yang } 319*41793000SKever Yang 320*41793000SKever Yang 321*41793000SKever Yang static ulong rk3328_i2c_get_clk(struct rk3328_cru *cru, ulong clk_id) 322*41793000SKever Yang { 323*41793000SKever Yang u32 div, con; 324*41793000SKever Yang 325*41793000SKever Yang switch (clk_id) { 326*41793000SKever Yang case SCLK_I2C0: 327*41793000SKever Yang con = readl(&cru->clksel_con[34]); 328*41793000SKever Yang div = con >> CLK_I2C0_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 329*41793000SKever Yang break; 330*41793000SKever Yang case SCLK_I2C1: 331*41793000SKever Yang con = readl(&cru->clksel_con[34]); 332*41793000SKever Yang div = con >> CLK_I2C1_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 333*41793000SKever Yang break; 334*41793000SKever Yang case SCLK_I2C2: 335*41793000SKever Yang con = readl(&cru->clksel_con[35]); 336*41793000SKever Yang div = con >> CLK_I2C2_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 337*41793000SKever Yang break; 338*41793000SKever Yang case SCLK_I2C3: 339*41793000SKever Yang con = readl(&cru->clksel_con[35]); 340*41793000SKever Yang div = con >> CLK_I2C3_DIV_CON_SHIFT & CLK_I2C_DIV_CON_MASK; 341*41793000SKever Yang break; 342*41793000SKever Yang default: 343*41793000SKever Yang printf("do not support this i2c bus\n"); 344*41793000SKever Yang return -EINVAL; 345*41793000SKever Yang } 346*41793000SKever Yang 347*41793000SKever Yang return DIV_TO_RATE(GPLL_HZ, div); 348*41793000SKever Yang } 349*41793000SKever Yang 350*41793000SKever Yang static ulong rk3328_i2c_set_clk(struct rk3328_cru *cru, ulong clk_id, uint hz) 351*41793000SKever Yang { 352*41793000SKever Yang int src_clk_div; 353*41793000SKever Yang 354*41793000SKever Yang src_clk_div = GPLL_HZ / hz; 355*41793000SKever Yang assert(src_clk_div - 1 < 127); 356*41793000SKever Yang 357*41793000SKever Yang switch (clk_id) { 358*41793000SKever Yang case SCLK_I2C0: 359*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[34], 360*41793000SKever Yang CLK_I2C_DIV_CON_MASK << CLK_I2C0_DIV_CON_SHIFT | 361*41793000SKever Yang CLK_I2C_PLL_SEL_MASK << CLK_I2C0_PLL_SEL_SHIFT, 362*41793000SKever Yang (src_clk_div - 1) << CLK_I2C0_DIV_CON_SHIFT | 363*41793000SKever Yang CLK_I2C_PLL_SEL_GPLL << CLK_I2C0_PLL_SEL_SHIFT); 364*41793000SKever Yang break; 365*41793000SKever Yang case SCLK_I2C1: 366*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[34], 367*41793000SKever Yang CLK_I2C_DIV_CON_MASK << CLK_I2C1_DIV_CON_SHIFT | 368*41793000SKever Yang CLK_I2C_PLL_SEL_MASK << CLK_I2C1_PLL_SEL_SHIFT, 369*41793000SKever Yang (src_clk_div - 1) << CLK_I2C1_DIV_CON_SHIFT | 370*41793000SKever Yang CLK_I2C_PLL_SEL_GPLL << CLK_I2C1_PLL_SEL_SHIFT); 371*41793000SKever Yang break; 372*41793000SKever Yang case SCLK_I2C2: 373*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[35], 374*41793000SKever Yang CLK_I2C_DIV_CON_MASK << CLK_I2C2_DIV_CON_SHIFT | 375*41793000SKever Yang CLK_I2C_PLL_SEL_MASK << CLK_I2C2_PLL_SEL_SHIFT, 376*41793000SKever Yang (src_clk_div - 1) << CLK_I2C2_DIV_CON_SHIFT | 377*41793000SKever Yang CLK_I2C_PLL_SEL_GPLL << CLK_I2C2_PLL_SEL_SHIFT); 378*41793000SKever Yang break; 379*41793000SKever Yang case SCLK_I2C3: 380*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[35], 381*41793000SKever Yang CLK_I2C_DIV_CON_MASK << CLK_I2C3_DIV_CON_SHIFT | 382*41793000SKever Yang CLK_I2C_PLL_SEL_MASK << CLK_I2C3_PLL_SEL_SHIFT, 383*41793000SKever Yang (src_clk_div - 1) << CLK_I2C3_DIV_CON_SHIFT | 384*41793000SKever Yang CLK_I2C_PLL_SEL_GPLL << CLK_I2C3_PLL_SEL_SHIFT); 385*41793000SKever Yang break; 386*41793000SKever Yang default: 387*41793000SKever Yang printf("do not support this i2c bus\n"); 388*41793000SKever Yang return -EINVAL; 389*41793000SKever Yang } 390*41793000SKever Yang 391*41793000SKever Yang return DIV_TO_RATE(GPLL_HZ, src_clk_div); 392*41793000SKever Yang } 393*41793000SKever Yang 394*41793000SKever Yang static ulong rk3328_mmc_get_clk(struct rk3328_cru *cru, uint clk_id) 395*41793000SKever Yang { 396*41793000SKever Yang u32 div, con, con_id; 397*41793000SKever Yang 398*41793000SKever Yang switch (clk_id) { 399*41793000SKever Yang case HCLK_SDMMC: 400*41793000SKever Yang con_id = 30; 401*41793000SKever Yang break; 402*41793000SKever Yang case HCLK_EMMC: 403*41793000SKever Yang con_id = 32; 404*41793000SKever Yang break; 405*41793000SKever Yang default: 406*41793000SKever Yang return -EINVAL; 407*41793000SKever Yang } 408*41793000SKever Yang con = readl(&cru->clksel_con[con_id]); 409*41793000SKever Yang div = (con & CLK_EMMC_DIV_CON_MASK) >> CLK_EMMC_DIV_CON_SHIFT; 410*41793000SKever Yang 411*41793000SKever Yang if ((con & CLK_EMMC_PLL_MASK) >> CLK_EMMC_PLL_SHIFT 412*41793000SKever Yang == CLK_EMMC_PLL_SEL_24M) 413*41793000SKever Yang return DIV_TO_RATE(OSC_HZ, div); 414*41793000SKever Yang else 415*41793000SKever Yang return DIV_TO_RATE(GPLL_HZ, div); 416*41793000SKever Yang } 417*41793000SKever Yang 418*41793000SKever Yang static ulong rk3328_mmc_set_clk(struct rk3328_cru *cru, 419*41793000SKever Yang ulong clk_id, ulong set_rate) 420*41793000SKever Yang { 421*41793000SKever Yang int src_clk_div; 422*41793000SKever Yang u32 con_id; 423*41793000SKever Yang 424*41793000SKever Yang switch (clk_id) { 425*41793000SKever Yang case HCLK_SDMMC: 426*41793000SKever Yang con_id = 30; 427*41793000SKever Yang break; 428*41793000SKever Yang case HCLK_EMMC: 429*41793000SKever Yang con_id = 32; 430*41793000SKever Yang break; 431*41793000SKever Yang default: 432*41793000SKever Yang return -EINVAL; 433*41793000SKever Yang } 434*41793000SKever Yang /* Select clk_sdmmc/emmc source from GPLL by default */ 435*41793000SKever Yang src_clk_div = GPLL_HZ / set_rate; 436*41793000SKever Yang 437*41793000SKever Yang if (src_clk_div > 127) { 438*41793000SKever Yang /* use 24MHz source for 400KHz clock */ 439*41793000SKever Yang src_clk_div = OSC_HZ / set_rate; 440*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[con_id], 441*41793000SKever Yang CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 442*41793000SKever Yang CLK_EMMC_PLL_SEL_24M << CLK_EMMC_PLL_SHIFT | 443*41793000SKever Yang (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 444*41793000SKever Yang } else { 445*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[con_id], 446*41793000SKever Yang CLK_EMMC_PLL_MASK | CLK_EMMC_DIV_CON_MASK, 447*41793000SKever Yang CLK_EMMC_PLL_SEL_GPLL << CLK_EMMC_PLL_SHIFT | 448*41793000SKever Yang (src_clk_div - 1) << CLK_EMMC_DIV_CON_SHIFT); 449*41793000SKever Yang } 450*41793000SKever Yang 451*41793000SKever Yang return rk3328_mmc_get_clk(cru, clk_id); 452*41793000SKever Yang } 453*41793000SKever Yang 454*41793000SKever Yang static ulong rk3328_pwm_get_clk(struct rk3328_cru *cru) 455*41793000SKever Yang { 456*41793000SKever Yang u32 div, con; 457*41793000SKever Yang 458*41793000SKever Yang con = readl(&cru->clksel_con[24]); 459*41793000SKever Yang div = (con & CLK_PWM_DIV_CON_MASK) >> CLK_PWM_DIV_CON_SHIFT; 460*41793000SKever Yang 461*41793000SKever Yang return DIV_TO_RATE(GPLL_HZ, div); 462*41793000SKever Yang } 463*41793000SKever Yang 464*41793000SKever Yang static ulong rk3328_pwm_set_clk(struct rk3328_cru *cru, uint hz) 465*41793000SKever Yang { 466*41793000SKever Yang u32 div = GPLL_HZ / hz; 467*41793000SKever Yang 468*41793000SKever Yang rk_clrsetreg(&cru->clksel_con[24], 469*41793000SKever Yang CLK_PWM_PLL_SEL_MASK | CLK_PWM_DIV_CON_MASK, 470*41793000SKever Yang CLK_PWM_PLL_SEL_GPLL << CLK_PWM_PLL_SEL_SHIFT | 471*41793000SKever Yang (div - 1) << CLK_PWM_DIV_CON_SHIFT); 472*41793000SKever Yang 473*41793000SKever Yang return DIV_TO_RATE(GPLL_HZ, div); 474*41793000SKever Yang } 475*41793000SKever Yang 476*41793000SKever Yang static ulong rk3328_clk_get_rate(struct clk *clk) 477*41793000SKever Yang { 478*41793000SKever Yang struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 479*41793000SKever Yang ulong rate = 0; 480*41793000SKever Yang 481*41793000SKever Yang switch (clk->id) { 482*41793000SKever Yang case 0 ... 29: 483*41793000SKever Yang return 0; 484*41793000SKever Yang case HCLK_SDMMC: 485*41793000SKever Yang case HCLK_EMMC: 486*41793000SKever Yang rate = rk3328_mmc_get_clk(priv->cru, clk->id); 487*41793000SKever Yang break; 488*41793000SKever Yang case SCLK_I2C0: 489*41793000SKever Yang case SCLK_I2C1: 490*41793000SKever Yang case SCLK_I2C2: 491*41793000SKever Yang case SCLK_I2C3: 492*41793000SKever Yang rate = rk3328_i2c_get_clk(priv->cru, clk->id); 493*41793000SKever Yang break; 494*41793000SKever Yang case SCLK_PWM: 495*41793000SKever Yang rate = rk3328_pwm_get_clk(priv->cru); 496*41793000SKever Yang break; 497*41793000SKever Yang default: 498*41793000SKever Yang return -ENOENT; 499*41793000SKever Yang } 500*41793000SKever Yang 501*41793000SKever Yang return rate; 502*41793000SKever Yang } 503*41793000SKever Yang 504*41793000SKever Yang static ulong rk3328_clk_set_rate(struct clk *clk, ulong rate) 505*41793000SKever Yang { 506*41793000SKever Yang struct rk3328_clk_priv *priv = dev_get_priv(clk->dev); 507*41793000SKever Yang ulong ret = 0; 508*41793000SKever Yang 509*41793000SKever Yang switch (clk->id) { 510*41793000SKever Yang case 0 ... 29: 511*41793000SKever Yang return 0; 512*41793000SKever Yang case HCLK_SDMMC: 513*41793000SKever Yang case HCLK_EMMC: 514*41793000SKever Yang ret = rk3328_mmc_set_clk(priv->cru, clk->id, rate); 515*41793000SKever Yang break; 516*41793000SKever Yang case SCLK_I2C0: 517*41793000SKever Yang case SCLK_I2C1: 518*41793000SKever Yang case SCLK_I2C2: 519*41793000SKever Yang case SCLK_I2C3: 520*41793000SKever Yang ret = rk3328_i2c_set_clk(priv->cru, clk->id, rate); 521*41793000SKever Yang break; 522*41793000SKever Yang case SCLK_PWM: 523*41793000SKever Yang ret = rk3328_pwm_set_clk(priv->cru, rate); 524*41793000SKever Yang break; 525*41793000SKever Yang default: 526*41793000SKever Yang return -ENOENT; 527*41793000SKever Yang } 528*41793000SKever Yang 529*41793000SKever Yang return ret; 530*41793000SKever Yang } 531*41793000SKever Yang 532*41793000SKever Yang static struct clk_ops rk3328_clk_ops = { 533*41793000SKever Yang .get_rate = rk3328_clk_get_rate, 534*41793000SKever Yang .set_rate = rk3328_clk_set_rate, 535*41793000SKever Yang }; 536*41793000SKever Yang 537*41793000SKever Yang static int rk3328_clk_probe(struct udevice *dev) 538*41793000SKever Yang { 539*41793000SKever Yang struct rk3328_clk_priv *priv = dev_get_priv(dev); 540*41793000SKever Yang 541*41793000SKever Yang rkclk_init(priv->cru); 542*41793000SKever Yang 543*41793000SKever Yang return 0; 544*41793000SKever Yang } 545*41793000SKever Yang 546*41793000SKever Yang static int rk3328_clk_ofdata_to_platdata(struct udevice *dev) 547*41793000SKever Yang { 548*41793000SKever Yang struct rk3328_clk_priv *priv = dev_get_priv(dev); 549*41793000SKever Yang 550*41793000SKever Yang priv->cru = (struct rk3328_cru *)dev_get_addr(dev); 551*41793000SKever Yang 552*41793000SKever Yang return 0; 553*41793000SKever Yang } 554*41793000SKever Yang 555*41793000SKever Yang static int rk3328_clk_bind(struct udevice *dev) 556*41793000SKever Yang { 557*41793000SKever Yang int ret; 558*41793000SKever Yang 559*41793000SKever Yang /* The reset driver does not have a device node, so bind it here */ 560*41793000SKever Yang ret = device_bind_driver(gd->dm_root, "rk3328_sysreset", "reset", &dev); 561*41793000SKever Yang if (ret) 562*41793000SKever Yang printf("Warning: No RK3328 reset driver: ret=%d\n", ret); 563*41793000SKever Yang 564*41793000SKever Yang return ret; 565*41793000SKever Yang } 566*41793000SKever Yang 567*41793000SKever Yang static const struct udevice_id rk3328_clk_ids[] = { 568*41793000SKever Yang { .compatible = "rockchip,rk3328-cru" }, 569*41793000SKever Yang { } 570*41793000SKever Yang }; 571*41793000SKever Yang 572*41793000SKever Yang U_BOOT_DRIVER(rockchip_rk3328_cru) = { 573*41793000SKever Yang .name = "rockchip_rk3328_cru", 574*41793000SKever Yang .id = UCLASS_CLK, 575*41793000SKever Yang .of_match = rk3328_clk_ids, 576*41793000SKever Yang .priv_auto_alloc_size = sizeof(struct rk3328_clk_priv), 577*41793000SKever Yang .ofdata_to_platdata = rk3328_clk_ofdata_to_platdata, 578*41793000SKever Yang .ops = &rk3328_clk_ops, 579*41793000SKever Yang .bind = rk3328_clk_bind, 580*41793000SKever Yang .probe = rk3328_clk_probe, 581*41793000SKever Yang }; 582