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 - https://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 19struct cm_perpll *const cmper = (struct cm_perpll *)CM_PER; 20struct cm_wkuppll *const cmwkup = (struct cm_wkuppll *)CM_WKUP; 21struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; 22struct cm_rtc *const cmrtc = (struct cm_rtc *)CM_RTC; 23 24const 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 31const 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 40const 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 47const 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 54const 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 61struct dpll_params dpll_mpu_opp100 = { 62 CONFIG_SYS_MPUCLK, OSC-1, 1, -1, -1, -1, -1}; 63const struct dpll_params dpll_core_opp100 = { 64 1000, OSC-1, -1, -1, 10, 8, 4}; 65 66const 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, 2, 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 101const 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 108const 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 115const 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 122const 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 129const 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 141const 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 148const 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 155void 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 191void 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->i2c2clkctrl, 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 */ 244void 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