uboot/arch/arm/cpu/armv7/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 <asm/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};
  22
  23struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
  24
  25#ifdef CONFIG_MXC_OCOTP
  26void enable_ocotp_clk(unsigned char enable)
  27{
  28        u32 reg;
  29
  30        reg = __raw_readl(&imx_ccm->CCGR2);
  31        if (enable)
  32                reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  33        else
  34                reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK;
  35        __raw_writel(reg, &imx_ccm->CCGR2);
  36}
  37#endif
  38
  39void enable_usboh3_clk(unsigned char enable)
  40{
  41        u32 reg;
  42
  43        reg = __raw_readl(&imx_ccm->CCGR6);
  44        if (enable)
  45                reg |= MXC_CCM_CCGR6_USBOH3_MASK;
  46        else
  47                reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK);
  48        __raw_writel(reg, &imx_ccm->CCGR6);
  49
  50}
  51
  52#ifdef CONFIG_SYS_I2C_MXC
  53/* i2c_num can be from 0 - 2 */
  54int enable_i2c_clk(unsigned char enable, unsigned i2c_num)
  55{
  56        u32 reg;
  57        u32 mask;
  58
  59        if (i2c_num > 2)
  60                return -EINVAL;
  61
  62        mask = MXC_CCM_CCGR_CG_MASK
  63                << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET + (i2c_num << 1));
  64        reg = __raw_readl(&imx_ccm->CCGR2);
  65        if (enable)
  66                reg |= mask;
  67        else
  68                reg &= ~mask;
  69        __raw_writel(reg, &imx_ccm->CCGR2);
  70        return 0;
  71}
  72#endif
  73
  74static u32 decode_pll(enum pll_clocks pll, u32 infreq)
  75{
  76        u32 div;
  77
  78        switch (pll) {
  79        case PLL_SYS:
  80                div = __raw_readl(&imx_ccm->analog_pll_sys);
  81                div &= BM_ANADIG_PLL_SYS_DIV_SELECT;
  82
  83                return (infreq * div) >> 1;
  84        case PLL_BUS:
  85                div = __raw_readl(&imx_ccm->analog_pll_528);
  86                div &= BM_ANADIG_PLL_528_DIV_SELECT;
  87
  88                return infreq * (20 + (div << 1));
  89        case PLL_USBOTG:
  90                div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl);
  91                div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT;
  92
  93                return infreq * (20 + (div << 1));
  94        case PLL_ENET:
  95                div = __raw_readl(&imx_ccm->analog_pll_enet);
  96                div &= BM_ANADIG_PLL_ENET_DIV_SELECT;
  97
  98                return 25000000 * (div + (div >> 1) + 1);
  99        default:
 100                return 0;
 101        }
 102        /* NOTREACHED */
 103}
 104static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
 105{
 106        u32 div;
 107        u64 freq;
 108
 109        switch (pll) {
 110        case PLL_BUS:
 111                if (pfd_num == 3) {
 112                        /* No PFD3 on PPL2 */
 113                        return 0;
 114                }
 115                div = __raw_readl(&imx_ccm->analog_pfd_528);
 116                freq = (u64)decode_pll(PLL_BUS, MXC_HCLK);
 117                break;
 118        case PLL_USBOTG:
 119                div = __raw_readl(&imx_ccm->analog_pfd_480);
 120                freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK);
 121                break;
 122        default:
 123                /* No PFD on other PLL                                       */
 124                return 0;
 125        }
 126
 127        return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >>
 128                              ANATOP_PFD_FRAC_SHIFT(pfd_num));
 129}
 130
 131static u32 get_mcu_main_clk(void)
 132{
 133        u32 reg, freq;
 134
 135        reg = __raw_readl(&imx_ccm->cacrr);
 136        reg &= MXC_CCM_CACRR_ARM_PODF_MASK;
 137        reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET;
 138        freq = decode_pll(PLL_SYS, MXC_HCLK);
 139
 140        return freq / (reg + 1);
 141}
 142
 143u32 get_periph_clk(void)
 144{
 145        u32 reg, freq = 0;
 146
 147        reg = __raw_readl(&imx_ccm->cbcdr);
 148        if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) {
 149                reg = __raw_readl(&imx_ccm->cbcmr);
 150                reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK;
 151                reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET;
 152
 153                switch (reg) {
 154                case 0:
 155                        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 156                        break;
 157                case 1:
 158                case 2:
 159                        freq = MXC_HCLK;
 160                        break;
 161                default:
 162                        break;
 163                }
 164        } else {
 165                reg = __raw_readl(&imx_ccm->cbcmr);
 166                reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK;
 167                reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET;
 168
 169                switch (reg) {
 170                case 0:
 171                        freq = decode_pll(PLL_BUS, MXC_HCLK);
 172                        break;
 173                case 1:
 174                        freq = mxc_get_pll_pfd(PLL_BUS, 2);
 175                        break;
 176                case 2:
 177                        freq = mxc_get_pll_pfd(PLL_BUS, 0);
 178                        break;
 179                case 3:
 180                        /* static / 2 divider */
 181                        freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2;
 182                        break;
 183                default:
 184                        break;
 185                }
 186        }
 187
 188        return freq;
 189}
 190
 191static u32 get_ipg_clk(void)
 192{
 193        u32 reg, ipg_podf;
 194
 195        reg = __raw_readl(&imx_ccm->cbcdr);
 196        reg &= MXC_CCM_CBCDR_IPG_PODF_MASK;
 197        ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET;
 198
 199        return get_ahb_clk() / (ipg_podf + 1);
 200}
 201
 202static u32 get_ipg_per_clk(void)
 203{
 204        u32 reg, perclk_podf;
 205
 206        reg = __raw_readl(&imx_ccm->cscmr1);
 207        perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK;
 208
 209        return get_ipg_clk() / (perclk_podf + 1);
 210}
 211
 212static u32 get_uart_clk(void)
 213{
 214        u32 reg, uart_podf;
 215        u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */
 216        reg = __raw_readl(&imx_ccm->cscdr1);
 217#ifdef CONFIG_MX6SL
 218        if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL)
 219                freq = MXC_HCLK;
 220#endif
 221        reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK;
 222        uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET;
 223
 224        return freq / (uart_podf + 1);
 225}
 226
 227static u32 get_cspi_clk(void)
 228{
 229        u32 reg, cspi_podf;
 230
 231        reg = __raw_readl(&imx_ccm->cscdr2);
 232        reg &= MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK;
 233        cspi_podf = reg >> MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET;
 234
 235        return  decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1));
 236}
 237
 238static u32 get_axi_clk(void)
 239{
 240        u32 root_freq, axi_podf;
 241        u32 cbcdr =  __raw_readl(&imx_ccm->cbcdr);
 242
 243        axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK;
 244        axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET;
 245
 246        if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
 247                if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
 248                        root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
 249                else
 250                        root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
 251        } else
 252                root_freq = get_periph_clk();
 253
 254        return  root_freq / (axi_podf + 1);
 255}
 256
 257static u32 get_emi_slow_clk(void)
 258{
 259        u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0;
 260
 261        cscmr1 =  __raw_readl(&imx_ccm->cscmr1);
 262        emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK;
 263        emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET;
 264        emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK;
 265        emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET;
 266
 267        switch (emi_clk_sel) {
 268        case 0:
 269                root_freq = get_axi_clk();
 270                break;
 271        case 1:
 272                root_freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 273                break;
 274        case 2:
 275                root_freq =  mxc_get_pll_pfd(PLL_BUS, 2);
 276                break;
 277        case 3:
 278                root_freq =  mxc_get_pll_pfd(PLL_BUS, 0);
 279                break;
 280        }
 281
 282        return root_freq / (emi_slow_podf + 1);
 283}
 284
 285#ifdef CONFIG_MX6SL
 286static u32 get_mmdc_ch0_clk(void)
 287{
 288        u32 cbcmr = __raw_readl(&imx_ccm->cbcmr);
 289        u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
 290        u32 freq, podf;
 291
 292        podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) \
 293                        >> MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET;
 294
 295        switch ((cbcmr & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >>
 296                MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) {
 297        case 0:
 298                freq = decode_pll(PLL_BUS, MXC_HCLK);
 299                break;
 300        case 1:
 301                freq = mxc_get_pll_pfd(PLL_BUS, 2);
 302                break;
 303        case 2:
 304                freq = mxc_get_pll_pfd(PLL_BUS, 0);
 305                break;
 306        case 3:
 307                /* static / 2 divider */
 308                freq =  mxc_get_pll_pfd(PLL_BUS, 2) / 2;
 309        }
 310
 311        return freq / (podf + 1);
 312
 313}
 314#else
 315static u32 get_mmdc_ch0_clk(void)
 316{
 317        u32 cbcdr = __raw_readl(&imx_ccm->cbcdr);
 318        u32 mmdc_ch0_podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >>
 319                                MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET;
 320
 321        return get_periph_clk() / (mmdc_ch0_podf + 1);
 322}
 323#endif
 324
 325#ifdef CONFIG_FEC_MXC
 326int enable_fec_anatop_clock(enum enet_freq freq)
 327{
 328        u32 reg = 0;
 329        s32 timeout = 100000;
 330
 331        struct anatop_regs __iomem *anatop =
 332                (struct anatop_regs __iomem *)ANATOP_BASE_ADDR;
 333
 334        if (freq < ENET_25MHz || freq > ENET_125MHz)
 335                return -EINVAL;
 336
 337        reg = readl(&anatop->pll_enet);
 338        reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT;
 339        reg |= freq;
 340
 341        if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) ||
 342            (!(reg & BM_ANADIG_PLL_ENET_LOCK))) {
 343                reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN;
 344                writel(reg, &anatop->pll_enet);
 345                while (timeout--) {
 346                        if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK)
 347                                break;
 348                }
 349                if (timeout < 0)
 350                        return -ETIMEDOUT;
 351        }
 352
 353        /* Enable FEC clock */
 354        reg |= BM_ANADIG_PLL_ENET_ENABLE;
 355        reg &= ~BM_ANADIG_PLL_ENET_BYPASS;
 356        writel(reg, &anatop->pll_enet);
 357
 358        return 0;
 359}
 360#endif
 361
 362static u32 get_usdhc_clk(u32 port)
 363{
 364        u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0;
 365        u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1);
 366        u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1);
 367
 368        switch (port) {
 369        case 0:
 370                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >>
 371                                        MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET;
 372                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL;
 373
 374                break;
 375        case 1:
 376                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >>
 377                                        MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET;
 378                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL;
 379
 380                break;
 381        case 2:
 382                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >>
 383                                        MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET;
 384                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL;
 385
 386                break;
 387        case 3:
 388                usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >>
 389                                        MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET;
 390                clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL;
 391
 392                break;
 393        default:
 394                break;
 395        }
 396
 397        if (clk_sel)
 398                root_freq = mxc_get_pll_pfd(PLL_BUS, 0);
 399        else
 400                root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
 401
 402        return root_freq / (usdhc_podf + 1);
 403}
 404
 405u32 imx_get_uartclk(void)
 406{
 407        return get_uart_clk();
 408}
 409
 410u32 imx_get_fecclk(void)
 411{
 412        return mxc_get_clock(MXC_IPG_CLK);
 413}
 414
 415static int enable_enet_pll(uint32_t en)
 416{
 417        struct mxc_ccm_reg *const imx_ccm
 418                = (struct mxc_ccm_reg *) CCM_BASE_ADDR;
 419        s32 timeout = 100000;
 420        u32 reg = 0;
 421
 422        /* Enable PLLs */
 423        reg = readl(&imx_ccm->analog_pll_enet);
 424        reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN;
 425        writel(reg, &imx_ccm->analog_pll_enet);
 426        reg |= BM_ANADIG_PLL_SYS_ENABLE;
 427        while (timeout--) {
 428                if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK)
 429                        break;
 430        }
 431        if (timeout <= 0)
 432                return -EIO;
 433        reg &= ~BM_ANADIG_PLL_SYS_BYPASS;
 434        writel(reg, &imx_ccm->analog_pll_enet);
 435        reg |= en;
 436        writel(reg, &imx_ccm->analog_pll_enet);
 437        return 0;
 438}
 439
 440static void ungate_sata_clock(void)
 441{
 442        struct mxc_ccm_reg *const imx_ccm =
 443                (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 444
 445        /* Enable SATA clock. */
 446        setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK);
 447}
 448
 449static void ungate_pcie_clock(void)
 450{
 451        struct mxc_ccm_reg *const imx_ccm =
 452                (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 453
 454        /* Enable PCIe clock. */
 455        setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK);
 456}
 457
 458int enable_sata_clock(void)
 459{
 460        ungate_sata_clock();
 461        return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA);
 462}
 463
 464int enable_pcie_clock(void)
 465{
 466        struct anatop_regs *anatop_regs =
 467                (struct anatop_regs *)ANATOP_BASE_ADDR;
 468        struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 469
 470        /*
 471         * Here be dragons!
 472         *
 473         * The register ANATOP_MISC1 is not documented in the Freescale
 474         * MX6RM. The register that is mapped in the ANATOP space and
 475         * marked as ANATOP_MISC1 is actually documented in the PMU section
 476         * of the datasheet as PMU_MISC1.
 477         *
 478         * Switch LVDS clock source to SATA (0xb), disable clock INPUT and
 479         * enable clock OUTPUT. This is important for PCI express link that
 480         * is clocked from the i.MX6.
 481         */
 482#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN          (1 << 12)
 483#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN          (1 << 10)
 484#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK     0x0000001F
 485        clrsetbits_le32(&anatop_regs->ana_misc1,
 486                        ANADIG_ANA_MISC1_LVDSCLK1_IBEN |
 487                        ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK,
 488                        ANADIG_ANA_MISC1_LVDSCLK1_OBEN | 0xb);
 489
 490        /* PCIe reference clock sourced from AXI. */
 491        clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL);
 492
 493        /* Party time! Ungate the clock to the PCIe. */
 494        ungate_sata_clock();
 495        ungate_pcie_clock();
 496
 497        return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA |
 498                               BM_ANADIG_PLL_ENET_ENABLE_PCIE);
 499}
 500
 501unsigned int mxc_get_clock(enum mxc_clock clk)
 502{
 503        switch (clk) {
 504        case MXC_ARM_CLK:
 505                return get_mcu_main_clk();
 506        case MXC_PER_CLK:
 507                return get_periph_clk();
 508        case MXC_AHB_CLK:
 509                return get_ahb_clk();
 510        case MXC_IPG_CLK:
 511                return get_ipg_clk();
 512        case MXC_IPG_PERCLK:
 513        case MXC_I2C_CLK:
 514                return get_ipg_per_clk();
 515        case MXC_UART_CLK:
 516                return get_uart_clk();
 517        case MXC_CSPI_CLK:
 518                return get_cspi_clk();
 519        case MXC_AXI_CLK:
 520                return get_axi_clk();
 521        case MXC_EMI_SLOW_CLK:
 522                return get_emi_slow_clk();
 523        case MXC_DDR_CLK:
 524                return get_mmdc_ch0_clk();
 525        case MXC_ESDHC_CLK:
 526                return get_usdhc_clk(0);
 527        case MXC_ESDHC2_CLK:
 528                return get_usdhc_clk(1);
 529        case MXC_ESDHC3_CLK:
 530                return get_usdhc_clk(2);
 531        case MXC_ESDHC4_CLK:
 532                return get_usdhc_clk(3);
 533        case MXC_SATA_CLK:
 534                return get_ahb_clk();
 535        default:
 536                break;
 537        }
 538
 539        return -1;
 540}
 541
 542/*
 543 * Dump some core clockes.
 544 */
 545int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 546{
 547        u32 freq;
 548        freq = decode_pll(PLL_SYS, MXC_HCLK);
 549        printf("PLL_SYS    %8d MHz\n", freq / 1000000);
 550        freq = decode_pll(PLL_BUS, MXC_HCLK);
 551        printf("PLL_BUS    %8d MHz\n", freq / 1000000);
 552        freq = decode_pll(PLL_USBOTG, MXC_HCLK);
 553        printf("PLL_OTG    %8d MHz\n", freq / 1000000);
 554        freq = decode_pll(PLL_ENET, MXC_HCLK);
 555        printf("PLL_NET    %8d MHz\n", freq / 1000000);
 556
 557        printf("\n");
 558        printf("IPG        %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000);
 559        printf("UART       %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000);
 560#ifdef CONFIG_MXC_SPI
 561        printf("CSPI       %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000);
 562#endif
 563        printf("AHB        %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000);
 564        printf("AXI        %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000);
 565        printf("DDR        %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000);
 566        printf("USDHC1     %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000);
 567        printf("USDHC2     %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000);
 568        printf("USDHC3     %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000);
 569        printf("USDHC4     %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000);
 570        printf("EMI SLOW   %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000);
 571        printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000);
 572
 573        return 0;
 574}
 575
 576void enable_ipu_clock(void)
 577{
 578        struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR;
 579        int reg;
 580        reg = readl(&mxc_ccm->CCGR3);
 581        reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK;
 582        writel(reg, &mxc_ccm->CCGR3);
 583}
 584/***************************************************/
 585
 586U_BOOT_CMD(
 587        clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks,
 588        "display clocks",
 589        ""
 590);
 591