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