X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=arch%2Farm%2Fcpu%2Farmv7%2Fmx5%2Fclock.c;h=bf52f0d19e546e0b98b2717b25618c4c6711e92b;hb=ae27120c31d58b8bb694d9155bcffdcfae8552a6;hp=64862b31f1f2073fca718c1471c249dac40bfd4c;hpb=d978780b2e676c005460cd561f4f15b5220bdf49;p=oweals%2Fu-boot.git diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c index 64862b31f1..bf52f0d19e 100644 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ b/arch/arm/cpu/armv7/mx5/clock.c @@ -4,23 +4,7 @@ * * (C) Copyright 2009 Freescale Semiconductor, Inc. * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA + * SPDX-License-Identifier: GPL-2.0+ */ #include @@ -36,7 +20,9 @@ enum pll_clocks { PLL1_CLOCK = 0, PLL2_CLOCK, PLL3_CLOCK, +#ifdef CONFIG_MX53 PLL4_CLOCK, +#endif PLL_CLOCKS, }; @@ -69,7 +55,7 @@ struct fixed_pll_mfd { }; const struct fixed_pll_mfd fixed_mfd[] = { - {CONFIG_SYS_MX5_HCLK, 24 * 16}, + {MXC_HCLK, 24 * 16}, }; struct pll_param { @@ -89,75 +75,85 @@ struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; void set_usboh3_clk(void) { - unsigned int reg; - - reg = readl(&mxc_ccm->cscmr1) & - ~MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK; - reg |= 1 << MXC_CCM_CSCMR1_USBOH3_CLK_SEL_OFFSET; - writel(reg, &mxc_ccm->cscmr1); + clrsetbits_le32(&mxc_ccm->cscmr1, + MXC_CCM_CSCMR1_USBOH3_CLK_SEL_MASK, + MXC_CCM_CSCMR1_USBOH3_CLK_SEL(1)); + clrsetbits_le32(&mxc_ccm->cscdr1, + MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK | + MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK, + MXC_CCM_CSCDR1_USBOH3_CLK_PRED(4) | + MXC_CCM_CSCDR1_USBOH3_CLK_PODF(1)); +} - reg = readl(&mxc_ccm->cscdr1); - reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PODF_MASK; - reg &= ~MXC_CCM_CSCDR1_USBOH3_CLK_PRED_MASK; - reg |= 4 << MXC_CCM_CSCDR1_USBOH3_CLK_PRED_OFFSET; - reg |= 1 << MXC_CCM_CSCDR1_USBOH3_CLK_PODF_OFFSET; +void enable_usboh3_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - writel(reg, &mxc_ccm->cscdr1); + clrsetbits_le32(&mxc_ccm->CCGR2, + MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR2_USBOH3_60M(cg)); } -void enable_usboh3_clk(unsigned char enable) +#ifdef CONFIG_SYS_I2C_MXC +/* i2c_num can be from 0, to 1 for i.MX51 and 2 for i.MX53 */ +int enable_i2c_clk(unsigned char enable, unsigned i2c_num) { - unsigned int reg; + u32 mask; - reg = readl(&mxc_ccm->CCGR2); +#if defined(CONFIG_MX51) + if (i2c_num > 1) +#elif defined(CONFIG_MX53) + if (i2c_num > 2) +#endif + return -EINVAL; + mask = MXC_CCM_CCGR_CG_MASK << + (MXC_CCM_CCGR1_I2C1_OFFSET + (i2c_num << 1)); if (enable) - reg |= 1 << MXC_CCM_CCGR2_CG14_OFFSET; + setbits_le32(&mxc_ccm->CCGR1, mask); else - reg &= ~(1 << MXC_CCM_CCGR2_CG14_OFFSET); - writel(reg, &mxc_ccm->CCGR2); + clrbits_le32(&mxc_ccm->CCGR1, mask); + return 0; } +#endif -void set_usb_phy1_clk(void) +void set_usb_phy_clk(void) { - unsigned int reg; - - reg = readl(&mxc_ccm->cscmr1); - reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; - writel(reg, &mxc_ccm->cscmr1); + clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL); } -void enable_usb_phy1_clk(unsigned char enable) +#if defined(CONFIG_MX51) +void enable_usb_phy1_clk(bool enable) { - unsigned int reg; + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - reg = readl(&mxc_ccm->CCGR4); - if (enable) - reg |= 1 << MXC_CCM_CCGR4_CG5_OFFSET; - else - reg &= ~(1 << MXC_CCM_CCGR4_CG5_OFFSET); - writel(reg, &mxc_ccm->CCGR4); + clrsetbits_le32(&mxc_ccm->CCGR2, + MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR2_USB_PHY(cg)); } -void set_usb_phy2_clk(void) +void enable_usb_phy2_clk(bool enable) { - unsigned int reg; + /* i.MX51 has a single USB PHY clock, so do nothing here. */ +} +#elif defined(CONFIG_MX53) +void enable_usb_phy1_clk(bool enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - reg = readl(&mxc_ccm->cscmr1); - reg &= ~MXC_CCM_CSCMR1_USB_PHY_CLK_SEL; - writel(reg, &mxc_ccm->cscmr1); + clrsetbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_USB_PHY1(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR4_USB_PHY1(cg)); } -void enable_usb_phy2_clk(unsigned char enable) +void enable_usb_phy2_clk(bool enable) { - unsigned int reg; + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - reg = readl(&mxc_ccm->CCGR4); - if (enable) - reg |= 1 << MXC_CCM_CCGR4_CG6_OFFSET; - else - reg &= ~(1 << MXC_CCM_CCGR4_CG6_OFFSET); - writel(reg, &mxc_ccm->CCGR4); + clrsetbits_le32(&mxc_ccm->CCGR4, + MXC_CCM_CCGR4_USB_PHY2(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR4_USB_PHY2(cg)); } +#endif /* * Calculate the frequency of PLLn. @@ -171,19 +167,19 @@ static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) ctrl = readl(&pll->ctrl); if (ctrl & MXC_DPLLC_CTL_HFSM) { - mfn = __raw_readl(&pll->hfs_mfn); - mfd = __raw_readl(&pll->hfs_mfd); - op = __raw_readl(&pll->hfs_op); + mfn = readl(&pll->hfs_mfn); + mfd = readl(&pll->hfs_mfd); + op = readl(&pll->hfs_op); } else { - mfn = __raw_readl(&pll->mfn); - mfd = __raw_readl(&pll->mfd); - op = __raw_readl(&pll->op); + mfn = readl(&pll->mfn); + mfd = readl(&pll->mfd); + op = readl(&pll->op); } mfd &= MXC_DPLLC_MFD_MFD_MASK; mfn &= MXC_DPLLC_MFN_MFN_MASK; pdf = op & MXC_DPLLC_OP_PDF_MASK; - mfi = (op & MXC_DPLLC_OP_MFI_MASK) >> MXC_DPLLC_OP_MFI_OFFSET; + mfi = MXC_DPLLC_OP_MFI_RD(op); /* 21.2.3 */ if (mfi < 5) @@ -213,6 +209,44 @@ static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) return ret; } +#ifdef CONFIG_MX51 +/* + * This function returns the Frequency Pre-Multiplier clock. + */ +static u32 get_fpm(void) +{ + u32 mult; + u32 ccr = readl(&mxc_ccm->ccr); + + if (ccr & MXC_CCM_CCR_FPM_MULT) + mult = 1024; + else + mult = 512; + + return MXC_CLK32 * mult; +} +#endif + +/* + * This function returns the low power audio clock. + */ +static u32 get_lp_apm(void) +{ + u32 ret_val = 0; + u32 ccsr = readl(&mxc_ccm->ccsr); + + if (ccsr & MXC_CCM_CCSR_LP_APM) +#if defined(CONFIG_MX51) + ret_val = get_fpm(); +#elif defined(CONFIG_MX53) + ret_val = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); +#endif + else + ret_val = MXC_HCLK; + + return ret_val; +} + /* * Get mcu main rate */ @@ -220,9 +254,8 @@ u32 get_mcu_main_clk(void) { u32 reg, freq; - reg = (__raw_readl(&mxc_ccm->cacrr) & MXC_CCM_CACRR_ARM_PODF_MASK) >> - MXC_CCM_CACRR_ARM_PODF_OFFSET; - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + reg = MXC_CCM_CACRR_ARM_PODF_RD(readl(&mxc_ccm->cacrr)); + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); return freq / (reg + 1); } @@ -233,16 +266,17 @@ u32 get_periph_clk(void) { u32 reg; - reg = __raw_readl(&mxc_ccm->cbcdr); + reg = readl(&mxc_ccm->cbcdr); if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) - return decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK); - reg = __raw_readl(&mxc_ccm->cbcmr); - switch ((reg & MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> - MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { + return decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); + reg = readl(&mxc_ccm->cbcmr); + switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD(reg)) { case 0: - return decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + return decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); case 1: - return decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK); + return decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); + case 2: + return get_lp_apm(); default: return 0; } @@ -258,9 +292,8 @@ static u32 get_ipg_clk(void) freq = get_ahb_clk(); - reg = __raw_readl(&mxc_ccm->cbcdr); - div = ((reg & MXC_CCM_CBCDR_IPG_PODF_MASK) >> - MXC_CCM_CBCDR_IPG_PODF_OFFSET) + 1; + reg = readl(&mxc_ccm->cbcdr); + div = MXC_CCM_CBCDR_IPG_PODF_RD(reg) + 1; return freq / div; } @@ -270,74 +303,62 @@ static u32 get_ipg_clk(void) */ static u32 get_ipg_per_clk(void) { - u32 pred1, pred2, podf; + u32 freq, pred1, pred2, podf; - if (__raw_readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) + if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) return get_ipg_clk(); - /* Fixme: not handle what about lpm*/ - podf = __raw_readl(&mxc_ccm->cbcdr); - pred1 = (podf & MXC_CCM_CBCDR_PERCLK_PRED1_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED1_OFFSET; - pred2 = (podf & MXC_CCM_CBCDR_PERCLK_PRED2_MASK) >> - MXC_CCM_CBCDR_PERCLK_PRED2_OFFSET; - podf = (podf & MXC_CCM_CBCDR_PERCLK_PODF_MASK) >> - MXC_CCM_CBCDR_PERCLK_PODF_OFFSET; - return get_periph_clk() / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); + if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_LP_APM_CLK_SEL) + freq = get_lp_apm(); + else + freq = get_periph_clk(); + podf = readl(&mxc_ccm->cbcdr); + pred1 = MXC_CCM_CBCDR_PERCLK_PRED1_RD(podf); + pred2 = MXC_CCM_CBCDR_PERCLK_PRED2_RD(podf); + podf = MXC_CCM_CBCDR_PERCLK_PODF_RD(podf); + return freq / ((pred1 + 1) * (pred2 + 1) * (podf + 1)); } -/* - * Get the rate of uart clk. - */ -static u32 get_uart_clk(void) +/* Get the output clock rate of a standard PLL MUX for peripherals. */ +static u32 get_standard_pll_sel_clk(u32 clk_sel) { - unsigned int freq, reg, pred, podf; + u32 freq = 0; - reg = __raw_readl(&mxc_ccm->cscmr1); - switch ((reg & MXC_CCM_CSCMR1_UART_CLK_SEL_MASK) >> - MXC_CCM_CSCMR1_UART_CLK_SEL_OFFSET) { - case 0x0: - freq = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_SYS_MX5_HCLK); + switch (clk_sel & 0x3) { + case 0: + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); break; - case 0x1: - freq = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_SYS_MX5_HCLK); + case 1: + freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); break; - case 0x2: - freq = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_SYS_MX5_HCLK); + case 2: + freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); + break; + case 3: + freq = get_lp_apm(); break; - default: - return 66500000; } - reg = __raw_readl(&mxc_ccm->cscdr1); - - pred = (reg & MXC_CCM_CSCDR1_UART_CLK_PRED_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PRED_OFFSET; - - podf = (reg & MXC_CCM_CSCDR1_UART_CLK_PODF_MASK) >> - MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; - freq /= (pred + 1) * (podf + 1); - return freq; } /* - * This function returns the low power audio clock. + * Get the rate of uart clk. */ -static u32 get_lp_apm(void) +static u32 get_uart_clk(void) { - u32 ret_val = 0; - u32 ccsr = __raw_readl(&mxc_ccm->ccsr); + unsigned int clk_sel, freq, reg, pred, podf; - if (((ccsr >> 9) & 1) == 0) - ret_val = CONFIG_SYS_MX5_HCLK; - else - ret_val = ((32768 * 1024)); + reg = readl(&mxc_ccm->cscmr1); + clk_sel = MXC_CCM_CSCMR1_UART_CLK_SEL_RD(reg); + freq = get_standard_pll_sel_clk(clk_sel); - return ret_val; + reg = readl(&mxc_ccm->cscdr1); + pred = MXC_CCM_CSCDR1_UART_CLK_PRED_RD(reg); + podf = MXC_CCM_CSCDR1_UART_CLK_PODF_RD(reg); + freq /= (pred + 1) * (podf + 1); + + return freq; } /* @@ -345,65 +366,77 @@ static u32 get_lp_apm(void) */ static u32 imx_get_cspiclk(void) { - u32 ret_val = 0, pdf, pre_pdf, clk_sel; - u32 cscmr1 = __raw_readl(&mxc_ccm->cscmr1); - u32 cscdr2 = __raw_readl(&mxc_ccm->cscdr2); + u32 ret_val = 0, pdf, pre_pdf, clk_sel, freq; + u32 cscmr1 = readl(&mxc_ccm->cscmr1); + u32 cscdr2 = readl(&mxc_ccm->cscdr2); + + pre_pdf = MXC_CCM_CSCDR2_CSPI_CLK_PRED_RD(cscdr2); + pdf = MXC_CCM_CSCDR2_CSPI_CLK_PODF_RD(cscdr2); + clk_sel = MXC_CCM_CSCMR1_CSPI_CLK_SEL_RD(cscmr1); + freq = get_standard_pll_sel_clk(clk_sel); + ret_val = freq / ((pre_pdf + 1) * (pdf + 1)); + return ret_val; +} - pre_pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PRED_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PRED_OFFSET; - pdf = (cscdr2 & MXC_CCM_CSCDR2_CSPI_CLK_PODF_MASK) \ - >> MXC_CCM_CSCDR2_CSPI_CLK_PODF_OFFSET; - clk_sel = (cscmr1 & MXC_CCM_CSCMR1_CSPI_CLK_SEL_MASK) \ - >> MXC_CCM_CSCMR1_CSPI_CLK_SEL_OFFSET; +/* + * get esdhc clock rate. + */ +static u32 get_esdhc_clk(u32 port) +{ + u32 clk_sel = 0, pred = 0, podf = 0, freq = 0; + u32 cscmr1 = readl(&mxc_ccm->cscmr1); + u32 cscdr1 = readl(&mxc_ccm->cscdr1); - switch (clk_sel) { + switch (port) { case 0: - ret_val = decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_SYS_MX5_HCLK) / - ((pre_pdf + 1) * (pdf + 1)); + clk_sel = MXC_CCM_CSCMR1_ESDHC1_MSHC1_CLK_SEL_RD(cscmr1); + pred = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PRED_RD(cscdr1); + podf = MXC_CCM_CSCDR1_ESDHC1_MSHC1_CLK_PODF_RD(cscdr1); break; case 1: - ret_val = decode_pll(mxc_plls[PLL2_CLOCK], - CONFIG_SYS_MX5_HCLK) / - ((pre_pdf + 1) * (pdf + 1)); + clk_sel = MXC_CCM_CSCMR1_ESDHC2_MSHC2_CLK_SEL_RD(cscmr1); + pred = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PRED_RD(cscdr1); + podf = MXC_CCM_CSCDR1_ESDHC2_MSHC2_CLK_PODF_RD(cscdr1); break; case 2: - ret_val = decode_pll(mxc_plls[PLL3_CLOCK], - CONFIG_SYS_MX5_HCLK) / - ((pre_pdf + 1) * (pdf + 1)); - break; + if (cscmr1 & MXC_CCM_CSCMR1_ESDHC3_CLK_SEL) + return get_esdhc_clk(1); + else + return get_esdhc_clk(0); + case 3: + if (cscmr1 & MXC_CCM_CSCMR1_ESDHC4_CLK_SEL) + return get_esdhc_clk(1); + else + return get_esdhc_clk(0); default: - ret_val = get_lp_apm() / ((pre_pdf + 1) * (pdf + 1)); break; } - return ret_val; + freq = get_standard_pll_sel_clk(clk_sel) / ((pred + 1) * (podf + 1)); + return freq; } static u32 get_axi_a_clk(void) { - u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr); - u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_A_PODF_MASK) \ - >> MXC_CCM_CBCDR_AXI_A_PODF_OFFSET; + u32 cbcdr = readl(&mxc_ccm->cbcdr); + u32 pdf = MXC_CCM_CBCDR_AXI_A_PODF_RD(cbcdr); return get_periph_clk() / (pdf + 1); } static u32 get_axi_b_clk(void) { - u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr); - u32 pdf = (cbcdr & MXC_CCM_CBCDR_AXI_B_PODF_MASK) \ - >> MXC_CCM_CBCDR_AXI_B_PODF_OFFSET; + u32 cbcdr = readl(&mxc_ccm->cbcdr); + u32 pdf = MXC_CCM_CBCDR_AXI_B_PODF_RD(cbcdr); return get_periph_clk() / (pdf + 1); } static u32 get_emi_slow_clk(void) { - u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr); + u32 cbcdr = readl(&mxc_ccm->cbcdr); u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL; - u32 pdf = (cbcdr & MXC_CCM_CBCDR_EMI_PODF_MASK) \ - >> MXC_CCM_CBCDR_EMI_PODF_OFFSET; + u32 pdf = MXC_CCM_CBCDR_EMI_PODF_RD(cbcdr); if (emi_clk_sel) return get_ahb_clk() / (pdf + 1); @@ -414,16 +447,14 @@ static u32 get_emi_slow_clk(void) static u32 get_ddr_clk(void) { u32 ret_val = 0; - u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr); - u32 ddr_clk_sel = (cbcmr & MXC_CCM_CBCMR_DDR_CLK_SEL_MASK) \ - >> MXC_CCM_CBCMR_DDR_CLK_SEL_OFFSET; + u32 cbcmr = readl(&mxc_ccm->cbcmr); + u32 ddr_clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); #ifdef CONFIG_MX51 - u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr); + u32 cbcdr = readl(&mxc_ccm->cbcdr); if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) { - u32 ddr_clk_podf = (cbcdr & MXC_CCM_CBCDR_DDR_PODF_MASK) >> \ - MXC_CCM_CBCDR_DDR_PODF_OFFSET; + u32 ddr_clk_podf = MXC_CCM_CBCDR_DDR_PODF_RD(cbcdr); - ret_val = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); ret_val /= ddr_clk_podf + 1; return ret_val; @@ -462,14 +493,22 @@ unsigned int mxc_get_clock(enum mxc_clock clk) case MXC_IPG_CLK: return get_ipg_clk(); case MXC_IPG_PERCLK: + case MXC_I2C_CLK: return get_ipg_per_clk(); case MXC_UART_CLK: return get_uart_clk(); case MXC_CSPI_CLK: return imx_get_cspiclk(); + case MXC_ESDHC_CLK: + return get_esdhc_clk(0); + case MXC_ESDHC2_CLK: + return get_esdhc_clk(1); + case MXC_ESDHC3_CLK: + return get_esdhc_clk(2); + case MXC_ESDHC4_CLK: + return get_esdhc_clk(3); case MXC_FEC_CLK: - return decode_pll(mxc_plls[PLL1_CLOCK], - CONFIG_SYS_MX5_HCLK); + return get_ipg_clk(); case MXC_SATA_CLK: return get_ahb_clk(); case MXC_DDR_CLK: @@ -485,10 +524,9 @@ u32 imx_get_uartclk(void) return get_uart_clk(); } - u32 imx_get_fecclk(void) { - return mxc_get_clock(MXC_IPG_CLK); + return get_ipg_clk(); } static int gcd(int m, int n) @@ -590,63 +628,73 @@ static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll) #define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \ { \ - __raw_writel(0x1232, &pll->ctrl); \ - __raw_writel(0x2, &pll->config); \ - __raw_writel((((pd) - 1) << 0) | ((fi) << 4), \ - &pll->op); \ - __raw_writel(fn, &(pll->mfn)); \ - __raw_writel((fd) - 1, &pll->mfd); \ - __raw_writel((((pd) - 1) << 0) | ((fi) << 4), \ - &pll->hfs_op); \ - __raw_writel(fn, &pll->hfs_mfn); \ - __raw_writel((fd) - 1, &pll->hfs_mfd); \ - __raw_writel(0x1232, &pll->ctrl); \ - while (!__raw_readl(&pll->ctrl) & 0x1) \ + writel(0x1232, &pll->ctrl); \ + writel(0x2, &pll->config); \ + writel((((pd) - 1) << 0) | ((fi) << 4), \ + &pll->op); \ + writel(fn, &(pll->mfn)); \ + writel((fd) - 1, &pll->mfd); \ + writel((((pd) - 1) << 0) | ((fi) << 4), \ + &pll->hfs_op); \ + writel(fn, &pll->hfs_mfn); \ + writel((fd) - 1, &pll->hfs_mfd); \ + writel(0x1232, &pll->ctrl); \ + while (!readl(&pll->ctrl) & 0x1) \ ;\ } static int config_pll_clk(enum pll_clocks index, struct pll_param *pll_param) { - u32 ccsr = __raw_readl(&mxc_ccm->ccsr); + u32 ccsr = readl(&mxc_ccm->ccsr); struct mxc_pll_reg *pll = mxc_plls[index]; switch (index) { case PLL1_CLOCK: /* Switch ARM to PLL2 clock */ - __raw_writel(ccsr | 0x4, &mxc_ccm->ccsr); + writel(ccsr | MXC_CCM_CCSR_PLL1_SW_CLK_SEL, + &mxc_ccm->ccsr); CHANGE_PLL_SETTINGS(pll, pll_param->pd, pll_param->mfi, pll_param->mfn, pll_param->mfd); /* Switch back */ - __raw_writel(ccsr & ~0x4, &mxc_ccm->ccsr); + writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL, + &mxc_ccm->ccsr); break; case PLL2_CLOCK: /* Switch to pll2 bypass clock */ - __raw_writel(ccsr | 0x2, &mxc_ccm->ccsr); + writel(ccsr | MXC_CCM_CCSR_PLL2_SW_CLK_SEL, + &mxc_ccm->ccsr); CHANGE_PLL_SETTINGS(pll, pll_param->pd, pll_param->mfi, pll_param->mfn, pll_param->mfd); /* Switch back */ - __raw_writel(ccsr & ~0x2, &mxc_ccm->ccsr); + writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL, + &mxc_ccm->ccsr); break; case PLL3_CLOCK: /* Switch to pll3 bypass clock */ - __raw_writel(ccsr | 0x1, &mxc_ccm->ccsr); + writel(ccsr | MXC_CCM_CCSR_PLL3_SW_CLK_SEL, + &mxc_ccm->ccsr); CHANGE_PLL_SETTINGS(pll, pll_param->pd, pll_param->mfi, pll_param->mfn, pll_param->mfd); /* Switch back */ - __raw_writel(ccsr & ~0x1, &mxc_ccm->ccsr); + writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL, + &mxc_ccm->ccsr); break; +#ifdef CONFIG_MX53 case PLL4_CLOCK: /* Switch to pll4 bypass clock */ - __raw_writel(ccsr | 0x20, &mxc_ccm->ccsr); + writel(ccsr | MXC_CCM_CCSR_PLL4_SW_CLK_SEL, + &mxc_ccm->ccsr); CHANGE_PLL_SETTINGS(pll, pll_param->pd, pll_param->mfi, pll_param->mfn, pll_param->mfd); /* Switch back */ - __raw_writel(ccsr & ~0x20, &mxc_ccm->ccsr); + writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL, + &mxc_ccm->ccsr); break; +#endif default: return -EINVAL; } @@ -674,25 +722,45 @@ static int config_core_clk(u32 ref, u32 freq) static int config_nfc_clk(u32 nfc_clk) { - u32 reg; u32 parent_rate = get_emi_slow_clk(); - u32 div = parent_rate / nfc_clk; + u32 div; - if (nfc_clk <= 0) + if (nfc_clk == 0) return -EINVAL; + div = parent_rate / nfc_clk; if (div == 0) div++; if (parent_rate / div > NFC_CLK_MAX) div++; - reg = __raw_readl(&mxc_ccm->cbcdr); - reg &= ~MXC_CCM_CBCDR_NFC_PODF_MASK; - reg |= (div - 1) << MXC_CCM_CBCDR_NFC_PODF_OFFSET; - __raw_writel(reg, &mxc_ccm->cbcdr); - while (__raw_readl(&mxc_ccm->cdhipr) != 0) + clrsetbits_le32(&mxc_ccm->cbcdr, + MXC_CCM_CBCDR_NFC_PODF_MASK, + MXC_CCM_CBCDR_NFC_PODF(div - 1)); + while (readl(&mxc_ccm->cdhipr) != 0) ; return 0; } +void enable_nfc_clk(unsigned char enable) +{ + unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; + + clrsetbits_le32(&mxc_ccm->CCGR5, + MXC_CCM_CCGR5_EMI_ENFC(MXC_CCM_CCGR_CG_MASK), + MXC_CCM_CCGR5_EMI_ENFC(cg)); +} + +#ifdef CONFIG_FSL_IIM +void enable_efuse_prog_supply(bool enable) +{ + if (enable) + setbits_le32(&mxc_ccm->cgpr, + MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); + else + clrbits_le32(&mxc_ccm->cgpr, + MXC_CCM_CGPR_EFUSE_PROG_SUPPLY_GATE); +} +#endif + /* Config main_bus_clock for periphs */ static int config_periph_clk(u32 ref, u32 freq) { @@ -701,16 +769,15 @@ static int config_periph_clk(u32 ref, u32 freq) memset(&pll_param, 0, sizeof(struct pll_param)); - if (__raw_readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { + if (readl(&mxc_ccm->cbcdr) & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { ret = calc_pll_params(ref, freq, &pll_param); if (ret != 0) { printf("Error:Can't find pll parameters: %d\n", ret); return ret; } - switch ((__raw_readl(&mxc_ccm->cbcmr) & \ - MXC_CCM_CBCMR_PERIPH_CLK_SEL_MASK) >> \ - MXC_CCM_CBCMR_PERIPH_CLK_SEL_OFFSET) { + switch (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD( + readl(&mxc_ccm->cbcmr))) { case 0: return config_pll_clk(PLL1_CLOCK, &pll_param); break; @@ -729,8 +796,7 @@ static int config_ddr_clk(u32 emi_clk) { u32 clk_src; s32 shift = 0, clk_sel, div = 1; - u32 cbcmr = __raw_readl(&mxc_ccm->cbcmr); - u32 cbcdr = __raw_readl(&mxc_ccm->cbcdr); + u32 cbcmr = readl(&mxc_ccm->cbcmr); if (emi_clk > MAX_DDR_CLK) { printf("Warning:DDR clock should not exceed %d MHz\n", @@ -740,7 +806,7 @@ static int config_ddr_clk(u32 emi_clk) clk_src = get_periph_clk(); /* Find DDR clock input */ - clk_sel = (cbcmr >> 10) & 0x3; + clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); switch (clk_sel) { case 0: shift = 16; @@ -765,12 +831,10 @@ static int config_ddr_clk(u32 emi_clk) if (div > 8) div = 8; - cbcdr = cbcdr & ~(0x7 << shift); - cbcdr |= ((div - 1) << shift); - __raw_writel(cbcdr, &mxc_ccm->cbcdr); - while (__raw_readl(&mxc_ccm->cdhipr) != 0) + clrsetbits_le32(&mxc_ccm->cbcdr, 0x7 << shift, (div - 1) << shift); + while (readl(&mxc_ccm->cdhipr) != 0) ; - __raw_writel(0x0, &mxc_ccm->ccdr); + writel(0x0, &mxc_ccm->ccdr); return 0; } @@ -841,9 +905,9 @@ void mxc_set_sata_internal_clock(void) u32 *tmp_base = (u32 *)(IIM_BASE_ADDR + 0x180c); - set_usb_phy1_clk(); + set_usb_phy_clk(); - writel((readl(tmp_base) & (~0x6)) | 0x4, tmp_base); + clrsetbits_le32(tmp_base, 0x6, 0x4); } #endif @@ -854,14 +918,14 @@ int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { u32 freq; - freq = decode_pll(mxc_plls[PLL1_CLOCK], CONFIG_SYS_MX5_HCLK); + freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); printf("PLL1 %8d MHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL2_CLOCK], CONFIG_SYS_MX5_HCLK); + freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); printf("PLL2 %8d MHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL3_CLOCK], CONFIG_SYS_MX5_HCLK); + freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); printf("PLL3 %8d MHz\n", freq / 1000000); #ifdef CONFIG_MX53 - freq = decode_pll(mxc_plls[PLL4_CLOCK], CONFIG_SYS_MX5_HCLK); + freq = decode_pll(mxc_plls[PLL4_CLOCK], MXC_HCLK); printf("PLL4 %8d MHz\n", freq / 1000000); #endif @@ -870,7 +934,9 @@ int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); - +#ifdef CONFIG_MXC_SPI + printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); +#endif return 0; }