1 /* 2 * clock_ti816x.c 3 * 4 * Clocks for TI816X based boards 5 * 6 * Copyright (C) 2013, Adeneo Embedded <www.adeneo-embedded.com> 7 * Antoine Tenart, <atenart@adeneo-embedded.com> 8 * 9 * Based on TI-PSP-04.00.02.14 : 10 * 11 * Copyright (C) 2009, Texas Instruments, Incorporated 12 * 13 * This program is free software; you can redistribute it and/or 14 * modify it under the terms of the GNU General Public License as 15 * published by the Free Software Foundation; either version 2 of 16 * the License, or (at your option) any later version. 17 * 18 * This program is distributed in the hope that it will be useful, 19 * but WITHOUT ANY WARRANTY; without even the implied warranty of 20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR /PURPOSE. See the 21 * GNU General Public License for more details. 22 */ 23 24 #include <common.h> 25 #include <asm/arch/ddr_defs.h> 26 #include <asm/arch/cpu.h> 27 #include <asm/arch/clock.h> 28 #include <asm/arch/hardware.h> 29 #include <asm/io.h> 30 31 #include <asm/emif.h> 32 33 #define CM_PLL_BASE (CTRL_BASE + 0x0400) 34 35 /* Main PLL */ 36 #define MAIN_N 64 37 #define MAIN_P 0x1 38 #define MAIN_INTFREQ1 0x8 39 #define MAIN_FRACFREQ1 0x800000 40 #define MAIN_MDIV1 0x2 41 #define MAIN_INTFREQ2 0xE 42 #define MAIN_FRACFREQ2 0x0 43 #define MAIN_MDIV2 0x1 44 #define MAIN_INTFREQ3 0x8 45 #define MAIN_FRACFREQ3 0xAAAAB0 46 #define MAIN_MDIV3 0x3 47 #define MAIN_INTFREQ4 0x9 48 #define MAIN_FRACFREQ4 0x55554F 49 #define MAIN_MDIV4 0x3 50 #define MAIN_INTFREQ5 0x9 51 #define MAIN_FRACFREQ5 0x374BC6 52 #define MAIN_MDIV5 0xC 53 #define MAIN_MDIV6 0x48 54 #define MAIN_MDIV7 0x4 55 56 /* DDR PLL */ 57 #define DDR_N 59 58 #define DDR_P 0x1 59 #define DDR_MDIV1 0x2 60 #define DDR_INTFREQ2 0x8 61 #define DDR_FRACFREQ2 0xD99999 62 #define DDR_MDIV2 0x1E 63 #define DDR_INTFREQ3 0x8 64 #define DDR_FRACFREQ3 0x0 65 #define DDR_MDIV3 0x4 66 #define DDR_INTFREQ4 0xE /* Expansion DDR clk */ 67 #define DDR_FRACFREQ4 0x0 68 #define DDR_MDIV4 0x4 69 #define DDR_INTFREQ5 0xE /* Expansion DDR clk */ 70 #define DDR_FRACFREQ5 0x0 71 #define DDR_MDIV5 0x4 72 73 #define CONTROL_STATUS (CTRL_BASE + 0x40) 74 #define DDR_RCD (CTRL_BASE + 0x070C) 75 #define CM_TIMER1_CLKSEL (PRCM_BASE + 0x390) 76 #define CM_ALWON_CUST_EFUSE_CLKCTRL (PRCM_BASE + 0x1628) 77 78 #define INTCPS_SYSCONFIG 0x48200010 79 #define CM_SYSCLK10_CLKSEL 0x48180324 80 81 struct cm_pll { 82 unsigned int mainpll_ctrl; /* offset 0x400 */ 83 unsigned int mainpll_pwd; 84 unsigned int mainpll_freq1; 85 unsigned int mainpll_div1; 86 unsigned int mainpll_freq2; 87 unsigned int mainpll_div2; 88 unsigned int mainpll_freq3; 89 unsigned int mainpll_div3; 90 unsigned int mainpll_freq4; 91 unsigned int mainpll_div4; 92 unsigned int mainpll_freq5; 93 unsigned int mainpll_div5; 94 unsigned int resv0[1]; 95 unsigned int mainpll_div6; 96 unsigned int resv1[1]; 97 unsigned int mainpll_div7; 98 unsigned int ddrpll_ctrl; /* offset 0x440 */ 99 unsigned int ddrpll_pwd; 100 unsigned int resv2[1]; 101 unsigned int ddrpll_div1; 102 unsigned int ddrpll_freq2; 103 unsigned int ddrpll_div2; 104 unsigned int ddrpll_freq3; 105 unsigned int ddrpll_div3; 106 unsigned int ddrpll_freq4; 107 unsigned int ddrpll_div4; 108 unsigned int ddrpll_freq5; 109 unsigned int ddrpll_div5; 110 unsigned int videopll_ctrl; /* offset 0x470 */ 111 unsigned int videopll_pwd; 112 unsigned int videopll_freq1; 113 unsigned int videopll_div1; 114 unsigned int videopll_freq2; 115 unsigned int videopll_div2; 116 unsigned int videopll_freq3; 117 unsigned int videopll_div3; 118 unsigned int resv3[4]; 119 unsigned int audiopll_ctrl; /* offset 0x4A0 */ 120 unsigned int audiopll_pwd; 121 unsigned int resv4[2]; 122 unsigned int audiopll_freq2; 123 unsigned int audiopll_div2; 124 unsigned int audiopll_freq3; 125 unsigned int audiopll_div3; 126 unsigned int audiopll_freq4; 127 unsigned int audiopll_div4; 128 unsigned int audiopll_freq5; 129 unsigned int audiopll_div5; 130 }; 131 132 const struct cm_alwon *cmalwon = (struct cm_alwon *)CM_ALWON_BASE; 133 const struct cm_def *cmdef = (struct cm_def *)CM_DEFAULT_BASE; 134 const struct cm_pll *cmpll = (struct cm_pll *)CM_PLL_BASE; 135 const struct wd_timer *wdtimer = (struct wd_timer *)WDT_BASE; 136 137 void enable_dmm_clocks(void) 138 { 139 writel(PRCM_MOD_EN, &cmdef->dmmclkctrl); 140 /* Wait for dmm to be fully functional, including OCP */ 141 while (((readl(&cmdef->dmmclkctrl) >> 17) & 0x3) != 0) 142 ; 143 } 144 145 void enable_emif_clocks(void) 146 { 147 writel(PRCM_MOD_EN, &cmdef->fwclkctrl); 148 writel(PRCM_MOD_EN, &cmdef->l3fastclkstctrl); 149 writel(PRCM_MOD_EN, &cmdef->emif0clkctrl); 150 writel(PRCM_MOD_EN, &cmdef->emif1clkctrl); 151 152 /* Wait for clocks to be active */ 153 while ((readl(&cmdef->l3fastclkstctrl) & 0x300) != 0x300) 154 ; 155 /* Wait for emif0 to be fully functional, including OCP */ 156 while (((readl(&cmdef->emif0clkctrl) >> 17) & 0x3) != 0) 157 ; 158 /* Wait for emif1 to be fully functional, including OCP */ 159 while (((readl(&cmdef->emif1clkctrl) >> 17) & 0x3) != 0) 160 ; 161 } 162 163 /* assume delay is aprox at least 1us */ 164 static void ddr_delay(int d) 165 { 166 int i; 167 168 /* 169 * read a control register. 170 * this is a bit more delay and cannot be optimized by the compiler 171 * assuming one read takes 200 cycles and A8 is runing 1 GHz 172 * somewhat conservative setting 173 */ 174 for (i = 0; i < 50*d; i++) 175 readl(CONTROL_STATUS); 176 } 177 178 static void main_pll_init_ti816x(void) 179 { 180 u32 main_pll_ctrl = 0; 181 182 /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ 183 main_pll_ctrl = readl(&cmpll->mainpll_ctrl); 184 main_pll_ctrl &= 0xFFFFFFFB; 185 main_pll_ctrl |= BIT(2); 186 writel(main_pll_ctrl, &cmpll->mainpll_ctrl); 187 188 /* Enable PLL by setting BIT3 in its ctrl reg */ 189 main_pll_ctrl = readl(&cmpll->mainpll_ctrl); 190 main_pll_ctrl &= 0xFFFFFFF7; 191 main_pll_ctrl |= BIT(3); 192 writel(main_pll_ctrl, &cmpll->mainpll_ctrl); 193 194 /* Write the values of N,P in the CTRL reg */ 195 main_pll_ctrl = readl(&cmpll->mainpll_ctrl); 196 main_pll_ctrl &= 0xFF; 197 main_pll_ctrl |= (MAIN_N<<16 | MAIN_P<<8); 198 writel(main_pll_ctrl, &cmpll->mainpll_ctrl); 199 200 /* Power up clock1-7 */ 201 writel(0x0, &cmpll->mainpll_pwd); 202 203 /* Program the freq and divider values for clock1-7 */ 204 writel((1<<31 | 1<<28 | (MAIN_INTFREQ1<<24) | MAIN_FRACFREQ1), 205 &cmpll->mainpll_freq1); 206 writel(((1<<8) | MAIN_MDIV1), &cmpll->mainpll_div1); 207 208 writel((1<<31 | 1<<28 | (MAIN_INTFREQ2<<24) | MAIN_FRACFREQ2), 209 &cmpll->mainpll_freq2); 210 writel(((1<<8) | MAIN_MDIV2), &cmpll->mainpll_div2); 211 212 writel((1<<31 | 1<<28 | (MAIN_INTFREQ3<<24) | MAIN_FRACFREQ3), 213 &cmpll->mainpll_freq3); 214 writel(((1<<8) | MAIN_MDIV3), &cmpll->mainpll_div3); 215 216 writel((1<<31 | 1<<28 | (MAIN_INTFREQ4<<24) | MAIN_FRACFREQ4), 217 &cmpll->mainpll_freq4); 218 writel(((1<<8) | MAIN_MDIV4), &cmpll->mainpll_div4); 219 220 writel((1<<31 | 1<<28 | (MAIN_INTFREQ5<<24) | MAIN_FRACFREQ5), 221 &cmpll->mainpll_freq5); 222 writel(((1<<8) | MAIN_MDIV5), &cmpll->mainpll_div5); 223 224 writel((1<<8 | MAIN_MDIV6), &cmpll->mainpll_div6); 225 226 writel((1<<8 | MAIN_MDIV7), &cmpll->mainpll_div7); 227 228 /* Wait for PLL to lock */ 229 while ((readl(&cmpll->mainpll_ctrl) & BIT(7)) != BIT(7)) 230 ; 231 232 /* Put the PLL in normal mode, disable bypass */ 233 main_pll_ctrl = readl(&cmpll->mainpll_ctrl); 234 main_pll_ctrl &= 0xFFFFFFFB; 235 writel(main_pll_ctrl, &cmpll->mainpll_ctrl); 236 } 237 238 static void ddr_pll_bypass_ti816x(void) 239 { 240 u32 ddr_pll_ctrl = 0; 241 242 /* Put the PLL in bypass mode by setting BIT2 in its ctrl reg */ 243 ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); 244 ddr_pll_ctrl &= 0xFFFFFFFB; 245 ddr_pll_ctrl |= BIT(2); 246 writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); 247 } 248 249 static void ddr_pll_init_ti816x(void) 250 { 251 u32 ddr_pll_ctrl = 0; 252 /* Enable PLL by setting BIT3 in its ctrl reg */ 253 ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); 254 ddr_pll_ctrl &= 0xFFFFFFF7; 255 ddr_pll_ctrl |= BIT(3); 256 writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); 257 258 /* Write the values of N,P in the CTRL reg */ 259 ddr_pll_ctrl = readl(&cmpll->ddrpll_ctrl); 260 ddr_pll_ctrl &= 0xFF; 261 ddr_pll_ctrl |= (DDR_N<<16 | DDR_P<<8); 262 writel(ddr_pll_ctrl, &cmpll->ddrpll_ctrl); 263 264 ddr_delay(10); 265 266 /* Power up clock1-5 */ 267 writel(0x0, &cmpll->ddrpll_pwd); 268 269 /* Program the freq and divider values for clock1-3 */ 270 writel(((0<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); 271 ddr_delay(1); 272 writel(((1<<8) | DDR_MDIV1), &cmpll->ddrpll_div1); 273 writel((1<<31 | 1<<28 | (DDR_INTFREQ2<<24) | DDR_FRACFREQ2), 274 &cmpll->ddrpll_freq2); 275 writel(((1<<8) | DDR_MDIV2), &cmpll->ddrpll_div2); 276 writel(((0<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); 277 ddr_delay(1); 278 writel(((1<<8) | DDR_MDIV3), &cmpll->ddrpll_div3); 279 ddr_delay(1); 280 writel((0<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), 281 &cmpll->ddrpll_freq3); 282 ddr_delay(1); 283 writel((1<<31 | 1<<28 | (DDR_INTFREQ3<<24) | DDR_FRACFREQ3), 284 &cmpll->ddrpll_freq3); 285 286 ddr_delay(5); 287 288 /* Wait for PLL to lock */ 289 while ((readl(&cmpll->ddrpll_ctrl) & BIT(7)) != BIT(7)) 290 ; 291 292 /* Power up RCD */ 293 writel(BIT(0), DDR_RCD); 294 } 295 296 static void peripheral_enable(void) 297 { 298 /* Wake-up the l3_slow clock */ 299 writel(PRCM_MOD_EN, &cmalwon->l3slowclkstctrl); 300 301 /* 302 * Note on Timers: 303 * There are 8 timers(0-7) out of which timer 0 is a secure timer. 304 * Timer 0 mux should not be changed 305 * 306 * To access the timer registers we need the to be 307 * enabled which is what we do in the first step 308 */ 309 310 /* Enable timer1 */ 311 writel(PRCM_MOD_EN, &cmalwon->timer1clkctrl); 312 /* Select timer1 clock to be CLKIN (27MHz) */ 313 writel(BIT(1), CM_TIMER1_CLKSEL); 314 315 /* Wait for timer1 to be ON-ACTIVE */ 316 while (((readl(&cmalwon->l3slowclkstctrl) 317 & (0x80000<<1))>>20) != 1) 318 ; 319 /* Wait for timer1 to be enabled */ 320 while (((readl(&cmalwon->timer1clkctrl) & 0x30000)>>16) != 0) 321 ; 322 /* Active posted mode */ 323 writel(PRCM_MOD_EN, (DM_TIMER1_BASE + 0x54)); 324 while (readl(DM_TIMER1_BASE + 0x10) & BIT(0)) 325 ; 326 /* Start timer1 */ 327 writel(BIT(0), (DM_TIMER1_BASE + 0x38)); 328 329 /* eFuse */ 330 writel(PRCM_MOD_EN, CM_ALWON_CUST_EFUSE_CLKCTRL); 331 while (readl(CM_ALWON_CUST_EFUSE_CLKCTRL) != PRCM_MOD_EN) 332 ; 333 334 /* Enable gpio0 */ 335 writel(PRCM_MOD_EN, &cmalwon->gpio0clkctrl); 336 while (readl(&cmalwon->gpio0clkctrl) != PRCM_MOD_EN) 337 ; 338 writel((BIT(1) | BIT(8)), &cmalwon->gpio0clkctrl); 339 340 /* Enable gpio1 */ 341 writel(PRCM_MOD_EN, &cmalwon->gpio1clkctrl); 342 while (readl(&cmalwon->gpio1clkctrl) != PRCM_MOD_EN) 343 ; 344 writel((BIT(1) | BIT(8)), &cmalwon->gpio1clkctrl); 345 346 /* Enable spi */ 347 writel(PRCM_MOD_EN, &cmalwon->spiclkctrl); 348 while (readl(&cmalwon->spiclkctrl) != PRCM_MOD_EN) 349 ; 350 351 /* Enable i2c0 */ 352 writel(PRCM_MOD_EN, &cmalwon->i2c0clkctrl); 353 while (readl(&cmalwon->i2c0clkctrl) != PRCM_MOD_EN) 354 ; 355 356 /* Enable ethernet0 */ 357 writel(PRCM_MOD_EN, &cmalwon->ethclkstctrl); 358 writel(PRCM_MOD_EN, &cmalwon->ethernet0clkctrl); 359 writel(PRCM_MOD_EN, &cmalwon->ethernet1clkctrl); 360 361 /* Enable hsmmc */ 362 writel(PRCM_MOD_EN, &cmalwon->sdioclkctrl); 363 while (readl(&cmalwon->sdioclkctrl) != PRCM_MOD_EN) 364 ; 365 } 366 367 void setup_clocks_for_console(void) 368 { 369 /* Fix ROM code bug - from TI-PSP-04.00.02.14 */ 370 writel(0x0, CM_SYSCLK10_CLKSEL); 371 372 ddr_pll_bypass_ti816x(); 373 374 /* Enable uart0-2 */ 375 writel(PRCM_MOD_EN, &cmalwon->uart0clkctrl); 376 while (readl(&cmalwon->uart0clkctrl) != PRCM_MOD_EN) 377 ; 378 writel(PRCM_MOD_EN, &cmalwon->uart1clkctrl); 379 while (readl(&cmalwon->uart1clkctrl) != PRCM_MOD_EN) 380 ; 381 writel(PRCM_MOD_EN, &cmalwon->uart2clkctrl); 382 while (readl(&cmalwon->uart2clkctrl) != PRCM_MOD_EN) 383 ; 384 while ((readl(&cmalwon->l3slowclkstctrl) & 0x2100) != 0x2100) 385 ; 386 } 387 388 void setup_early_clocks(void) 389 { 390 setup_clocks_for_console(); 391 } 392 393 void prcm_init(void) 394 { 395 /* Enable the control */ 396 writel(PRCM_MOD_EN, &cmalwon->controlclkctrl); 397 398 main_pll_init_ti816x(); 399 ddr_pll_init_ti816x(); 400 401 /* 402 * With clk freqs setup to desired values, 403 * enable the required peripherals 404 */ 405 peripheral_enable(); 406 } 407