1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * clock_am33xx.c 4 * 5 * clocks for AM33XX based boards 6 * 7 * Copyright (C) 2013, Texas Instruments, Incorporated - http://www.ti.com/ 8 */ 9 10 #include <common.h> 11 #include <asm/arch/cpu.h> 12 #include <asm/arch/sys_proto.h> 13 #include <asm/arch/clock.h> 14 #include <asm/arch/hardware.h> 15 #include <asm/io.h> 16 17 #define OSC (V_OSCK/1000000) 18 19 struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; 20 struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; 21 struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; 22 struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC; 23 24 const struct dpll_regs dpll_mpu_regs = { 25 .cm_clkmode_dpll = CM_WKUP + 0x88, 26 .cm_idlest_dpll = CM_WKUP + 0x20, 27 .cm_clksel_dpll = CM_WKUP + 0x2C, 28 .cm_div_m2_dpll = CM_WKUP + 0xA8, 29 }; 30 31 const struct dpll_regs dpll_core_regs = { 32 .cm_clkmode_dpll = CM_WKUP + 0x90, 33 .cm_idlest_dpll = CM_WKUP + 0x5C, 34 .cm_clksel_dpll = CM_WKUP + 0x68, 35 .cm_div_m4_dpll = CM_WKUP + 0x80, 36 .cm_div_m5_dpll = CM_WKUP + 0x84, 37 .cm_div_m6_dpll = CM_WKUP + 0xD8, 38 }; 39 40 const struct dpll_regs dpll_per_regs = { 41 .cm_clkmode_dpll = CM_WKUP + 0x8C, 42 .cm_idlest_dpll = CM_WKUP + 0x70, 43 .cm_clksel_dpll = CM_WKUP + 0x9C, 44 .cm_div_m2_dpll = CM_WKUP + 0xAC, 45 }; 46 47 const struct dpll_regs dpll_ddr_regs = { 48 .cm_clkmode_dpll = CM_WKUP + 0x94, 49 .cm_idlest_dpll = CM_WKUP + 0x34, 50 .cm_clksel_dpll = CM_WKUP + 0x40, 51 .cm_div_m2_dpll = CM_WKUP + 0xA0, 52 }; 53 54 const struct dpll_regs dpll_disp_regs = { 55 .cm_clkmode_dpll = CM_WKUP + 0x98, 56 .cm_idlest_dpll = CM_WKUP + 0x48, 57 .cm_clksel_dpll = CM_WKUP + 0x54, 58 .cm_div_m2_dpll = CM_WKUP + 0xA4, 59 }; 60 61 struct dpll_params dpll_mpu_opp100 = { 62 CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1}; 63 const struct dpll_params dpll_core_opp100 = { 64 1000, OSC-1, -1, -1, 10, 8, 4}; 65 66 const struct dpll_params dpll_mpu_opp[NUM_CRYSTAL_FREQ][NUM_OPPS] = { 67 { /* 19.2 MHz */ 68 {125, 3, 2, -1, -1, -1, -1}, /* OPP 50 */ 69 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */ 70 {125, 3, 1, -1, -1, -1, -1}, /* OPP 100 */ 71 {150, 3, 1, -1, -1, -1, -1}, /* OPP 120 */ 72 {125, 2, 1, -1, -1, -1, -1}, /* OPP TB */ 73 {625, 11, 1, -1, -1, -1, -1} /* OPP NT */ 74 }, 75 { /* 24 MHz */ 76 {25, 0, 2, -1, -1, -1, -1}, /* OPP 50 */ 77 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */ 78 {25, 0, 1, -1, -1, -1, -1}, /* OPP 100 */ 79 {30, 0, 1, -1, -1, -1, -1}, /* OPP 120 */ 80 {100, 3, 1, -1, -1, -1, -1}, /* OPP TB */ 81 {125, 2, 1, -1, -1, -1, -1} /* OPP NT */ 82 }, 83 { /* 25 MHz */ 84 {24, 0, 2, -1, -1, -1, -1}, /* OPP 50 */ 85 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */ 86 {24, 0, 1, -1, -1, -1, -1}, /* OPP 100 */ 87 {144, 4, 1, -1, -1, -1, -1}, /* OPP 120 */ 88 {32, 0, 1, -1, -1, -1, -1}, /* OPP TB */ 89 {40, 0, 1, -1, -1, -1, -1} /* OPP NT */ 90 }, 91 { /* 26 MHz */ 92 {300, 12, 2, -1, -1, -1, -1}, /* OPP 50 */ 93 {-1, -1, -1, -1, -1, -1, -1}, /* OPP RESERVED */ 94 {300, 12, 1, -1, -1, -1, -1}, /* OPP 100 */ 95 {360, 12, 1, -1, -1, -1, -1}, /* OPP 120 */ 96 {400, 12, 1, -1, -1, -1, -1}, /* OPP TB */ 97 {500, 12, 1, -1, -1, -1, -1} /* OPP NT */ 98 }, 99 }; 100 101 const struct dpll_params dpll_core_1000MHz[NUM_CRYSTAL_FREQ] = { 102 {625, 11, -1, -1, 10, 8, 4}, /* 19.2 MHz */ 103 {125, 2, -1, -1, 10, 8, 4}, /* 24 MHz */ 104 {40, 0, -1, -1, 10, 8, 4}, /* 25 MHz */ 105 {500, 12, -1, -1, 10, 8, 4} /* 26 MHz */ 106 }; 107 108 const struct dpll_params dpll_per_192MHz[NUM_CRYSTAL_FREQ] = { 109 {400, 7, 5, -1, -1, -1, -1}, /* 19.2 MHz */ 110 {400, 9, 5, -1, -1, -1, -1}, /* 24 MHz */ 111 {384, 9, 5, -1, -1, -1, -1}, /* 25 MHz */ 112 {480, 12, 5, -1, -1, -1, -1} /* 26 MHz */ 113 }; 114 115 const struct dpll_params dpll_ddr3_303MHz[NUM_CRYSTAL_FREQ] = { 116 {505, 15, 2, -1, -1, -1, -1}, /*19.2*/ 117 {101, 3, 2, -1, -1, -1, -1}, /* 24 MHz */ 118 {303, 24, 1, -1, -1, -1, -1}, /* 25 MHz */ 119 {303, 12, 2, -1, -1, -1, -1} /* 26 MHz */ 120 }; 121 122 const struct dpll_params dpll_ddr3_400MHz[NUM_CRYSTAL_FREQ] = { 123 {125, 5, 1, -1, -1, -1, -1}, /*19.2*/ 124 {50, 2, 1, -1, -1, -1, -1}, /* 24 MHz */ 125 {16, 0, 1, -1, -1, -1, -1}, /* 25 MHz */ 126 {200, 12, 1, -1, -1, -1, -1} /* 26 MHz */ 127 }; 128 129 const struct dpll_params dpll_ddr2_266MHz[NUM_CRYSTAL_FREQ] = { 130 {665, 47, 1, -1, -1, -1, -1}, /*19.2*/ 131 {133, 11, 1, -1, -1, -1, -1}, /* 24 MHz */ 132 {266, 24, 1, -1, -1, -1, -1}, /* 25 MHz */ 133 {133, 12, 1, -1, -1, -1, -1} /* 26 MHz */ 134 }; 135 136 __weak const struct dpll_params *get_dpll_mpu_params(void) 137 { 138 return &dpll_mpu_opp100; 139 } 140 141 const struct dpll_params *get_dpll_core_params(void) 142 { 143 int ind = get_sys_clk_index(); 144 145 return &dpll_core_1000MHz[ind]; 146 } 147 148 const struct dpll_params *get_dpll_per_params(void) 149 { 150 int ind = get_sys_clk_index(); 151 152 return &dpll_per_192MHz[ind]; 153 } 154 155 void setup_clocks_for_console(void) 156 { 157 clrsetbits_le32(&cmwkup->wkclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, 158 CD_CLKCTRL_CLKTRCTRL_SW_WKUP << 159 CD_CLKCTRL_CLKTRCTRL_SHIFT); 160 161 clrsetbits_le32(&cmper->l4hsclkstctrl, CD_CLKCTRL_CLKTRCTRL_MASK, 162 CD_CLKCTRL_CLKTRCTRL_SW_WKUP << 163 CD_CLKCTRL_CLKTRCTRL_SHIFT); 164 165 clrsetbits_le32(&cmwkup->wkup_uart0ctrl, 166 MODULE_CLKCTRL_MODULEMODE_MASK, 167 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 168 MODULE_CLKCTRL_MODULEMODE_SHIFT); 169 clrsetbits_le32(&cmper->uart1clkctrl, 170 MODULE_CLKCTRL_MODULEMODE_MASK, 171 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 172 MODULE_CLKCTRL_MODULEMODE_SHIFT); 173 clrsetbits_le32(&cmper->uart2clkctrl, 174 MODULE_CLKCTRL_MODULEMODE_MASK, 175 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 176 MODULE_CLKCTRL_MODULEMODE_SHIFT); 177 clrsetbits_le32(&cmper->uart3clkctrl, 178 MODULE_CLKCTRL_MODULEMODE_MASK, 179 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 180 MODULE_CLKCTRL_MODULEMODE_SHIFT); 181 clrsetbits_le32(&cmper->uart4clkctrl, 182 MODULE_CLKCTRL_MODULEMODE_MASK, 183 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 184 MODULE_CLKCTRL_MODULEMODE_SHIFT); 185 clrsetbits_le32(&cmper->uart5clkctrl, 186 MODULE_CLKCTRL_MODULEMODE_MASK, 187 MODULE_CLKCTRL_MODULEMODE_SW_EXPLICIT_EN << 188 MODULE_CLKCTRL_MODULEMODE_SHIFT); 189 } 190 191 void enable_basic_clocks(void) 192 { 193 u32 *const clk_domains[] = { 194 &cmper->l3clkstctrl, 195 &cmper->l4fwclkstctrl, 196 &cmper->l3sclkstctrl, 197 &cmper->l4lsclkstctrl, 198 &cmwkup->wkclkstctrl, 199 &cmper->emiffwclkctrl, 200 &cmrtc->clkstctrl, 201 0 202 }; 203 204 u32 *const clk_modules_explicit_en[] = { 205 &cmper->l3clkctrl, 206 &cmper->l4lsclkctrl, 207 &cmper->l4fwclkctrl, 208 &cmwkup->wkl4wkclkctrl, 209 &cmper->l3instrclkctrl, 210 &cmper->l4hsclkctrl, 211 &cmwkup->wkgpio0clkctrl, 212 &cmwkup->wkctrlclkctrl, 213 &cmper->timer2clkctrl, 214 &cmper->gpmcclkctrl, 215 &cmper->elmclkctrl, 216 &cmper->mmc0clkctrl, 217 &cmper->mmc1clkctrl, 218 &cmwkup->wkup_i2c0ctrl, 219 &cmper->gpio1clkctrl, 220 &cmper->gpio2clkctrl, 221 &cmper->gpio3clkctrl, 222 &cmper->i2c1clkctrl, 223 &cmper->cpgmac0clkctrl, 224 &cmper->spi0clkctrl, 225 &cmrtc->rtcclkctrl, 226 &cmper->usb0clkctrl, 227 &cmper->emiffwclkctrl, 228 &cmper->emifclkctrl, 229 0 230 }; 231 232 do_enable_clocks(clk_domains, clk_modules_explicit_en, 1); 233 234 /* Select the Master osc 24 MHZ as Timer2 clock source */ 235 writel(0x1, &cmdpll->clktimer2clk); 236 } 237 238 /* 239 * Enable Spread Spectrum for the MPU by calculating the required 240 * values and setting the registers accordingly. 241 * @param permille The spreading in permille (10th of a percent) 242 */ 243 void set_mpu_spreadspectrum(int permille) 244 { 245 u32 multiplier_m; 246 u32 predivider_n; 247 u32 cm_clksel_dpll_mpu; 248 u32 cm_clkmode_dpll_mpu; 249 u32 ref_clock; 250 u32 pll_bandwidth; 251 u32 mod_freq_divider; 252 u32 exponent; 253 u32 mantissa; 254 u32 delta_m_step; 255 256 printf("Enabling Spread Spectrum of %d permille for MPU\n", 257 permille); 258 259 /* Read PLL parameter m and n */ 260 cm_clksel_dpll_mpu = readl(&cmwkup->clkseldpllmpu); 261 multiplier_m = (cm_clksel_dpll_mpu >> 8) & 0x3FF; 262 predivider_n = cm_clksel_dpll_mpu & 0x7F; 263 264 /* 265 * Calculate reference clock (clock after pre-divider), 266 * its max. PLL bandwidth, 267 * and resulting mod_freq_divider 268 */ 269 ref_clock = V_OSCK / (predivider_n + 1); 270 pll_bandwidth = ref_clock / 70; 271 mod_freq_divider = ref_clock / (4 * pll_bandwidth); 272 273 /* Calculate Mantissa/Exponent */ 274 exponent = 0; 275 mantissa = mod_freq_divider; 276 while ((mantissa > 127) && (exponent < 7)) { 277 exponent++; 278 mantissa /= 2; 279 } 280 if (mantissa > 127) 281 mantissa = 127; 282 283 mod_freq_divider = mantissa << exponent; 284 285 /* 286 * Calculate Modulation steps 287 * As we use Downspread only, the spread is twice the value of 288 * permille, so Div2! 289 * As it takes the value in percent, divide by ten! 290 */ 291 delta_m_step = ((u32)((multiplier_m * permille) / 10 / 2)) << 18; 292 delta_m_step /= 100; 293 delta_m_step /= mod_freq_divider; 294 if (delta_m_step > 0xFFFFF) 295 delta_m_step = 0xFFFFF; 296 297 /* Setup Spread Spectrum */ 298 writel(delta_m_step, &cmwkup->sscdeltamstepdllmpu); 299 writel((exponent << 8) | mantissa, &cmwkup->sscmodfreqdivdpllmpu); 300 cm_clkmode_dpll_mpu = readl(&cmwkup->clkmoddpllmpu); 301 /* clear all SSC flags */ 302 cm_clkmode_dpll_mpu &= ~(0xF << CM_CLKMODE_DPLL_SSC_EN_SHIFT); 303 /* enable SSC with Downspread only */ 304 cm_clkmode_dpll_mpu |= CM_CLKMODE_DPLL_SSC_EN_MASK | 305 CM_CLKMODE_DPLL_SSC_DOWNSPREAD_MASK; 306 writel(cm_clkmode_dpll_mpu, &cmwkup->clkmoddpllmpu); 307 while (!(readl(&cmwkup->clkmoddpllmpu) & 0x2000)) 308 ; 309 } 310