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