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