uboot/arch/arm/mach-imx/mx6/clock.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2010-2011 Freescale Semiconductor, Inc.
   3 *
   4 * SPDX-License-Identifier:     GPL-2.0+
   5 */
   6
   7#include <common.h>
   8#include <div64.h>
   9#include <asm/io.h>
  10#include <linux/errno.h>
  11#include <asm/arch/imx-regs.h>
  12#include <asm/arch/crm_regs.h>
  13#include <asm/arch/clock.h>
  14#include <asm/arch/sys_proto.h>
  15
  16enum pll_clocks {
  17        PLL_SYS,        /* System PLL */
  18        PLL_BUS,        /* System Bus PLL*/
  19        PLL_USBOTG,     /* OTG USB PLL */
  20        PLL_ENET,       /* ENET PLL */
  21        PLL_AUDIO,      /* AUDIO PLL */
  22        PLL_VIDEO,      /* VIDEO PLL */
  23};
  24
  25struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  26
  27#ifdef CONFIG_MXC_OCOTP
  28void enable_ocotp_clk(unsigned char enable)
  29{
  30        u32 reg;
  31
  32        reg = __raw_readl(&imx_ccm->CCGR2);
  33        if (enable)
  34                reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  35        else
  36                reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  37        __raw_writel(reg, &imx_ccm->CCGR2);
  38}
  39#endif
  40
  41#ifdef CONFIG_NAND_MXS
  42void setup_gpmi_io_clk(u32 cfg)
  43{
  44        /* Disable clocks per ERR007177 from MX6 errata */
  45        clrbits_le32(&imx_ccm->CCGR4,
  46                     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
  47                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
  48                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
  49                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
  50                     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
  51
  52#if defined(CONFIG_MX6SX)
  53        clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK);
  54
  55        clrsetbits_le32(&imx_ccm->cs2cdr,
  56                        MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK |
  57                        MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK |
  58                        MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK,
  59                        cfg);
  60
  61        setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK);
  62#else
  63        clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  64
  65        clrsetbits_le32(&imx_ccm->cs2cdr,
  66                        MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK |
  67                        MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK |
  68                        MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK,
  69                        cfg);
  70
  71        setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK);
  72#endif
  73        setbits_le32(&imx_ccm->CCGR4,
  74                     MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK |
  75                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK |
  76                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK |
  77                     MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK |
  78                     MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK);
  79}
  80#endif
  81
  82void enable_usboh3_clk(unsigned char enable)
  83{
  84        u32 reg;
  85
  86        reg = __raw_readl(&imx_ccm->CCGR6);
  87        if (enable)
  88                reg |= MXC_CCM_CCGR6_USBOH3_MASK;
  89        else
  90                reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
  91        __raw_writel(reg, &imx_ccm->CCGR6);
  92
  93}
  94
  95#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX)
  96void enable_enet_clk(unsigned char enable)
  97{
  98        u32 mask, *addr;
  99
 100        if (is_mx6ull()) {
 101                mask = MXC_CCM_CCGR0_ENET_CLK_ENABLE_MASK;
 102                addr = &imx_ccm->CCGR0;
 103        } else if (is_mx6ul()) {
 104                mask = MXC_CCM_CCGR3_ENET_MASK;
 105                addr = &imx_ccm->CCGR3;
 106        } else {
 107                mask = MXC_CCM_CCGR1_ENET_MASK;
 108                addr = &imx_ccm->CCGR1;
 109        }
 110
 111        if (enable)
 112                setbits_le32(addr, mask);
 113        else
 114                clrbits_le32(addr, mask);
 115}
 116#endif
 117
 118#ifdef CONFIG_MXC_UART
 119void enable_uart_clk(unsigned char enable)
 120{
 121        u32 mask;
 122
 123        if (is_mx6ul() || is_mx6ull())
 124                mask = MXC_CCM_CCGR5_UART_MASK;
 125        else
 126                mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK;
 127
 128        if (enable)
 129                setbits_le32(&imx_ccm->CCGR5, mask);
 130        else
 131                clrbits_le32(&imx_ccm->CCGR5, mask);
 132}
 133#endif
 134
 135#ifdef CONFIG_MMC
 136int enable_usdhc_clk(unsigned char enable, unsigned bus_num)
 137{
 138        u32 mask;
 139
 140        if (bus_num > 3)
 141                return -EINVAL;
 142
 143        mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2);
 144        if (enable)
 145                setbits_le32(&imx_ccm->CCGR6, mask);
 146        else
 147                clrbits_le32(&imx_ccm->CCGR6, mask);
 148
 149        return 0;
 150}
 151#endif
 152
 153#ifdef CONFIG_SYS_I2C_MXC
 154/* i2c_num can be from 0 - 3 */
 155int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
 156{
 157        u32 reg;
 158        u32 mask;
 159        u32 *addr;
 160
 161        if (i2c_num > 3)
 162                return -EINVAL;
 163        if (i2c_num < 3) {
 164                mask = MXC_CCM_CCGR_CG_MASK
 165                        << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET
 166                        + (i2c_num << 1));
 167                reg = __raw_readl(&imx_ccm->CCGR2);
 168                if (enable)
 169                        reg |= mask;
 170                else
 171                        reg &= ~mask;
 172                __raw_writel(reg, &imx_ccm->CCGR2);
 173        } else {
 174                if (is_mx6sll())
 175                        return -EINVAL;
 176                if (is_mx6sx() || is_mx6ul() || is_mx6ull()) {
 177                        mask = MXC_CCM_CCGR6_I2C4_MASK;
 178                        addr = &imx_ccm->CCGR6;
 179                } else {
 180                        mask = MXC_CCM_CCGR1_I2C4_SERIAL_MASK;
 181                        addr = &imx_ccm->CCGR1;
 182                }
 183                reg = __raw_readl(addr);
 184                if (enable)
 185                        reg |= mask;
 186                else
 187                        reg &= ~mask;
 188                __raw_writel(reg, addr);
 189        }
 190        return 0;
 191}
 192#endif
 193
 194/* spi_num can be from 0 - SPI_MAX_NUM */
 195int enable_spi_clk(unsigned char enable, unsigned spi_num)
 196{
 197        u32 reg;
 198        u32 mask;
 199
 200        if (spi_num > SPI_MAX_NUM)
 201                return -EINVAL;
 202
 203        mask = MXC_CCM_CCGR_CG_MASK << (spi_num << 1);
 204        reg = __raw_readl(&imx_ccm->CCGR1);
 205        if (enable)
 206                reg |= mask;
 207        else
 208                reg &= ~mask;
 209        __raw_writel(reg, &imx_ccm->CCGR1);
 210        return 0;
 211}
 212static u32 decode_pll(enum pll_clocks pll, u32 infreq)
 213{
 214        u32 div, test_div, pll_num, pll_denom;
 215
 216        switch (pll) {
 217        case PLL_SYS:
 218                div = __raw_readl(&imx_ccm->analog_pll_sys);
 219                div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
 220
 221                return (infreq * div) >> 1;
 222        case PLL_BUS:
 223                div = __raw_readl(&imx_ccm->analog_pll_528);
 224                div &= BM_ANADIG_PLL_528_DIV_SELECT;
 225
 226                return infreq * (20 + (div << 1));
 227        case PLL_USBOTG:
 228                div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
 229                div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
 230
 231                return infreq * (20 + (div << 1));
 232        case PLL_ENET:
 233                div = __raw_readl(&imx_ccm->analog_pll_enet);
 234                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
 235
 236                return 25000000 * (div + (div >> 1) + 1);
 237        case PLL_AUDIO:
 238                div = __raw_readl(&imx_ccm->analog_pll_audio);
 239                if (!(div & BM_ANADIG_PLL_AUDIO_ENABLE))
 240                        return 0;
 241                /* BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC is ignored */
 242                if (div & BM_ANADIG_PLL_AUDIO_BYPASS)
 243                        return MXC_HCLK;
 244                pll_num = __raw_readl(&imx_ccm->analog_pll_audio_num);
 245                pll_denom = __raw_readl(&imx_ccm->analog_pll_audio_denom);
 246                test_div = (div & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) >>
 247                        BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT;
 248                div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT;
 249                if (test_div == 3) {
 250                        debug("Error test_div\n");
 251                        return 0;
 252                }
 253                test_div = 1 << (2 - test_div);
 254
 255                return infreq * (div + pll_num / pll_denom) / test_div;
 256        case PLL_VIDEO:
 257                div = __raw_readl(&imx_ccm->analog_pll_video);
 258                if (!(div & BM_ANADIG_PLL_VIDEO_ENABLE))
 259                        return 0;
 260                /* BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC is ignored */
 261                if (div & BM_ANADIG_PLL_VIDEO_BYPASS)
 262                        return MXC_HCLK;
 263                pll_num = __raw_readl(&imx_ccm->analog_pll_video_num);
 264                pll_denom = __raw_readl(&imx_ccm->analog_pll_video_denom);
 265                test_div = (div & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT) >>
 266                        BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT;
 267                div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT;
 268                if (test_div == 3) {
 269                        debug("Error test_div\n");
 270                        return 0;
 271                }
 272                test_div = 1 << (2 - test_div);
 273
 274                return infreq * (div + pll_num / pll_denom) / test_div;
 275        default:
 276                return 0;
 277        }
 278        /* NOTREACHED */
 279}
 280static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
 281{
 282        u32 div;
 283        u64 freq;
 284
 285        switch (pll) {
 286        case PLL_BUS:
 287                if (!is_mx6ul() && !is_mx6ull()) {
 288                        if (pfd_num == 3) {
 289                                /* No PFD3 on PLL2 */
 290                                return 0;
 291                        }
 292                }
 293                div = __raw_readl(&imx_ccm->analog_pfd_528);
 294                freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
 295                break;
 296        case PLL_USBOTG:
 297                div = __raw_readl(&imx_ccm->analog_pfd_480);
 298                freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK);
 299                break;
 300        default:
 301                /* No PFD on other PLL                                       */
 302                return 0;
 303        }
 304
 305        return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >>
 306                              ANATOP_PFD_FRAC_SHIFT(pfd_num));
 307}
 308
 309static u32 get_mcu_main_clk(void)
 310{
 311        u32 reg, freq;
 312
 313        reg = __raw_readl(&imx_ccm->cacrr);
 314        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
 315        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
 316        freq = decode_pll(PLL_SYS, MXC_HCLK);
 317
 318        return freq / (reg + 1);
 319}
 320
 321u32 get_periph_clk(void)
 322{
 323        u32 reg, div = 0, freq = 0;
 324
 325        reg = __raw_readl(&imx_ccm->cbcdr);
 326        if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
 327                div = (reg & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >>
 328                       MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET;
 329                reg = __raw_readl(&imx_ccm->cbcmr);
 330                reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
 331                reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
 332
 333                switch (reg) {
 334                case 0:
 335                        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 336                        break;
 337                case 1:
 338                case 2:
 339                        freq = MXC_HCLK;
 340                        break;
 341                default:
 342                        break;
 343                }
 344        } else {
 345                reg = __raw_readl(&imx_ccm->cbcmr);
 346                reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
 347                reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
 348
 349                switch (reg) {
 350                case 0:
 351                        freq = decode_pll(PLL_BUS, MXC_HCLK);
 352                        break;
 353                case 1:
 354                        freq = mxc_get_pll_pfd(PLL_BUS, 2);
 355                        break;
 356                case 2:
 357                        freq = mxc_get_pll_pfd(PLL_BUS, 0);
 358                        break;
 359                case 3:
 360                        /* static / 2 divider */
 361                        freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
 362                        break;
 363                default:
 364                        break;
 365                }
 366        }
 367
 368        return freq / (div + 1);
 369}
 370
 371static u32 get_ipg_clk(void)
 372{
 373        u32 reg, ipg_podf;
 374
 375        reg = __raw_readl(&imx_ccm->cbcdr);
 376        reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
 377        ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
 378
 379        return get_ahb_clk() / (ipg_podf + 1);
 380}
 381
 382static u32 get_ipg_per_clk(void)
 383{
 384        u32 reg, perclk_podf;
 385
 386        reg = __raw_readl(&imx_ccm->cscmr1);
 387        if (is_mx6sll() || is_mx6sl() || is_mx6sx() ||
 388            is_mx6dqp() || is_mx6ul() || is_mx6ull()) {
 389                if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK)
 390                        return MXC_HCLK; /* OSC 24Mhz */
 391        }
 392
 393        perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
 394
 395        return get_ipg_clk() / (perclk_podf + 1);
 396}
 397
 398static u32 get_uart_clk(void)
 399{
 400        u32 reg, uart_podf;
 401        u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */
 402        reg = __raw_readl(&imx_ccm->cscdr1);
 403
 404        if (is_mx6sl() || is_mx6sx() || is_mx6dqp() || is_mx6ul() ||
 405            is_mx6sll() || is_mx6ull()) {
 406                if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
 407                        freq = MXC_HCLK;
 408        }
 409
 410        reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
 411        uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
 412
 413        return freq / (uart_podf + 1);
 414}
 415
 416static u32 get_cspi_clk(void)
 417{
 418        u32 reg, cspi_podf;
 419
 420        reg = __raw_readl(&imx_ccm->cscdr2);
 421        cspi_podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK) >>
 422                     MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
 423
 424        if (is_mx6dqp() || is_mx6sl() || is_mx6sx() || is_mx6ul() ||
 425            is_mx6sll() || is_mx6ull()) {
 426                if (reg & MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK)
 427                        return MXC_HCLK / (cspi_podf + 1);
 428        }
 429
 430        return  decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1));
 431}
 432
 433static u32 get_axi_clk(void)
 434{
 435        u32 root_freq, axi_podf;
 436        u32 cbcdr =  __raw_readl(&imx_ccm->cbcdr);
 437
 438        axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
 439        axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
 440
 441        if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
 442                if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
 443                        root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
 444                else
 445                        root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
 446        } else
 447                root_freq = get_periph_clk();
 448
 449        return  root_freq / (axi_podf + 1);
 450}
 451
 452static u32 get_emi_slow_clk(void)
 453{
 454        u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0;
 455
 456        cscmr1 =  __raw_readl(&imx_ccm->cscmr1);
 457        emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
 458        emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
 459        emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
 460        emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
 461
 462        switch (emi_clk_sel) {
 463        case 0:
 464                root_freq = get_axi_clk();
 465                break;
 466        case 1:
 467                root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 468                break;
 469        case 2:
 470                root_freq =  mxc_get_pll_pfd(PLL_BUS, 2);
 471                break;
 472        case 3:
 473                root_freq =  mxc_get_pll_pfd(PLL_BUS, 0);
 474                break;
 475        }
 476
 477        return root_freq / (emi_slow_podf + 1);
 478}
 479
 480static u32 get_mmdc_ch0_clk(void)
 481{
 482        u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
 483        u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
 484
 485        u32 freq, podf, per2_clk2_podf, pmu_misc2_audio_div;
 486
 487        if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl() ||
 488            is_mx6sll()) {
 489                podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) >>
 490                        MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
 491                if (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK_SEL) {
 492                        per2_clk2_podf = (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK) >>
 493                                MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET;
 494                        if (is_mx6sl()) {
 495                                if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL)
 496                                        freq = MXC_HCLK;
 497                                else
 498                                        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 499                        } else {
 500                                if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL)
 501                                        freq = decode_pll(PLL_BUS, MXC_HCLK);
 502                                else
 503                                        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 504                        }
 505                } else {
 506                        per2_clk2_podf = 0;
 507                        switch ((cbcmr &
 508                                MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
 509                                MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
 510                        case 0:
 511                                freq = decode_pll(PLL_BUS, MXC_HCLK);
 512                                break;
 513                        case 1:
 514                                freq = mxc_get_pll_pfd(PLL_BUS, 2);
 515                                break;
 516                        case 2:
 517                                freq = mxc_get_pll_pfd(PLL_BUS, 0);
 518                                break;
 519                        case 3:
 520                                if (is_mx6sl()) {
 521                                        freq = mxc_get_pll_pfd(PLL_BUS, 2) >> 1;
 522                                        break;
 523                                }
 524
 525                                pmu_misc2_audio_div = PMU_MISC2_AUDIO_DIV(__raw_readl(&imx_ccm->pmu_misc2));
 526                                switch (pmu_misc2_audio_div) {
 527                                case 0:
 528                                case 2:
 529                                        pmu_misc2_audio_div = 1;
 530                                        break;
 531                                case 1:
 532                                        pmu_misc2_audio_div = 2;
 533                                        break;
 534                                case 3:
 535                                        pmu_misc2_audio_div = 4;
 536                                        break;
 537                                }
 538                                freq = decode_pll(PLL_AUDIO, MXC_HCLK) /
 539                                        pmu_misc2_audio_div;
 540                                break;
 541                        }
 542                }
 543                return freq / (podf + 1) / (per2_clk2_podf + 1);
 544        } else {
 545                podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
 546                        MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
 547                return get_periph_clk() / (podf + 1);
 548        }
 549}
 550
 551#if defined(CONFIG_VIDEO_MXS)
 552static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom,
 553                            u32 post_div)
 554{
 555        u32 reg = 0;
 556        ulong start;
 557
 558        debug("pll5 div = %d, num = %d, denom = %d\n",
 559              pll_div, pll_num, pll_denom);
 560
 561        /* Power up PLL5 video */
 562        writel(BM_ANADIG_PLL_VIDEO_POWERDOWN |
 563               BM_ANADIG_PLL_VIDEO_BYPASS |
 564               BM_ANADIG_PLL_VIDEO_DIV_SELECT |
 565               BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT,
 566               &imx_ccm->analog_pll_video_clr);
 567
 568        /* Set div, num and denom */
 569        switch (post_div) {
 570        case 1:
 571                writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
 572                       BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x2),
 573                       &imx_ccm->analog_pll_video_set);
 574                break;
 575        case 2:
 576                writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
 577                       BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x1),
 578                       &imx_ccm->analog_pll_video_set);
 579                break;
 580        case 4:
 581                writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) |
 582                       BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x0),
 583                       &imx_ccm->analog_pll_video_set);
 584                break;
 585        default:
 586                puts("Wrong test_div!\n");
 587                return -EINVAL;
 588        }
 589
 590        writel(BF_ANADIG_PLL_VIDEO_NUM_A(pll_num),
 591               &imx_ccm->analog_pll_video_num);
 592        writel(BF_ANADIG_PLL_VIDEO_DENOM_B(pll_denom),
 593               &imx_ccm->analog_pll_video_denom);
 594
 595        /* Wait PLL5 lock */
 596        start = get_timer(0);   /* Get current timestamp */
 597
 598        do {
 599                reg = readl(&imx_ccm->analog_pll_video);
 600                if (reg & BM_ANADIG_PLL_VIDEO_LOCK) {
 601                        /* Enable PLL out */
 602                        writel(BM_ANADIG_PLL_VIDEO_ENABLE,
 603                               &imx_ccm->analog_pll_video_set);
 604                        return 0;
 605                }
 606        } while (get_timer(0) < (start + 10)); /* Wait 10ms */
 607
 608        puts("Lock PLL5 timeout\n");
 609
 610        return -ETIME;
 611}
 612
 613/*
 614 * 24M--> PLL_VIDEO -> LCDIFx_PRED -> LCDIFx_PODF -> LCD
 615 *
 616 * 'freq' using KHz as unit, see driver/video/mxsfb.c.
 617 */
 618void mxs_set_lcdclk(u32 base_addr, u32 freq)
 619{
 620        u32 reg = 0;
 621        u32 hck = MXC_HCLK / 1000;
 622        /* DIV_SELECT ranges from 27 to 54 */
 623        u32 min = hck * 27;
 624        u32 max = hck * 54;
 625        u32 temp, best = 0;
 626        u32 i, j, max_pred = 8, max_postd = 8, pred = 1, postd = 1;
 627        u32 pll_div, pll_num, pll_denom, post_div = 1;
 628
 629        debug("mxs_set_lcdclk, freq = %dKHz\n", freq);
 630
 631        if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl() &&
 632            !is_mx6sll()) {
 633                debug("This chip not support lcd!\n");
 634                return;
 635        }
 636
 637        if (!is_mx6sl()) {
 638                if (base_addr == LCDIF1_BASE_ADDR) {
 639                        reg = readl(&imx_ccm->cscdr2);
 640                        /* Can't change clocks when clock not from pre-mux */
 641                        if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0)
 642                                return;
 643                }
 644        }
 645
 646        if (is_mx6sx()) {
 647                reg = readl(&imx_ccm->cscdr2);
 648                /* Can't change clocks when clock not from pre-mux */
 649                if ((reg & MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK) != 0)
 650                        return;
 651        }
 652
 653        temp = freq * max_pred * max_postd;
 654        if (temp < min) {
 655                /*
 656                 * Register: PLL_VIDEO
 657                 * Bit Field: POST_DIV_SELECT
 658                 * 00 — Divide by 4.
 659                 * 01 — Divide by 2.
 660                 * 10 — Divide by 1.
 661                 * 11 — Reserved
 662                 * No need to check post_div(1)
 663                 */
 664                for (post_div = 2; post_div <= 4; post_div <<= 1) {
 665                        if ((temp * post_div) > min) {
 666                                freq *= post_div;
 667                                break;
 668                        }
 669                }
 670
 671                if (post_div > 4) {
 672                        printf("Fail to set rate to %dkhz", freq);
 673                        return;
 674                }
 675        }
 676
 677        /* Choose the best pred and postd to match freq for lcd */
 678        for (i = 1; i <= max_pred; i++) {
 679                for (j = 1; j <= max_postd; j++) {
 680                        temp = freq * i * j;
 681                        if (temp > max || temp < min)
 682                                continue;
 683                        if (best == 0 || temp < best) {
 684                                best = temp;
 685                                pred = i;
 686                                postd = j;
 687                        }
 688                }
 689        }
 690
 691        if (best == 0) {
 692                printf("Fail to set rate to %dKHz", freq);
 693                return;
 694        }
 695
 696        debug("best %d, pred = %d, postd = %d\n", best, pred, postd);
 697
 698        pll_div = best / hck;
 699        pll_denom = 1000000;
 700        pll_num = (best - hck * pll_div) * pll_denom / hck;
 701
 702        /*
 703         *                                  pll_num
 704         *             (24MHz * (pll_div + --------- ))
 705         *                                 pll_denom
 706         *freq KHz =  --------------------------------
 707         *             post_div * pred * postd * 1000
 708         */
 709
 710        if (base_addr == LCDIF1_BASE_ADDR) {
 711                if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
 712                        return;
 713
 714                enable_lcdif_clock(base_addr, 0);
 715                if (!is_mx6sl()) {
 716                        /* Select pre-lcd clock to PLL5 and set pre divider */
 717                        clrsetbits_le32(&imx_ccm->cscdr2,
 718                                        MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK |
 719                                        MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK,
 720                                        (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET) |
 721                                        ((pred - 1) <<
 722                                         MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET));
 723
 724                        /* Set the post divider */
 725                        clrsetbits_le32(&imx_ccm->cbcmr,
 726                                        MXC_CCM_CBCMR_LCDIF1_PODF_MASK,
 727                                        ((postd - 1) <<
 728                                        MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET));
 729                } else {
 730                        /* Select pre-lcd clock to PLL5 and set pre divider */
 731                        clrsetbits_le32(&imx_ccm->cscdr2,
 732                                        MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_MASK |
 733                                        MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_MASK,
 734                                        (0x2 << MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_OFFSET) |
 735                                        ((pred - 1) <<
 736                                         MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_OFFSET));
 737
 738                        /* Set the post divider */
 739                        clrsetbits_le32(&imx_ccm->cscmr1,
 740                                        MXC_CCM_CSCMR1_LCDIF_PIX_PODF_MASK,
 741                                        (((postd - 1)^0x6) <<
 742                                         MXC_CCM_CSCMR1_LCDIF_PIX_PODF_OFFSET));
 743                }
 744
 745                enable_lcdif_clock(base_addr, 1);
 746        } else if (is_mx6sx()) {
 747                /* Setting LCDIF2 for i.MX6SX */
 748                if (enable_pll_video(pll_div, pll_num, pll_denom, post_div))
 749                        return;
 750
 751                enable_lcdif_clock(base_addr, 0);
 752                /* Select pre-lcd clock to PLL5 and set pre divider */
 753                clrsetbits_le32(&imx_ccm->cscdr2,
 754                                MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_MASK |
 755                                MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_MASK,
 756                                (0x2 << MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_OFFSET) |
 757                                ((pred - 1) <<
 758                                 MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_OFFSET));
 759
 760                /* Set the post divider */
 761                clrsetbits_le32(&imx_ccm->cscmr1,
 762                                MXC_CCM_CSCMR1_LCDIF2_PODF_MASK,
 763                                ((postd - 1) <<
 764                                 MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET));
 765
 766                enable_lcdif_clock(base_addr, 1);
 767        }
 768}
 769
 770int enable_lcdif_clock(u32 base_addr, bool enable)
 771{
 772        u32 reg = 0;
 773        u32 lcdif_clk_sel_mask, lcdif_ccgr3_mask;
 774
 775        if (is_mx6sx()) {
 776                if ((base_addr != LCDIF1_BASE_ADDR) &&
 777                    (base_addr != LCDIF2_BASE_ADDR)) {
 778                        puts("Wrong LCD interface!\n");
 779                        return -EINVAL;
 780                }
 781                /* Set to pre-mux clock at default */
 782                lcdif_clk_sel_mask = (base_addr == LCDIF2_BASE_ADDR) ?
 783                        MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK :
 784                        MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
 785                lcdif_ccgr3_mask = (base_addr == LCDIF2_BASE_ADDR) ?
 786                        (MXC_CCM_CCGR3_LCDIF2_PIX_MASK |
 787                         MXC_CCM_CCGR3_DISP_AXI_MASK) :
 788                        (MXC_CCM_CCGR3_LCDIF1_PIX_MASK |
 789                         MXC_CCM_CCGR3_DISP_AXI_MASK);
 790        } else if (is_mx6ul() || is_mx6ull() || is_mx6sll()) {
 791                if (base_addr != LCDIF1_BASE_ADDR) {
 792                        puts("Wrong LCD interface!\n");
 793                        return -EINVAL;
 794                }
 795                /* Set to pre-mux clock at default */
 796                lcdif_clk_sel_mask = MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK;
 797                lcdif_ccgr3_mask =  MXC_CCM_CCGR3_LCDIF1_PIX_MASK;
 798        } else if (is_mx6sl()) {
 799                if (base_addr != LCDIF1_BASE_ADDR) {
 800                        puts("Wrong LCD interface!\n");
 801                        return -EINVAL;
 802                }
 803
 804                reg = readl(&imx_ccm->CCGR3);
 805                reg &= ~(MXC_CCM_CCGR3_LCDIF_AXI_MASK |
 806                         MXC_CCM_CCGR3_LCDIF_PIX_MASK);
 807                writel(reg, &imx_ccm->CCGR3);
 808
 809                if (enable) {
 810                        reg = readl(&imx_ccm->cscdr3);
 811                        reg &= ~MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_MASK;
 812                        reg |= 1 << MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_OFFSET;
 813                        writel(reg, &imx_ccm->cscdr3);
 814
 815                        reg = readl(&imx_ccm->CCGR3);
 816                        reg |= MXC_CCM_CCGR3_LCDIF_AXI_MASK |
 817                                MXC_CCM_CCGR3_LCDIF_PIX_MASK;
 818                        writel(reg, &imx_ccm->CCGR3);
 819                }
 820
 821                return 0;
 822        } else {
 823                return 0;
 824        }
 825
 826        /* Gate LCDIF clock first */
 827        reg = readl(&imx_ccm->CCGR3);
 828        reg &= ~lcdif_ccgr3_mask;
 829        writel(reg, &imx_ccm->CCGR3);
 830
 831        reg = readl(&imx_ccm->CCGR2);
 832        reg &= ~MXC_CCM_CCGR2_LCD_MASK;
 833        writel(reg, &imx_ccm->CCGR2);
 834
 835        if (enable) {
 836                /* Select pre-mux */
 837                reg = readl(&imx_ccm->cscdr2);
 838                reg &= ~lcdif_clk_sel_mask;
 839                writel(reg, &imx_ccm->cscdr2);
 840
 841                /* Enable the LCDIF pix clock */
 842                reg = readl(&imx_ccm->CCGR3);
 843                reg |= lcdif_ccgr3_mask;
 844                writel(reg, &imx_ccm->CCGR3);
 845
 846                reg = readl(&imx_ccm->CCGR2);
 847                reg |= MXC_CCM_CCGR2_LCD_MASK;
 848                writel(reg, &imx_ccm->CCGR2);
 849        }
 850
 851        return 0;
 852}
 853#endif
 854
 855#ifdef CONFIG_FSL_QSPI
 856/* qspi_num can be from 0 - 1 */
 857void enable_qspi_clk(int qspi_num)
 858{
 859        u32 reg = 0;
 860        /* Enable QuadSPI clock */
 861        switch (qspi_num) {
 862        case 0:
 863                /* disable the clock gate */
 864                clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
 865
 866                /* set 50M  : (50 = 396 / 2 / 4) */
 867                reg = readl(&imx_ccm->cscmr1);
 868                reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK |
 869                         MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK);
 870                reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) |
 871                        (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET));
 872                writel(reg, &imx_ccm->cscmr1);
 873
 874                /* enable the clock gate */
 875                setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK);
 876                break;
 877        case 1:
 878                /*
 879                 * disable the clock gate
 880                 * QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate,
 881                 * disable both of them.
 882                 */
 883                clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
 884                             MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
 885
 886                /* set 50M  : (50 = 396 / 2 / 4) */
 887                reg = readl(&imx_ccm->cs2cdr);
 888                reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK |
 889                         MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK |
 890                         MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK);
 891                reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) |
 892                        MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3));
 893                writel(reg, &imx_ccm->cs2cdr);
 894
 895                /*enable the clock gate*/
 896                setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK |
 897                             MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK);
 898                break;
 899        default:
 900                break;
 901        }
 902}
 903#endif
 904
 905#ifdef CONFIG_FEC_MXC
 906int enable_fec_anatop_clock(int fec_id, enum enet_freq freq)
 907{
 908        u32 reg = 0;
 909        s32 timeout = 100000;
 910
 911        struct anatop_regs __iomem *anatop =
 912                (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 913
 914        if (freq < ENET_25MHZ || freq > ENET_125MHZ)
 915                return -EINVAL;
 916
 917        reg = readl(&anatop->pll_enet);
 918
 919        if (fec_id == 0) {
 920                reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
 921                reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq);
 922        } else if (fec_id == 1) {
 923                /* Only i.MX6SX/UL support ENET2 */
 924                if (!(is_mx6sx() || is_mx6ul() || is_mx6ull()))
 925                        return -EINVAL;
 926                reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT;
 927                reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(freq);
 928        } else {
 929                return -EINVAL;
 930        }
 931
 932        if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||
 933            (!(reg & BM_ANADIG_PLL_ENET_LOCK))) {
 934                reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
 935                writel(reg, &anatop->pll_enet);
 936                while (timeout--) {
 937                        if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
 938                                break;
 939                }
 940                if (timeout < 0)
 941                        return -ETIMEDOUT;
 942        }
 943
 944        /* Enable FEC clock */
 945        if (fec_id == 0)
 946                reg |= BM_ANADIG_PLL_ENET_ENABLE;
 947        else
 948                reg |= BM_ANADIG_PLL_ENET2_ENABLE;
 949        reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
 950        writel(reg, &anatop->pll_enet);
 951
 952#ifdef CONFIG_MX6SX
 953        /* Disable enet system clcok before switching clock parent */
 954        reg = readl(&imx_ccm->CCGR3);
 955        reg &= ~MXC_CCM_CCGR3_ENET_MASK;
 956        writel(reg, &imx_ccm->CCGR3);
 957
 958        /*
 959         * Set enet ahb clock to 200MHz
 960         * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB
 961         */
 962        reg = readl(&imx_ccm->chsccdr);
 963        reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK
 964                 | MXC_CCM_CHSCCDR_ENET_PODF_MASK
 965                 | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK);
 966        /* PLL2 PFD2 */
 967        reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET);
 968        /* Div = 2*/
 969        reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET);
 970        reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET);
 971        writel(reg, &imx_ccm->chsccdr);
 972
 973        /* Enable enet system clock */
 974        reg = readl(&imx_ccm->CCGR3);
 975        reg |= MXC_CCM_CCGR3_ENET_MASK;
 976        writel(reg, &imx_ccm->CCGR3);
 977#endif
 978        return 0;
 979}
 980#endif
 981
 982static u32 get_usdhc_clk(u32 port)
 983{
 984        u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
 985        u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
 986        u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
 987
 988        if (is_mx6ul() || is_mx6ull()) {
 989                if (port > 1)
 990                        return 0;
 991        }
 992
 993        if (is_mx6sll()) {
 994                if (port > 2)
 995                        return 0;
 996        }
 997
 998        switch (port) {
 999        case 0:
1000                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
1001                                        MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
1002                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
1003
1004                break;
1005        case 1:
1006                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
1007                                        MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
1008                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
1009
1010                break;
1011        case 2:
1012                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
1013                                        MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
1014                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
1015
1016                break;
1017        case 3:
1018                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
1019                                        MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
1020                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
1021
1022                break;
1023        default:
1024                break;
1025        }
1026
1027        if (clk_sel)
1028                root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
1029        else
1030                root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
1031
1032        return root_freq / (usdhc_podf + 1);
1033}
1034
1035u32 imx_get_uartclk(void)
1036{
1037        return get_uart_clk();
1038}
1039
1040u32 imx_get_fecclk(void)
1041{
1042        return mxc_get_clock(MXC_IPG_CLK);
1043}
1044
1045#if defined(CONFIG_SATA) || defined(CONFIG_PCIE_IMX)
1046static int enable_enet_pll(uint32_t en)
1047{
1048        struct mxc_ccm_reg *const imx_ccm
1049                = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
1050        s32 timeout = 100000;
1051        u32 reg = 0;
1052
1053        /* Enable PLLs */
1054        reg = readl(&imx_ccm->analog_pll_enet);
1055        reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
1056        writel(reg, &imx_ccm->analog_pll_enet);
1057        reg |= BM_ANADIG_PLL_SYS_ENABLE;
1058        while (timeout--) {
1059                if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
1060                        break;
1061        }
1062        if (timeout <= 0)
1063                return -EIO;
1064        reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
1065        writel(reg, &imx_ccm->analog_pll_enet);
1066        reg |= en;
1067        writel(reg, &imx_ccm->analog_pll_enet);
1068        return 0;
1069}
1070#endif
1071
1072#ifdef CONFIG_SATA
1073static void ungate_sata_clock(void)
1074{
1075        struct mxc_ccm_reg *const imx_ccm =
1076                (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1077
1078        /* Enable SATA clock. */
1079        setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
1080}
1081
1082int enable_sata_clock(void)
1083{
1084        ungate_sata_clock();
1085        return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
1086}
1087
1088void disable_sata_clock(void)
1089{
1090        struct mxc_ccm_reg *const imx_ccm =
1091                (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1092
1093        clrbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
1094}
1095#endif
1096
1097#ifdef CONFIG_PCIE_IMX
1098static void ungate_pcie_clock(void)
1099{
1100        struct mxc_ccm_reg *const imx_ccm =
1101                (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1102
1103        /* Enable PCIe clock. */
1104        setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
1105}
1106
1107int enable_pcie_clock(void)
1108{
1109        struct anatop_regs *anatop_regs =
1110                (struct anatop_regs *)ANATOP_BASE_ADDR;
1111        struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1112        u32 lvds1_clk_sel;
1113
1114        /*
1115         * Here be dragons!
1116         *
1117         * The register ANATOP_MISC1 is not documented in the Freescale
1118         * MX6RM. The register that is mapped in the ANATOP space and
1119         * marked as ANATOP_MISC1 is actually documented in the PMU section
1120         * of the datasheet as PMU_MISC1.
1121         *
1122         * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on
1123         * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important
1124         * for PCI express link that is clocked from the i.MX6.
1125         */
1126#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN          (1 << 12)
1127#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN          (1 << 10)
1128#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK     0x0000001F
1129#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa
1130#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb
1131
1132        if (is_mx6sx())
1133                lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF;
1134        else
1135                lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF;
1136
1137        clrsetbits_le32(&anatop_regs->ana_misc1,
1138                        ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
1139                        ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
1140                        ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel);
1141
1142        /* PCIe reference clock sourced from AXI. */
1143        clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
1144
1145        /* Party time! Ungate the clock to the PCIe. */
1146#ifdef CONFIG_SATA
1147        ungate_sata_clock();
1148#endif
1149        ungate_pcie_clock();
1150
1151        return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
1152                               BM_ANADIG_PLL_ENET_ENABLE_PCIE);
1153}
1154#endif
1155
1156#ifdef CONFIG_SECURE_BOOT
1157void hab_caam_clock_enable(unsigned char enable)
1158{
1159        u32 reg;
1160
1161        if (is_mx6ull() || is_mx6sll()) {
1162                /* CG5, DCP clock */
1163                reg = __raw_readl(&imx_ccm->CCGR0);
1164                if (enable)
1165                        reg |= MXC_CCM_CCGR0_DCP_CLK_MASK;
1166                else
1167                        reg &= ~MXC_CCM_CCGR0_DCP_CLK_MASK;
1168                __raw_writel(reg, &imx_ccm->CCGR0);
1169        } else {
1170                /* CG4 ~ CG6, CAAM clocks */
1171                reg = __raw_readl(&imx_ccm->CCGR0);
1172                if (enable)
1173                        reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
1174                                MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
1175                                MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
1176                else
1177                        reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK |
1178                                MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK |
1179                                MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK);
1180                __raw_writel(reg, &imx_ccm->CCGR0);
1181        }
1182
1183        /* EMI slow clk */
1184        reg = __raw_readl(&imx_ccm->CCGR6);
1185        if (enable)
1186                reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
1187        else
1188                reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
1189        __raw_writel(reg, &imx_ccm->CCGR6);
1190}
1191#endif
1192
1193static void enable_pll3(void)
1194{
1195        struct anatop_regs __iomem *anatop =
1196                (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
1197
1198        /* make sure pll3 is enabled */
1199        if ((readl(&anatop->usb1_pll_480_ctrl) &
1200                        BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) {
1201                /* enable pll's power */
1202                writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER,
1203                       &anatop->usb1_pll_480_ctrl_set);
1204                writel(0x80, &anatop->ana_misc2_clr);
1205                /* wait for pll lock */
1206                while ((readl(&anatop->usb1_pll_480_ctrl) &
1207                        BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0)
1208                        ;
1209                /* disable bypass */
1210                writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS,
1211                       &anatop->usb1_pll_480_ctrl_clr);
1212                /* enable pll output */
1213                writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE,
1214                       &anatop->usb1_pll_480_ctrl_set);
1215        }
1216}
1217
1218void enable_thermal_clk(void)
1219{
1220        enable_pll3();
1221}
1222
1223unsigned int mxc_get_clock(enum mxc_clock clk)
1224{
1225        switch (clk) {
1226        case MXC_ARM_CLK:
1227                return get_mcu_main_clk();
1228        case MXC_PER_CLK:
1229                return get_periph_clk();
1230        case MXC_AHB_CLK:
1231                return get_ahb_clk();
1232        case MXC_IPG_CLK:
1233                return get_ipg_clk();
1234        case MXC_IPG_PERCLK:
1235        case MXC_I2C_CLK:
1236                return get_ipg_per_clk();
1237        case MXC_UART_CLK:
1238                return get_uart_clk();
1239        case MXC_CSPI_CLK:
1240                return get_cspi_clk();
1241        case MXC_AXI_CLK:
1242                return get_axi_clk();
1243        case MXC_EMI_SLOW_CLK:
1244                return get_emi_slow_clk();
1245        case MXC_DDR_CLK:
1246                return get_mmdc_ch0_clk();
1247        case MXC_ESDHC_CLK:
1248                return get_usdhc_clk(0);
1249        case MXC_ESDHC2_CLK:
1250                return get_usdhc_clk(1);
1251        case MXC_ESDHC3_CLK:
1252                return get_usdhc_clk(2);
1253        case MXC_ESDHC4_CLK:
1254                return get_usdhc_clk(3);
1255        case MXC_SATA_CLK:
1256                return get_ahb_clk();
1257        default:
1258                printf("Unsupported MXC CLK: %d\n", clk);
1259                break;
1260        }
1261
1262        return 0;
1263}
1264
1265/*
1266 * Dump some core clockes.
1267 */
1268int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
1269{
1270        u32 freq;
1271        freq = decode_pll(PLL_SYS, MXC_HCLK);
1272        printf("PLL_SYS    %8d MHz\n", freq / 1000000);
1273        freq = decode_pll(PLL_BUS, MXC_HCLK);
1274        printf("PLL_BUS    %8d MHz\n", freq / 1000000);
1275        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
1276        printf("PLL_OTG    %8d MHz\n", freq / 1000000);
1277        freq = decode_pll(PLL_ENET, MXC_HCLK);
1278        printf("PLL_NET    %8d MHz\n", freq / 1000000);
1279
1280        printf("\n");
1281        printf("ARM        %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000);
1282        printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
1283        printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
1284#ifdef CONFIG_MXC_SPI
1285        printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
1286#endif
1287        printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
1288        printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
1289        printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
1290        printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
1291        printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
1292        printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
1293        printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
1294        printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
1295        printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
1296
1297        return 0;
1298}
1299
1300#ifndef CONFIG_MX6SX
1301void enable_ipu_clock(void)
1302{
1303        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1304        int reg;
1305        reg = readl(&mxc_ccm->CCGR3);
1306        reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
1307        writel(reg, &mxc_ccm->CCGR3);
1308
1309        if (is_mx6dqp()) {
1310                setbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK);
1311                setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK);
1312        }
1313}
1314#endif
1315
1316#if defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) || defined(CONFIG_MX6DL) || \
1317        defined(CONFIG_MX6S)
1318static void disable_ldb_di_clock_sources(void)
1319{
1320        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1321        int reg;
1322
1323        /* Make sure PFDs are disabled at boot. */
1324        reg = readl(&mxc_ccm->analog_pfd_528);
1325        /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */
1326        if (is_mx6sdl())
1327                reg |= 0x80008080;
1328        else
1329                reg |= 0x80808080;
1330        writel(reg, &mxc_ccm->analog_pfd_528);
1331
1332        /* Disable PLL3 PFDs */
1333        reg = readl(&mxc_ccm->analog_pfd_480);
1334        reg |= 0x80808080;
1335        writel(reg, &mxc_ccm->analog_pfd_480);
1336
1337        /* Disable PLL5 */
1338        reg = readl(&mxc_ccm->analog_pll_video);
1339        reg &= ~(1 << 13);
1340        writel(reg, &mxc_ccm->analog_pll_video);
1341}
1342
1343static void enable_ldb_di_clock_sources(void)
1344{
1345        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1346        int reg;
1347
1348        reg = readl(&mxc_ccm->analog_pfd_528);
1349        if (is_mx6sdl())
1350                reg &= ~(0x80008080);
1351        else
1352                reg &= ~(0x80808080);
1353        writel(reg, &mxc_ccm->analog_pfd_528);
1354
1355        reg = readl(&mxc_ccm->analog_pfd_480);
1356        reg &= ~(0x80808080);
1357        writel(reg, &mxc_ccm->analog_pfd_480);
1358}
1359
1360/*
1361 * Try call this function as early in the boot process as possible since the
1362 * function temporarily disables PLL2 PFD's, PLL3 PFD's and PLL5.
1363 */
1364void select_ldb_di_clock_source(enum ldb_di_clock clk)
1365{
1366        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
1367        int reg;
1368
1369        /*
1370         * Need to follow a strict procedure when changing the LDB
1371         * clock, else we can introduce a glitch. Things to keep in
1372         * mind:
1373         * 1. The current and new parent clocks must be disabled.
1374         * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has
1375         * no CG bit.
1376         * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux
1377         * the top four options are in one mux and the PLL3 option along
1378         * with another option is in the second mux. There is third mux
1379         * used to decide between the first and second mux.
1380         * The code below switches the parent to the bottom mux first
1381         * and then manipulates the top mux. This ensures that no glitch
1382         * will enter the divider.
1383         *
1384         * Need to disable MMDC_CH1 clock manually as there is no CG bit
1385         * for this clock. The only way to disable this clock is to move
1386         * it to pll3_sw_clk and then to disable pll3_sw_clk
1387         * Make sure periph2_clk2_sel is set to pll3_sw_clk
1388         */
1389
1390        /* Disable all ldb_di clock parents */
1391        disable_ldb_di_clock_sources();
1392
1393        /* Set MMDC_CH1 mask bit */
1394        reg = readl(&mxc_ccm->ccdr);
1395        reg |= MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
1396        writel(reg, &mxc_ccm->ccdr);
1397
1398        /* Set periph2_clk2_sel to be sourced from PLL3_sw_clk */
1399        reg = readl(&mxc_ccm->cbcmr);
1400        reg &= ~MXC_CCM_CBCMR_PERIPH2_CLK2_SEL;
1401        writel(reg, &mxc_ccm->cbcmr);
1402
1403        /*
1404         * Set the periph2_clk_sel to the top mux so that
1405         * mmdc_ch1 is from pll3_sw_clk.
1406         */
1407        reg = readl(&mxc_ccm->cbcdr);
1408        reg |= MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
1409        writel(reg, &mxc_ccm->cbcdr);
1410
1411        /* Wait for the clock switch */
1412        while (readl(&mxc_ccm->cdhipr))
1413                ;
1414        /* Disable pll3_sw_clk by selecting bypass clock source */
1415        reg = readl(&mxc_ccm->ccsr);
1416        reg |= MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
1417        writel(reg, &mxc_ccm->ccsr);
1418
1419        /* Set the ldb_di0_clk and ldb_di1_clk to 111b */
1420        reg = readl(&mxc_ccm->cs2cdr);
1421        reg |= ((7 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
1422              | (7 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
1423        writel(reg, &mxc_ccm->cs2cdr);
1424
1425        /* Set the ldb_di0_clk and ldb_di1_clk to 100b */
1426        reg = readl(&mxc_ccm->cs2cdr);
1427        reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK
1428              | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK);
1429        reg |= ((4 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
1430              | (4 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
1431        writel(reg, &mxc_ccm->cs2cdr);
1432
1433        /* Set the ldb_di0_clk and ldb_di1_clk to desired source */
1434        reg = readl(&mxc_ccm->cs2cdr);
1435        reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK
1436              | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK);
1437        reg |= ((clk << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET)
1438              | (clk << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET));
1439        writel(reg, &mxc_ccm->cs2cdr);
1440
1441        /* Unbypass pll3_sw_clk */
1442        reg = readl(&mxc_ccm->ccsr);
1443        reg &= ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL;
1444        writel(reg, &mxc_ccm->ccsr);
1445
1446        /*
1447         * Set the periph2_clk_sel back to the bottom mux so that
1448         * mmdc_ch1 is from its original parent.
1449         */
1450        reg = readl(&mxc_ccm->cbcdr);
1451        reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL;
1452        writel(reg, &mxc_ccm->cbcdr);
1453
1454        /* Wait for the clock switch */
1455        while (readl(&mxc_ccm->cdhipr))
1456                ;
1457        /* Clear MMDC_CH1 mask bit */
1458        reg = readl(&mxc_ccm->ccdr);
1459        reg &= ~MXC_CCM_CCDR_MMDC_CH1_HS_MASK;
1460        writel(reg, &mxc_ccm->ccdr);
1461
1462        enable_ldb_di_clock_sources();
1463}
1464#endif
1465
1466#ifdef CONFIG_MTD_NOR_FLASH
1467void enable_eim_clk(unsigned char enable)
1468{
1469        u32 reg;
1470
1471        reg = __raw_readl(&imx_ccm->CCGR6);
1472        if (enable)
1473                reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK;
1474        else
1475                reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK;
1476        __raw_writel(reg, &imx_ccm->CCGR6);
1477}
1478#endif
1479
1480/***************************************************/
1481
1482U_BOOT_CMD(
1483        clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
1484        "display clocks",
1485        ""
1486);
1487