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