diff options
author | Stefano Babic <sbabic@denx.de> | 2017-06-29 10:16:06 +0200 |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2017-07-12 10:17:44 +0200 |
commit | 552a848e4f75e224515269a84a1155c84b762bc7 (patch) | |
tree | abef72c4452bf6934525563520690119bb8d1301 /arch/arm/cpu/armv7 | |
parent | f34ccce50a1805a6fdb2d1604ec4e40d79302455 (diff) |
imx: reorganize IMX code as other SOCs
Change is consistent with other SOCs and it is in preparation
for adding SOMs. SOC's related files are moved from cpu/ to
mach-imx/<SOC>.
This change is also coherent with the structure in kernel.
Signed-off-by: Stefano Babic <sbabic@denx.de>
CC: Fabio Estevam <fabio.estevam@nxp.com>
CC: Akshay Bhat <akshaybhat@timesys.com>
CC: Ken Lin <Ken.Lin@advantech.com.tw>
CC: Marek Vasut <marek.vasut@gmail.com>
CC: Heiko Schocher <hs@denx.de>
CC: "Sébastien Szymanski" <sebastien.szymanski@armadeus.com>
CC: Christian Gmeiner <christian.gmeiner@gmail.com>
CC: Stefan Roese <sr@denx.de>
CC: Patrick Bruenn <p.bruenn@beckhoff.com>
CC: Troy Kisky <troy.kisky@boundarydevices.com>
CC: Nikita Kiryanov <nikita@compulab.co.il>
CC: Otavio Salvador <otavio@ossystems.com.br>
CC: "Eric Bénard" <eric@eukrea.com>
CC: Jagan Teki <jagan@amarulasolutions.com>
CC: Ye Li <ye.li@nxp.com>
CC: Peng Fan <peng.fan@nxp.com>
CC: Adrian Alonso <adrian.alonso@nxp.com>
CC: Alison Wang <b18965@freescale.com>
CC: Tim Harvey <tharvey@gateworks.com>
CC: Martin Donnelly <martin.donnelly@ge.com>
CC: Marcin Niestroj <m.niestroj@grinn-global.com>
CC: Lukasz Majewski <lukma@denx.de>
CC: Adam Ford <aford173@gmail.com>
CC: "Albert ARIBAUD (3ADEV)" <albert.aribaud@3adev.fr>
CC: Boris Brezillon <boris.brezillon@free-electrons.com>
CC: Soeren Moch <smoch@web.de>
CC: Richard Hu <richard.hu@technexion.com>
CC: Wig Cheng <wig.cheng@technexion.com>
CC: Vanessa Maegima <vanessa.maegima@nxp.com>
CC: Max Krummenacher <max.krummenacher@toradex.com>
CC: Stefan Agner <stefan.agner@toradex.com>
CC: Markus Niebel <Markus.Niebel@tq-group.com>
CC: Breno Lima <breno.lima@nxp.com>
CC: Francesco Montefoschi <francesco.montefoschi@udoo.org>
CC: Jaehoon Chung <jh80.chung@samsung.com>
CC: Scott Wood <oss@buserror.net>
CC: Joe Hershberger <joe.hershberger@ni.com>
CC: Anatolij Gustschin <agust@denx.de>
CC: Simon Glass <sjg@chromium.org>
CC: "Andrew F. Davis" <afd@ti.com>
CC: "Łukasz Majewski" <l.majewski@samsung.com>
CC: Patrice Chotard <patrice.chotard@st.com>
CC: Nobuhiro Iwamatsu <iwamatsu@nigauri.org>
CC: Hans de Goede <hdegoede@redhat.com>
CC: Masahiro Yamada <yamada.masahiro@socionext.com>
CC: Stephen Warren <swarren@nvidia.com>
CC: Andre Przywara <andre.przywara@arm.com>
CC: "Álvaro Fernández Rojas" <noltari@gmail.com>
CC: York Sun <york.sun@nxp.com>
CC: Xiaoliang Yang <xiaoliang.yang@nxp.com>
CC: Chen-Yu Tsai <wens@csie.org>
CC: George McCollister <george.mccollister@gmail.com>
CC: Sven Ebenfeld <sven.ebenfeld@gmail.com>
CC: Filip Brozovic <fbrozovic@gmail.com>
CC: Petr Kulhavy <brain@jikos.cz>
CC: Eric Nelson <eric@nelint.com>
CC: Bai Ping <ping.bai@nxp.com>
CC: Anson Huang <Anson.Huang@nxp.com>
CC: Sanchayan Maity <maitysanchayan@gmail.com>
CC: Lokesh Vutla <lokeshvutla@ti.com>
CC: Patrick Delaunay <patrick.delaunay@st.com>
CC: Gary Bisson <gary.bisson@boundarydevices.com>
CC: Alexander Graf <agraf@suse.de>
CC: u-boot@lists.denx.de
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Reviewed-by: Christian Gmeiner <christian.gmeiner@gmail.com>
Diffstat (limited to 'arch/arm/cpu/armv7')
29 files changed, 1 insertions, 10983 deletions
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 45dd3caec6..b14ee54519 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -33,10 +33,6 @@ obj-$(if $(filter bcm281xx,$(SOC)),y) += bcm281xx/ obj-$(if $(filter bcmcygnus,$(SOC)),y) += bcmcygnus/ obj-$(if $(filter bcmnsp,$(SOC)),y) += bcmnsp/ obj-$(if $(filter ls102xa,$(SOC)),y) += ls102xa/ -obj-$(if $(filter mx5,$(SOC)),y) += mx5/ -obj-$(CONFIG_MX6) += mx6/ -obj-$(CONFIG_MX7) += mx7/ -obj-$(CONFIG_ARCH_MX7ULP) += mx7ulp/ obj-$(CONFIG_RMOBILE) += rmobile/ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ diff --git a/arch/arm/cpu/armv7/mx5/Kconfig b/arch/arm/cpu/armv7/mx5/Kconfig deleted file mode 100644 index ef37c351d0..0000000000 --- a/arch/arm/cpu/armv7/mx5/Kconfig +++ /dev/null @@ -1,76 +0,0 @@ -if ARCH_MX5 - -config MX5 - bool - default y - -config MX51 - bool - -config MX53 - bool - -choice - prompt "MX5 board select" - optional - -config TARGET_M53EVK - bool "Support m53evk" - select MX53 - select SUPPORT_SPL - -config TARGET_MX51EVK - bool "Support mx51evk" - select BOARD_LATE_INIT - select MX51 - -config TARGET_MX53ARD - bool "Support mx53ard" - select MX53 - -config TARGET_MX53CX9020 - bool "Support CX9020" - select BOARD_LATE_INIT - select MX53 - select DM - select DM_SERIAL - -config TARGET_MX53EVK - bool "Support mx53evk" - select BOARD_LATE_INIT - select MX53 - -config TARGET_MX53LOCO - bool "Support mx53loco" - select BOARD_LATE_INIT - select MX53 - -config TARGET_MX53SMD - bool "Support mx53smd" - select MX53 - -config TARGET_TS4800 - bool "Support TS4800" - select MX51 - select SYS_FSL_ERRATUM_ESDHC_A001 - -config TARGET_USBARMORY - bool "Support USB armory" - select MX53 - -endchoice - -config SYS_SOC - default "mx5" - -source "board/aries/m53evk/Kconfig" -source "board/beckhoff/mx53cx9020/Kconfig" -source "board/freescale/mx51evk/Kconfig" -source "board/freescale/mx53ard/Kconfig" -source "board/freescale/mx53evk/Kconfig" -source "board/freescale/mx53loco/Kconfig" -source "board/freescale/mx53smd/Kconfig" -source "board/inversepath/usbarmory/Kconfig" -source "board/technologic/ts4800/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/mx5/Makefile b/arch/arm/cpu/armv7/mx5/Makefile deleted file mode 100644 index d021842f68..0000000000 --- a/arch/arm/cpu/armv7/mx5/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2009 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := soc.o clock.o -obj-y += lowlevel_init.o diff --git a/arch/arm/cpu/armv7/mx5/clock.c b/arch/arm/cpu/armv7/mx5/clock.c deleted file mode 100644 index 610098c175..0000000000 --- a/arch/arm/cpu/armv7/mx5/clock.c +++ /dev/null @@ -1,949 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <linux/errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/clock.h> -#include <div64.h> -#include <asm/arch/sys_proto.h> - -enum pll_clocks { - PLL1_CLOCK = 0, - PLL2_CLOCK, - PLL3_CLOCK, -#ifdef CONFIG_MX53 - PLL4_CLOCK, -#endif - PLL_CLOCKS, -}; - -struct mxc_pll_reg *mxc_plls[PLL_CLOCKS] = { - [PLL1_CLOCK] = (struct mxc_pll_reg *)PLL1_BASE_ADDR, - [PLL2_CLOCK] = (struct mxc_pll_reg *)PLL2_BASE_ADDR, - [PLL3_CLOCK] = (struct mxc_pll_reg *)PLL3_BASE_ADDR, -#ifdef CONFIG_MX53 - [PLL4_CLOCK] = (struct mxc_pll_reg *)PLL4_BASE_ADDR, -#endif -}; - -#define AHB_CLK_ROOT 133333333 -#define SZ_DEC_1M 1000000 -#define PLL_PD_MAX 16 /* Actual pd+1 */ -#define PLL_MFI_MAX 15 -#define PLL_MFI_MIN 5 -#define ARM_DIV_MAX 8 -#define IPG_DIV_MAX 4 -#define AHB_DIV_MAX 8 -#define EMI_DIV_MAX 8 -#define NFC_DIV_MAX 8 - -#define MX5_CBCMR 0x00015154 -#define MX5_CBCDR 0x02888945 - -struct fixed_pll_mfd { - u32 ref_clk_hz; - u32 mfd; -}; - -const struct fixed_pll_mfd fixed_mfd[] = { - {MXC_HCLK, 24 * 16}, -}; - -struct pll_param { - u32 pd; - u32 mfi; - u32 mfn; - u32 mfd; -}; - -#define PLL_FREQ_MAX(ref_clk) (4 * (ref_clk) * PLL_MFI_MAX) -#define PLL_FREQ_MIN(ref_clk) \ - ((2 * (ref_clk) * (PLL_MFI_MIN - 1)) / PLL_PD_MAX) -#define MAX_DDR_CLK 420000000 -#define NFC_CLK_MAX 34000000 - -struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)MXC_CCM_BASE; - -void set_usboh3_clk(void) -{ - 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)); -} - -void enable_usboh3_clk(bool enable) -{ - unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - - clrsetbits_le32(&mxc_ccm->CCGR2, - MXC_CCM_CCGR2_USBOH3_60M(MXC_CCM_CCGR_CG_MASK), - MXC_CCM_CCGR2_USBOH3_60M(cg)); -} - -#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) -{ - u32 mask; - -#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) - setbits_le32(&mxc_ccm->CCGR1, mask); - else - clrbits_le32(&mxc_ccm->CCGR1, mask); - return 0; -} -#endif - -void set_usb_phy_clk(void) -{ - clrbits_le32(&mxc_ccm->cscmr1, MXC_CCM_CSCMR1_USB_PHY_CLK_SEL); -} - -#if defined(CONFIG_MX51) -void enable_usb_phy1_clk(bool enable) -{ - unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - - clrsetbits_le32(&mxc_ccm->CCGR2, - MXC_CCM_CCGR2_USB_PHY(MXC_CCM_CCGR_CG_MASK), - MXC_CCM_CCGR2_USB_PHY(cg)); -} - -void enable_usb_phy2_clk(bool enable) -{ - /* 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; - - 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(bool enable) -{ - unsigned int cg = enable ? MXC_CCM_CCGR_CG_ON : MXC_CCM_CCGR_CG_OFF; - - 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. - */ -static uint32_t decode_pll(struct mxc_pll_reg *pll, uint32_t infreq) -{ - uint32_t ctrl, op, mfd, mfn, mfi, pdf, ret; - uint64_t refclk, temp; - int32_t mfn_abs; - - ctrl = readl(&pll->ctrl); - - if (ctrl & MXC_DPLLC_CTL_HFSM) { - mfn = readl(&pll->hfs_mfn); - mfd = readl(&pll->hfs_mfd); - op = readl(&pll->hfs_op); - } else { - 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 = MXC_DPLLC_OP_MFI_RD(op); - - /* 21.2.3 */ - if (mfi < 5) - mfi = 5; - - /* Sign extend */ - if (mfn >= 0x04000000) { - mfn |= 0xfc000000; - mfn_abs = -mfn; - } else - mfn_abs = mfn; - - refclk = infreq * 2; - if (ctrl & MXC_DPLLC_CTL_DPDCK0_2_EN) - refclk *= 2; - - do_div(refclk, pdf + 1); - temp = refclk * mfn_abs; - do_div(temp, mfd + 1); - ret = refclk * mfi; - - if ((int)mfn < 0) - ret -= temp; - else - ret += temp; - - 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 - */ -u32 get_mcu_main_clk(void) -{ - u32 reg, freq; - - reg = MXC_CCM_CACRR_ARM_PODF_RD(readl(&mxc_ccm->cacrr)); - freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); - return freq / (reg + 1); -} - -/* - * Get the rate of peripheral's root clock. - */ -u32 get_periph_clk(void) -{ - u32 reg; - - reg = readl(&mxc_ccm->cbcdr); - if (!(reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL)) - 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], MXC_HCLK); - case 1: - return decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); - case 2: - return get_lp_apm(); - default: - return 0; - } - /* NOTREACHED */ -} - -/* - * Get the rate of ipg clock. - */ -static u32 get_ipg_clk(void) -{ - uint32_t freq, reg, div; - - freq = get_ahb_clk(); - - reg = readl(&mxc_ccm->cbcdr); - div = MXC_CCM_CBCDR_IPG_PODF_RD(reg) + 1; - - return freq / div; -} - -/* - * Get the rate of ipg_per clock. - */ -static u32 get_ipg_per_clk(void) -{ - u32 freq, pred1, pred2, podf; - - if (readl(&mxc_ccm->cbcmr) & MXC_CCM_CBCMR_PERCLK_IPG_CLK_SEL) - return get_ipg_clk(); - - 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 output clock rate of a standard PLL MUX for peripherals. */ -static u32 get_standard_pll_sel_clk(u32 clk_sel) -{ - u32 freq = 0; - - switch (clk_sel & 0x3) { - case 0: - freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); - break; - case 1: - freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); - break; - case 2: - freq = decode_pll(mxc_plls[PLL3_CLOCK], MXC_HCLK); - break; - case 3: - freq = get_lp_apm(); - break; - } - - return freq; -} - -/* - * Get the rate of uart clk. - */ -static u32 get_uart_clk(void) -{ - unsigned int clk_sel, freq, reg, pred, podf; - - reg = readl(&mxc_ccm->cscmr1); - clk_sel = MXC_CCM_CSCMR1_UART_CLK_SEL_RD(reg); - freq = get_standard_pll_sel_clk(clk_sel); - - 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; -} - -/* - * get cspi clock rate. - */ -static u32 imx_get_cspiclk(void) -{ - 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; -} - -/* - * 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 (port) { - case 0: - 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: - 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: - 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: - break; - } - - freq = get_standard_pll_sel_clk(clk_sel) / ((pred + 1) * (podf + 1)); - return freq; -} - -static u32 get_axi_a_clk(void) -{ - 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 = 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 = readl(&mxc_ccm->cbcdr); - u32 emi_clk_sel = cbcdr & MXC_CCM_CBCDR_EMI_CLK_SEL; - u32 pdf = MXC_CCM_CBCDR_EMI_PODF_RD(cbcdr); - - if (emi_clk_sel) - return get_ahb_clk() / (pdf + 1); - - return get_periph_clk() / (pdf + 1); -} - -static u32 get_ddr_clk(void) -{ - u32 ret_val = 0; - u32 cbcmr = readl(&mxc_ccm->cbcmr); - u32 ddr_clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); -#ifdef CONFIG_MX51 - u32 cbcdr = readl(&mxc_ccm->cbcdr); - if (cbcdr & MXC_CCM_CBCDR_DDR_HIFREQ_SEL) { - u32 ddr_clk_podf = MXC_CCM_CBCDR_DDR_PODF_RD(cbcdr); - - ret_val = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); - ret_val /= ddr_clk_podf + 1; - - return ret_val; - } -#endif - switch (ddr_clk_sel) { - case 0: - ret_val = get_axi_a_clk(); - break; - case 1: - ret_val = get_axi_b_clk(); - break; - case 2: - ret_val = get_emi_slow_clk(); - break; - case 3: - ret_val = get_ahb_clk(); - break; - default: - break; - } - - return ret_val; -} - -/* - * The API of get mxc clocks. - */ -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return get_mcu_main_clk(); - case MXC_AHB_CLK: - return get_ahb_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 get_ipg_clk(); - case MXC_SATA_CLK: - return get_ahb_clk(); - case MXC_DDR_CLK: - return get_ddr_clk(); - default: - break; - } - return -EINVAL; -} - -u32 imx_get_uartclk(void) -{ - return get_uart_clk(); -} - -u32 imx_get_fecclk(void) -{ - return get_ipg_clk(); -} - -static int gcd(int m, int n) -{ - int t; - while (m > 0) { - if (n > m) { - t = m; - m = n; - n = t; - } /* swap */ - m -= n; - } - return n; -} - -/* - * This is to calculate various parameters based on reference clock and - * targeted clock based on the equation: - * t_clk = 2*ref_freq*(mfi + mfn/(mfd+1))/(pd+1) - * This calculation is based on a fixed MFD value for simplicity. - */ -static int calc_pll_params(u32 ref, u32 target, struct pll_param *pll) -{ - u64 pd, mfi = 1, mfn, mfd, t1; - u32 n_target = target; - u32 n_ref = ref, i; - - /* - * Make sure targeted freq is in the valid range. - * Otherwise the following calculation might be wrong!!! - */ - if (n_target < PLL_FREQ_MIN(ref) || - n_target > PLL_FREQ_MAX(ref)) { - printf("Targeted peripheral clock should be" - "within [%d - %d]\n", - PLL_FREQ_MIN(ref) / SZ_DEC_1M, - PLL_FREQ_MAX(ref) / SZ_DEC_1M); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(fixed_mfd); i++) { - if (fixed_mfd[i].ref_clk_hz == ref) { - mfd = fixed_mfd[i].mfd; - break; - } - } - - if (i == ARRAY_SIZE(fixed_mfd)) - return -EINVAL; - - /* Use n_target and n_ref to avoid overflow */ - for (pd = 1; pd <= PLL_PD_MAX; pd++) { - t1 = n_target * pd; - do_div(t1, (4 * n_ref)); - mfi = t1; - if (mfi > PLL_MFI_MAX) - return -EINVAL; - else if (mfi < 5) - continue; - break; - } - /* - * Now got pd and mfi already - * - * mfn = (((n_target * pd) / 4 - n_ref * mfi) * mfd) / n_ref; - */ - t1 = n_target * pd; - do_div(t1, 4); - t1 -= n_ref * mfi; - t1 *= mfd; - do_div(t1, n_ref); - mfn = t1; - debug("ref=%d, target=%d, pd=%d," "mfi=%d,mfn=%d, mfd=%d\n", - ref, n_target, (u32)pd, (u32)mfi, (u32)mfn, (u32)mfd); - i = 1; - if (mfn != 0) - i = gcd(mfd, mfn); - pll->pd = (u32)pd; - pll->mfi = (u32)mfi; - do_div(mfn, i); - pll->mfn = (u32)mfn; - do_div(mfd, i); - pll->mfd = (u32)mfd; - - return 0; -} - -#define calc_div(tgt_clk, src_clk, limit) ({ \ - u32 v = 0; \ - if (((src_clk) % (tgt_clk)) <= 100) \ - v = (src_clk) / (tgt_clk); \ - else \ - v = ((src_clk) / (tgt_clk)) + 1;\ - if (v > limit) \ - v = limit; \ - (v - 1); \ - }) - -#define CHANGE_PLL_SETTINGS(pll, pd, fi, fn, fd) \ - { \ - 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 = readl(&mxc_ccm->ccsr); - struct mxc_pll_reg *pll = mxc_plls[index]; - - switch (index) { - case PLL1_CLOCK: - /* Switch ARM to PLL2 clock */ - 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 */ - writel(ccsr & ~MXC_CCM_CCSR_PLL1_SW_CLK_SEL, - &mxc_ccm->ccsr); - break; - case PLL2_CLOCK: - /* Switch to pll2 bypass clock */ - 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 */ - writel(ccsr & ~MXC_CCM_CCSR_PLL2_SW_CLK_SEL, - &mxc_ccm->ccsr); - break; - case PLL3_CLOCK: - /* Switch to pll3 bypass clock */ - 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 */ - writel(ccsr & ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL, - &mxc_ccm->ccsr); - break; -#ifdef CONFIG_MX53 - case PLL4_CLOCK: - /* Switch to pll4 bypass clock */ - 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 */ - writel(ccsr & ~MXC_CCM_CCSR_PLL4_SW_CLK_SEL, - &mxc_ccm->ccsr); - break; -#endif - default: - return -EINVAL; - } - - return 0; -} - -/* Config CPU clock */ -static int config_core_clk(u32 ref, u32 freq) -{ - int ret = 0; - struct pll_param pll_param; - - memset(&pll_param, 0, sizeof(struct pll_param)); - - /* The case that periph uses PLL1 is not considered here */ - ret = calc_pll_params(ref, freq, &pll_param); - if (ret != 0) { - printf("Error:Can't find pll parameters: %d\n", ret); - return ret; - } - - return config_pll_clk(PLL1_CLOCK, &pll_param); -} - -static int config_nfc_clk(u32 nfc_clk) -{ - u32 parent_rate = get_emi_slow_clk(); - u32 div; - - if (nfc_clk == 0) - return -EINVAL; - div = parent_rate / nfc_clk; - if (div == 0) - div++; - if (parent_rate / div > NFC_CLK_MAX) - div++; - 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) -{ - int ret = 0; - struct pll_param pll_param; - - memset(&pll_param, 0, sizeof(struct pll_param)); - - 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 (MXC_CCM_CBCMR_PERIPH_CLK_SEL_RD( - readl(&mxc_ccm->cbcmr))) { - case 0: - return config_pll_clk(PLL1_CLOCK, &pll_param); - break; - case 1: - return config_pll_clk(PLL3_CLOCK, &pll_param); - break; - default: - return -EINVAL; - } - } - - return 0; -} - -static int config_ddr_clk(u32 emi_clk) -{ - u32 clk_src; - s32 shift = 0, clk_sel, div = 1; - u32 cbcmr = readl(&mxc_ccm->cbcmr); - - if (emi_clk > MAX_DDR_CLK) { - printf("Warning:DDR clock should not exceed %d MHz\n", - MAX_DDR_CLK / SZ_DEC_1M); - emi_clk = MAX_DDR_CLK; - } - - clk_src = get_periph_clk(); - /* Find DDR clock input */ - clk_sel = MXC_CCM_CBCMR_DDR_CLK_SEL_RD(cbcmr); - switch (clk_sel) { - case 0: - shift = 16; - break; - case 1: - shift = 19; - break; - case 2: - shift = 22; - break; - case 3: - shift = 10; - break; - default: - return -EINVAL; - } - - if ((clk_src % emi_clk) < 10000000) - div = clk_src / emi_clk; - else - div = (clk_src / emi_clk) + 1; - if (div > 8) - div = 8; - - clrsetbits_le32(&mxc_ccm->cbcdr, 0x7 << shift, (div - 1) << shift); - while (readl(&mxc_ccm->cdhipr) != 0) - ; - writel(0x0, &mxc_ccm->ccdr); - - return 0; -} - -/* - * This function assumes the expected core clock has to be changed by - * modifying the PLL. This is NOT true always but for most of the times, - * it is. So it assumes the PLL output freq is the same as the expected - * core clock (presc=1) unless the core clock is less than PLL_FREQ_MIN. - * In the latter case, it will try to increase the presc value until - * (presc*core_clk) is greater than PLL_FREQ_MIN. It then makes call to - * calc_pll_params() and obtains the values of PD, MFI,MFN, MFD based - * on the targeted PLL and reference input clock to the PLL. Lastly, - * it sets the register based on these values along with the dividers. - * Note 1) There is no value checking for the passed-in divider values - * so the caller has to make sure those values are sensible. - * 2) Also adjust the NFC divider such that the NFC clock doesn't - * exceed NFC_CLK_MAX. - * 3) IPU HSP clock is independent of AHB clock. Even it can go up to - * 177MHz for higher voltage, this function fixes the max to 133MHz. - * 4) This function should not have allowed diag_printf() calls since - * the serial driver has been stoped. But leave then here to allow - * easy debugging by NOT calling the cyg_hal_plf_serial_stop(). - */ -int mxc_set_clock(u32 ref, u32 freq, enum mxc_clock clk) -{ - freq *= SZ_DEC_1M; - - switch (clk) { - case MXC_ARM_CLK: - if (config_core_clk(ref, freq)) - return -EINVAL; - break; - case MXC_PERIPH_CLK: - if (config_periph_clk(ref, freq)) - return -EINVAL; - break; - case MXC_DDR_CLK: - if (config_ddr_clk(freq)) - return -EINVAL; - break; - case MXC_NFC_CLK: - if (config_nfc_clk(freq)) - return -EINVAL; - break; - default: - printf("Warning:Unsupported or invalid clock type\n"); - } - - return 0; -} - -#ifdef CONFIG_MX53 -/* - * The clock for the external interface can be set to use internal clock - * if fuse bank 4, row 3, bit 2 is set. - * This is an undocumented feature and it was confirmed by Freescale's support: - * Fuses (but not pins) may be used to configure SATA clocks. - * Particularly the i.MX53 Fuse_Map contains the next information - * about configuring SATA clocks : SATA_ALT_REF_CLK[1:0] (offset 0x180C) - * '00' - 100MHz (External) - * '01' - 50MHz (External) - * '10' - 120MHz, internal (USB PHY) - * '11' - Reserved -*/ -void mxc_set_sata_internal_clock(void) -{ - u32 *tmp_base = - (u32 *)(IIM_BASE_ADDR + 0x180c); - - set_usb_phy_clk(); - - clrsetbits_le32(tmp_base, 0x6, 0x4); -} -#endif - -/* - * Dump some core clockes. - */ -int do_mx5_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 freq; - - freq = decode_pll(mxc_plls[PLL1_CLOCK], MXC_HCLK); - printf("PLL1 %8d MHz\n", freq / 1000000); - freq = decode_pll(mxc_plls[PLL2_CLOCK], MXC_HCLK); - printf("PLL2 %8d MHz\n", freq / 1000000); - 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], MXC_HCLK); - printf("PLL4 %8d MHz\n", freq / 1000000); -#endif - - printf("\n"); - printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); - 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; -} - -/***************************************************/ - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_mx5_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/armv7/mx5/lowlevel_init.S b/arch/arm/cpu/armv7/mx5/lowlevel_init.S deleted file mode 100644 index f5bc6728b7..0000000000 --- a/arch/arm/cpu/armv7/mx5/lowlevel_init.S +++ /dev/null @@ -1,429 +0,0 @@ -/* - * Copyright (C) 2007, Guennadi Liakhovetski <lg@denx.de> - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <config.h> -#include <asm/arch/imx-regs.h> -#include <generated/asm-offsets.h> -#include <linux/linkage.h> - -.section ".text.init", "x" - -.macro init_arm_erratum - /* ARM erratum ID #468414 */ - mrc 15, 0, r1, c1, c0, 1 - orr r1, r1, #(1 << 5) /* enable L1NEON bit */ - mcr 15, 0, r1, c1, c0, 1 -.endm - -/* - * L2CC Cache setup/invalidation/disable - */ -.macro init_l2cc - /* explicitly disable L2 cache */ - mrc 15, 0, r0, c1, c0, 1 - bic r0, r0, #0x2 - mcr 15, 0, r0, c1, c0, 1 - - /* reconfigure L2 cache aux control reg */ - ldr r0, =0xC0 | /* tag RAM */ \ - 0x4 | /* data RAM */ \ - 1 << 24 | /* disable write allocate delay */ \ - 1 << 23 | /* disable write allocate combine */ \ - 1 << 22 /* disable write allocate */ - -#if defined(CONFIG_MX51) - ldr r3, [r4, #ROM_SI_REV] - cmp r3, #0x10 - - /* disable write combine for TO 2 and lower revs */ - orrls r0, r0, #1 << 25 -#endif - - mcr 15, 1, r0, c9, c0, 2 - - /* enable L2 cache */ - mrc 15, 0, r0, c1, c0, 1 - orr r0, r0, #2 - mcr 15, 0, r0, c1, c0, 1 - -.endm /* init_l2cc */ - -/* AIPS setup - Only setup MPROTx registers. - * The PACR default values are good.*/ -.macro init_aips - /* - * Set all MPROTx to be non-bufferable, trusted for R/W, - * not forced to user-mode. - */ - ldr r0, =AIPS1_BASE_ADDR - ldr r1, =0x77777777 - str r1, [r0, #0x0] - str r1, [r0, #0x4] - ldr r0, =AIPS2_BASE_ADDR - str r1, [r0, #0x0] - str r1, [r0, #0x4] - /* - * Clear the on and off peripheral modules Supervisor Protect bit - * for SDMA to access them. Did not change the AIPS control registers - * (offset 0x20) access type - */ -.endm /* init_aips */ - -/* M4IF setup */ -.macro init_m4if -#ifdef CONFIG_MX51 - /* VPU and IPU given higher priority (0x4) - * IPU accesses with ID=0x1 given highest priority (=0xA) - */ - ldr r0, =M4IF_BASE_ADDR - - ldr r1, =0x00000203 - str r1, [r0, #0x40] - - str r4, [r0, #0x44] - - ldr r1, =0x00120125 - str r1, [r0, #0x9C] - - ldr r1, =0x001901A3 - str r1, [r0, #0x48] - -#endif -.endm /* init_m4if */ - -.macro setup_pll pll, freq - ldr r0, =\pll - adr r2, W_DP_\freq - bl setup_pll_func -.endm - -#define W_DP_OP 0 -#define W_DP_MFD 4 -#define W_DP_MFN 8 - -setup_pll_func: - ldr r1, =0x00001232 - str r1, [r0, #PLL_DP_CTL] /* Set DPLL ON (set UPEN bit): BRMO=1 */ - mov r1, #0x2 - str r1, [r0, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ - - ldr r1, [r2, #W_DP_OP] - str r1, [r0, #PLL_DP_OP] - str r1, [r0, #PLL_DP_HFS_OP] - - ldr r1, [r2, #W_DP_MFD] - str r1, [r0, #PLL_DP_MFD] - str r1, [r0, #PLL_DP_HFS_MFD] - - ldr r1, [r2, #W_DP_MFN] - str r1, [r0, #PLL_DP_MFN] - str r1, [r0, #PLL_DP_HFS_MFN] - - ldr r1, =0x00001232 - str r1, [r0, #PLL_DP_CTL] -1: ldr r1, [r0, #PLL_DP_CTL] - ands r1, r1, #0x1 - beq 1b - - /* r10 saved upper lr */ - mov pc, lr - -.macro setup_pll_errata pll, freq - ldr r2, =\pll - str r4, [r2, #PLL_DP_CONFIG] /* Disable auto-restart AREN bit */ - ldr r1, =0x00001236 - str r1, [r2, #PLL_DP_CTL] /* Restart PLL with PLM=1 */ -1: ldr r1, [r2, #PLL_DP_CTL] /* Wait for lock */ - ands r1, r1, #0x1 - beq 1b - - ldr r5, \freq - str r5, [r2, #PLL_DP_MFN] /* Modify MFN value */ - str r5, [r2, #PLL_DP_HFS_MFN] - - mov r1, #0x1 - str r1, [r2, #PLL_DP_CONFIG] /* Reload MFN value */ - -2: ldr r1, [r2, #PLL_DP_CONFIG] - tst r1, #1 - bne 2b - - ldr r1, =100 /* Wait at least 4 us */ -3: subs r1, r1, #1 - bge 3b - - mov r1, #0x2 - str r1, [r2, #PLL_DP_CONFIG] /* Enable auto-restart AREN bit */ -.endm - -.macro init_clock -#if defined (CONFIG_MX51) - ldr r0, =CCM_BASE_ADDR - - /* Gate of clocks to the peripherals first */ - ldr r1, =0x3FFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r4, [r0, #CLKCTL_CCGR1] - str r4, [r0, #CLKCTL_CCGR2] - str r4, [r0, #CLKCTL_CCGR3] - - ldr r1, =0x00030000 - str r1, [r0, #CLKCTL_CCGR4] - ldr r1, =0x00FFF030 - str r1, [r0, #CLKCTL_CCGR5] - ldr r1, =0x00000300 - str r1, [r0, #CLKCTL_CCGR6] - - /* Disable IPU and HSC dividers */ - mov r1, #0x60000 - str r1, [r0, #CLKCTL_CCDR] - - /* Make sure to switch the DDR away from PLL 1 */ - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - /* Switch ARM to step clock */ - mov r1, #0x4 - str r1, [r0, #CLKCTL_CCSR] - -#if defined(CONFIG_MX51_PLL_ERRATA) - setup_pll PLL1_BASE_ADDR, 864 - setup_pll_errata PLL1_BASE_ADDR, W_DP_MFN_800_DIT -#else - setup_pll PLL1_BASE_ADDR, 800 -#endif - - setup_pll PLL3_BASE_ADDR, 665 - - /* Switch peripheral to PLL 3 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x000010C0 | CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - ldr r1, =0x13239145 - str r1, [r0, #CLKCTL_CBCDR] - setup_pll PLL2_BASE_ADDR, 665 - - /* Switch peripheral to PLL2 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x19239145 - str r1, [r0, #CLKCTL_CBCDR] - ldr r1, =0x000020C0 | CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - - setup_pll PLL3_BASE_ADDR, 216 - - /* Set the platform clock dividers */ - ldr r0, =ARM_BASE_ADDR - ldr r1, =0x00000725 - str r1, [r0, #0x14] - - ldr r0, =CCM_BASE_ADDR - - /* Run 3.0 at Full speed, for other TO's wait till we increase VDDGP */ - ldr r3, [r4, #ROM_SI_REV] - cmp r3, #0x10 - movls r1, #0x1 - movhi r1, #0 - - str r1, [r0, #CLKCTL_CACRR] - - /* Switch ARM back to PLL 1 */ - str r4, [r0, #CLKCTL_CCSR] - - /* setup the rest */ - /* Use lp_apm (24MHz) source for perclk */ - ldr r1, =0x000020C2 | CONFIG_SYS_DDR_CLKSEL - str r1, [r0, #CLKCTL_CBCMR] - /* ddr clock from PLL 1, all perclk dividers are 1 since using 24MHz */ - ldr r1, =CONFIG_SYS_CLKTL_CBCDR - str r1, [r0, #CLKCTL_CBCDR] - - /* Restore the default values in the Gate registers */ - ldr r1, =0xFFFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - str r1, [r0, #CLKCTL_CCGR4] - str r1, [r0, #CLKCTL_CCGR5] - str r1, [r0, #CLKCTL_CCGR6] - - /* Use PLL 2 for UART's, get 66.5MHz from it */ - ldr r1, =0xA5A2A020 - str r1, [r0, #CLKCTL_CSCMR1] - ldr r1, =0x00C30321 - str r1, [r0, #CLKCTL_CSCDR1] - /* make sure divider effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - str r4, [r0, #CLKCTL_CCDR] - - /* for cko - for ARM div by 8 */ - mov r1, #0x000A0000 - add r1, r1, #0x00000F0 - str r1, [r0, #CLKCTL_CCOSR] -#else /* CONFIG_MX53 */ - ldr r0, =CCM_BASE_ADDR - - /* Gate of clocks to the peripherals first */ - ldr r1, =0x3FFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r4, [r0, #CLKCTL_CCGR1] - str r4, [r0, #CLKCTL_CCGR2] - str r4, [r0, #CLKCTL_CCGR3] - str r4, [r0, #CLKCTL_CCGR7] - ldr r1, =0x00030000 - str r1, [r0, #CLKCTL_CCGR4] - ldr r1, =0x00FFF030 - str r1, [r0, #CLKCTL_CCGR5] - ldr r1, =0x0F00030F - str r1, [r0, #CLKCTL_CCGR6] - - /* Switch ARM to step clock */ - mov r1, #0x4 - str r1, [r0, #CLKCTL_CCSR] - - setup_pll PLL1_BASE_ADDR, 800 - - setup_pll PLL3_BASE_ADDR, 400 - - /* Switch peripheral to PLL3 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x00015154 - str r1, [r0, #CLKCTL_CBCMR] - ldr r1, =0x02898945 - str r1, [r0, #CLKCTL_CBCDR] - /* make sure change is effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - setup_pll PLL2_BASE_ADDR, 400 - - /* Switch peripheral to PLL2 */ - ldr r0, =CCM_BASE_ADDR - ldr r1, =0x00888945 - str r1, [r0, #CLKCTL_CBCDR] - - ldr r1, =0x00016154 - str r1, [r0, #CLKCTL_CBCMR] - - /*change uart clk parent to pll2*/ - ldr r1, [r0, #CLKCTL_CSCMR1] - and r1, r1, #0xfcffffff - orr r1, r1, #0x01000000 - str r1, [r0, #CLKCTL_CSCMR1] - - /* make sure change is effective */ -1: ldr r1, [r0, #CLKCTL_CDHIPR] - cmp r1, #0x0 - bne 1b - - setup_pll PLL3_BASE_ADDR, 216 - - setup_pll PLL4_BASE_ADDR, 455 - - /* Set the platform clock dividers */ - ldr r0, =ARM_BASE_ADDR - ldr r1, =0x00000124 - str r1, [r0, #0x14] - - ldr r0, =CCM_BASE_ADDR - mov r1, #0 - str r1, [r0, #CLKCTL_CACRR] - - /* Switch ARM back to PLL 1. */ - mov r1, #0x0 - str r1, [r0, #CLKCTL_CCSR] - - /* make uart div=6 */ - ldr r1, [r0, #CLKCTL_CSCDR1] - and r1, r1, #0xffffffc0 - orr r1, r1, #0x0a - str r1, [r0, #CLKCTL_CSCDR1] - - /* Restore the default values in the Gate registers */ - ldr r1, =0xFFFFFFFF - str r1, [r0, #CLKCTL_CCGR0] - str r1, [r0, #CLKCTL_CCGR1] - str r1, [r0, #CLKCTL_CCGR2] - str r1, [r0, #CLKCTL_CCGR3] - str r1, [r0, #CLKCTL_CCGR4] - str r1, [r0, #CLKCTL_CCGR5] - str r1, [r0, #CLKCTL_CCGR6] - str r1, [r0, #CLKCTL_CCGR7] - - mov r1, #0x00000 - str r1, [r0, #CLKCTL_CCDR] - - /* for cko - for ARM div by 8 */ - mov r1, #0x000A0000 - add r1, r1, #0x00000F0 - str r1, [r0, #CLKCTL_CCOSR] - -#endif /* CONFIG_MX53 */ -.endm - -ENTRY(lowlevel_init) - mov r10, lr - mov r4, #0 /* Fix R4 to 0 */ - -#if defined(CONFIG_SYS_MAIN_PWR_ON) - ldr r0, =GPIO1_BASE_ADDR - ldr r1, [r0, #0x0] - orr r1, r1, #1 << 23 - str r1, [r0, #0x0] - ldr r1, [r0, #0x4] - orr r1, r1, #1 << 23 - str r1, [r0, #0x4] -#endif - - init_arm_erratum - - init_l2cc - - init_aips - - init_m4if - - init_clock - - mov pc, r10 -ENDPROC(lowlevel_init) - -/* Board level setting value */ -#if defined(CONFIG_MX51_PLL_ERRATA) -W_DP_864: .word DP_OP_864 - .word DP_MFD_864 - .word DP_MFN_864 -W_DP_MFN_800_DIT: .word DP_MFN_800_DIT -#else -W_DP_800: .word DP_OP_800 - .word DP_MFD_800 - .word DP_MFN_800 -#endif -#if defined(CONFIG_MX51) -W_DP_665: .word DP_OP_665 - .word DP_MFD_665 - .word DP_MFN_665 -#endif -W_DP_216: .word DP_OP_216 - .word DP_MFD_216 - .word DP_MFN_216 -W_DP_400: .word DP_OP_400 - .word DP_MFD_400 - .word DP_MFN_400 -W_DP_455: .word DP_OP_455 - .word DP_MFD_455 - .word DP_MFN_455 diff --git a/arch/arm/cpu/armv7/mx5/soc.c b/arch/arm/cpu/armv7/mx5/soc.c deleted file mode 100644 index e6cc7cb9c4..0000000000 --- a/arch/arm/cpu/armv7/mx5/soc.c +++ /dev/null @@ -1,116 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> - -#include <linux/errno.h> -#include <asm/io.h> -#include <asm/imx-common/boot_mode.h> - -#if !(defined(CONFIG_MX51) || defined(CONFIG_MX53)) -#error "CPU_TYPE not defined" -#endif - -u32 get_cpu_rev(void) -{ -#ifdef CONFIG_MX51 - int system_rev = 0x51000; -#else - int system_rev = 0x53000; -#endif - int reg = __raw_readl(ROM_SI_REV); - -#if defined(CONFIG_MX51) - switch (reg) { - case 0x02: - system_rev |= CHIP_REV_1_1; - break; - case 0x10: - if ((__raw_readl(GPIO1_BASE_ADDR + 0x0) & (0x1 << 22)) == 0) - system_rev |= CHIP_REV_2_5; - else - system_rev |= CHIP_REV_2_0; - break; - case 0x20: - system_rev |= CHIP_REV_3_0; - break; - default: - system_rev |= CHIP_REV_1_0; - break; - } -#else - if (reg < 0x20) - system_rev |= CHIP_REV_1_0; - else - system_rev |= reg; -#endif - return system_rev; -} - -#ifdef CONFIG_REVISION_TAG -u32 __weak get_board_rev(void) -{ - return get_cpu_rev(); -} -#endif - -#ifndef CONFIG_SYS_DCACHE_OFF -void enable_caches(void) -{ - /* Enable D-cache. I-cache is already enabled in start.S */ - dcache_enable(); -} -#endif - -#if defined(CONFIG_FEC_MXC) -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) -{ - int i; - struct iim_regs *iim = (struct iim_regs *)IMX_IIM_BASE; - struct fuse_bank *bank = &iim->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - - for (i = 0; i < 6; i++) - mac[i] = readl(&fuse->mac_addr[i]) & 0xff; -} -#endif - -#ifdef CONFIG_MX53 -void boot_mode_apply(unsigned cfg_val) -{ - writel(cfg_val, &((struct srtc_regs *)SRTC_BASE_ADDR)->lpgr); -} -/* - * cfg_val will be used for - * Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] - * - * If bit 28 of LPGR is set upon watchdog reset, - * bits[25:0] of LPGR will move to SBMR. - */ -const struct boot_mode soc_boot_modes[] = { - {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, - /* usb or serial download */ - {"usb", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x13)}, - {"sata", MAKE_CFGVAL(0x28, 0x00, 0x00, 0x12)}, - {"escpi1:0", MAKE_CFGVAL(0x38, 0x20, 0x00, 0x12)}, - {"escpi1:1", MAKE_CFGVAL(0x38, 0x20, 0x04, 0x12)}, - {"escpi1:2", MAKE_CFGVAL(0x38, 0x20, 0x08, 0x12)}, - {"escpi1:3", MAKE_CFGVAL(0x38, 0x20, 0x0c, 0x12)}, - /* 4 bit bus width */ - {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x12)}, - {"esdhc2", MAKE_CFGVAL(0x40, 0x20, 0x08, 0x12)}, - {"esdhc3", MAKE_CFGVAL(0x40, 0x20, 0x10, 0x12)}, - {"esdhc4", MAKE_CFGVAL(0x40, 0x20, 0x18, 0x12)}, - {NULL, 0}, -}; -#endif diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig deleted file mode 100644 index 1595a764c5..0000000000 --- a/arch/arm/cpu/armv7/mx6/Kconfig +++ /dev/null @@ -1,447 +0,0 @@ -if ARCH_MX6 - -config MX6 - bool - default y - select ARM_ERRATA_743622 if !MX6UL - select ARM_ERRATA_751472 if !MX6UL - select ARM_ERRATA_761320 if !MX6UL - select ARM_ERRATA_794072 if !MX6UL - imply CMD_FUSE - -config MX6D - bool - -config MX6DL - bool - -config MX6Q - bool - -config MX6QDL - bool - -config MX6S - bool - -config MX6SL - bool - -config MX6SX - select ROM_UNIFIED_SECTIONS - bool - -config MX6SLL - select ROM_UNIFIED_SECTIONS - bool - -config MX6UL - select SYS_L2CACHE_OFF - select ROM_UNIFIED_SECTIONS - bool - -config MX6UL_LITESOM - bool - select MX6UL - select DM - select DM_THERMAL - select SUPPORT_SPL - -config MX6UL_OPOS6UL - bool - select MX6UL - select BOARD_LATE_INIT - select DM - select DM_GPIO - select DM_MMC - select DM_THERMAL - select SUPPORT_SPL - -config MX6ULL - bool - select MX6UL - -config MX6_DDRCAL - bool "Include dynamic DDR calibration routines" - depends on SPL - default n - help - Say "Y" if your board uses dynamic (per-boot) DDR calibration. - If unsure, say N. - -choice - prompt "MX6 board select" - optional - -config TARGET_ADVANTECH_DMS_BA16 - bool "Advantech dms-ba16" - select BOARD_LATE_INIT - select MX6Q - imply CMD_SATA - -config TARGET_APALIS_IMX6 - bool "Toradex Apalis iMX6 board" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_SERIAL - select DM_THERMAL - imply CMD_SATA - -config TARGET_ARISTAINETOS - bool "aristainetos" - -config TARGET_ARISTAINETOS2 - bool "aristainetos2" - select BOARD_LATE_INIT - -config TARGET_ARISTAINETOS2B - bool "Support aristainetos2-revB" - select BOARD_LATE_INIT - -config TARGET_CGTQMX6EVAL - bool "cgtqmx6eval" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_THERMAL - -config TARGET_CM_FX6 - bool "CM-FX6" - select SUPPORT_SPL - select DM - select DM_SERIAL - select DM_GPIO - -config TARGET_COLIBRI_IMX6 - bool "Toradex Colibri iMX6 board" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_SERIAL - select DM_THERMAL - -config TARGET_EMBESTMX6BOARDS - bool "embestmx6boards" - select BOARD_LATE_INIT - -config TARGET_GE_B450V3 - bool "General Electric B450v3" - select BOARD_LATE_INIT - select MX6Q - -config TARGET_GE_B650V3 - bool "General Electric B650v3" - select BOARD_LATE_INIT - select MX6Q - -config TARGET_GE_B850V3 - bool "General Electric B850v3" - select BOARD_LATE_INIT - select MX6Q - -config TARGET_GW_VENTANA - bool "gw_ventana" - select SUPPORT_SPL - imply CMD_SATA - -config TARGET_KOSAGI_NOVENA - bool "Kosagi Novena" - select BOARD_LATE_INIT - select SUPPORT_SPL - -config TARGET_MCCMON6 - bool "mccmon6" - select SUPPORT_SPL - -config TARGET_MX6CUBOXI - bool "Solid-run mx6 boards" - select BOARD_LATE_INIT - select SUPPORT_SPL - -config TARGET_MX6LOGICPD - bool "Logic PD i.MX6 SOM" - select BOARD_EARLY_INIT_F - select BOARD_LATE_INIT - select DM - select DM_ETH - select DM_GPIO - select DM_I2C - select DM_MMC - select DM_PMIC - select DM_REGULATOR - select OF_CONTROL - -config TARGET_MX6QARM2 - bool "mx6qarm2" - -config TARGET_MX6Q_ICORE - bool "Support Engicam i.Core" - select BOARD_LATE_INIT - select MX6QDL - select OF_CONTROL - select SPL_OF_LIBFDT - select DM - select DM_ETH - select DM_GPIO - select DM_I2C - select DM_MMC - select DM_THERMAL - select SUPPORT_SPL - select SPL_LOAD_FIT - -config TARGET_MX6Q_ICORE_RQS - bool "Support Engicam i.Core RQS" - select BOARD_LATE_INIT - select MX6QDL - select OF_CONTROL - select SPL_OF_LIBFDT - select DM - select DM_ETH - select DM_GPIO - select DM_I2C - select DM_MMC - select DM_THERMAL - select SUPPORT_SPL - select SPL_LOAD_FIT - -config TARGET_MX6SABREAUTO - bool "mx6sabreauto" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_THERMAL - select BOARD_EARLY_INIT_F - -config TARGET_MX6SABRESD - bool "mx6sabresd" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_THERMAL - select BOARD_EARLY_INIT_F - -config TARGET_MX6SLEVK - bool "mx6slevk" - select SUPPORT_SPL - -config TARGET_MX6SLLEVK - bool "mx6sll evk" - select BOARD_LATE_INIT - select MX6SLL - select DM - select DM_THERMAL - -config TARGET_MX6SXSABRESD - bool "mx6sxsabresd" - select MX6SX - select SUPPORT_SPL - select DM - select DM_THERMAL - select BOARD_EARLY_INIT_F - -config TARGET_MX6SXSABREAUTO - bool "mx6sxsabreauto" - select BOARD_LATE_INIT - select MX6SX - select DM - select DM_THERMAL - select BOARD_EARLY_INIT_F - -config TARGET_MX6UL_9X9_EVK - bool "mx6ul_9x9_evk" - select BOARD_LATE_INIT - select MX6UL - select DM - select DM_THERMAL - select SUPPORT_SPL - -config TARGET_MX6UL_14X14_EVK - select BOARD_LATE_INIT - bool "mx6ul_14x14_evk" - select MX6UL - select DM - select DM_THERMAL - select SUPPORT_SPL - -config TARGET_MX6UL_GEAM - bool "Support Engicam GEAM6UL" - select BOARD_LATE_INIT - select MX6UL - select OF_CONTROL - select DM - select DM_ETH - select DM_GPIO - select DM_I2C - select DM_MMC - select DM_THERMAL - select SUPPORT_SPL -config TARGET_MX6UL_ISIOT - bool "Support Engicam Is.IoT MX6UL" - select BOARD_LATE_INIT - select MX6UL - select OF_CONTROL - select DM - select DM_ETH - select DM_GPIO - select DM_I2C - select DM_MMC - select DM_THERMAL - select SUPPORT_SPL - -config TARGET_MX6ULL_14X14_EVK - bool "Support mx6ull_14x14_evk" - select BOARD_LATE_INIT - select MX6ULL - select DM - select DM_THERMAL - -config TARGET_NITROGEN6X - bool "nitrogen6x" - -config TARGET_OPOS6ULDEV - bool "Armadeus OPOS6ULDev board" - select MX6UL_OPOS6UL - -config TARGET_OT1200 - bool "Bachmann OT1200" - select SUPPORT_SPL - imply CMD_SATA - -config TARGET_PICO_IMX6UL - bool "PICO-IMX6UL-EMMC" - select MX6UL - -config TARGET_LITEBOARD - bool "Grinn liteBoard (i.MX6UL)" - select BOARD_LATE_INIT - select MX6UL_LITESOM - -config TARGET_PLATINUM_PICON - bool "platinum-picon" - select SUPPORT_SPL - -config TARGET_PLATINUM_TITANIUM - bool "platinum-titanium" - select SUPPORT_SPL - -config TARGET_PCM058 - bool "Phytec PCM058 i.MX6 Quad" - select BOARD_LATE_INIT - select SUPPORT_SPL - -config TARGET_SECOMX6 - bool "secomx6 boards" - -config TARGET_TBS2910 - bool "TBS2910 Matrix ARM mini PC" - -config TARGET_TITANIUM - bool "titanium" - -config TARGET_TQMA6 - bool "TQ Systems TQMa6 board" - select BOARD_LATE_INIT - -config TARGET_UDOO - bool "udoo" - select BOARD_LATE_INIT - select SUPPORT_SPL - -config TARGET_UDOO_NEO - bool "UDOO Neo" - select BOARD_LATE_INIT - select SUPPORT_SPL - select MX6SX - select DM - select DM_THERMAL - -config TARGET_SAMTEC_VINING_2000 - bool "samtec VIN|ING 2000" - select BOARD_LATE_INIT - select MX6SX - select DM - select DM_THERMAL - -config TARGET_WANDBOARD - bool "wandboard" - select BOARD_LATE_INIT - select SUPPORT_SPL - -config TARGET_WARP - bool "WaRP" - select BOARD_LATE_INIT - -config TARGET_XPRESS - bool "CCV xPress" - select BOARD_LATE_INIT - select MX6UL - select DM - select DM_THERMAL - select SUPPORT_SPL - -config TARGET_ZC5202 - bool "zc5202" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_THERMAL - -config TARGET_ZC5601 - bool "zc5601" - select BOARD_LATE_INIT - select SUPPORT_SPL - select DM - select DM_THERMAL - -endchoice - -config SYS_SOC - default "mx6" - -source "board/ge/bx50v3/Kconfig" -source "board/advantech/dms-ba16/Kconfig" -source "board/aristainetos/Kconfig" -source "board/armadeus/opos6uldev/Kconfig" -source "board/bachmann/ot1200/Kconfig" -source "board/barco/platinum/Kconfig" -source "board/barco/titanium/Kconfig" -source "board/boundary/nitrogen6x/Kconfig" -source "board/ccv/xpress/Kconfig" -source "board/compulab/cm_fx6/Kconfig" -source "board/congatec/cgtqmx6eval/Kconfig" -source "board/el/el6x/Kconfig" -source "board/embest/mx6boards/Kconfig" -source "board/engicam/geam6ul/Kconfig" -source "board/engicam/icorem6/Kconfig" -source "board/engicam/icorem6_rqs/Kconfig" -source "board/engicam/isiotmx6ul/Kconfig" -source "board/freescale/mx6qarm2/Kconfig" -source "board/freescale/mx6sabreauto/Kconfig" -source "board/freescale/mx6sabresd/Kconfig" -source "board/freescale/mx6slevk/Kconfig" -source "board/freescale/mx6sllevk/Kconfig" -source "board/freescale/mx6sxsabresd/Kconfig" -source "board/freescale/mx6sxsabreauto/Kconfig" -source "board/freescale/mx6ul_14x14_evk/Kconfig" -source "board/freescale/mx6ullevk/Kconfig" -source "board/grinn/liteboard/Kconfig" -source "board/phytec/pcm058/Kconfig" -source "board/gateworks/gw_ventana/Kconfig" -source "board/kosagi/novena/Kconfig" -source "board/samtec/vining_2000/Kconfig" -source "board/liebherr/mccmon6/Kconfig" -source "board/logicpd/imx6/Kconfig" -source "board/seco/Kconfig" -source "board/solidrun/mx6cuboxi/Kconfig" -source "board/technexion/pico-imx6ul/Kconfig" -source "board/tbs/tbs2910/Kconfig" -source "board/tqc/tqma6/Kconfig" -source "board/toradex/apalis_imx6/Kconfig" -source "board/toradex/colibri_imx6/Kconfig" -source "board/udoo/Kconfig" -source "board/udoo/neo/Kconfig" -source "board/wandboard/Kconfig" -source "board/warp/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile deleted file mode 100644 index c183eb4a2f..0000000000 --- a/arch/arm/cpu/armv7/mx6/Makefile +++ /dev/null @@ -1,14 +0,0 @@ -# -# (C) Copyright 2000-2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2011 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-y := soc.o clock.o -obj-$(CONFIG_SPL_BUILD) += ddr.o -obj-$(CONFIG_MP) += mp.o -obj-$(CONFIG_MX6UL_LITESOM) += litesom.o -obj-$(CONFIG_MX6UL_OPOS6UL) += opos6ul.o diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c deleted file mode 100644 index 1f2739e864..0000000000 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ /dev/null @@ -1,1486 +0,0 @@ -/* - * Copyright (C) 2010-2011 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <linux/errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> - -enum pll_clocks { - PLL_SYS, /* System PLL */ - PLL_BUS, /* System Bus PLL*/ - PLL_USBOTG, /* OTG USB PLL */ - PLL_ENET, /* ENET PLL */ - PLL_AUDIO, /* AUDIO PLL */ - PLL_VIDEO, /* AUDIO PLL */ -}; - -struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - -#ifdef CONFIG_MXC_OCOTP -void enable_ocotp_clk(unsigned char enable) -{ - u32 reg; - - reg = __raw_readl(&imx_ccm->CCGR2); - if (enable) - reg |= MXC_CCM_CCGR2_OCOTP_CTRL_MASK; - else - reg &= ~MXC_CCM_CCGR2_OCOTP_CTRL_MASK; - __raw_writel(reg, &imx_ccm->CCGR2); -} -#endif - -#ifdef CONFIG_NAND_MXS -void setup_gpmi_io_clk(u32 cfg) -{ - /* Disable clocks per ERR007177 from MX6 errata */ - clrbits_le32(&imx_ccm->CCGR4, - MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | - MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); - -#if defined(CONFIG_MX6SX) - clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK); - - clrsetbits_le32(&imx_ccm->cs2cdr, - MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | - MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | - MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK, - cfg); - - setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK); -#else - clrbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); - - clrsetbits_le32(&imx_ccm->cs2cdr, - MXC_CCM_CS2CDR_ENFC_CLK_PODF_MASK | - MXC_CCM_CS2CDR_ENFC_CLK_PRED_MASK | - MXC_CCM_CS2CDR_ENFC_CLK_SEL_MASK, - cfg); - - setbits_le32(&imx_ccm->CCGR2, MXC_CCM_CCGR2_IOMUX_IPT_CLK_IO_MASK); -#endif - setbits_le32(&imx_ccm->CCGR4, - MXC_CCM_CCGR4_RAWNAND_U_BCH_INPUT_APB_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_BCH_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_INPUT_APB_MASK | - MXC_CCM_CCGR4_PL301_MX6QPER1_BCH_MASK); -} -#endif - -void enable_usboh3_clk(unsigned char enable) -{ - u32 reg; - - reg = __raw_readl(&imx_ccm->CCGR6); - if (enable) - reg |= MXC_CCM_CCGR6_USBOH3_MASK; - else - reg &= ~(MXC_CCM_CCGR6_USBOH3_MASK); - __raw_writel(reg, &imx_ccm->CCGR6); - -} - -#if defined(CONFIG_FEC_MXC) && !defined(CONFIG_MX6SX) -void enable_enet_clk(unsigned char enable) -{ - u32 mask, *addr; - - if (is_mx6ull()) { - mask = MXC_CCM_CCGR0_ENET_CLK_ENABLE_MASK; - addr = &imx_ccm->CCGR0; - } else if (is_mx6ul()) { - mask = MXC_CCM_CCGR3_ENET_MASK; - addr = &imx_ccm->CCGR3; - } else { - mask = MXC_CCM_CCGR1_ENET_MASK; - addr = &imx_ccm->CCGR1; - } - - if (enable) - setbits_le32(addr, mask); - else - clrbits_le32(addr, mask); -} -#endif - -#ifdef CONFIG_MXC_UART -void enable_uart_clk(unsigned char enable) -{ - u32 mask; - - if (is_mx6ul() || is_mx6ull()) - mask = MXC_CCM_CCGR5_UART_MASK; - else - mask = MXC_CCM_CCGR5_UART_MASK | MXC_CCM_CCGR5_UART_SERIAL_MASK; - - if (enable) - setbits_le32(&imx_ccm->CCGR5, mask); - else - clrbits_le32(&imx_ccm->CCGR5, mask); -} -#endif - -#ifdef CONFIG_MMC -int enable_usdhc_clk(unsigned char enable, unsigned bus_num) -{ - u32 mask; - - if (bus_num > 3) - return -EINVAL; - - mask = MXC_CCM_CCGR_CG_MASK << (bus_num * 2 + 2); - if (enable) - setbits_le32(&imx_ccm->CCGR6, mask); - else - clrbits_le32(&imx_ccm->CCGR6, mask); - - return 0; -} -#endif - -#ifdef CONFIG_SYS_I2C_MXC -/* i2c_num can be from 0 - 3 */ -int enable_i2c_clk(unsigned char enable, unsigned i2c_num) -{ - u32 reg; - u32 mask; - u32 *addr; - - if (i2c_num > 3) - return -EINVAL; - if (i2c_num < 3) { - mask = MXC_CCM_CCGR_CG_MASK - << (MXC_CCM_CCGR2_I2C1_SERIAL_OFFSET - + (i2c_num << 1)); - reg = __raw_readl(&imx_ccm->CCGR2); - if (enable) - reg |= mask; - else - reg &= ~mask; - __raw_writel(reg, &imx_ccm->CCGR2); - } else { - if (is_mx6sll()) - return -EINVAL; - if (is_mx6sx() || is_mx6ul() || is_mx6ull()) { - mask = MXC_CCM_CCGR6_I2C4_MASK; - addr = &imx_ccm->CCGR6; - } else { - mask = MXC_CCM_CCGR1_I2C4_SERIAL_MASK; - addr = &imx_ccm->CCGR1; - } - reg = __raw_readl(addr); - if (enable) - reg |= mask; - else - reg &= ~mask; - __raw_writel(reg, addr); - } - return 0; -} -#endif - -/* spi_num can be from 0 - SPI_MAX_NUM */ -int enable_spi_clk(unsigned char enable, unsigned spi_num) -{ - u32 reg; - u32 mask; - - if (spi_num > SPI_MAX_NUM) - return -EINVAL; - - mask = MXC_CCM_CCGR_CG_MASK << (spi_num << 1); - reg = __raw_readl(&imx_ccm->CCGR1); - if (enable) - reg |= mask; - else - reg &= ~mask; - __raw_writel(reg, &imx_ccm->CCGR1); - return 0; -} -static u32 decode_pll(enum pll_clocks pll, u32 infreq) -{ - u32 div, test_div, pll_num, pll_denom; - - switch (pll) { - case PLL_SYS: - div = __raw_readl(&imx_ccm->analog_pll_sys); - div &= BM_ANADIG_PLL_SYS_DIV_SELECT; - - return (infreq * div) >> 1; - case PLL_BUS: - div = __raw_readl(&imx_ccm->analog_pll_528); - div &= BM_ANADIG_PLL_528_DIV_SELECT; - - return infreq * (20 + (div << 1)); - case PLL_USBOTG: - div = __raw_readl(&imx_ccm->analog_usb1_pll_480_ctrl); - div &= BM_ANADIG_USB1_PLL_480_CTRL_DIV_SELECT; - - return infreq * (20 + (div << 1)); - case PLL_ENET: - div = __raw_readl(&imx_ccm->analog_pll_enet); - div &= BM_ANADIG_PLL_ENET_DIV_SELECT; - - return 25000000 * (div + (div >> 1) + 1); - case PLL_AUDIO: - div = __raw_readl(&imx_ccm->analog_pll_audio); - if (!(div & BM_ANADIG_PLL_AUDIO_ENABLE)) - return 0; - /* BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC is ignored */ - if (div & BM_ANADIG_PLL_AUDIO_BYPASS) - return MXC_HCLK; - pll_num = __raw_readl(&imx_ccm->analog_pll_audio_num); - pll_denom = __raw_readl(&imx_ccm->analog_pll_audio_denom); - test_div = (div & BM_ANADIG_PLL_AUDIO_TEST_DIV_SELECT) >> - BP_ANADIG_PLL_AUDIO_TEST_DIV_SELECT; - div &= BM_ANADIG_PLL_AUDIO_DIV_SELECT; - if (test_div == 3) { - debug("Error test_div\n"); - return 0; - } - test_div = 1 << (2 - test_div); - - return infreq * (div + pll_num / pll_denom) / test_div; - case PLL_VIDEO: - div = __raw_readl(&imx_ccm->analog_pll_video); - if (!(div & BM_ANADIG_PLL_VIDEO_ENABLE)) - return 0; - /* BM_ANADIG_PLL_AUDIO_BYPASS_CLK_SRC is ignored */ - if (div & BM_ANADIG_PLL_VIDEO_BYPASS) - return MXC_HCLK; - pll_num = __raw_readl(&imx_ccm->analog_pll_video_num); - pll_denom = __raw_readl(&imx_ccm->analog_pll_video_denom); - test_div = (div & BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT) >> - BP_ANADIG_PLL_VIDEO_POST_DIV_SELECT; - div &= BM_ANADIG_PLL_VIDEO_DIV_SELECT; - if (test_div == 3) { - debug("Error test_div\n"); - return 0; - } - test_div = 1 << (2 - test_div); - - return infreq * (div + pll_num / pll_denom) / test_div; - default: - return 0; - } - /* NOTREACHED */ -} -static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num) -{ - u32 div; - u64 freq; - - switch (pll) { - case PLL_BUS: - if (!is_mx6ul() && !is_mx6ull()) { - if (pfd_num == 3) { - /* No PFD3 on PLL2 */ - return 0; - } - } - div = __raw_readl(&imx_ccm->analog_pfd_528); - freq = (u64)decode_pll(PLL_BUS, MXC_HCLK); - break; - case PLL_USBOTG: - div = __raw_readl(&imx_ccm->analog_pfd_480); - freq = (u64)decode_pll(PLL_USBOTG, MXC_HCLK); - break; - default: - /* No PFD on other PLL */ - return 0; - } - - return lldiv(freq * 18, (div & ANATOP_PFD_FRAC_MASK(pfd_num)) >> - ANATOP_PFD_FRAC_SHIFT(pfd_num)); -} - -static u32 get_mcu_main_clk(void) -{ - u32 reg, freq; - - reg = __raw_readl(&imx_ccm->cacrr); - reg &= MXC_CCM_CACRR_ARM_PODF_MASK; - reg >>= MXC_CCM_CACRR_ARM_PODF_OFFSET; - freq = decode_pll(PLL_SYS, MXC_HCLK); - - return freq / (reg + 1); -} - -u32 get_periph_clk(void) -{ - u32 reg, div = 0, freq = 0; - - reg = __raw_readl(&imx_ccm->cbcdr); - if (reg & MXC_CCM_CBCDR_PERIPH_CLK_SEL) { - div = (reg & MXC_CCM_CBCDR_PERIPH_CLK2_PODF_MASK) >> - MXC_CCM_CBCDR_PERIPH_CLK2_PODF_OFFSET; - reg = __raw_readl(&imx_ccm->cbcmr); - reg &= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_MASK; - reg >>= MXC_CCM_CBCMR_PERIPH_CLK2_SEL_OFFSET; - - switch (reg) { - case 0: - freq = decode_pll(PLL_USBOTG, MXC_HCLK); - break; - case 1: - case 2: - freq = MXC_HCLK; - break; - default: - break; - } - } else { - reg = __raw_readl(&imx_ccm->cbcmr); - reg &= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK; - reg >>= MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET; - - switch (reg) { - case 0: - freq = decode_pll(PLL_BUS, MXC_HCLK); - break; - case 1: - freq = mxc_get_pll_pfd(PLL_BUS, 2); - break; - case 2: - freq = mxc_get_pll_pfd(PLL_BUS, 0); - break; - case 3: - /* static / 2 divider */ - freq = mxc_get_pll_pfd(PLL_BUS, 2) / 2; - break; - default: - break; - } - } - - return freq / (div + 1); -} - -static u32 get_ipg_clk(void) -{ - u32 reg, ipg_podf; - - reg = __raw_readl(&imx_ccm->cbcdr); - reg &= MXC_CCM_CBCDR_IPG_PODF_MASK; - ipg_podf = reg >> MXC_CCM_CBCDR_IPG_PODF_OFFSET; - - return get_ahb_clk() / (ipg_podf + 1); -} - -static u32 get_ipg_per_clk(void) -{ - u32 reg, perclk_podf; - - reg = __raw_readl(&imx_ccm->cscmr1); - if (is_mx6sll() || is_mx6sl() || is_mx6sx() || - is_mx6dqp() || is_mx6ul() || is_mx6ull()) { - if (reg & MXC_CCM_CSCMR1_PER_CLK_SEL_MASK) - return MXC_HCLK; /* OSC 24Mhz */ - } - - perclk_podf = reg & MXC_CCM_CSCMR1_PERCLK_PODF_MASK; - - return get_ipg_clk() / (perclk_podf + 1); -} - -static u32 get_uart_clk(void) -{ - u32 reg, uart_podf; - u32 freq = decode_pll(PLL_USBOTG, MXC_HCLK) / 6; /* static divider */ - reg = __raw_readl(&imx_ccm->cscdr1); - - if (is_mx6sl() || is_mx6sx() || is_mx6dqp() || is_mx6ul() || - is_mx6sll() || is_mx6ull()) { - if (reg & MXC_CCM_CSCDR1_UART_CLK_SEL) - freq = MXC_HCLK; - } - - reg &= MXC_CCM_CSCDR1_UART_CLK_PODF_MASK; - uart_podf = reg >> MXC_CCM_CSCDR1_UART_CLK_PODF_OFFSET; - - return freq / (uart_podf + 1); -} - -static u32 get_cspi_clk(void) -{ - u32 reg, cspi_podf; - - reg = __raw_readl(&imx_ccm->cscdr2); - cspi_podf = (reg & MXC_CCM_CSCDR2_ECSPI_CLK_PODF_MASK) >> - MXC_CCM_CSCDR2_ECSPI_CLK_PODF_OFFSET; - - if (is_mx6dqp() || is_mx6sl() || is_mx6sx() || is_mx6ul() || - is_mx6sll() || is_mx6ull()) { - if (reg & MXC_CCM_CSCDR2_ECSPI_CLK_SEL_MASK) - return MXC_HCLK / (cspi_podf + 1); - } - - return decode_pll(PLL_USBOTG, MXC_HCLK) / (8 * (cspi_podf + 1)); -} - -static u32 get_axi_clk(void) -{ - u32 root_freq, axi_podf; - u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); - - axi_podf = cbcdr & MXC_CCM_CBCDR_AXI_PODF_MASK; - axi_podf >>= MXC_CCM_CBCDR_AXI_PODF_OFFSET; - - if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) { - if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL) - root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1); - else - root_freq = mxc_get_pll_pfd(PLL_BUS, 2); - } else - root_freq = get_periph_clk(); - - return root_freq / (axi_podf + 1); -} - -static u32 get_emi_slow_clk(void) -{ - u32 emi_clk_sel, emi_slow_podf, cscmr1, root_freq = 0; - - cscmr1 = __raw_readl(&imx_ccm->cscmr1); - emi_clk_sel = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_MASK; - emi_clk_sel >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_OFFSET; - emi_slow_podf = cscmr1 & MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_MASK; - emi_slow_podf >>= MXC_CCM_CSCMR1_ACLK_EMI_SLOW_PODF_OFFSET; - - switch (emi_clk_sel) { - case 0: - root_freq = get_axi_clk(); - break; - case 1: - root_freq = decode_pll(PLL_USBOTG, MXC_HCLK); - break; - case 2: - root_freq = mxc_get_pll_pfd(PLL_BUS, 2); - break; - case 3: - root_freq = mxc_get_pll_pfd(PLL_BUS, 0); - break; - } - - return root_freq / (emi_slow_podf + 1); -} - -static u32 get_mmdc_ch0_clk(void) -{ - u32 cbcmr = __raw_readl(&imx_ccm->cbcmr); - u32 cbcdr = __raw_readl(&imx_ccm->cbcdr); - - u32 freq, podf, per2_clk2_podf, pmu_misc2_audio_div; - - if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl() || - is_mx6sll()) { - podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH1_PODF_MASK) >> - MXC_CCM_CBCDR_MMDC_CH1_PODF_OFFSET; - if (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK_SEL) { - per2_clk2_podf = (cbcdr & MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_MASK) >> - MXC_CCM_CBCDR_PERIPH2_CLK2_PODF_OFFSET; - if (is_mx6sl()) { - if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL) - freq = MXC_HCLK; - else - freq = decode_pll(PLL_USBOTG, MXC_HCLK); - } else { - if (cbcmr & MXC_CCM_CBCMR_PERIPH2_CLK2_SEL) - freq = decode_pll(PLL_BUS, MXC_HCLK); - else - freq = decode_pll(PLL_USBOTG, MXC_HCLK); - } - } else { - per2_clk2_podf = 0; - switch ((cbcmr & - MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) >> - MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET) { - case 0: - freq = decode_pll(PLL_BUS, MXC_HCLK); - break; - case 1: - freq = mxc_get_pll_pfd(PLL_BUS, 2); - break; - case 2: - freq = mxc_get_pll_pfd(PLL_BUS, 0); - break; - case 3: - if (is_mx6sl()) { - freq = mxc_get_pll_pfd(PLL_BUS, 2) >> 1; - break; - } - - pmu_misc2_audio_div = PMU_MISC2_AUDIO_DIV(__raw_readl(&imx_ccm->pmu_misc2)); - switch (pmu_misc2_audio_div) { - case 0: - case 2: - pmu_misc2_audio_div = 1; - break; - case 1: - pmu_misc2_audio_div = 2; - break; - case 3: - pmu_misc2_audio_div = 4; - break; - } - freq = decode_pll(PLL_AUDIO, MXC_HCLK) / - pmu_misc2_audio_div; - break; - } - } - return freq / (podf + 1) / (per2_clk2_podf + 1); - } else { - podf = (cbcdr & MXC_CCM_CBCDR_MMDC_CH0_PODF_MASK) >> - MXC_CCM_CBCDR_MMDC_CH0_PODF_OFFSET; - return get_periph_clk() / (podf + 1); - } -} - -#if defined(CONFIG_VIDEO_MXS) -static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom, - u32 post_div) -{ - u32 reg = 0; - ulong start; - - debug("pll5 div = %d, num = %d, denom = %d\n", - pll_div, pll_num, pll_denom); - - /* Power up PLL5 video */ - writel(BM_ANADIG_PLL_VIDEO_POWERDOWN | - BM_ANADIG_PLL_VIDEO_BYPASS | - BM_ANADIG_PLL_VIDEO_DIV_SELECT | - BM_ANADIG_PLL_VIDEO_POST_DIV_SELECT, - &imx_ccm->analog_pll_video_clr); - - /* Set div, num and denom */ - switch (post_div) { - case 1: - writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | - BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x2), - &imx_ccm->analog_pll_video_set); - break; - case 2: - writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | - BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x1), - &imx_ccm->analog_pll_video_set); - break; - case 4: - writel(BF_ANADIG_PLL_VIDEO_DIV_SELECT(pll_div) | - BF_ANADIG_PLL_VIDEO_POST_DIV_SELECT(0x0), - &imx_ccm->analog_pll_video_set); - break; - default: - puts("Wrong test_div!\n"); - return -EINVAL; - } - - writel(BF_ANADIG_PLL_VIDEO_NUM_A(pll_num), - &imx_ccm->analog_pll_video_num); - writel(BF_ANADIG_PLL_VIDEO_DENOM_B(pll_denom), - &imx_ccm->analog_pll_video_denom); - - /* Wait PLL5 lock */ - start = get_timer(0); /* Get current timestamp */ - - do { - reg = readl(&imx_ccm->analog_pll_video); - if (reg & BM_ANADIG_PLL_VIDEO_LOCK) { - /* Enable PLL out */ - writel(BM_ANADIG_PLL_VIDEO_ENABLE, - &imx_ccm->analog_pll_video_set); - return 0; - } - } while (get_timer(0) < (start + 10)); /* Wait 10ms */ - - puts("Lock PLL5 timeout\n"); - - return -ETIME; -} - -/* - * 24M--> PLL_VIDEO -> LCDIFx_PRED -> LCDIFx_PODF -> LCD - * - * 'freq' using KHz as unit, see driver/video/mxsfb.c. - */ -void mxs_set_lcdclk(u32 base_addr, u32 freq) -{ - u32 reg = 0; - u32 hck = MXC_HCLK / 1000; - /* DIV_SELECT ranges from 27 to 54 */ - u32 min = hck * 27; - u32 max = hck * 54; - u32 temp, best = 0; - u32 i, j, max_pred = 8, max_postd = 8, pred = 1, postd = 1; - u32 pll_div, pll_num, pll_denom, post_div = 1; - - debug("mxs_set_lcdclk, freq = %dKHz\n", freq); - - if (!is_mx6sx() && !is_mx6ul() && !is_mx6ull() && !is_mx6sl() && - !is_mx6sll()) { - debug("This chip not support lcd!\n"); - return; - } - - if (!is_mx6sl()) { - if (base_addr == LCDIF1_BASE_ADDR) { - reg = readl(&imx_ccm->cscdr2); - /* Can't change clocks when clock not from pre-mux */ - if ((reg & MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK) != 0) - return; - } - } - - if (is_mx6sx()) { - reg = readl(&imx_ccm->cscdr2); - /* Can't change clocks when clock not from pre-mux */ - if ((reg & MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK) != 0) - return; - } - - temp = freq * max_pred * max_postd; - if (temp < min) { - /* - * Register: PLL_VIDEO - * Bit Field: POST_DIV_SELECT - * 00 — Divide by 4. - * 01 — Divide by 2. - * 10 — Divide by 1. - * 11 — Reserved - * No need to check post_div(1) - */ - for (post_div = 2; post_div <= 4; post_div <<= 1) { - if ((temp * post_div) > min) { - freq *= post_div; - break; - } - } - - if (post_div > 4) { - printf("Fail to set rate to %dkhz", freq); - return; - } - } - - /* Choose the best pred and postd to match freq for lcd */ - for (i = 1; i <= max_pred; i++) { - for (j = 1; j <= max_postd; j++) { - temp = freq * i * j; - if (temp > max || temp < min) - continue; - if (best == 0 || temp < best) { - best = temp; - pred = i; - postd = j; - } - } - } - - if (best == 0) { - printf("Fail to set rate to %dKHz", freq); - return; - } - - debug("best %d, pred = %d, postd = %d\n", best, pred, postd); - - pll_div = best / hck; - pll_denom = 1000000; - pll_num = (best - hck * pll_div) * pll_denom / hck; - - /* - * pll_num - * (24MHz * (pll_div + --------- )) - * pll_denom - *freq KHz = -------------------------------- - * post_div * pred * postd * 1000 - */ - - if (base_addr == LCDIF1_BASE_ADDR) { - if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) - return; - - enable_lcdif_clock(base_addr, 0); - if (!is_mx6sl()) { - /* Select pre-lcd clock to PLL5 and set pre divider */ - clrsetbits_le32(&imx_ccm->cscdr2, - MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_MASK | - MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_MASK, - (0x2 << MXC_CCM_CSCDR2_LCDIF1_PRED_SEL_OFFSET) | - ((pred - 1) << - MXC_CCM_CSCDR2_LCDIF1_PRE_DIV_OFFSET)); - - /* Set the post divider */ - clrsetbits_le32(&imx_ccm->cbcmr, - MXC_CCM_CBCMR_LCDIF1_PODF_MASK, - ((postd - 1) << - MXC_CCM_CBCMR_LCDIF1_PODF_OFFSET)); - } else { - /* Select pre-lcd clock to PLL5 and set pre divider */ - clrsetbits_le32(&imx_ccm->cscdr2, - MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_MASK | - MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_MASK, - (0x2 << MXC_CCM_CSCDR2_LCDIF_PIX_CLK_SEL_OFFSET) | - ((pred - 1) << - MXC_CCM_CSCDR2_LCDIF_PIX_PRE_DIV_OFFSET)); - - /* Set the post divider */ - clrsetbits_le32(&imx_ccm->cscmr1, - MXC_CCM_CSCMR1_LCDIF_PIX_PODF_MASK, - (((postd - 1)^0x6) << - MXC_CCM_CSCMR1_LCDIF_PIX_PODF_OFFSET)); - } - - enable_lcdif_clock(base_addr, 1); - } else if (is_mx6sx()) { - /* Setting LCDIF2 for i.MX6SX */ - if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) - return; - - enable_lcdif_clock(base_addr, 0); - /* Select pre-lcd clock to PLL5 and set pre divider */ - clrsetbits_le32(&imx_ccm->cscdr2, - MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_MASK | - MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_MASK, - (0x2 << MXC_CCM_CSCDR2_LCDIF2_PRED_SEL_OFFSET) | - ((pred - 1) << - MXC_CCM_CSCDR2_LCDIF2_PRE_DIV_OFFSET)); - - /* Set the post divider */ - clrsetbits_le32(&imx_ccm->cscmr1, - MXC_CCM_CSCMR1_LCDIF2_PODF_MASK, - ((postd - 1) << - MXC_CCM_CSCMR1_LCDIF2_PODF_OFFSET)); - - enable_lcdif_clock(base_addr, 1); - } -} - -int enable_lcdif_clock(u32 base_addr, bool enable) -{ - u32 reg = 0; - u32 lcdif_clk_sel_mask, lcdif_ccgr3_mask; - - if (is_mx6sx()) { - if ((base_addr != LCDIF1_BASE_ADDR) && - (base_addr != LCDIF2_BASE_ADDR)) { - puts("Wrong LCD interface!\n"); - return -EINVAL; - } - /* Set to pre-mux clock at default */ - lcdif_clk_sel_mask = (base_addr == LCDIF2_BASE_ADDR) ? - MXC_CCM_CSCDR2_LCDIF2_CLK_SEL_MASK : - MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK; - lcdif_ccgr3_mask = (base_addr == LCDIF2_BASE_ADDR) ? - (MXC_CCM_CCGR3_LCDIF2_PIX_MASK | - MXC_CCM_CCGR3_DISP_AXI_MASK) : - (MXC_CCM_CCGR3_LCDIF1_PIX_MASK | - MXC_CCM_CCGR3_DISP_AXI_MASK); - } else if (is_mx6ul() || is_mx6ull() || is_mx6sll()) { - if (base_addr != LCDIF1_BASE_ADDR) { - puts("Wrong LCD interface!\n"); - return -EINVAL; - } - /* Set to pre-mux clock at default */ - lcdif_clk_sel_mask = MXC_CCM_CSCDR2_LCDIF1_CLK_SEL_MASK; - lcdif_ccgr3_mask = MXC_CCM_CCGR3_LCDIF1_PIX_MASK; - } else if (is_mx6sl()) { - if (base_addr != LCDIF1_BASE_ADDR) { - puts("Wrong LCD interface!\n"); - return -EINVAL; - } - - reg = readl(&imx_ccm->CCGR3); - reg &= ~(MXC_CCM_CCGR3_LCDIF_AXI_MASK | - MXC_CCM_CCGR3_LCDIF_PIX_MASK); - writel(reg, &imx_ccm->CCGR3); - - if (enable) { - reg = readl(&imx_ccm->cscdr3); - reg &= ~MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_MASK; - reg |= 1 << MXC_CCM_CSCDR3_LCDIF_AXI_CLK_SEL_OFFSET; - writel(reg, &imx_ccm->cscdr3); - - reg = readl(&imx_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_LCDIF_AXI_MASK | - MXC_CCM_CCGR3_LCDIF_PIX_MASK; - writel(reg, &imx_ccm->CCGR3); - } - - return 0; - } else { - return 0; - } - - /* Gate LCDIF clock first */ - reg = readl(&imx_ccm->CCGR3); - reg &= ~lcdif_ccgr3_mask; - writel(reg, &imx_ccm->CCGR3); - - reg = readl(&imx_ccm->CCGR2); - reg &= ~MXC_CCM_CCGR2_LCD_MASK; - writel(reg, &imx_ccm->CCGR2); - - if (enable) { - /* Select pre-mux */ - reg = readl(&imx_ccm->cscdr2); - reg &= ~lcdif_clk_sel_mask; - writel(reg, &imx_ccm->cscdr2); - - /* Enable the LCDIF pix clock */ - reg = readl(&imx_ccm->CCGR3); - reg |= lcdif_ccgr3_mask; - writel(reg, &imx_ccm->CCGR3); - - reg = readl(&imx_ccm->CCGR2); - reg |= MXC_CCM_CCGR2_LCD_MASK; - writel(reg, &imx_ccm->CCGR2); - } - - return 0; -} -#endif - -#ifdef CONFIG_FSL_QSPI -/* qspi_num can be from 0 - 1 */ -void enable_qspi_clk(int qspi_num) -{ - u32 reg = 0; - /* Enable QuadSPI clock */ - switch (qspi_num) { - case 0: - /* disable the clock gate */ - clrbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); - - /* set 50M : (50 = 396 / 2 / 4) */ - reg = readl(&imx_ccm->cscmr1); - reg &= ~(MXC_CCM_CSCMR1_QSPI1_PODF_MASK | - MXC_CCM_CSCMR1_QSPI1_CLK_SEL_MASK); - reg |= ((1 << MXC_CCM_CSCMR1_QSPI1_PODF_OFFSET) | - (2 << MXC_CCM_CSCMR1_QSPI1_CLK_SEL_OFFSET)); - writel(reg, &imx_ccm->cscmr1); - - /* enable the clock gate */ - setbits_le32(&imx_ccm->CCGR3, MXC_CCM_CCGR3_QSPI1_MASK); - break; - case 1: - /* - * disable the clock gate - * QSPI2 and GPMI_BCH_INPUT_GPMI_IO share the same clock gate, - * disable both of them. - */ - clrbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); - - /* set 50M : (50 = 396 / 2 / 4) */ - reg = readl(&imx_ccm->cs2cdr); - reg &= ~(MXC_CCM_CS2CDR_QSPI2_CLK_PODF_MASK | - MXC_CCM_CS2CDR_QSPI2_CLK_PRED_MASK | - MXC_CCM_CS2CDR_QSPI2_CLK_SEL_MASK); - reg |= (MXC_CCM_CS2CDR_QSPI2_CLK_PRED(0x1) | - MXC_CCM_CS2CDR_QSPI2_CLK_SEL(0x3)); - writel(reg, &imx_ccm->cs2cdr); - - /*enable the clock gate*/ - setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_QSPI2_ENFC_MASK | - MXC_CCM_CCGR4_RAWNAND_U_GPMI_BCH_INPUT_GPMI_IO_MASK); - break; - default: - break; - } -} -#endif - -#ifdef CONFIG_FEC_MXC -int enable_fec_anatop_clock(int fec_id, enum enet_freq freq) -{ - u32 reg = 0; - s32 timeout = 100000; - - struct anatop_regs __iomem *anatop = - (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; - - if (freq < ENET_25MHZ || freq > ENET_125MHZ) - return -EINVAL; - - reg = readl(&anatop->pll_enet); - - if (fec_id == 0) { - reg &= ~BM_ANADIG_PLL_ENET_DIV_SELECT; - reg |= BF_ANADIG_PLL_ENET_DIV_SELECT(freq); - } else if (fec_id == 1) { - /* Only i.MX6SX/UL support ENET2 */ - if (!(is_mx6sx() || is_mx6ul() || is_mx6ull())) - return -EINVAL; - reg &= ~BM_ANADIG_PLL_ENET2_DIV_SELECT; - reg |= BF_ANADIG_PLL_ENET2_DIV_SELECT(freq); - } else { - return -EINVAL; - } - - if ((reg & BM_ANADIG_PLL_ENET_POWERDOWN) || - (!(reg & BM_ANADIG_PLL_ENET_LOCK))) { - reg &= ~BM_ANADIG_PLL_ENET_POWERDOWN; - writel(reg, &anatop->pll_enet); - while (timeout--) { - if (readl(&anatop->pll_enet) & BM_ANADIG_PLL_ENET_LOCK) - break; - } - if (timeout < 0) - return -ETIMEDOUT; - } - - /* Enable FEC clock */ - if (fec_id == 0) - reg |= BM_ANADIG_PLL_ENET_ENABLE; - else - reg |= BM_ANADIG_PLL_ENET2_ENABLE; - reg &= ~BM_ANADIG_PLL_ENET_BYPASS; - writel(reg, &anatop->pll_enet); - -#ifdef CONFIG_MX6SX - /* Disable enet system clcok before switching clock parent */ - reg = readl(&imx_ccm->CCGR3); - reg &= ~MXC_CCM_CCGR3_ENET_MASK; - writel(reg, &imx_ccm->CCGR3); - - /* - * Set enet ahb clock to 200MHz - * pll2_pfd2_396m-> ENET_PODF-> ENET_AHB - */ - reg = readl(&imx_ccm->chsccdr); - reg &= ~(MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_MASK - | MXC_CCM_CHSCCDR_ENET_PODF_MASK - | MXC_CCM_CHSCCDR_ENET_CLK_SEL_MASK); - /* PLL2 PFD2 */ - reg |= (4 << MXC_CCM_CHSCCDR_ENET_PRE_CLK_SEL_OFFSET); - /* Div = 2*/ - reg |= (1 << MXC_CCM_CHSCCDR_ENET_PODF_OFFSET); - reg |= (0 << MXC_CCM_CHSCCDR_ENET_CLK_SEL_OFFSET); - writel(reg, &imx_ccm->chsccdr); - - /* Enable enet system clock */ - reg = readl(&imx_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_ENET_MASK; - writel(reg, &imx_ccm->CCGR3); -#endif - return 0; -} -#endif - -static u32 get_usdhc_clk(u32 port) -{ - u32 root_freq = 0, usdhc_podf = 0, clk_sel = 0; - u32 cscmr1 = __raw_readl(&imx_ccm->cscmr1); - u32 cscdr1 = __raw_readl(&imx_ccm->cscdr1); - - if (is_mx6ul() || is_mx6ull()) { - if (port > 1) - return 0; - } - - if (is_mx6sll()) { - if (port > 2) - return 0; - } - - switch (port) { - case 0: - usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC1_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC1_PODF_OFFSET; - clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC1_CLK_SEL; - - break; - case 1: - usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC2_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC2_PODF_OFFSET; - clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC2_CLK_SEL; - - break; - case 2: - usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC3_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC3_PODF_OFFSET; - clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC3_CLK_SEL; - - break; - case 3: - usdhc_podf = (cscdr1 & MXC_CCM_CSCDR1_USDHC4_PODF_MASK) >> - MXC_CCM_CSCDR1_USDHC4_PODF_OFFSET; - clk_sel = cscmr1 & MXC_CCM_CSCMR1_USDHC4_CLK_SEL; - - break; - default: - break; - } - - if (clk_sel) - root_freq = mxc_get_pll_pfd(PLL_BUS, 0); - else - root_freq = mxc_get_pll_pfd(PLL_BUS, 2); - - return root_freq / (usdhc_podf + 1); -} - -u32 imx_get_uartclk(void) -{ - return get_uart_clk(); -} - -u32 imx_get_fecclk(void) -{ - return mxc_get_clock(MXC_IPG_CLK); -} - -#if defined(CONFIG_SATA) || defined(CONFIG_PCIE_IMX) -static int enable_enet_pll(uint32_t en) -{ - struct mxc_ccm_reg *const imx_ccm - = (struct mxc_ccm_reg *) CCM_BASE_ADDR; - s32 timeout = 100000; - u32 reg = 0; - - /* Enable PLLs */ - reg = readl(&imx_ccm->analog_pll_enet); - reg &= ~BM_ANADIG_PLL_SYS_POWERDOWN; - writel(reg, &imx_ccm->analog_pll_enet); - reg |= BM_ANADIG_PLL_SYS_ENABLE; - while (timeout--) { - if (readl(&imx_ccm->analog_pll_enet) & BM_ANADIG_PLL_SYS_LOCK) - break; - } - if (timeout <= 0) - return -EIO; - reg &= ~BM_ANADIG_PLL_SYS_BYPASS; - writel(reg, &imx_ccm->analog_pll_enet); - reg |= en; - writel(reg, &imx_ccm->analog_pll_enet); - return 0; -} -#endif - -#ifdef CONFIG_SATA -static void ungate_sata_clock(void) -{ - struct mxc_ccm_reg *const imx_ccm = - (struct mxc_ccm_reg *)CCM_BASE_ADDR; - - /* Enable SATA clock. */ - setbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK); -} - -int enable_sata_clock(void) -{ - ungate_sata_clock(); - return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA); -} - -void disable_sata_clock(void) -{ - struct mxc_ccm_reg *const imx_ccm = - (struct mxc_ccm_reg *)CCM_BASE_ADDR; - - clrbits_le32(&imx_ccm->CCGR5, MXC_CCM_CCGR5_SATA_MASK); -} -#endif - -#ifdef CONFIG_PCIE_IMX -static void ungate_pcie_clock(void) -{ - struct mxc_ccm_reg *const imx_ccm = - (struct mxc_ccm_reg *)CCM_BASE_ADDR; - - /* Enable PCIe clock. */ - setbits_le32(&imx_ccm->CCGR4, MXC_CCM_CCGR4_PCIE_MASK); -} - -int enable_pcie_clock(void) -{ - struct anatop_regs *anatop_regs = - (struct anatop_regs *)ANATOP_BASE_ADDR; - struct mxc_ccm_reg *ccm_regs = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 lvds1_clk_sel; - - /* - * Here be dragons! - * - * The register ANATOP_MISC1 is not documented in the Freescale - * MX6RM. The register that is mapped in the ANATOP space and - * marked as ANATOP_MISC1 is actually documented in the PMU section - * of the datasheet as PMU_MISC1. - * - * Switch LVDS clock source to SATA (0xb) on mx6q/dl or PCI (0xa) on - * mx6sx, disable clock INPUT and enable clock OUTPUT. This is important - * for PCI express link that is clocked from the i.MX6. - */ -#define ANADIG_ANA_MISC1_LVDSCLK1_IBEN (1 << 12) -#define ANADIG_ANA_MISC1_LVDSCLK1_OBEN (1 << 10) -#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK 0x0000001F -#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF 0xa -#define ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF 0xb - - if (is_mx6sx()) - lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_PCIE_REF; - else - lvds1_clk_sel = ANADIG_ANA_MISC1_LVDS1_CLK_SEL_SATA_REF; - - clrsetbits_le32(&anatop_regs->ana_misc1, - ANADIG_ANA_MISC1_LVDSCLK1_IBEN | - ANADIG_ANA_MISC1_LVDS1_CLK_SEL_MASK, - ANADIG_ANA_MISC1_LVDSCLK1_OBEN | lvds1_clk_sel); - - /* PCIe reference clock sourced from AXI. */ - clrbits_le32(&ccm_regs->cbcmr, MXC_CCM_CBCMR_PCIE_AXI_CLK_SEL); - - /* Party time! Ungate the clock to the PCIe. */ -#ifdef CONFIG_SATA - ungate_sata_clock(); -#endif - ungate_pcie_clock(); - - return enable_enet_pll(BM_ANADIG_PLL_ENET_ENABLE_SATA | - BM_ANADIG_PLL_ENET_ENABLE_PCIE); -} -#endif - -#ifdef CONFIG_SECURE_BOOT -void hab_caam_clock_enable(unsigned char enable) -{ - u32 reg; - - if (is_mx6ull() || is_mx6sll()) { - /* CG5, DCP clock */ - reg = __raw_readl(&imx_ccm->CCGR0); - if (enable) - reg |= MXC_CCM_CCGR0_DCP_CLK_MASK; - else - reg &= ~MXC_CCM_CCGR0_DCP_CLK_MASK; - __raw_writel(reg, &imx_ccm->CCGR0); - } else { - /* CG4 ~ CG6, CAAM clocks */ - reg = __raw_readl(&imx_ccm->CCGR0); - if (enable) - reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | - MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | - MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); - else - reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | - MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | - MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); - __raw_writel(reg, &imx_ccm->CCGR0); - } - - /* EMI slow clk */ - reg = __raw_readl(&imx_ccm->CCGR6); - if (enable) - reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; - else - reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK; - __raw_writel(reg, &imx_ccm->CCGR6); -} -#endif - -static void enable_pll3(void) -{ - struct anatop_regs __iomem *anatop = - (struct anatop_regs __iomem *)ANATOP_BASE_ADDR; - - /* make sure pll3 is enabled */ - if ((readl(&anatop->usb1_pll_480_ctrl) & - BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) { - /* enable pll's power */ - writel(BM_ANADIG_USB1_PLL_480_CTRL_POWER, - &anatop->usb1_pll_480_ctrl_set); - writel(0x80, &anatop->ana_misc2_clr); - /* wait for pll lock */ - while ((readl(&anatop->usb1_pll_480_ctrl) & - BM_ANADIG_USB1_PLL_480_CTRL_LOCK) == 0) - ; - /* disable bypass */ - writel(BM_ANADIG_USB1_PLL_480_CTRL_BYPASS, - &anatop->usb1_pll_480_ctrl_clr); - /* enable pll output */ - writel(BM_ANADIG_USB1_PLL_480_CTRL_ENABLE, - &anatop->usb1_pll_480_ctrl_set); - } -} - -void enable_thermal_clk(void) -{ - enable_pll3(); -} - -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return get_mcu_main_clk(); - case MXC_PER_CLK: - return get_periph_clk(); - case MXC_AHB_CLK: - return get_ahb_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 get_cspi_clk(); - case MXC_AXI_CLK: - return get_axi_clk(); - case MXC_EMI_SLOW_CLK: - return get_emi_slow_clk(); - case MXC_DDR_CLK: - return get_mmdc_ch0_clk(); - case MXC_ESDHC_CLK: - return get_usdhc_clk(0); - case MXC_ESDHC2_CLK: - return get_usdhc_clk(1); - case MXC_ESDHC3_CLK: - return get_usdhc_clk(2); - case MXC_ESDHC4_CLK: - return get_usdhc_clk(3); - case MXC_SATA_CLK: - return get_ahb_clk(); - default: - printf("Unsupported MXC CLK: %d\n", clk); - break; - } - - return 0; -} - -/* - * Dump some core clockes. - */ -int do_mx6_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 freq; - freq = decode_pll(PLL_SYS, MXC_HCLK); - printf("PLL_SYS %8d MHz\n", freq / 1000000); - freq = decode_pll(PLL_BUS, MXC_HCLK); - printf("PLL_BUS %8d MHz\n", freq / 1000000); - freq = decode_pll(PLL_USBOTG, MXC_HCLK); - printf("PLL_OTG %8d MHz\n", freq / 1000000); - freq = decode_pll(PLL_ENET, MXC_HCLK); - printf("PLL_NET %8d MHz\n", freq / 1000000); - - printf("\n"); - printf("ARM %8d kHz\n", mxc_get_clock(MXC_ARM_CLK) / 1000); - printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); - printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); -#ifdef CONFIG_MXC_SPI - printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); -#endif - printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); - printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000); - printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); - printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); - printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); - printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); - printf("USDHC4 %8d kHz\n", mxc_get_clock(MXC_ESDHC4_CLK) / 1000); - printf("EMI SLOW %8d kHz\n", mxc_get_clock(MXC_EMI_SLOW_CLK) / 1000); - printf("IPG PERCLK %8d kHz\n", mxc_get_clock(MXC_IPG_PERCLK) / 1000); - - return 0; -} - -#ifndef CONFIG_MX6SX -void enable_ipu_clock(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - reg = readl(&mxc_ccm->CCGR3); - reg |= MXC_CCM_CCGR3_IPU1_IPU_MASK; - writel(reg, &mxc_ccm->CCGR3); - - if (is_mx6dqp()) { - setbits_le32(&mxc_ccm->CCGR6, MXC_CCM_CCGR6_PRG_CLK0_MASK); - setbits_le32(&mxc_ccm->CCGR3, MXC_CCM_CCGR3_IPU2_IPU_MASK); - } -} -#endif - -#if defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) || defined(CONFIG_MX6DL) || \ - defined(CONFIG_MX6S) -static void disable_ldb_di_clock_sources(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - - /* Make sure PFDs are disabled at boot. */ - reg = readl(&mxc_ccm->analog_pfd_528); - /* Cannot disable pll2_pfd2_396M, as it is the MMDC clock in iMX6DL */ - if (is_mx6sdl()) - reg |= 0x80008080; - else - reg |= 0x80808080; - writel(reg, &mxc_ccm->analog_pfd_528); - - /* Disable PLL3 PFDs */ - reg = readl(&mxc_ccm->analog_pfd_480); - reg |= 0x80808080; - writel(reg, &mxc_ccm->analog_pfd_480); - - /* Disable PLL5 */ - reg = readl(&mxc_ccm->analog_pll_video); - reg &= ~(1 << 13); - writel(reg, &mxc_ccm->analog_pll_video); -} - -static void enable_ldb_di_clock_sources(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - - reg = readl(&mxc_ccm->analog_pfd_528); - if (is_mx6sdl()) - reg &= ~(0x80008080); - else - reg &= ~(0x80808080); - writel(reg, &mxc_ccm->analog_pfd_528); - - reg = readl(&mxc_ccm->analog_pfd_480); - reg &= ~(0x80808080); - writel(reg, &mxc_ccm->analog_pfd_480); -} - -/* - * Try call this function as early in the boot process as possible since the - * function temporarily disables PLL2 PFD's, PLL3 PFD's and PLL5. - */ -void select_ldb_di_clock_source(enum ldb_di_clock clk) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - int reg; - - /* - * Need to follow a strict procedure when changing the LDB - * clock, else we can introduce a glitch. Things to keep in - * mind: - * 1. The current and new parent clocks must be disabled. - * 2. The default clock for ldb_dio_clk is mmdc_ch1 which has - * no CG bit. - * 3. In the RTL implementation of the LDB_DI_CLK_SEL mux - * the top four options are in one mux and the PLL3 option along - * with another option is in the second mux. There is third mux - * used to decide between the first and second mux. - * The code below switches the parent to the bottom mux first - * and then manipulates the top mux. This ensures that no glitch - * will enter the divider. - * - * Need to disable MMDC_CH1 clock manually as there is no CG bit - * for this clock. The only way to disable this clock is to move - * it to pll3_sw_clk and then to disable pll3_sw_clk - * Make sure periph2_clk2_sel is set to pll3_sw_clk - */ - - /* Disable all ldb_di clock parents */ - disable_ldb_di_clock_sources(); - - /* Set MMDC_CH1 mask bit */ - reg = readl(&mxc_ccm->ccdr); - reg |= MXC_CCM_CCDR_MMDC_CH1_HS_MASK; - writel(reg, &mxc_ccm->ccdr); - - /* Set periph2_clk2_sel to be sourced from PLL3_sw_clk */ - reg = readl(&mxc_ccm->cbcmr); - reg &= ~MXC_CCM_CBCMR_PERIPH2_CLK2_SEL; - writel(reg, &mxc_ccm->cbcmr); - - /* - * Set the periph2_clk_sel to the top mux so that - * mmdc_ch1 is from pll3_sw_clk. - */ - reg = readl(&mxc_ccm->cbcdr); - reg |= MXC_CCM_CBCDR_PERIPH2_CLK_SEL; - writel(reg, &mxc_ccm->cbcdr); - - /* Wait for the clock switch */ - while (readl(&mxc_ccm->cdhipr)) - ; - /* Disable pll3_sw_clk by selecting bypass clock source */ - reg = readl(&mxc_ccm->ccsr); - reg |= MXC_CCM_CCSR_PLL3_SW_CLK_SEL; - writel(reg, &mxc_ccm->ccsr); - - /* Set the ldb_di0_clk and ldb_di1_clk to 111b */ - reg = readl(&mxc_ccm->cs2cdr); - reg |= ((7 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET) - | (7 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)); - writel(reg, &mxc_ccm->cs2cdr); - - /* Set the ldb_di0_clk and ldb_di1_clk to 100b */ - reg = readl(&mxc_ccm->cs2cdr); - reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK - | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK); - reg |= ((4 << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET) - | (4 << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)); - writel(reg, &mxc_ccm->cs2cdr); - - /* Set the ldb_di0_clk and ldb_di1_clk to desired source */ - reg = readl(&mxc_ccm->cs2cdr); - reg &= ~(MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_MASK - | MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_MASK); - reg |= ((clk << MXC_CCM_CS2CDR_LDB_DI1_CLK_SEL_OFFSET) - | (clk << MXC_CCM_CS2CDR_LDB_DI0_CLK_SEL_OFFSET)); - writel(reg, &mxc_ccm->cs2cdr); - - /* Unbypass pll3_sw_clk */ - reg = readl(&mxc_ccm->ccsr); - reg &= ~MXC_CCM_CCSR_PLL3_SW_CLK_SEL; - writel(reg, &mxc_ccm->ccsr); - - /* - * Set the periph2_clk_sel back to the bottom mux so that - * mmdc_ch1 is from its original parent. - */ - reg = readl(&mxc_ccm->cbcdr); - reg &= ~MXC_CCM_CBCDR_PERIPH2_CLK_SEL; - writel(reg, &mxc_ccm->cbcdr); - - /* Wait for the clock switch */ - while (readl(&mxc_ccm->cdhipr)) - ; - /* Clear MMDC_CH1 mask bit */ - reg = readl(&mxc_ccm->ccdr); - reg &= ~MXC_CCM_CCDR_MMDC_CH1_HS_MASK; - writel(reg, &mxc_ccm->ccdr); - - enable_ldb_di_clock_sources(); -} -#endif - -#ifdef CONFIG_MTD_NOR_FLASH -void enable_eim_clk(unsigned char enable) -{ - u32 reg; - - reg = __raw_readl(&imx_ccm->CCGR6); - if (enable) - reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; - else - reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK; - __raw_writel(reg, &imx_ccm->CCGR6); -} -#endif - -/***************************************************/ - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_mx6_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/armv7/mx6/ddr.c b/arch/arm/cpu/armv7/mx6/ddr.c deleted file mode 100644 index 0cf391eb9c..0000000000 --- a/arch/arm/cpu/armv7/mx6/ddr.c +++ /dev/null @@ -1,1538 +0,0 @@ -/* - * Copyright (C) 2014 Gateworks Corporation - * Author: Tim Harvey <tharvey@gateworks.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/types.h> -#include <asm/arch/clock.h> -#include <asm/arch/mx6-ddr.h> -#include <asm/arch/sys_proto.h> -#include <asm/io.h> -#include <asm/types.h> -#include <wait_bit.h> - -#if defined(CONFIG_MX6_DDRCAL) -static void reset_read_data_fifos(void) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - - /* Reset data FIFOs twice. */ - setbits_le32(&mmdc0->mpdgctrl0, 1 << 31); - wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0); - - setbits_le32(&mmdc0->mpdgctrl0, 1 << 31); - wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 31, 0, 100, 0); -} - -static void precharge_all(const bool cs0_enable, const bool cs1_enable) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - - /* - * Issue the Precharge-All command to the DDR device for both - * chip selects. Note, CON_REQ bit should also remain set. If - * only using one chip select, then precharge only the desired - * chip select. - */ - if (cs0_enable) { /* CS0 */ - writel(0x04008050, &mmdc0->mdscr); - wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0); - } - - if (cs1_enable) { /* CS1 */ - writel(0x04008058, &mmdc0->mdscr); - wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0); - } -} - -static void force_delay_measurement(int bus_size) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - - writel(0x800, &mmdc0->mpmur0); - if (bus_size == 0x2) - writel(0x800, &mmdc1->mpmur0); -} - -static void modify_dg_result(u32 *reg_st0, u32 *reg_st1, u32 *reg_ctrl) -{ - u32 dg_tmp_val, dg_dl_abs_offset, dg_hc_del, val_ctrl; - - /* - * DQS gating absolute offset should be modified from reflecting - * (HW_DG_LOWx + HW_DG_UPx)/2 to reflecting (HW_DG_UPx - 0x80) - */ - - val_ctrl = readl(reg_ctrl); - val_ctrl &= 0xf0000000; - - dg_tmp_val = ((readl(reg_st0) & 0x07ff0000) >> 16) - 0xc0; - dg_dl_abs_offset = dg_tmp_val & 0x7f; - dg_hc_del = (dg_tmp_val & 0x780) << 1; - - val_ctrl |= dg_dl_abs_offset + dg_hc_del; - - dg_tmp_val = ((readl(reg_st1) & 0x07ff0000) >> 16) - 0xc0; - dg_dl_abs_offset = dg_tmp_val & 0x7f; - dg_hc_del = (dg_tmp_val & 0x780) << 1; - - val_ctrl |= (dg_dl_abs_offset + dg_hc_del) << 16; - - writel(val_ctrl, reg_ctrl); -} - -int mmdc_do_write_level_calibration(struct mx6_ddr_sysinfo const *sysinfo) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - u32 esdmisc_val, zq_val; - u32 errors = 0; - u32 ldectrl[4] = {0}; - u32 ddr_mr1 = 0x4; - u32 rwalat_max; - - /* - * Stash old values in case calibration fails, - * we need to restore them - */ - ldectrl[0] = readl(&mmdc0->mpwldectrl0); - ldectrl[1] = readl(&mmdc0->mpwldectrl1); - if (sysinfo->dsize == 2) { - ldectrl[2] = readl(&mmdc1->mpwldectrl0); - ldectrl[3] = readl(&mmdc1->mpwldectrl1); - } - - /* disable DDR logic power down timer */ - clrbits_le32(&mmdc0->mdpdc, 0xff00); - - /* disable Adopt power down timer */ - setbits_le32(&mmdc0->mapsr, 0x1); - - debug("Starting write leveling calibration.\n"); - - /* - * 2. disable auto refresh and ZQ calibration - * before proceeding with Write Leveling calibration - */ - esdmisc_val = readl(&mmdc0->mdref); - writel(0x0000C000, &mmdc0->mdref); - zq_val = readl(&mmdc0->mpzqhwctrl); - writel(zq_val & ~0x3, &mmdc0->mpzqhwctrl); - - /* 3. increase walat and ralat to maximum */ - rwalat_max = (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17); - setbits_le32(&mmdc0->mdmisc, rwalat_max); - if (sysinfo->dsize == 2) - setbits_le32(&mmdc1->mdmisc, rwalat_max); - /* - * 4 & 5. Configure the external DDR device to enter write-leveling - * mode through Load Mode Register command. - * Register setting: - * Bits[31:16] MR1 value (0x0080 write leveling enable) - * Bit[9] set WL_EN to enable MMDC DQS output - * Bits[6:4] set CMD bits for Load Mode Register programming - * Bits[2:0] set CMD_BA to 0x1 for DDR MR1 programming - */ - writel(0x00808231, &mmdc0->mdscr); - - /* 6. Activate automatic calibration by setting MPWLGCR[HW_WL_EN] */ - writel(0x00000001, &mmdc0->mpwlgcr); - - /* - * 7. Upon completion of this process the MMDC de-asserts - * the MPWLGCR[HW_WL_EN] - */ - wait_for_bit("MMDC", &mmdc0->mpwlgcr, 1 << 0, 0, 100, 0); - - /* - * 8. check for any errors: check both PHYs for x64 configuration, - * if x32, check only PHY0 - */ - if (readl(&mmdc0->mpwlgcr) & 0x00000F00) - errors |= 1; - if (sysinfo->dsize == 2) - if (readl(&mmdc1->mpwlgcr) & 0x00000F00) - errors |= 2; - - debug("Ending write leveling calibration. Error mask: 0x%x\n", errors); - - /* check to see if cal failed */ - if ((readl(&mmdc0->mpwldectrl0) == 0x001F001F) && - (readl(&mmdc0->mpwldectrl1) == 0x001F001F) && - ((sysinfo->dsize < 2) || - ((readl(&mmdc1->mpwldectrl0) == 0x001F001F) && - (readl(&mmdc1->mpwldectrl1) == 0x001F001F)))) { - debug("Cal seems to have soft-failed due to memory not supporting write leveling on all channels. Restoring original write leveling values.\n"); - writel(ldectrl[0], &mmdc0->mpwldectrl0); - writel(ldectrl[1], &mmdc0->mpwldectrl1); - if (sysinfo->dsize == 2) { - writel(ldectrl[2], &mmdc1->mpwldectrl0); - writel(ldectrl[3], &mmdc1->mpwldectrl1); - } - errors |= 4; - } - - /* - * User should issue MRS command to exit write leveling mode - * through Load Mode Register command - * Register setting: - * Bits[31:16] MR1 value "ddr_mr1" value from initialization - * Bit[9] clear WL_EN to disable MMDC DQS output - * Bits[6:4] set CMD bits for Load Mode Register programming - * Bits[2:0] set CMD_BA to 0x1 for DDR MR1 programming - */ - writel((ddr_mr1 << 16) + 0x8031, &mmdc0->mdscr); - - /* re-enable auto refresh and zq cal */ - writel(esdmisc_val, &mmdc0->mdref); - writel(zq_val, &mmdc0->mpzqhwctrl); - - debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n", - readl(&mmdc0->mpwldectrl0)); - debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n", - readl(&mmdc0->mpwldectrl1)); - if (sysinfo->dsize == 2) { - debug("\tMMDC_MPWLDECTRL0 after write level cal: 0x%08X\n", - readl(&mmdc1->mpwldectrl0)); - debug("\tMMDC_MPWLDECTRL1 after write level cal: 0x%08X\n", - readl(&mmdc1->mpwldectrl1)); - } - - /* We must force a readback of these values, to get them to stick */ - readl(&mmdc0->mpwldectrl0); - readl(&mmdc0->mpwldectrl1); - if (sysinfo->dsize == 2) { - readl(&mmdc1->mpwldectrl0); - readl(&mmdc1->mpwldectrl1); - } - - /* enable DDR logic power down timer: */ - setbits_le32(&mmdc0->mdpdc, 0x00005500); - - /* Enable Adopt power down timer: */ - clrbits_le32(&mmdc0->mapsr, 0x1); - - /* Clear CON_REQ */ - writel(0, &mmdc0->mdscr); - - return errors; -} - -int mmdc_do_dqs_calibration(struct mx6_ddr_sysinfo const *sysinfo) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux = - (struct mx6dq_iomux_ddr_regs *)MX6DQ_IOM_DDR_BASE; - bool cs0_enable; - bool cs1_enable; - bool cs0_enable_initial; - bool cs1_enable_initial; - u32 esdmisc_val; - u32 temp_ref; - u32 pddword = 0x00ffff00; /* best so far, place into MPPDCMPR1 */ - u32 errors = 0; - u32 initdelay = 0x40404040; - - /* check to see which chip selects are enabled */ - cs0_enable_initial = readl(&mmdc0->mdctl) & 0x80000000; - cs1_enable_initial = readl(&mmdc0->mdctl) & 0x40000000; - - /* disable DDR logic power down timer: */ - clrbits_le32(&mmdc0->mdpdc, 0xff00); - - /* disable Adopt power down timer: */ - setbits_le32(&mmdc0->mapsr, 0x1); - - /* set DQS pull ups */ - setbits_le32(&mx6_ddr_iomux->dram_sdqs0, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs1, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs2, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs3, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs4, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs5, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs6, 0x7000); - setbits_le32(&mx6_ddr_iomux->dram_sdqs7, 0x7000); - - /* Save old RALAT and WALAT values */ - esdmisc_val = readl(&mmdc0->mdmisc); - - setbits_le32(&mmdc0->mdmisc, - (1 << 6) | (1 << 7) | (1 << 8) | (1 << 16) | (1 << 17)); - - /* Disable auto refresh before proceeding with calibration */ - temp_ref = readl(&mmdc0->mdref); - writel(0x0000c000, &mmdc0->mdref); - - /* - * Per the ref manual, issue one refresh cycle MDSCR[CMD]= 0x2, - * this also sets the CON_REQ bit. - */ - if (cs0_enable_initial) - writel(0x00008020, &mmdc0->mdscr); - if (cs1_enable_initial) - writel(0x00008028, &mmdc0->mdscr); - - /* poll to make sure the con_ack bit was asserted */ - wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 1, 100, 0); - - /* - * Check MDMISC register CALIB_PER_CS to see which CS calibration - * is targeted to (under normal cases, it should be cleared - * as this is the default value, indicating calibration is directed - * to CS0). - * Disable the other chip select not being target for calibration - * to avoid any potential issues. This will get re-enabled at end - * of calibration. - */ - if ((readl(&mmdc0->mdmisc) & 0x00100000) == 0) - clrbits_le32(&mmdc0->mdctl, 1 << 30); /* clear SDE_1 */ - else - clrbits_le32(&mmdc0->mdctl, 1 << 31); /* clear SDE_0 */ - - /* - * Check to see which chip selects are now enabled for - * the remainder of the calibration. - */ - cs0_enable = readl(&mmdc0->mdctl) & 0x80000000; - cs1_enable = readl(&mmdc0->mdctl) & 0x40000000; - - precharge_all(cs0_enable, cs1_enable); - - /* Write the pre-defined value into MPPDCMPR1 */ - writel(pddword, &mmdc0->mppdcmpr1); - - /* - * Issue a write access to the external DDR device by setting - * the bit SW_DUMMY_WR (bit 0) in the MPSWDAR0 and then poll - * this bit until it clears to indicate completion of the write access. - */ - setbits_le32(&mmdc0->mpswdar0, 1); - wait_for_bit("MMDC", &mmdc0->mpswdar0, 1 << 0, 0, 100, 0); - - /* Set the RD_DL_ABS# bits to their default values - * (will be calibrated later in the read delay-line calibration). - * Both PHYs for x64 configuration, if x32, do only PHY0. - */ - writel(initdelay, &mmdc0->mprddlctl); - if (sysinfo->dsize == 0x2) - writel(initdelay, &mmdc1->mprddlctl); - - /* Force a measurment, for previous delay setup to take effect. */ - force_delay_measurement(sysinfo->dsize); - - /* - * *************************** - * Read DQS Gating calibration - * *************************** - */ - debug("Starting Read DQS Gating calibration.\n"); - - /* - * Reset the read data FIFOs (two resets); only need to issue reset - * to PHY0 since in x64 mode, the reset will also go to PHY1. - */ - reset_read_data_fifos(); - - /* - * Start the automatic read DQS gating calibration process by - * asserting MPDGCTRL0[HW_DG_EN] and MPDGCTRL0[DG_CMP_CYC] - * and then poll MPDGCTRL0[HW_DG_EN]] until this bit clears - * to indicate completion. - * Also, ensure that MPDGCTRL0[HW_DG_ERR] is clear to indicate - * no errors were seen during calibration. - */ - - /* - * Set bit 30: chooses option to wait 32 cycles instead of - * 16 before comparing read data. - */ - setbits_le32(&mmdc0->mpdgctrl0, 1 << 30); - if (sysinfo->dsize == 2) - setbits_le32(&mmdc1->mpdgctrl0, 1 << 30); - - /* Set bit 28 to start automatic read DQS gating calibration */ - setbits_le32(&mmdc0->mpdgctrl0, 5 << 28); - - /* Poll for completion. MPDGCTRL0[HW_DG_EN] should be 0 */ - wait_for_bit("MMDC", &mmdc0->mpdgctrl0, 1 << 28, 0, 100, 0); - - /* - * Check to see if any errors were encountered during calibration - * (check MPDGCTRL0[HW_DG_ERR]). - * Check both PHYs for x64 configuration, if x32, check only PHY0. - */ - if (readl(&mmdc0->mpdgctrl0) & 0x00001000) - errors |= 1; - - if ((sysinfo->dsize == 0x2) && (readl(&mmdc1->mpdgctrl0) & 0x00001000)) - errors |= 2; - - /* now disable mpdgctrl0[DG_CMP_CYC] */ - clrbits_le32(&mmdc0->mpdgctrl0, 1 << 30); - if (sysinfo->dsize == 2) - clrbits_le32(&mmdc1->mpdgctrl0, 1 << 30); - - /* - * DQS gating absolute offset should be modified from - * reflecting (HW_DG_LOWx + HW_DG_UPx)/2 to - * reflecting (HW_DG_UPx - 0x80) - */ - modify_dg_result(&mmdc0->mpdghwst0, &mmdc0->mpdghwst1, - &mmdc0->mpdgctrl0); - modify_dg_result(&mmdc0->mpdghwst2, &mmdc0->mpdghwst3, - &mmdc0->mpdgctrl1); - if (sysinfo->dsize == 0x2) { - modify_dg_result(&mmdc1->mpdghwst0, &mmdc1->mpdghwst1, - &mmdc1->mpdgctrl0); - modify_dg_result(&mmdc1->mpdghwst2, &mmdc1->mpdghwst3, - &mmdc1->mpdgctrl1); - } - debug("Ending Read DQS Gating calibration. Error mask: 0x%x\n", errors); - - /* - * ********************** - * Read Delay calibration - * ********************** - */ - debug("Starting Read Delay calibration.\n"); - - reset_read_data_fifos(); - - /* - * 4. Issue the Precharge-All command to the DDR device for both - * chip selects. If only using one chip select, then precharge - * only the desired chip select. - */ - precharge_all(cs0_enable, cs1_enable); - - /* - * 9. Read delay-line calibration - * Start the automatic read calibration process by asserting - * MPRDDLHWCTL[HW_RD_DL_EN]. - */ - writel(0x00000030, &mmdc0->mprddlhwctl); - - /* - * 10. poll for completion - * MMDC indicates that the write data calibration had finished by - * setting MPRDDLHWCTL[HW_RD_DL_EN] = 0. Also, ensure that - * no error bits were set. - */ - wait_for_bit("MMDC", &mmdc0->mprddlhwctl, 1 << 4, 0, 100, 0); - - /* check both PHYs for x64 configuration, if x32, check only PHY0 */ - if (readl(&mmdc0->mprddlhwctl) & 0x0000000f) - errors |= 4; - - if ((sysinfo->dsize == 0x2) && - (readl(&mmdc1->mprddlhwctl) & 0x0000000f)) - errors |= 8; - - debug("Ending Read Delay calibration. Error mask: 0x%x\n", errors); - - /* - * *********************** - * Write Delay Calibration - * *********************** - */ - debug("Starting Write Delay calibration.\n"); - - reset_read_data_fifos(); - - /* - * 4. Issue the Precharge-All command to the DDR device for both - * chip selects. If only using one chip select, then precharge - * only the desired chip select. - */ - precharge_all(cs0_enable, cs1_enable); - - /* - * 8. Set the WR_DL_ABS# bits to their default values. - * Both PHYs for x64 configuration, if x32, do only PHY0. - */ - writel(initdelay, &mmdc0->mpwrdlctl); - if (sysinfo->dsize == 0x2) - writel(initdelay, &mmdc1->mpwrdlctl); - - /* - * XXX This isn't in the manual. Force a measurement, - * for previous delay setup to effect. - */ - force_delay_measurement(sysinfo->dsize); - - /* - * 9. 10. Start the automatic write calibration process - * by asserting MPWRDLHWCTL0[HW_WR_DL_EN]. - */ - writel(0x00000030, &mmdc0->mpwrdlhwctl); - - /* - * Poll for completion. - * MMDC indicates that the write data calibration had finished - * by setting MPWRDLHWCTL[HW_WR_DL_EN] = 0. - * Also, ensure that no error bits were set. - */ - wait_for_bit("MMDC", &mmdc0->mpwrdlhwctl, 1 << 4, 0, 100, 0); - - /* Check both PHYs for x64 configuration, if x32, check only PHY0 */ - if (readl(&mmdc0->mpwrdlhwctl) & 0x0000000f) - errors |= 16; - - if ((sysinfo->dsize == 0x2) && - (readl(&mmdc1->mpwrdlhwctl) & 0x0000000f)) - errors |= 32; - - debug("Ending Write Delay calibration. Error mask: 0x%x\n", errors); - - reset_read_data_fifos(); - - /* Enable DDR logic power down timer */ - setbits_le32(&mmdc0->mdpdc, 0x00005500); - - /* Enable Adopt power down timer */ - clrbits_le32(&mmdc0->mapsr, 0x1); - - /* Restore MDMISC value (RALAT, WALAT) to MMDCP1 */ - writel(esdmisc_val, &mmdc0->mdmisc); - - /* Clear DQS pull ups */ - clrbits_le32(&mx6_ddr_iomux->dram_sdqs0, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs1, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs2, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs3, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs4, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs5, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs6, 0x7000); - clrbits_le32(&mx6_ddr_iomux->dram_sdqs7, 0x7000); - - /* Re-enable SDE (chip selects) if they were set initially */ - if (cs1_enable_initial) - /* Set SDE_1 */ - setbits_le32(&mmdc0->mdctl, 1 << 30); - - if (cs0_enable_initial) - /* Set SDE_0 */ - setbits_le32(&mmdc0->mdctl, 1 << 31); - - /* Re-enable to auto refresh */ - writel(temp_ref, &mmdc0->mdref); - - /* Clear the MDSCR (including the con_req bit) */ - writel(0x0, &mmdc0->mdscr); /* CS0 */ - - /* Poll to make sure the con_ack bit is clear */ - wait_for_bit("MMDC", &mmdc0->mdscr, 1 << 14, 0, 100, 0); - - /* - * Print out the registers that were updated as a result - * of the calibration process. - */ - debug("MMDC registers updated from calibration\n"); - debug("Read DQS gating calibration:\n"); - debug("\tMPDGCTRL0 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl0)); - debug("\tMPDGCTRL1 PHY0 = 0x%08X\n", readl(&mmdc0->mpdgctrl1)); - if (sysinfo->dsize == 2) { - debug("\tMPDGCTRL0 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl0)); - debug("\tMPDGCTRL1 PHY1 = 0x%08X\n", readl(&mmdc1->mpdgctrl1)); - } - debug("Read calibration:\n"); - debug("\tMPRDDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mprddlctl)); - if (sysinfo->dsize == 2) - debug("\tMPRDDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mprddlctl)); - debug("Write calibration:\n"); - debug("\tMPWRDLCTL PHY0 = 0x%08X\n", readl(&mmdc0->mpwrdlctl)); - if (sysinfo->dsize == 2) - debug("\tMPWRDLCTL PHY1 = 0x%08X\n", readl(&mmdc1->mpwrdlctl)); - - /* - * Registers below are for debugging purposes. These print out - * the upper and lower boundaries captured during - * read DQS gating calibration. - */ - debug("Status registers bounds for read DQS gating:\n"); - debug("\tMPDGHWST0 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst0)); - debug("\tMPDGHWST1 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst1)); - debug("\tMPDGHWST2 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst2)); - debug("\tMPDGHWST3 PHY0 = 0x%08x\n", readl(&mmdc0->mpdghwst3)); - if (sysinfo->dsize == 2) { - debug("\tMPDGHWST0 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst0)); - debug("\tMPDGHWST1 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst1)); - debug("\tMPDGHWST2 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst2)); - debug("\tMPDGHWST3 PHY1 = 0x%08x\n", readl(&mmdc1->mpdghwst3)); - } - - debug("Final do_dqs_calibration error mask: 0x%x\n", errors); - - return errors; -} -#endif - -#if defined(CONFIG_MX6SX) -/* Configure MX6SX mmdc iomux */ -void mx6sx_dram_iocfg(unsigned width, - const struct mx6sx_iomux_ddr_regs *ddr, - const struct mx6sx_iomux_grp_regs *grp) -{ - struct mx6sx_iomux_ddr_regs *mx6_ddr_iomux; - struct mx6sx_iomux_grp_regs *mx6_grp_iomux; - - mx6_ddr_iomux = (struct mx6sx_iomux_ddr_regs *)MX6SX_IOM_DDR_BASE; - mx6_grp_iomux = (struct mx6sx_iomux_grp_regs *)MX6SX_IOM_GRP_BASE; - - /* DDR IO TYPE */ - writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type); - writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke); - - /* CLOCK */ - writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0); - - /* ADDRESS */ - writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas); - writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras); - writel(grp->grp_addds, &mx6_grp_iomux->grp_addds); - - /* Control */ - writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset); - writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2); - writel(ddr->dram_sdcke0, &mx6_ddr_iomux->dram_sdcke0); - writel(ddr->dram_sdcke1, &mx6_ddr_iomux->dram_sdcke1); - writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0); - writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1); - writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds); - - /* Data Strobes */ - writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl); - writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0); - writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1); - if (width >= 32) { - writel(ddr->dram_sdqs2, &mx6_ddr_iomux->dram_sdqs2); - writel(ddr->dram_sdqs3, &mx6_ddr_iomux->dram_sdqs3); - } - - /* Data */ - writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode); - writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds); - writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds); - if (width >= 32) { - writel(grp->grp_b2ds, &mx6_grp_iomux->grp_b2ds); - writel(grp->grp_b3ds, &mx6_grp_iomux->grp_b3ds); - } - writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0); - writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1); - if (width >= 32) { - writel(ddr->dram_dqm2, &mx6_ddr_iomux->dram_dqm2); - writel(ddr->dram_dqm3, &mx6_ddr_iomux->dram_dqm3); - } -} -#endif - -#ifdef CONFIG_MX6UL -void mx6ul_dram_iocfg(unsigned width, - const struct mx6ul_iomux_ddr_regs *ddr, - const struct mx6ul_iomux_grp_regs *grp) -{ - struct mx6ul_iomux_ddr_regs *mx6_ddr_iomux; - struct mx6ul_iomux_grp_regs *mx6_grp_iomux; - - mx6_ddr_iomux = (struct mx6ul_iomux_ddr_regs *)MX6UL_IOM_DDR_BASE; - mx6_grp_iomux = (struct mx6ul_iomux_grp_regs *)MX6UL_IOM_GRP_BASE; - - /* DDR IO TYPE */ - writel(grp->grp_ddr_type, &mx6_grp_iomux->grp_ddr_type); - writel(grp->grp_ddrpke, &mx6_grp_iomux->grp_ddrpke); - - /* CLOCK */ - writel(ddr->dram_sdclk_0, &mx6_ddr_iomux->dram_sdclk_0); - - /* ADDRESS */ - writel(ddr->dram_cas, &mx6_ddr_iomux->dram_cas); - writel(ddr->dram_ras, &mx6_ddr_iomux->dram_ras); - writel(grp->grp_addds, &mx6_grp_iomux->grp_addds); - - /* Control */ - writel(ddr->dram_reset, &mx6_ddr_iomux->dram_reset); - writel(ddr->dram_sdba2, &mx6_ddr_iomux->dram_sdba2); - writel(ddr->dram_odt0, &mx6_ddr_iomux->dram_odt0); - writel(ddr->dram_odt1, &mx6_ddr_iomux->dram_odt1); - writel(grp->grp_ctlds, &mx6_grp_iomux->grp_ctlds); - - /* Data Strobes */ - writel(grp->grp_ddrmode_ctl, &mx6_grp_iomux->grp_ddrmode_ctl); - writel(ddr->dram_sdqs0, &mx6_ddr_iomux->dram_sdqs0); - writel(ddr->dram_sdqs1, &mx6_ddr_iomux->dram_sdqs1); - - /* Data */ - writel(grp->grp_ddrmode, &mx6_grp_iomux->grp_ddrmode); - writel(grp->grp_b0ds, &mx6_grp_iomux->grp_b0ds); - writel(grp->grp_b1ds, &mx6_grp_iomux->grp_b1ds); - writel(ddr->dram_dqm0, &mx6_ddr_iomux->dram_dqm0); - writel(ddr->dram_dqm1, &mx6_ddr_iomux->dram_dqm1); -} -#endif - -#if defined(CONFIG_MX6SL) -void mx6sl_dram_iocfg(unsigned width, - const struct mx6sl_iomux_ddr_regs *ddr, - const struct mx6sl_iomux_grp_regs *grp) -{ - struct mx6sl_iomux_ddr_regs *mx6_ddr_iomux; - struct mx6sl_iomux_grp_regs *mx6_grp_iomux; - - mx6_ddr_iomux = (struct mx6sl_iomux_ddr_regs *)MX6SL_IOM_DDR_BASE; - mx6_grp_iomux = (struct mx6sl_iomux_grp_regs *)MX6SL_IOM_GRP_BASE; - - /* DDR IO TYPE */ - mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; - mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; - - /* CLOCK */ - mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; - - /* ADDRESS */ - mx6_ddr_iomux->dram_cas = ddr->dram_cas; - mx6_ddr_iomux->dram_ras = ddr->dram_ras; - mx6_grp_iomux->grp_addds = grp->grp_addds; - - /* Control */ - mx6_ddr_iomux->dram_reset = ddr->dram_reset; - mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; - mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; - - /* Data Strobes */ - mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; - mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; - mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; - if (width >= 32) { - mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; - mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; - } - - /* Data */ - mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; - mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; - mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; - if (width >= 32) { - mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; - mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; - } - - mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; - mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; - if (width >= 32) { - mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; - mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; - } -} -#endif - -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6Q) || defined(CONFIG_MX6D) -/* Configure MX6DQ mmdc iomux */ -void mx6dq_dram_iocfg(unsigned width, - const struct mx6dq_iomux_ddr_regs *ddr, - const struct mx6dq_iomux_grp_regs *grp) -{ - volatile struct mx6dq_iomux_ddr_regs *mx6_ddr_iomux; - volatile struct mx6dq_iomux_grp_regs *mx6_grp_iomux; - - mx6_ddr_iomux = (struct mx6dq_iomux_ddr_regs *)MX6DQ_IOM_DDR_BASE; - mx6_grp_iomux = (struct mx6dq_iomux_grp_regs *)MX6DQ_IOM_GRP_BASE; - - /* DDR IO Type */ - mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; - mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; - - /* Clock */ - mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; - mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; - - /* Address */ - mx6_ddr_iomux->dram_cas = ddr->dram_cas; - mx6_ddr_iomux->dram_ras = ddr->dram_ras; - mx6_grp_iomux->grp_addds = grp->grp_addds; - - /* Control */ - mx6_ddr_iomux->dram_reset = ddr->dram_reset; - mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; - mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; - mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; - mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; - mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; - mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; - - /* Data Strobes */ - mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; - mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; - mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; - if (width >= 32) { - mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; - mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; - } - if (width >= 64) { - mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; - mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; - mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; - mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; - } - - /* Data */ - mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; - mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; - mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; - if (width >= 32) { - mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; - mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; - } - if (width >= 64) { - mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; - mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; - mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; - mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; - } - mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; - mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; - if (width >= 32) { - mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; - mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; - } - if (width >= 64) { - mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; - mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; - mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; - mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; - } -} -#endif - -#if defined(CONFIG_MX6QDL) || defined(CONFIG_MX6DL) || defined(CONFIG_MX6S) -/* Configure MX6SDL mmdc iomux */ -void mx6sdl_dram_iocfg(unsigned width, - const struct mx6sdl_iomux_ddr_regs *ddr, - const struct mx6sdl_iomux_grp_regs *grp) -{ - volatile struct mx6sdl_iomux_ddr_regs *mx6_ddr_iomux; - volatile struct mx6sdl_iomux_grp_regs *mx6_grp_iomux; - - mx6_ddr_iomux = (struct mx6sdl_iomux_ddr_regs *)MX6SDL_IOM_DDR_BASE; - mx6_grp_iomux = (struct mx6sdl_iomux_grp_regs *)MX6SDL_IOM_GRP_BASE; - - /* DDR IO Type */ - mx6_grp_iomux->grp_ddr_type = grp->grp_ddr_type; - mx6_grp_iomux->grp_ddrpke = grp->grp_ddrpke; - - /* Clock */ - mx6_ddr_iomux->dram_sdclk_0 = ddr->dram_sdclk_0; - mx6_ddr_iomux->dram_sdclk_1 = ddr->dram_sdclk_1; - - /* Address */ - mx6_ddr_iomux->dram_cas = ddr->dram_cas; - mx6_ddr_iomux->dram_ras = ddr->dram_ras; - mx6_grp_iomux->grp_addds = grp->grp_addds; - - /* Control */ - mx6_ddr_iomux->dram_reset = ddr->dram_reset; - mx6_ddr_iomux->dram_sdcke0 = ddr->dram_sdcke0; - mx6_ddr_iomux->dram_sdcke1 = ddr->dram_sdcke1; - mx6_ddr_iomux->dram_sdba2 = ddr->dram_sdba2; - mx6_ddr_iomux->dram_sdodt0 = ddr->dram_sdodt0; - mx6_ddr_iomux->dram_sdodt1 = ddr->dram_sdodt1; - mx6_grp_iomux->grp_ctlds = grp->grp_ctlds; - - /* Data Strobes */ - mx6_grp_iomux->grp_ddrmode_ctl = grp->grp_ddrmode_ctl; - mx6_ddr_iomux->dram_sdqs0 = ddr->dram_sdqs0; - mx6_ddr_iomux->dram_sdqs1 = ddr->dram_sdqs1; - if (width >= 32) { - mx6_ddr_iomux->dram_sdqs2 = ddr->dram_sdqs2; - mx6_ddr_iomux->dram_sdqs3 = ddr->dram_sdqs3; - } - if (width >= 64) { - mx6_ddr_iomux->dram_sdqs4 = ddr->dram_sdqs4; - mx6_ddr_iomux->dram_sdqs5 = ddr->dram_sdqs5; - mx6_ddr_iomux->dram_sdqs6 = ddr->dram_sdqs6; - mx6_ddr_iomux->dram_sdqs7 = ddr->dram_sdqs7; - } - - /* Data */ - mx6_grp_iomux->grp_ddrmode = grp->grp_ddrmode; - mx6_grp_iomux->grp_b0ds = grp->grp_b0ds; - mx6_grp_iomux->grp_b1ds = grp->grp_b1ds; - if (width >= 32) { - mx6_grp_iomux->grp_b2ds = grp->grp_b2ds; - mx6_grp_iomux->grp_b3ds = grp->grp_b3ds; - } - if (width >= 64) { - mx6_grp_iomux->grp_b4ds = grp->grp_b4ds; - mx6_grp_iomux->grp_b5ds = grp->grp_b5ds; - mx6_grp_iomux->grp_b6ds = grp->grp_b6ds; - mx6_grp_iomux->grp_b7ds = grp->grp_b7ds; - } - mx6_ddr_iomux->dram_dqm0 = ddr->dram_dqm0; - mx6_ddr_iomux->dram_dqm1 = ddr->dram_dqm1; - if (width >= 32) { - mx6_ddr_iomux->dram_dqm2 = ddr->dram_dqm2; - mx6_ddr_iomux->dram_dqm3 = ddr->dram_dqm3; - } - if (width >= 64) { - mx6_ddr_iomux->dram_dqm4 = ddr->dram_dqm4; - mx6_ddr_iomux->dram_dqm5 = ddr->dram_dqm5; - mx6_ddr_iomux->dram_dqm6 = ddr->dram_dqm6; - mx6_ddr_iomux->dram_dqm7 = ddr->dram_dqm7; - } -} -#endif - -/* - * Configure mx6 mmdc registers based on: - * - board-specific memory configuration - * - board-specific calibration data - * - ddr3/lpddr2 chip details - * - * The various calculations here are derived from the Freescale - * 1. i.Mx6DQSDL DDR3 Script Aid spreadsheet (DOC-94917) designed to generate - * MMDC configuration registers based on memory system and memory chip - * parameters. - * - * 2. i.Mx6SL LPDDR2 Script Aid spreadsheet V0.04 designed to generate MMDC - * configuration registers based on memory system and memory chip - * parameters. - * - * The defaults here are those which were specified in the spreadsheet. - * For details on each register, refer to the IMX6DQRM and/or IMX6SDLRM - * and/or IMX6SLRM section titled MMDC initialization. - */ -#define MR(val, ba, cmd, cs1) \ - ((val << 16) | (1 << 15) | (cmd << 4) | (cs1 << 3) | ba) -#define MMDC1(entry, value) do { \ - if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl()) \ - mmdc1->entry = value; \ - } while (0) - -/* - * According JESD209-2B-LPDDR2: Table 103 - * WL: write latency - */ -static int lpddr2_wl(uint32_t mem_speed) -{ - switch (mem_speed) { - case 1066: - case 933: - return 4; - case 800: - return 3; - case 677: - case 533: - return 2; - case 400: - case 333: - return 1; - default: - puts("invalid memory speed\n"); - hang(); - } - - return 0; -} - -/* - * According JESD209-2B-LPDDR2: Table 103 - * RL: read latency - */ -static int lpddr2_rl(uint32_t mem_speed) -{ - switch (mem_speed) { - case 1066: - return 8; - case 933: - return 7; - case 800: - return 6; - case 677: - return 5; - case 533: - return 4; - case 400: - case 333: - return 3; - default: - puts("invalid memory speed\n"); - hang(); - } - - return 0; -} - -void mx6_lpddr2_cfg(const struct mx6_ddr_sysinfo *sysinfo, - const struct mx6_mmdc_calibration *calib, - const struct mx6_lpddr2_cfg *lpddr2_cfg) -{ - volatile struct mmdc_p_regs *mmdc0; - u32 val; - u8 tcke, tcksrx, tcksre, trrd; - u8 twl, txp, tfaw, tcl; - u16 tras, twr, tmrd, trtp, twtr, trfc, txsr; - u16 trcd_lp, trppb_lp, trpab_lp, trc_lp; - u16 cs0_end; - u8 coladdr; - int clkper; /* clock period in picoseconds */ - int clock; /* clock freq in mHz */ - int cs; - - /* only support 16/32 bits */ - if (sysinfo->dsize > 1) - hang(); - - mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - - clock = mxc_get_clock(MXC_DDR_CLK) / 1000000U; - clkper = (1000 * 1000) / clock; /* pico seconds */ - - twl = lpddr2_wl(lpddr2_cfg->mem_speed) - 1; - - /* LPDDR2-S2 and LPDDR2-S4 have the same tRFC value. */ - switch (lpddr2_cfg->density) { - case 1: - case 2: - case 4: - trfc = DIV_ROUND_UP(130000, clkper) - 1; - txsr = DIV_ROUND_UP(140000, clkper) - 1; - break; - case 8: - trfc = DIV_ROUND_UP(210000, clkper) - 1; - txsr = DIV_ROUND_UP(220000, clkper) - 1; - break; - default: - /* - * 64Mb, 128Mb, 256Mb, 512Mb are not supported currently. - */ - hang(); - break; - } - /* - * txpdll, txpr, taonpd and taofpd are not relevant in LPDDR2 mode, - * set them to 0. */ - txp = DIV_ROUND_UP(7500, clkper) - 1; - tcke = 3; - if (lpddr2_cfg->mem_speed == 333) - tfaw = DIV_ROUND_UP(60000, clkper) - 1; - else - tfaw = DIV_ROUND_UP(50000, clkper) - 1; - trrd = DIV_ROUND_UP(10000, clkper) - 1; - - /* tckesr for LPDDR2 */ - tcksre = DIV_ROUND_UP(15000, clkper); - tcksrx = tcksre; - twr = DIV_ROUND_UP(15000, clkper) - 1; - /* - * tMRR: 2, tMRW: 5 - * tMRD should be set to max(tMRR, tMRW) - */ - tmrd = 5; - tras = DIV_ROUND_UP(lpddr2_cfg->trasmin, clkper / 10) - 1; - /* LPDDR2 mode use tRCD_LP filed in MDCFG3. */ - trcd_lp = DIV_ROUND_UP(lpddr2_cfg->trcd_lp, clkper / 10) - 1; - trc_lp = DIV_ROUND_UP(lpddr2_cfg->trasmin + lpddr2_cfg->trppb_lp, - clkper / 10) - 1; - trppb_lp = DIV_ROUND_UP(lpddr2_cfg->trppb_lp, clkper / 10) - 1; - trpab_lp = DIV_ROUND_UP(lpddr2_cfg->trpab_lp, clkper / 10) - 1; - /* To LPDDR2, CL in MDCFG0 refers to RL */ - tcl = lpddr2_rl(lpddr2_cfg->mem_speed) - 3; - twtr = DIV_ROUND_UP(7500, clkper) - 1; - trtp = DIV_ROUND_UP(7500, clkper) - 1; - - cs0_end = 4 * sysinfo->cs_density - 1; - - debug("density:%d Gb (%d Gb per chip)\n", - sysinfo->cs_density, lpddr2_cfg->density); - debug("clock: %dMHz (%d ps)\n", clock, clkper); - debug("memspd:%d\n", lpddr2_cfg->mem_speed); - debug("trcd_lp=%d\n", trcd_lp); - debug("trppb_lp=%d\n", trppb_lp); - debug("trpab_lp=%d\n", trpab_lp); - debug("trc_lp=%d\n", trc_lp); - debug("tcke=%d\n", tcke); - debug("tcksrx=%d\n", tcksrx); - debug("tcksre=%d\n", tcksre); - debug("trfc=%d\n", trfc); - debug("txsr=%d\n", txsr); - debug("txp=%d\n", txp); - debug("tfaw=%d\n", tfaw); - debug("tcl=%d\n", tcl); - debug("tras=%d\n", tras); - debug("twr=%d\n", twr); - debug("tmrd=%d\n", tmrd); - debug("twl=%d\n", twl); - debug("trtp=%d\n", trtp); - debug("twtr=%d\n", twtr); - debug("trrd=%d\n", trrd); - debug("cs0_end=%d\n", cs0_end); - debug("ncs=%d\n", sysinfo->ncs); - - /* - * board-specific configuration: - * These values are determined empirically and vary per board layout - */ - mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0; - mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1; - mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0; - mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; - mmdc0->mprddlctl = calib->p0_mprddlctl; - mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; - mmdc0->mpzqlp2ctl = calib->mpzqlp2ctl; - - /* Read data DQ Byte0-3 delay */ - mmdc0->mprddqby0dl = 0x33333333; - mmdc0->mprddqby1dl = 0x33333333; - if (sysinfo->dsize > 0) { - mmdc0->mprddqby2dl = 0x33333333; - mmdc0->mprddqby3dl = 0x33333333; - } - - /* Write data DQ Byte0-3 delay */ - mmdc0->mpwrdqby0dl = 0xf3333333; - mmdc0->mpwrdqby1dl = 0xf3333333; - if (sysinfo->dsize > 0) { - mmdc0->mpwrdqby2dl = 0xf3333333; - mmdc0->mpwrdqby3dl = 0xf3333333; - } - - /* - * In LPDDR2 mode this register should be cleared, - * so no termination will be activated. - */ - mmdc0->mpodtctrl = 0; - - /* complete calibration */ - val = (1 << 11); /* Force measurement on delay-lines */ - mmdc0->mpmur0 = val; - - /* Step 1: configuration request */ - mmdc0->mdscr = (u32)(1 << 15); /* config request */ - - /* Step 2: Timing configuration */ - mmdc0->mdcfg0 = (trfc << 24) | (txsr << 16) | (txp << 13) | - (tfaw << 4) | tcl; - mmdc0->mdcfg1 = (tras << 16) | (twr << 9) | (tmrd << 5) | twl; - mmdc0->mdcfg2 = (trtp << 6) | (twtr << 3) | trrd; - mmdc0->mdcfg3lp = (trc_lp << 16) | (trcd_lp << 8) | - (trppb_lp << 4) | trpab_lp; - mmdc0->mdotc = 0; - - mmdc0->mdasp = cs0_end; /* CS addressing */ - - /* Step 3: Configure DDR type */ - mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | - (sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | - (sysinfo->ralat << 6) | (1 << 3); - - /* Step 4: Configure delay while leaving reset */ - mmdc0->mdor = (sysinfo->sde_to_rst << 8) | - (sysinfo->rst_to_cke << 0); - - /* Step 5: Configure DDR physical parameters (density and burst len) */ - coladdr = lpddr2_cfg->coladdr; - if (lpddr2_cfg->coladdr == 8) /* 8-bit COL is 0x3 */ - coladdr += 4; - else if (lpddr2_cfg->coladdr == 12) /* 12-bit COL is 0x4 */ - coladdr += 1; - mmdc0->mdctl = (lpddr2_cfg->rowaddr - 11) << 24 | /* ROW */ - (coladdr - 9) << 20 | /* COL */ - (0 << 19) | /* Burst Length = 4 for LPDDR2 */ - (sysinfo->dsize << 16); /* DDR data bus size */ - - /* Step 6: Perform ZQ calibration */ - val = 0xa1390003; /* one-time HW ZQ calib */ - mmdc0->mpzqhwctrl = val; - - /* Step 7: Enable MMDC with desired chip select */ - mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */ - ((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ - - /* Step 8: Write Mode Registers to Init LPDDR2 devices */ - for (cs = 0; cs < sysinfo->ncs; cs++) { - /* MR63: reset */ - mmdc0->mdscr = MR(63, 0, 3, cs); - /* MR10: calibration, - * 0xff is calibration command after intilization. - */ - val = 0xA | (0xff << 8); - mmdc0->mdscr = MR(val, 0, 3, cs); - /* MR1 */ - val = 0x1 | (0x82 << 8); - mmdc0->mdscr = MR(val, 0, 3, cs); - /* MR2 */ - val = 0x2 | (0x04 << 8); - mmdc0->mdscr = MR(val, 0, 3, cs); - /* MR3 */ - val = 0x3 | (0x02 << 8); - mmdc0->mdscr = MR(val, 0, 3, cs); - } - - /* Step 10: Power down control and self-refresh */ - mmdc0->mdpdc = (tcke & 0x7) << 16 | - 5 << 12 | /* PWDT_1: 256 cycles */ - 5 << 8 | /* PWDT_0: 256 cycles */ - 1 << 6 | /* BOTH_CS_PD */ - (tcksrx & 0x7) << 3 | - (tcksre & 0x7); - mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ - - /* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ - val = 0xa1310003; - mmdc0->mpzqhwctrl = val; - - /* Step 12: Configure and activate periodic refresh */ - mmdc0->mdref = (sysinfo->refsel << 14) | (sysinfo->refr << 11); - - /* Step 13: Deassert config request - init complete */ - mmdc0->mdscr = 0x00000000; - - /* wait for auto-ZQ calibration to complete */ - mdelay(1); -} - -void mx6_ddr3_cfg(const struct mx6_ddr_sysinfo *sysinfo, - const struct mx6_mmdc_calibration *calib, - const struct mx6_ddr3_cfg *ddr3_cfg) -{ - volatile struct mmdc_p_regs *mmdc0; - volatile struct mmdc_p_regs *mmdc1; - u32 val; - u8 tcke, tcksrx, tcksre, txpdll, taofpd, taonpd, trrd; - u8 todtlon, taxpd, tanpd, tcwl, txp, tfaw, tcl; - u8 todt_idle_off = 0x4; /* from DDR3 Script Aid spreadsheet */ - u16 trcd, trc, tras, twr, tmrd, trtp, trp, twtr, trfc, txs, txpr; - u16 cs0_end; - u16 tdllk = 0x1ff; /* DLL locking time: 512 cycles (JEDEC DDR3) */ - u8 coladdr; - int clkper; /* clock period in picoseconds */ - int clock; /* clock freq in MHz */ - int cs; - u16 mem_speed = ddr3_cfg->mem_speed; - - mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - if (!is_mx6sx() && !is_mx6ul() && !is_mx6sl()) - mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - - /* Limit mem_speed for MX6D/MX6Q */ - if (is_mx6dq() || is_mx6dqp()) { - if (mem_speed > 1066) - mem_speed = 1066; /* 1066 MT/s */ - - tcwl = 4; - } - /* Limit mem_speed for MX6S/MX6DL */ - else { - if (mem_speed > 800) - mem_speed = 800; /* 800 MT/s */ - - tcwl = 3; - } - - clock = mem_speed / 2; - /* - * Data rate of 1066 MT/s requires 533 MHz DDR3 clock, but MX6D/Q supports - * up to 528 MHz, so reduce the clock to fit chip specs - */ - if (is_mx6dq() || is_mx6dqp()) { - if (clock > 528) - clock = 528; /* 528 MHz */ - } - - clkper = (1000 * 1000) / clock; /* pico seconds */ - todtlon = tcwl; - taxpd = tcwl; - tanpd = tcwl; - - switch (ddr3_cfg->density) { - case 1: /* 1Gb per chip */ - trfc = DIV_ROUND_UP(110000, clkper) - 1; - txs = DIV_ROUND_UP(120000, clkper) - 1; - break; - case 2: /* 2Gb per chip */ - trfc = DIV_ROUND_UP(160000, clkper) - 1; - txs = DIV_ROUND_UP(170000, clkper) - 1; - break; - case 4: /* 4Gb per chip */ - trfc = DIV_ROUND_UP(260000, clkper) - 1; - txs = DIV_ROUND_UP(270000, clkper) - 1; - break; - case 8: /* 8Gb per chip */ - trfc = DIV_ROUND_UP(350000, clkper) - 1; - txs = DIV_ROUND_UP(360000, clkper) - 1; - break; - default: - /* invalid density */ - puts("invalid chip density\n"); - hang(); - break; - } - txpr = txs; - - switch (mem_speed) { - case 800: - txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; - tcke = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; - if (ddr3_cfg->pagesz == 1) { - tfaw = DIV_ROUND_UP(40000, clkper) - 1; - trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; - } else { - tfaw = DIV_ROUND_UP(50000, clkper) - 1; - trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; - } - break; - case 1066: - txp = DIV_ROUND_UP(max(3 * clkper, 7500), clkper) - 1; - tcke = DIV_ROUND_UP(max(3 * clkper, 5625), clkper) - 1; - if (ddr3_cfg->pagesz == 1) { - tfaw = DIV_ROUND_UP(37500, clkper) - 1; - trrd = DIV_ROUND_UP(max(4 * clkper, 7500), clkper) - 1; - } else { - tfaw = DIV_ROUND_UP(50000, clkper) - 1; - trrd = DIV_ROUND_UP(max(4 * clkper, 10000), clkper) - 1; - } - break; - default: - puts("invalid memory speed\n"); - hang(); - break; - } - txpdll = DIV_ROUND_UP(max(10 * clkper, 24000), clkper) - 1; - tcksre = DIV_ROUND_UP(max(5 * clkper, 10000), clkper); - taonpd = DIV_ROUND_UP(2000, clkper) - 1; - tcksrx = tcksre; - taofpd = taonpd; - twr = DIV_ROUND_UP(15000, clkper) - 1; - tmrd = DIV_ROUND_UP(max(12 * clkper, 15000), clkper) - 1; - trc = DIV_ROUND_UP(ddr3_cfg->trcmin, clkper / 10) - 1; - tras = DIV_ROUND_UP(ddr3_cfg->trasmin, clkper / 10) - 1; - tcl = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 3; - trp = DIV_ROUND_UP(ddr3_cfg->trcd, clkper / 10) - 1; - twtr = ROUND(max(4 * clkper, 7500) / clkper, 1) - 1; - trcd = trp; - trtp = twtr; - cs0_end = 4 * sysinfo->cs_density - 1; - - debug("density:%d Gb (%d Gb per chip)\n", - sysinfo->cs_density, ddr3_cfg->density); - debug("clock: %dMHz (%d ps)\n", clock, clkper); - debug("memspd:%d\n", mem_speed); - debug("tcke=%d\n", tcke); - debug("tcksrx=%d\n", tcksrx); - debug("tcksre=%d\n", tcksre); - debug("taofpd=%d\n", taofpd); - debug("taonpd=%d\n", taonpd); - debug("todtlon=%d\n", todtlon); - debug("tanpd=%d\n", tanpd); - debug("taxpd=%d\n", taxpd); - debug("trfc=%d\n", trfc); - debug("txs=%d\n", txs); - debug("txp=%d\n", txp); - debug("txpdll=%d\n", txpdll); - debug("tfaw=%d\n", tfaw); - debug("tcl=%d\n", tcl); - debug("trcd=%d\n", trcd); - debug("trp=%d\n", trp); - debug("trc=%d\n", trc); - debug("tras=%d\n", tras); - debug("twr=%d\n", twr); - debug("tmrd=%d\n", tmrd); - debug("tcwl=%d\n", tcwl); - debug("tdllk=%d\n", tdllk); - debug("trtp=%d\n", trtp); - debug("twtr=%d\n", twtr); - debug("trrd=%d\n", trrd); - debug("txpr=%d\n", txpr); - debug("cs0_end=%d\n", cs0_end); - debug("ncs=%d\n", sysinfo->ncs); - debug("Rtt_wr=%d\n", sysinfo->rtt_wr); - debug("Rtt_nom=%d\n", sysinfo->rtt_nom); - debug("SRT=%d\n", ddr3_cfg->SRT); - debug("twr=%d\n", twr); - - /* - * board-specific configuration: - * These values are determined empirically and vary per board layout - * see: - * appnote, ddr3 spreadsheet - */ - mmdc0->mpwldectrl0 = calib->p0_mpwldectrl0; - mmdc0->mpwldectrl1 = calib->p0_mpwldectrl1; - mmdc0->mpdgctrl0 = calib->p0_mpdgctrl0; - mmdc0->mpdgctrl1 = calib->p0_mpdgctrl1; - mmdc0->mprddlctl = calib->p0_mprddlctl; - mmdc0->mpwrdlctl = calib->p0_mpwrdlctl; - if (sysinfo->dsize > 1) { - MMDC1(mpwldectrl0, calib->p1_mpwldectrl0); - MMDC1(mpwldectrl1, calib->p1_mpwldectrl1); - MMDC1(mpdgctrl0, calib->p1_mpdgctrl0); - MMDC1(mpdgctrl1, calib->p1_mpdgctrl1); - MMDC1(mprddlctl, calib->p1_mprddlctl); - MMDC1(mpwrdlctl, calib->p1_mpwrdlctl); - } - - /* Read data DQ Byte0-3 delay */ - mmdc0->mprddqby0dl = 0x33333333; - mmdc0->mprddqby1dl = 0x33333333; - if (sysinfo->dsize > 0) { - mmdc0->mprddqby2dl = 0x33333333; - mmdc0->mprddqby3dl = 0x33333333; - } - - if (sysinfo->dsize > 1) { - MMDC1(mprddqby0dl, 0x33333333); - MMDC1(mprddqby1dl, 0x33333333); - MMDC1(mprddqby2dl, 0x33333333); - MMDC1(mprddqby3dl, 0x33333333); - } - - /* MMDC Termination: rtt_nom:2 RZQ/2(120ohm), rtt_nom:1 RZQ/4(60ohm) */ - val = (sysinfo->rtt_nom == 2) ? 0x00011117 : 0x00022227; - mmdc0->mpodtctrl = val; - if (sysinfo->dsize > 1) - MMDC1(mpodtctrl, val); - - /* complete calibration */ - val = (1 << 11); /* Force measurement on delay-lines */ - mmdc0->mpmur0 = val; - if (sysinfo->dsize > 1) - MMDC1(mpmur0, val); - - /* Step 1: configuration request */ - mmdc0->mdscr = (u32)(1 << 15); /* config request */ - - /* Step 2: Timing configuration */ - mmdc0->mdcfg0 = (trfc << 24) | (txs << 16) | (txp << 13) | - (txpdll << 9) | (tfaw << 4) | tcl; - mmdc0->mdcfg1 = (trcd << 29) | (trp << 26) | (trc << 21) | - (tras << 16) | (1 << 15) /* trpa */ | - (twr << 9) | (tmrd << 5) | tcwl; - mmdc0->mdcfg2 = (tdllk << 16) | (trtp << 6) | (twtr << 3) | trrd; - mmdc0->mdotc = (taofpd << 27) | (taonpd << 24) | (tanpd << 20) | - (taxpd << 16) | (todtlon << 12) | (todt_idle_off << 4); - mmdc0->mdasp = cs0_end; /* CS addressing */ - - /* Step 3: Configure DDR type */ - mmdc0->mdmisc = (sysinfo->cs1_mirror << 19) | (sysinfo->walat << 16) | - (sysinfo->bi_on << 12) | (sysinfo->mif3_mode << 9) | - (sysinfo->ralat << 6); - - /* Step 4: Configure delay while leaving reset */ - mmdc0->mdor = (txpr << 16) | (sysinfo->sde_to_rst << 8) | - (sysinfo->rst_to_cke << 0); - - /* Step 5: Configure DDR physical parameters (density and burst len) */ - coladdr = ddr3_cfg->coladdr; - if (ddr3_cfg->coladdr == 8) /* 8-bit COL is 0x3 */ - coladdr += 4; - else if (ddr3_cfg->coladdr == 12) /* 12-bit COL is 0x4 */ - coladdr += 1; - mmdc0->mdctl = (ddr3_cfg->rowaddr - 11) << 24 | /* ROW */ - (coladdr - 9) << 20 | /* COL */ - (1 << 19) | /* Burst Length = 8 for DDR3 */ - (sysinfo->dsize << 16); /* DDR data bus size */ - - /* Step 6: Perform ZQ calibration */ - val = 0xa1390001; /* one-time HW ZQ calib */ - mmdc0->mpzqhwctrl = val; - if (sysinfo->dsize > 1) - MMDC1(mpzqhwctrl, val); - - /* Step 7: Enable MMDC with desired chip select */ - mmdc0->mdctl |= (1 << 31) | /* SDE_0 for CS0 */ - ((sysinfo->ncs == 2) ? 1 : 0) << 30; /* SDE_1 for CS1 */ - - /* Step 8: Write Mode Registers to Init DDR3 devices */ - for (cs = 0; cs < sysinfo->ncs; cs++) { - /* MR2 */ - val = (sysinfo->rtt_wr & 3) << 9 | (ddr3_cfg->SRT & 1) << 7 | - ((tcwl - 3) & 3) << 3; - debug("MR2 CS%d: 0x%08x\n", cs, (u32)MR(val, 2, 3, cs)); - mmdc0->mdscr = MR(val, 2, 3, cs); - /* MR3 */ - debug("MR3 CS%d: 0x%08x\n", cs, (u32)MR(0, 3, 3, cs)); - mmdc0->mdscr = MR(0, 3, 3, cs); - /* MR1 */ - val = ((sysinfo->rtt_nom & 1) ? 1 : 0) << 2 | - ((sysinfo->rtt_nom & 2) ? 1 : 0) << 6; - debug("MR1 CS%d: 0x%08x\n", cs, (u32)MR(val, 1, 3, cs)); - mmdc0->mdscr = MR(val, 1, 3, cs); - /* MR0 */ - val = ((tcl - 1) << 4) | /* CAS */ - (1 << 8) | /* DLL Reset */ - ((twr - 3) << 9) | /* Write Recovery */ - (sysinfo->pd_fast_exit << 12); /* Precharge PD PLL on */ - debug("MR0 CS%d: 0x%08x\n", cs, (u32)MR(val, 0, 3, cs)); - mmdc0->mdscr = MR(val, 0, 3, cs); - /* ZQ calibration */ - val = (1 << 10); - mmdc0->mdscr = MR(val, 0, 4, cs); - } - - /* Step 10: Power down control and self-refresh */ - mmdc0->mdpdc = (tcke & 0x7) << 16 | - 5 << 12 | /* PWDT_1: 256 cycles */ - 5 << 8 | /* PWDT_0: 256 cycles */ - 1 << 6 | /* BOTH_CS_PD */ - (tcksrx & 0x7) << 3 | - (tcksre & 0x7); - if (!sysinfo->pd_fast_exit) - mmdc0->mdpdc |= (1 << 7); /* SLOW_PD */ - mmdc0->mapsr = 0x00001006; /* ADOPT power down enabled */ - - /* Step 11: Configure ZQ calibration: one-time and periodic 1ms */ - val = 0xa1390003; - mmdc0->mpzqhwctrl = val; - if (sysinfo->dsize > 1) - MMDC1(mpzqhwctrl, val); - - /* Step 12: Configure and activate periodic refresh */ - mmdc0->mdref = (sysinfo->refsel << 14) | (sysinfo->refr << 11); - - /* Step 13: Deassert config request - init complete */ - mmdc0->mdscr = 0x00000000; - - /* wait for auto-ZQ calibration to complete */ - mdelay(1); -} - -void mmdc_read_calibration(struct mx6_ddr_sysinfo const *sysinfo, - struct mx6_mmdc_calibration *calib) -{ - struct mmdc_p_regs *mmdc0 = (struct mmdc_p_regs *)MMDC_P0_BASE_ADDR; - struct mmdc_p_regs *mmdc1 = (struct mmdc_p_regs *)MMDC_P1_BASE_ADDR; - - calib->p0_mpwldectrl0 = readl(&mmdc0->mpwldectrl0); - calib->p0_mpwldectrl1 = readl(&mmdc0->mpwldectrl1); - calib->p0_mpdgctrl0 = readl(&mmdc0->mpdgctrl0); - calib->p0_mpdgctrl1 = readl(&mmdc0->mpdgctrl1); - calib->p0_mprddlctl = readl(&mmdc0->mprddlctl); - calib->p0_mpwrdlctl = readl(&mmdc0->mpwrdlctl); - - if (sysinfo->dsize == 2) { - calib->p1_mpwldectrl0 = readl(&mmdc1->mpwldectrl0); - calib->p1_mpwldectrl1 = readl(&mmdc1->mpwldectrl1); - calib->p1_mpdgctrl0 = readl(&mmdc1->mpdgctrl0); - calib->p1_mpdgctrl1 = readl(&mmdc1->mpdgctrl1); - calib->p1_mprddlctl = readl(&mmdc1->mprddlctl); - calib->p1_mpwrdlctl = readl(&mmdc1->mpwrdlctl); - } -} - -void mx6_dram_cfg(const struct mx6_ddr_sysinfo *sysinfo, - const struct mx6_mmdc_calibration *calib, - const void *ddr_cfg) -{ - if (sysinfo->ddr_type == DDR_TYPE_DDR3) { - mx6_ddr3_cfg(sysinfo, calib, ddr_cfg); - } else if (sysinfo->ddr_type == DDR_TYPE_LPDDR2) { - mx6_lpddr2_cfg(sysinfo, calib, ddr_cfg); - } else { - puts("Unsupported ddr type\n"); - hang(); - } -} diff --git a/arch/arm/cpu/armv7/mx6/litesom.c b/arch/arm/cpu/armv7/mx6/litesom.c deleted file mode 100644 index ac2eccff06..0000000000 --- a/arch/arm/cpu/armv7/mx6/litesom.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (C) 2015-2016 Freescale Semiconductor, Inc. - * Copyright (C) 2016 Grinn - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/arch/clock.h> -#include <asm/arch/iomux.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/mx6ul_pins.h> -#include <asm/arch/mx6-pins.h> -#include <asm/arch/sys_proto.h> -#include <asm/gpio.h> -#include <asm/imx-common/iomux-v3.h> -#include <asm/imx-common/boot_mode.h> -#include <asm/io.h> -#include <common.h> -#include <fsl_esdhc.h> -#include <linux/sizes.h> -#include <mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define USDHC_PAD_CTRL (PAD_CTL_PKE | PAD_CTL_PUE | \ - PAD_CTL_PUS_22K_UP | PAD_CTL_SPEED_LOW | \ - PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST | PAD_CTL_HYS) - -int dram_init(void) -{ - gd->ram_size = imx_ddr_size(); - - return 0; -} - -static iomux_v3_cfg_t const emmc_pads[] = { - MX6_PAD_NAND_RE_B__USDHC2_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_WE_B__USDHC2_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA00__USDHC2_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA01__USDHC2_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA02__USDHC2_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA03__USDHC2_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA04__USDHC2_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA05__USDHC2_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA06__USDHC2_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_DATA07__USDHC2_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - - /* RST_B */ - MX6_PAD_NAND_ALE__GPIO4_IO10 | MUX_PAD_CTRL(NO_PAD_CTRL), -}; - -#ifdef CONFIG_FSL_ESDHC -static struct fsl_esdhc_cfg emmc_cfg = {USDHC2_BASE_ADDR, 0, 8}; - -#define EMMC_PWR_GPIO IMX_GPIO_NR(4, 10) - -int litesom_mmc_init(bd_t *bis) -{ - int ret; - - /* eMMC */ - imx_iomux_v3_setup_multiple_pads(emmc_pads, ARRAY_SIZE(emmc_pads)); - gpio_direction_output(EMMC_PWR_GPIO, 0); - udelay(500); - gpio_direction_output(EMMC_PWR_GPIO, 1); - emmc_cfg.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); - - ret = fsl_esdhc_initialize(bis, &emmc_cfg); - if (ret) { - printf("Warning: failed to initialize mmc dev 1 (eMMC)\n"); - return ret; - } - - return 0; -} -#endif - -#ifdef CONFIG_SPL_BUILD -#include <libfdt.h> -#include <spl.h> -#include <asm/arch/mx6-ddr.h> - - -static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = { - .grp_addds = 0x00000030, - .grp_ddrmode_ctl = 0x00020000, - .grp_b0ds = 0x00000030, - .grp_ctlds = 0x00000030, - .grp_b1ds = 0x00000030, - .grp_ddrpke = 0x00000000, - .grp_ddrmode = 0x00020000, - .grp_ddr_type = 0x000c0000, -}; - -static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = { - .dram_dqm0 = 0x00000030, - .dram_dqm1 = 0x00000030, - .dram_ras = 0x00000030, - .dram_cas = 0x00000030, - .dram_odt0 = 0x00000030, - .dram_odt1 = 0x00000030, - .dram_sdba2 = 0x00000000, - .dram_sdclk_0 = 0x00000030, - .dram_sdqs0 = 0x00000030, - .dram_sdqs1 = 0x00000030, - .dram_reset = 0x00000030, -}; - -static struct mx6_mmdc_calibration mx6_mmcd_calib = { - .p0_mpwldectrl0 = 0x00000000, - .p0_mpdgctrl0 = 0x41570155, - .p0_mprddlctl = 0x4040474A, - .p0_mpwrdlctl = 0x40405550, -}; - -struct mx6_ddr_sysinfo ddr_sysinfo = { - .dsize = 0, - .cs_density = 20, - .ncs = 1, - .cs1_mirror = 0, - .rtt_wr = 2, - .rtt_nom = 1, /* RTT_Nom = RZQ/2 */ - .walat = 0, /* Write additional latency */ - .ralat = 5, /* Read additional latency */ - .mif3_mode = 3, /* Command prediction working mode */ - .bi_on = 1, /* Bank interleaving enabled */ - .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ - .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ - .ddr_type = DDR_TYPE_DDR3, - .refsel = 0, /* Refresh cycles at 64KHz */ - .refr = 1, /* 2 refresh commands per refresh cycle */ -}; - -static struct mx6_ddr3_cfg mem_ddr = { - .mem_speed = 800, - .density = 4, - .width = 16, - .banks = 8, - .rowaddr = 15, - .coladdr = 10, - .pagesz = 2, - .trcd = 1375, - .trcmin = 4875, - .trasmin = 3500, -}; - -static void ccgr_init(void) -{ - struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - - writel(0xFFFFFFFF, &ccm->CCGR0); - writel(0xFFFFFFFF, &ccm->CCGR1); - writel(0xFFFFFFFF, &ccm->CCGR2); - writel(0xFFFFFFFF, &ccm->CCGR3); - writel(0xFFFFFFFF, &ccm->CCGR4); - writel(0xFFFFFFFF, &ccm->CCGR5); - writel(0xFFFFFFFF, &ccm->CCGR6); - writel(0xFFFFFFFF, &ccm->CCGR7); -} - -static void spl_dram_init(void) -{ - unsigned long ram_size; - - mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs); - mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr); - - /* - * Get actual RAM size, so we can adjust DDR row size for <512M - * memories - */ - ram_size = get_ram_size((void *)CONFIG_SYS_SDRAM_BASE, SZ_512M); - if (ram_size < SZ_512M) { - mem_ddr.rowaddr = 14; - mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr); - } -} - -void litesom_init_f(void) -{ - ccgr_init(); - - /* setup AIPS and disable watchdog */ - arch_cpu_init(); - -#ifdef CONFIG_BOARD_EARLY_INIT_F - board_early_init_f(); -#endif - - /* setup GP timer */ - timer_init(); - - /* UART clocks enabled and gd valid - init serial console */ - preloader_console_init(); - - /* DDR initialization */ - spl_dram_init(); -} -#endif diff --git a/arch/arm/cpu/armv7/mx6/mp.c b/arch/arm/cpu/armv7/mx6/mp.c deleted file mode 100644 index e28018b26e..0000000000 --- a/arch/arm/cpu/armv7/mx6/mp.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * (C) Copyright 2014 - * Gabriel Huau <contact@huau-gabriel.fr> - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <linux/errno.h> -#include <asm/arch/sys_proto.h> -#include <asm/arch/imx-regs.h> - -#define MAX_CPUS 4 -static struct src *src = (struct src *)SRC_BASE_ADDR; - -static uint32_t cpu_reset_mask[MAX_CPUS] = { - 0, /* We don't really want to modify the cpu0 */ - SRC_SCR_CORE_1_RESET_MASK, - SRC_SCR_CORE_2_RESET_MASK, - SRC_SCR_CORE_3_RESET_MASK -}; - -static uint32_t cpu_ctrl_mask[MAX_CPUS] = { - 0, /* We don't really want to modify the cpu0 */ - SRC_SCR_CORE_1_ENABLE_MASK, - SRC_SCR_CORE_2_ENABLE_MASK, - SRC_SCR_CORE_3_ENABLE_MASK -}; - -int cpu_reset(int nr) -{ - /* Software reset of the CPU N */ - src->scr |= cpu_reset_mask[nr]; - return 0; -} - -int cpu_status(int nr) -{ - printf("core %d => %d\n", nr, !!(src->scr & cpu_ctrl_mask[nr])); - return 0; -} - -int cpu_release(int nr, int argc, char *const argv[]) -{ - uint32_t boot_addr; - - boot_addr = simple_strtoul(argv[0], NULL, 16); - - switch (nr) { - case 1: - src->gpr3 = boot_addr; - break; - case 2: - src->gpr5 = boot_addr; - break; - case 3: - src->gpr7 = boot_addr; - break; - default: - return 1; - } - - /* CPU N is ready to start */ - src->scr |= cpu_ctrl_mask[nr]; - - return 0; -} - -int is_core_valid(unsigned int core) -{ - uint32_t nr_cores = get_nr_cpus(); - - if (core > nr_cores) - return 0; - - return 1; -} - -int cpu_disable(int nr) -{ - /* Disable the CPU N */ - src->scr &= ~cpu_ctrl_mask[nr]; - return 0; -} diff --git a/arch/arm/cpu/armv7/mx6/opos6ul.c b/arch/arm/cpu/armv7/mx6/opos6ul.c deleted file mode 100644 index ea2f0ec251..0000000000 --- a/arch/arm/cpu/armv7/mx6/opos6ul.c +++ /dev/null @@ -1,302 +0,0 @@ -/* - * Copyright (C) 2017 Armadeus Systems - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/arch/clock.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/iomux.h> -#include <asm/arch/mx6-pins.h> -#include <asm/arch/mx6ul_pins.h> -#include <asm/arch/sys_proto.h> -#include <asm/gpio.h> -#include <asm/imx-common/iomux-v3.h> -#include <asm/io.h> -#include <common.h> -#include <environment.h> -#include <fsl_esdhc.h> -#include <mmc.h> - -DECLARE_GLOBAL_DATA_PTR; - -#ifdef CONFIG_FEC_MXC -#include <miiphy.h> - -#define MDIO_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PU ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_PAD_CTRL_PD ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_DOWN | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_40ohm \ -) - -#define ENET_CLK_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_100K_UP | PAD_CTL_SPEED_LOW | \ - PAD_CTL_DSE_40ohm | PAD_CTL_SRE_FAST \ -) - -static iomux_v3_cfg_t const fec1_pads[] = { - MX6_PAD_GPIO1_IO06__ENET1_MDIO | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_GPIO1_IO07__ENET1_MDC | MUX_PAD_CTRL(MDIO_PAD_CTRL), - MX6_PAD_ENET1_RX_ER__ENET1_RX_ER | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_EN__ENET1_RX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA1__ENET1_RDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_RX_DATA0__ENET1_RDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_DATA0__ENET1_TDATA00 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_DATA1__ENET1_TDATA01 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - MX6_PAD_ENET1_TX_EN__ENET1_TX_EN | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Int */ - MX6_PAD_NAND_DQS__GPIO4_IO16 | MUX_PAD_CTRL(ENET_PAD_CTRL_PU), - /* PHY Reset */ - MX6_PAD_NAND_DATA00__GPIO4_IO02 | MUX_PAD_CTRL(ENET_PAD_CTRL_PD), - MX6_PAD_ENET1_TX_CLK__ENET1_REF_CLK1 | MUX_PAD_CTRL(ENET_CLK_PAD_CTRL), -}; - -int board_phy_config(struct phy_device *phydev) -{ - phy_write(phydev, MDIO_DEVAD_NONE, 0x1f, 0x8190); - - if (phydev->drv->config) - phydev->drv->config(phydev); - - return 0; -} - -int board_eth_init(bd_t *bis) -{ - struct iomuxc *const iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR; - struct gpio_desc rst; - int ret; - - /* Use 50M anatop loopback REF_CLK1 for ENET1, - * clear gpr1[13], set gpr1[17] */ - clrsetbits_le32(&iomuxc_regs->gpr[1], IOMUX_GPR1_FEC1_MASK, - IOMUX_GPR1_FEC1_CLOCK_MUX1_SEL_MASK); - - ret = enable_fec_anatop_clock(0, ENET_50MHZ); - if (ret) - return ret; - - enable_enet_clk(1); - - imx_iomux_v3_setup_multiple_pads(fec1_pads, ARRAY_SIZE(fec1_pads)); - - ret = dm_gpio_lookup_name("GPIO4_2", &rst); - if (ret) { - printf("Cannot get GPIO4_2\n"); - return ret; - } - - ret = dm_gpio_request(&rst, "phy-rst"); - if (ret) { - printf("Cannot request GPIO4_2\n"); - return ret; - } - - dm_gpio_set_dir_flags(&rst, GPIOD_IS_OUT); - dm_gpio_set_value(&rst, 0); - udelay(1000); - dm_gpio_set_value(&rst, 1); - - return fecmxc_initialize(bis); -} -#endif /* CONFIG_FEC_MXC */ - -int board_init(void) -{ - /* Address of boot parameters */ - gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100; - - return 0; -} - -int __weak opos6ul_board_late_init(void) -{ - return 0; -} - -int board_late_init(void) -{ - struct src *psrc = (struct src *)SRC_BASE_ADDR; - unsigned reg = readl(&psrc->sbmr2); - - /* In bootstrap don't use the env vars */ - if (((reg & 0x3000000) >> 24) == 0x1) { - set_default_env(NULL); - setenv("preboot", ""); - } - - return opos6ul_board_late_init(); -} - -int board_mmc_getcd(struct mmc *mmc) -{ - struct fsl_esdhc_cfg *cfg = (struct fsl_esdhc_cfg *)mmc->priv; - return cfg->esdhc_base == USDHC1_BASE_ADDR; -} - -int dram_init(void) -{ - gd->ram_size = imx_ddr_size(); - - return 0; -} - -#ifdef CONFIG_SPL_BUILD -#include <asm/arch/mx6-ddr.h> -#include <asm/arch/opos6ul.h> -#include <libfdt.h> -#include <spl.h> - -#define USDHC_PAD_CTRL ( \ - PAD_CTL_HYS | PAD_CTL_PUS_47K_UP | PAD_CTL_SPEED_MED | \ - PAD_CTL_DSE_80ohm | PAD_CTL_SRE_FAST \ -) - -struct fsl_esdhc_cfg usdhc_cfg[1] = { - {USDHC1_BASE_ADDR, 0, 8}, -}; - -static iomux_v3_cfg_t const usdhc1_pads[] = { - MX6_PAD_SD1_CLK__USDHC1_CLK | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_CMD__USDHC1_CMD | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DATA0__USDHC1_DATA0 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DATA1__USDHC1_DATA1 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DATA2__USDHC1_DATA2 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_SD1_DATA3__USDHC1_DATA3 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_READY_B__USDHC1_DATA4 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_CE0_B__USDHC1_DATA5 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_CE1_B__USDHC1_DATA6 | MUX_PAD_CTRL(USDHC_PAD_CTRL), - MX6_PAD_NAND_CLE__USDHC1_DATA7 | MUX_PAD_CTRL(USDHC_PAD_CTRL), -}; - -static struct mx6ul_iomux_grp_regs mx6_grp_ioregs = { - .grp_addds = 0x00000030, - .grp_ddrmode_ctl = 0x00020000, - .grp_b0ds = 0x00000030, - .grp_ctlds = 0x00000030, - .grp_b1ds = 0x00000030, - .grp_ddrpke = 0x00000000, - .grp_ddrmode = 0x00020000, - .grp_ddr_type = 0x000c0000, -}; - -static struct mx6ul_iomux_ddr_regs mx6_ddr_ioregs = { - .dram_dqm0 = 0x00000030, - .dram_dqm1 = 0x00000030, - .dram_ras = 0x00000030, - .dram_cas = 0x00000030, - .dram_odt0 = 0x00000030, - .dram_odt1 = 0x00000030, - .dram_sdba2 = 0x00000000, - .dram_sdclk_0 = 0x00000008, - .dram_sdqs0 = 0x00000038, - .dram_sdqs1 = 0x00000030, - .dram_reset = 0x00000030, -}; - -static struct mx6_mmdc_calibration mx6_mmcd_calib = { - .p0_mpwldectrl0 = 0x00070007, - .p0_mpdgctrl0 = 0x41490145, - .p0_mprddlctl = 0x40404546, - .p0_mpwrdlctl = 0x4040524D, -}; - -struct mx6_ddr_sysinfo ddr_sysinfo = { - .dsize = 0, - .cs_density = 20, - .ncs = 1, - .cs1_mirror = 0, - .rtt_wr = 2, - .rtt_nom = 1, /* RTT_Nom = RZQ/2 */ - .walat = 1, /* Write additional latency */ - .ralat = 5, /* Read additional latency */ - .mif3_mode = 3, /* Command prediction working mode */ - .bi_on = 1, /* Bank interleaving enabled */ - .sde_to_rst = 0x10, /* 14 cycles, 200us (JEDEC default) */ - .rst_to_cke = 0x23, /* 33 cycles, 500us (JEDEC default) */ - .ddr_type = DDR_TYPE_DDR3, -}; - -static struct mx6_ddr3_cfg mem_ddr = { - .mem_speed = 800, - .density = 2, - .width = 16, - .banks = 8, - .rowaddr = 14, - .coladdr = 10, - .pagesz = 2, - .trcd = 1500, - .trcmin = 5250, - .trasmin = 3750, -}; - -int board_mmc_init(bd_t *bis) -{ - imx_iomux_v3_setup_multiple_pads(usdhc1_pads, ARRAY_SIZE(usdhc1_pads)); - usdhc_cfg[0].sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); - return fsl_esdhc_initialize(bis, &usdhc_cfg[0]); -} - -static void ccgr_init(void) -{ - struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - - writel(0xFFFFFFFF, &ccm->CCGR0); - writel(0xFFFFFFFF, &ccm->CCGR1); - writel(0xFFFFFFFF, &ccm->CCGR2); - writel(0xFFFFFFFF, &ccm->CCGR3); - writel(0xFFFFFFFF, &ccm->CCGR4); - writel(0xFFFFFFFF, &ccm->CCGR5); - writel(0xFFFFFFFF, &ccm->CCGR6); - writel(0xFFFFFFFF, &ccm->CCGR7); -} - -static void spl_dram_init(void) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[4]; - struct fuse_bank4_regs *fuse = - (struct fuse_bank4_regs *)bank->fuse_regs; - int reg = readl(&fuse->gp1); - - /* 512MB of RAM */ - if (reg & 0x1) { - mem_ddr.density = 4; - mem_ddr.rowaddr = 15; - mem_ddr.trcd = 1375; - mem_ddr.trcmin = 4875; - mem_ddr.trasmin = 3500; - } - - mx6ul_dram_iocfg(mem_ddr.width, &mx6_ddr_ioregs, &mx6_grp_ioregs); - mx6_dram_cfg(&ddr_sysinfo, &mx6_mmcd_calib, &mem_ddr); -} - -void board_init_f(ulong dummy) -{ - ccgr_init(); - - /* setup AIPS and disable watchdog */ - arch_cpu_init(); - - /* setup GP timer */ - timer_init(); - - /* UART clocks enabled and gd valid - init serial console */ - opos6ul_setup_uart_debug(); - preloader_console_init(); - - /* DDR initialization */ - spl_dram_init(); -} -#endif /* CONFIG_SPL_BUILD */ diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c deleted file mode 100644 index 832ef251b8..0000000000 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ /dev/null @@ -1,703 +0,0 @@ -/* - * (C) Copyright 2007 - * Sascha Hauer, Pengutronix - * - * (C) Copyright 2009 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <linux/errno.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> -#include <asm/imx-common/boot_mode.h> -#include <asm/imx-common/dma.h> -#include <asm/imx-common/hab.h> -#include <stdbool.h> -#include <asm/arch/mxc_hdmi.h> -#include <asm/arch/crm_regs.h> -#include <dm.h> -#include <imx_thermal.h> -#include <mmc.h> - -enum ldo_reg { - LDO_ARM, - LDO_SOC, - LDO_PU, -}; - -struct scu_regs { - u32 ctrl; - u32 config; - u32 status; - u32 invalidate; - u32 fpga_rev; -}; - -#if defined(CONFIG_IMX_THERMAL) -static const struct imx_thermal_plat imx6_thermal_plat = { - .regs = (void *)ANATOP_BASE_ADDR, - .fuse_bank = 1, - .fuse_word = 6, -}; - -U_BOOT_DEVICE(imx6_thermal) = { - .name = "imx_thermal", - .platdata = &imx6_thermal_plat, -}; -#endif - -#if defined(CONFIG_SECURE_BOOT) -struct imx_sec_config_fuse_t const imx_sec_config_fuse = { - .bank = 0, - .word = 6, -}; -#endif - -u32 get_nr_cpus(void) -{ - struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; - return readl(&scu->config) & 3; -} - -u32 get_cpu_rev(void) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - u32 reg = readl(&anatop->digprog_sololite); - u32 type = ((reg >> 16) & 0xff); - u32 major, cfg = 0; - - if (type != MXC_CPU_MX6SL) { - reg = readl(&anatop->digprog); - struct scu_regs *scu = (struct scu_regs *)SCU_BASE_ADDR; - cfg = readl(&scu->config) & 3; - type = ((reg >> 16) & 0xff); - if (type == MXC_CPU_MX6DL) { - if (!cfg) - type = MXC_CPU_MX6SOLO; - } - - if (type == MXC_CPU_MX6Q) { - if (cfg == 1) - type = MXC_CPU_MX6D; - } - - } - major = ((reg >> 8) & 0xff); - if ((major >= 1) && - ((type == MXC_CPU_MX6Q) || (type == MXC_CPU_MX6D))) { - major--; - type = MXC_CPU_MX6QP; - if (cfg == 1) - type = MXC_CPU_MX6DP; - } - reg &= 0xff; /* mx6 silicon revision */ - return (type << 12) | (reg + (0x10 * (major + 1))); -} - -/* - * OCOTP_CFG3[17:16] (see Fusemap Description Table offset 0x440) - * defines a 2-bit SPEED_GRADING - */ -#define OCOTP_CFG3_SPEED_SHIFT 16 -#define OCOTP_CFG3_SPEED_800MHZ 0 -#define OCOTP_CFG3_SPEED_850MHZ 1 -#define OCOTP_CFG3_SPEED_1GHZ 2 -#define OCOTP_CFG3_SPEED_1P2GHZ 3 - -/* - * For i.MX6UL - */ -#define OCOTP_CFG3_SPEED_528MHZ 1 -#define OCOTP_CFG3_SPEED_696MHZ 2 - -u32 get_cpu_speed_grade_hz(void) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[0]; - struct fuse_bank0_regs *fuse = - (struct fuse_bank0_regs *)bank->fuse_regs; - uint32_t val; - - val = readl(&fuse->cfg3); - val >>= OCOTP_CFG3_SPEED_SHIFT; - val &= 0x3; - - if (is_mx6ul() || is_mx6ull()) { - if (val == OCOTP_CFG3_SPEED_528MHZ) - return 528000000; - else if (val == OCOTP_CFG3_SPEED_696MHZ) - return 69600000; - else - return 0; - } - - switch (val) { - /* Valid for IMX6DQ */ - case OCOTP_CFG3_SPEED_1P2GHZ: - if (is_mx6dq() || is_mx6dqp()) - return 1200000000; - /* Valid for IMX6SX/IMX6SDL/IMX6DQ */ - case OCOTP_CFG3_SPEED_1GHZ: - return 996000000; - /* Valid for IMX6DQ */ - case OCOTP_CFG3_SPEED_850MHZ: - if (is_mx6dq() || is_mx6dqp()) - return 852000000; - /* Valid for IMX6SX/IMX6SDL/IMX6DQ */ - case OCOTP_CFG3_SPEED_800MHZ: - return 792000000; - } - return 0; -} - -/* - * OCOTP_MEM0[7:6] (see Fusemap Description Table offset 0x480) - * defines a 2-bit Temperature Grade - * - * return temperature grade and min/max temperature in Celsius - */ -#define OCOTP_MEM0_TEMP_SHIFT 6 - -u32 get_cpu_temp_grade(int *minc, int *maxc) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - uint32_t val; - - val = readl(&fuse->mem0); - val >>= OCOTP_MEM0_TEMP_SHIFT; - val &= 0x3; - - if (minc && maxc) { - if (val == TEMP_AUTOMOTIVE) { - *minc = -40; - *maxc = 125; - } else if (val == TEMP_INDUSTRIAL) { - *minc = -40; - *maxc = 105; - } else if (val == TEMP_EXTCOMMERCIAL) { - *minc = -20; - *maxc = 105; - } else { - *minc = 0; - *maxc = 95; - } - } - return val; -} - -#ifdef CONFIG_REVISION_TAG -u32 __weak get_board_rev(void) -{ - u32 cpurev = get_cpu_rev(); - u32 type = ((cpurev >> 12) & 0xff); - if (type == MXC_CPU_MX6SOLO) - cpurev = (MXC_CPU_MX6DL) << 12 | (cpurev & 0xFFF); - - if (type == MXC_CPU_MX6D) - cpurev = (MXC_CPU_MX6Q) << 12 | (cpurev & 0xFFF); - - return cpurev; -} -#endif - -static void clear_ldo_ramp(void) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - int reg; - - /* ROM may modify LDO ramp up time according to fuse setting, so in - * order to be in the safe side we neeed to reset these settings to - * match the reset value: 0'b00 - */ - reg = readl(&anatop->ana_misc2); - reg &= ~(0x3f << 24); - writel(reg, &anatop->ana_misc2); -} - -/* - * Set the PMU_REG_CORE register - * - * Set LDO_SOC/PU/ARM regulators to the specified millivolt level. - * Possible values are from 0.725V to 1.450V in steps of - * 0.025V (25mV). - */ -static int set_ldo_voltage(enum ldo_reg ldo, u32 mv) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - u32 val, step, old, reg = readl(&anatop->reg_core); - u8 shift; - - if (mv < 725) - val = 0x00; /* Power gated off */ - else if (mv > 1450) - val = 0x1F; /* Power FET switched full on. No regulation */ - else - val = (mv - 700) / 25; - - clear_ldo_ramp(); - - switch (ldo) { - case LDO_SOC: - shift = 18; - break; - case LDO_PU: - shift = 9; - break; - case LDO_ARM: - shift = 0; - break; - default: - return -EINVAL; - } - - old = (reg & (0x1F << shift)) >> shift; - step = abs(val - old); - if (step == 0) - return 0; - - reg = (reg & ~(0x1F << shift)) | (val << shift); - writel(reg, &anatop->reg_core); - - /* - * The LDO ramp-up is based on 64 clock cycles of 24 MHz = 2.6 us per - * step - */ - udelay(3 * step); - - return 0; -} - -static void set_ahb_rate(u32 val) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg, div; - - div = get_periph_clk() / val - 1; - reg = readl(&mxc_ccm->cbcdr); - - writel((reg & (~MXC_CCM_CBCDR_AHB_PODF_MASK)) | - (div << MXC_CCM_CBCDR_AHB_PODF_OFFSET), &mxc_ccm->cbcdr); -} - -static void clear_mmdc_ch_mask(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg; - reg = readl(&mxc_ccm->ccdr); - - /* Clear MMDC channel mask */ - if (is_mx6sx() || is_mx6ul() || is_mx6ull() || is_mx6sl()) - reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK); - else - reg &= ~(MXC_CCM_CCDR_MMDC_CH1_HS_MASK | MXC_CCM_CCDR_MMDC_CH0_HS_MASK); - writel(reg, &mxc_ccm->ccdr); -} - -#define OCOTP_MEM0_REFTOP_TRIM_SHIFT 8 - -static void init_bandgap(void) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - uint32_t val; - - /* - * Ensure the bandgap has stabilized. - */ - while (!(readl(&anatop->ana_misc0) & 0x80)) - ; - /* - * For best noise performance of the analog blocks using the - * outputs of the bandgap, the reftop_selfbiasoff bit should - * be set. - */ - writel(BM_ANADIG_ANA_MISC0_REFTOP_SELBIASOFF, &anatop->ana_misc0_set); - /* - * On i.MX6ULL,we need to set VBGADJ bits according to the - * REFTOP_TRIM[3:0] in fuse table - * 000 - set REFTOP_VBGADJ[2:0] to 3b'110, - * 110 - set REFTOP_VBGADJ[2:0] to 3b'000, - * 001 - set REFTOP_VBGADJ[2:0] to 3b'001, - * 010 - set REFTOP_VBGADJ[2:0] to 3b'010, - * 011 - set REFTOP_VBGADJ[2:0] to 3b'011, - * 100 - set REFTOP_VBGADJ[2:0] to 3b'100, - * 101 - set REFTOP_VBGADJ[2:0] to 3b'101, - * 111 - set REFTOP_VBGADJ[2:0] to 3b'111, - */ - if (is_mx6ull()) { - val = readl(&fuse->mem0); - val >>= OCOTP_MEM0_REFTOP_TRIM_SHIFT; - val &= 0x7; - - writel(val << BM_ANADIG_ANA_MISC0_REFTOP_VBGADJ_SHIFT, - &anatop->ana_misc0_set); - } -} - -#ifdef CONFIG_MX6SL -static void set_preclk_from_osc(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 reg; - - reg = readl(&mxc_ccm->cscmr1); - reg |= MXC_CCM_CSCMR1_PER_CLK_SEL_MASK; - writel(reg, &mxc_ccm->cscmr1); -} -#endif - -int arch_cpu_init(void) -{ - init_aips(); - - /* Need to clear MMDC_CHx_MASK to make warm reset work. */ - clear_mmdc_ch_mask(); - - /* - * Disable self-bias circuit in the analog bandap. - * The self-bias circuit is used by the bandgap during startup. - * This bit should be set after the bandgap has initialized. - */ - init_bandgap(); - - if (!is_mx6ul() && !is_mx6ull()) { - /* - * When low freq boot is enabled, ROM will not set AHB - * freq, so we need to ensure AHB freq is 132MHz in such - * scenario. - * - * To i.MX6UL, when power up, default ARM core and - * AHB rate is 396M and 132M. - */ - if (mxc_get_clock(MXC_ARM_CLK) == 396000000) - set_ahb_rate(132000000); - } - - if (is_mx6ul()) { - if (is_soc_rev(CHIP_REV_1_0) == 0) { - /* - * According to the design team's requirement on - * i.MX6UL,the PMIC_STBY_REQ PAD should be configured - * as open drain 100K (0x0000b8a0). - * Only exists on TO1.0 - */ - writel(0x0000b8a0, IOMUXC_BASE_ADDR + 0x29c); - } else { - /* - * From TO1.1, SNVS adds internal pull up control - * for POR_B, the register filed is GPBIT[1:0], - * after system boot up, it can be set to 2b'01 - * to disable internal pull up.It can save about - * 30uA power in SNVS mode. - */ - writel((readl(MX6UL_SNVS_LP_BASE_ADDR + 0x10) & - (~0x1400)) | 0x400, - MX6UL_SNVS_LP_BASE_ADDR + 0x10); - } - } - - if (is_mx6ull()) { - /* - * GPBIT[1:0] is suggested to set to 2'b11: - * 2'b00 : always PUP100K - * 2'b01 : PUP100K when PMIC_ON_REQ or SOC_NOT_FAIL - * 2'b10 : always disable PUP100K - * 2'b11 : PDN100K when SOC_FAIL, PUP100K when SOC_NOT_FAIL - * register offset is different from i.MX6UL, since - * i.MX6UL is fixed by ECO. - */ - writel(readl(MX6UL_SNVS_LP_BASE_ADDR) | - 0x3, MX6UL_SNVS_LP_BASE_ADDR); - } - - /* Set perclk to source from OSC 24MHz */ -#if defined(CONFIG_MX6SL) - set_preclk_from_osc(); -#endif - - imx_set_wdog_powerdown(false); /* Disable PDE bit of WMCR register */ - - init_src(); - - return 0; -} - -#ifdef CONFIG_ENV_IS_IN_MMC -__weak int board_mmc_get_env_dev(int devno) -{ - return CONFIG_SYS_MMC_ENV_DEV; -} - -static int mmc_get_boot_dev(void) -{ - struct src *src_regs = (struct src *)SRC_BASE_ADDR; - u32 soc_sbmr = readl(&src_regs->sbmr1); - u32 bootsel; - int devno; - - /* - * Refer to - * "i.MX 6Dual/6Quad Applications Processor Reference Manual" - * Chapter "8.5.3.1 Expansion Device eFUSE Configuration" - * i.MX6SL/SX/UL has same layout. - */ - bootsel = (soc_sbmr & 0x000000FF) >> 6; - - /* No boot from sd/mmc */ - if (bootsel != 1) - return -1; - - /* BOOT_CFG2[3] and BOOT_CFG2[4] */ - devno = (soc_sbmr & 0x00001800) >> 11; - - return devno; -} - -int mmc_get_env_dev(void) -{ - int devno = mmc_get_boot_dev(); - - /* If not boot from sd/mmc, use default value */ - if (devno < 0) - return CONFIG_SYS_MMC_ENV_DEV; - - return board_mmc_get_env_dev(devno); -} - -#ifdef CONFIG_SYS_MMC_ENV_PART -__weak int board_mmc_get_env_part(int devno) -{ - return CONFIG_SYS_MMC_ENV_PART; -} - -uint mmc_get_env_part(struct mmc *mmc) -{ - int devno = mmc_get_boot_dev(); - - /* If not boot from sd/mmc, use default value */ - if (devno < 0) - return CONFIG_SYS_MMC_ENV_PART; - - return board_mmc_get_env_part(devno); -} -#endif -#endif - -int board_postclk_init(void) -{ - set_ldo_voltage(LDO_SOC, 1175); /* Set VDDSOC to 1.175V */ - - return 0; -} - -#if defined(CONFIG_FEC_MXC) -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[4]; - struct fuse_bank4_regs *fuse = - (struct fuse_bank4_regs *)bank->fuse_regs; - - if ((is_mx6sx() || is_mx6ul() || is_mx6ull()) && dev_id == 1) { - u32 value = readl(&fuse->mac_addr2); - mac[0] = value >> 24 ; - mac[1] = value >> 16 ; - mac[2] = value >> 8 ; - mac[3] = value ; - - value = readl(&fuse->mac_addr1); - mac[4] = value >> 24 ; - mac[5] = value >> 16 ; - - } else { - u32 value = readl(&fuse->mac_addr1); - mac[0] = (value >> 8); - mac[1] = value ; - - value = readl(&fuse->mac_addr0); - mac[2] = value >> 24 ; - mac[3] = value >> 16 ; - mac[4] = value >> 8 ; - mac[5] = value ; - } - -} -#endif - -/* - * cfg_val will be used for - * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] - * After reset, if GPR10[28] is 1, ROM will use GPR9[25:0] - * instead of SBMR1 to determine the boot device. - */ -const struct boot_mode soc_boot_modes[] = { - {"normal", MAKE_CFGVAL(0x00, 0x00, 0x00, 0x00)}, - /* reserved value should start rom usb */ -#if defined(CONFIG_MX6UL) || defined(CONFIG_MX6ULL) - {"usb", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)}, -#else - {"usb", MAKE_CFGVAL(0x10, 0x00, 0x00, 0x00)}, -#endif - {"sata", MAKE_CFGVAL(0x20, 0x00, 0x00, 0x00)}, - {"ecspi1:0", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x08)}, - {"ecspi1:1", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x18)}, - {"ecspi1:2", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x28)}, - {"ecspi1:3", MAKE_CFGVAL(0x30, 0x00, 0x00, 0x38)}, - /* 4 bit bus width */ - {"esdhc1", MAKE_CFGVAL(0x40, 0x20, 0x00, 0x00)}, - {"esdhc2", MAKE_CFGVAL(0x40, 0x28, 0x00, 0x00)}, - {"esdhc3", MAKE_CFGVAL(0x40, 0x30, 0x00, 0x00)}, - {"esdhc4", MAKE_CFGVAL(0x40, 0x38, 0x00, 0x00)}, - {NULL, 0}, -}; - -void reset_misc(void) -{ -#ifdef CONFIG_VIDEO_MXS - lcdif_power_down(); -#endif -} - -void s_init(void) -{ - struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR; - struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - u32 mask480; - u32 mask528; - u32 reg, periph1, periph2; - - if (is_mx6sx() || is_mx6ul() || is_mx6ull()) - return; - - /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs - * to make sure PFD is working right, otherwise, PFDs may - * not output clock after reset, MX6DL and MX6SL have added 396M pfd - * workaround in ROM code, as bus clock need it - */ - - mask480 = ANATOP_PFD_CLKGATE_MASK(0) | - ANATOP_PFD_CLKGATE_MASK(1) | - ANATOP_PFD_CLKGATE_MASK(2) | - ANATOP_PFD_CLKGATE_MASK(3); - mask528 = ANATOP_PFD_CLKGATE_MASK(1) | - ANATOP_PFD_CLKGATE_MASK(3); - - reg = readl(&ccm->cbcmr); - periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) - >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET); - periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) - >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET); - - /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */ - if ((periph2 != 0x2) && (periph1 != 0x2)) - mask528 |= ANATOP_PFD_CLKGATE_MASK(0); - - if ((periph2 != 0x1) && (periph1 != 0x1) && - (periph2 != 0x3) && (periph1 != 0x3)) - mask528 |= ANATOP_PFD_CLKGATE_MASK(2); - - writel(mask480, &anatop->pfd_480_set); - writel(mask528, &anatop->pfd_528_set); - writel(mask480, &anatop->pfd_480_clr); - writel(mask528, &anatop->pfd_528_clr); -} - -#ifdef CONFIG_IMX_HDMI -void imx_enable_hdmi_phy(void) -{ - struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; - u8 reg; - reg = readb(&hdmi->phy_conf0); - reg |= HDMI_PHY_CONF0_PDZ_MASK; - writeb(reg, &hdmi->phy_conf0); - udelay(3000); - reg |= HDMI_PHY_CONF0_ENTMDS_MASK; - writeb(reg, &hdmi->phy_conf0); - udelay(3000); - reg |= HDMI_PHY_CONF0_GEN2_TXPWRON_MASK; - writeb(reg, &hdmi->phy_conf0); - writeb(HDMI_MC_PHYRSTZ_ASSERT, &hdmi->mc_phyrstz); -} - -void imx_setup_hdmi(void) -{ - struct mxc_ccm_reg *mxc_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - struct hdmi_regs *hdmi = (struct hdmi_regs *)HDMI_ARB_BASE_ADDR; - int reg, count; - u8 val; - - /* Turn on HDMI PHY clock */ - reg = readl(&mxc_ccm->CCGR2); - reg |= MXC_CCM_CCGR2_HDMI_TX_IAHBCLK_MASK| - MXC_CCM_CCGR2_HDMI_TX_ISFRCLK_MASK; - writel(reg, &mxc_ccm->CCGR2); - writeb(HDMI_MC_PHYRSTZ_DEASSERT, &hdmi->mc_phyrstz); - reg = readl(&mxc_ccm->chsccdr); - reg &= ~(MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_MASK| - MXC_CCM_CHSCCDR_IPU1_DI0_PODF_MASK| - MXC_CCM_CHSCCDR_IPU1_DI0_CLK_SEL_MASK); - reg |= (CHSCCDR_PODF_DIVIDE_BY_3 - << MXC_CCM_CHSCCDR_IPU1_DI0_PODF_OFFSET) - |(CHSCCDR_IPU_PRE_CLK_540M_PFD - << MXC_CCM_CHSCCDR_IPU1_DI0_PRE_CLK_SEL_OFFSET); - writel(reg, &mxc_ccm->chsccdr); - - /* Clear the overflow condition */ - if (readb(&hdmi->ih_fc_stat2) & HDMI_IH_FC_STAT2_OVERFLOW_MASK) { - /* TMDS software reset */ - writeb((u8)~HDMI_MC_SWRSTZ_TMDSSWRST_REQ, &hdmi->mc_swrstz); - val = readb(&hdmi->fc_invidconf); - /* Need minimum 3 times to write to clear the register */ - for (count = 0 ; count < 5 ; count++) - writeb(val, &hdmi->fc_invidconf); - } -} -#endif - -#ifdef CONFIG_IMX_BOOTAUX -int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) -{ - struct src *src_reg; - u32 stack, pc; - - if (!boot_private_data) - return -EINVAL; - - stack = *(u32 *)boot_private_data; - pc = *(u32 *)(boot_private_data + 4); - - /* Set the stack and pc to M4 bootROM */ - writel(stack, M4_BOOTROM_BASE_ADDR); - writel(pc, M4_BOOTROM_BASE_ADDR + 4); - - /* Enable M4 */ - src_reg = (struct src *)SRC_BASE_ADDR; - clrsetbits_le32(&src_reg->scr, SRC_SCR_M4C_NON_SCLR_RST_MASK, - SRC_SCR_M4_ENABLE_MASK); - - return 0; -} - -int arch_auxiliary_core_check_up(u32 core_id) -{ - struct src *src_reg = (struct src *)SRC_BASE_ADDR; - unsigned val; - - val = readl(&src_reg->scr); - - if (val & SRC_SCR_M4C_NON_SCLR_RST_MASK) - return 0; /* assert in reset */ - - return 1; -} -#endif diff --git a/arch/arm/cpu/armv7/mx7/Kconfig b/arch/arm/cpu/armv7/mx7/Kconfig deleted file mode 100644 index aea85265ef..0000000000 --- a/arch/arm/cpu/armv7/mx7/Kconfig +++ /dev/null @@ -1,59 +0,0 @@ -if ARCH_MX7 - -config MX7 - bool - select ROM_UNIFIED_SECTIONS - select CPU_V7_HAS_VIRT - select CPU_V7_HAS_NONSEC - select ARCH_SUPPORT_PSCI - imply CMD_FUSE - default y - -config MX7D - select ROM_UNIFIED_SECTIONS - imply CMD_FUSE - bool - -choice - prompt "MX7 board select" - optional - -config TARGET_MX7DSABRESD - bool "mx7dsabresd" - select BOARD_LATE_INIT - select MX7D - select DM - select DM_THERMAL - -config TARGET_PICO_IMX7D - bool "pico-imx7d" - select BOARD_LATE_INIT - select MX7D - select DM - select DM_THERMAL - -config TARGET_WARP7 - bool "warp7" - select BOARD_LATE_INIT - select MX7D - select DM - select DM_THERMAL - -config TARGET_COLIBRI_IMX7 - bool "Support Colibri iMX7S/iMX7D modules" - select BOARD_LATE_INIT - select DM - select DM_SERIAL - select DM_THERMAL - -endchoice - -config SYS_SOC - default "mx7" - -source "board/freescale/mx7dsabresd/Kconfig" -source "board/technexion/pico-imx7d/Kconfig" -source "board/toradex/colibri_imx7/Kconfig" -source "board/warp7/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/mx7/Makefile b/arch/arm/cpu/armv7/mx7/Makefile deleted file mode 100644 index d21f87f18c..0000000000 --- a/arch/arm/cpu/armv7/mx7/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# -# (C) Copyright 2015 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# -# - -obj-y := soc.o clock.o clock_slice.o - -ifdef CONFIG_ARMV7_PSCI -obj-y += psci-mx7.o psci.o -endif diff --git a/arch/arm/cpu/armv7/mx7/clock.c b/arch/arm/cpu/armv7/mx7/clock.c deleted file mode 100644 index 2cfde46a55..0000000000 --- a/arch/arm/cpu/armv7/mx7/clock.c +++ /dev/null @@ -1,1133 +0,0 @@ -/* - * Copyright (C) 2015 Freescale Semiconductor, Inc. - * - * Author: - * Peng Fan <Peng.Fan@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <linux/errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> - -struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) - ANATOP_BASE_ADDR; -struct mxc_ccm_reg *ccm_reg = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - -#ifdef CONFIG_FSL_ESDHC -DECLARE_GLOBAL_DATA_PTR; -#endif - -int get_clocks(void) -{ -#ifdef CONFIG_FSL_ESDHC -#if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC2_BASE_ADDR - gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); -#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC3_BASE_ADDR - gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC3_CLK); -#else - gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); -#endif -#endif - return 0; -} - -u32 get_ahb_clk(void) -{ - return get_root_clk(AHB_CLK_ROOT); -} - -static u32 get_ipg_clk(void) -{ - /* - * The AHB and IPG are fixed at 2:1 ratio, and synchronized to - * each other. - */ - return get_ahb_clk() / 2; -} - -u32 imx_get_uartclk(void) -{ - return get_root_clk(UART1_CLK_ROOT); -} - -u32 imx_get_fecclk(void) -{ - return get_root_clk(ENET_AXI_CLK_ROOT); -} - -#ifdef CONFIG_MXC_OCOTP -void enable_ocotp_clk(unsigned char enable) -{ - clock_enable(CCGR_OCOTP, enable); -} - -void enable_thermal_clk(void) -{ - enable_ocotp_clk(1); -} -#endif - -void enable_usboh3_clk(unsigned char enable) -{ - u32 target; - - if (enable) { - /* disable the clock gate first */ - clock_enable(CCGR_USB_HSIC, 0); - - /* 120Mhz */ - target = CLK_ROOT_ON | - USB_HSIC_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(USB_HSIC_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_USB_CTRL, 1); - clock_enable(CCGR_USB_HSIC, 1); - clock_enable(CCGR_USB_PHY1, 1); - clock_enable(CCGR_USB_PHY2, 1); - } else { - clock_enable(CCGR_USB_CTRL, 0); - clock_enable(CCGR_USB_HSIC, 0); - clock_enable(CCGR_USB_PHY1, 0); - clock_enable(CCGR_USB_PHY2, 0); - } -} - -static u32 decode_pll(enum pll_clocks pll, u32 infreq) -{ - u32 reg, div_sel; - u32 num, denom; - - /* - * Alought there are four choices for the bypass src, - * we choose OSC_24M which is the default set in ROM. - */ - switch (pll) { - case PLL_CORE: - reg = readl(&ccm_anatop->pll_arm); - - if (reg & CCM_ANALOG_PLL_ARM_POWERDOWN_MASK) - return 0; - - if (reg & CCM_ANALOG_PLL_ARM_BYPASS_MASK) - return MXC_HCLK; - - div_sel = (reg & CCM_ANALOG_PLL_ARM_DIV_SELECT_MASK) >> - CCM_ANALOG_PLL_ARM_DIV_SELECT_SHIFT; - - return (infreq * div_sel) / 2; - - case PLL_SYS: - reg = readl(&ccm_anatop->pll_480); - - if (reg & CCM_ANALOG_PLL_480_POWERDOWN_MASK) - return 0; - - if (reg & CCM_ANALOG_PLL_480_BYPASS_MASK) - return MXC_HCLK; - - if (((reg & CCM_ANALOG_PLL_480_DIV_SELECT_MASK) >> - CCM_ANALOG_PLL_480_DIV_SELECT_SHIFT) == 0) - return 480000000u; - else - return 528000000u; - - case PLL_ENET: - reg = readl(&ccm_anatop->pll_enet); - - if (reg & CCM_ANALOG_PLL_ENET_POWERDOWN_MASK) - return 0; - - if (reg & CCM_ANALOG_PLL_ENET_BYPASS_MASK) - return MXC_HCLK; - - return 1000000000u; - - case PLL_DDR: - reg = readl(&ccm_anatop->pll_ddr); - - if (reg & CCM_ANALOG_PLL_DDR_POWERDOWN_MASK) - return 0; - - num = ccm_anatop->pll_ddr_num; - denom = ccm_anatop->pll_ddr_denom; - - if (reg & CCM_ANALOG_PLL_DDR_BYPASS_MASK) - return MXC_HCLK; - - div_sel = (reg & CCM_ANALOG_PLL_DDR_DIV_SELECT_MASK) >> - CCM_ANALOG_PLL_DDR_DIV_SELECT_SHIFT; - - return infreq * (div_sel + num / denom); - - case PLL_USB: - return 480000000u; - - default: - printf("Unsupported pll clocks %d\n", pll); - break; - } - - return 0; -} - -static u32 mxc_get_pll_sys_derive(int derive) -{ - u32 freq, div, frac; - u32 reg; - - div = 1; - reg = readl(&ccm_anatop->pll_480); - freq = decode_pll(PLL_SYS, MXC_HCLK); - - switch (derive) { - case PLL_SYS_MAIN_480M_CLK: - if (reg & CCM_ANALOG_PLL_480_MAIN_DIV1_CLKGATE_MASK) - return 0; - else - return freq; - case PLL_SYS_MAIN_240M_CLK: - if (reg & CCM_ANALOG_PLL_480_MAIN_DIV2_CLKGATE_MASK) - return 0; - else - return freq / 2; - case PLL_SYS_MAIN_120M_CLK: - if (reg & CCM_ANALOG_PLL_480_MAIN_DIV4_CLKGATE_MASK) - return 0; - else - return freq / 4; - case PLL_SYS_PFD0_392M_CLK: - reg = readl(&ccm_anatop->pfd_480a); - if (reg & CCM_ANALOG_PFD_480A_PFD0_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT; - break; - case PLL_SYS_PFD0_196M_CLK: - if (reg & CCM_ANALOG_PLL_480_PFD0_DIV2_CLKGATE_MASK) - return 0; - reg = readl(&ccm_anatop->pfd_480a); - frac = (reg & CCM_ANALOG_PFD_480A_PFD0_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD0_FRAC_SHIFT; - div = 2; - break; - case PLL_SYS_PFD1_332M_CLK: - reg = readl(&ccm_anatop->pfd_480a); - if (reg & CCM_ANALOG_PFD_480A_PFD1_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT; - break; - case PLL_SYS_PFD1_166M_CLK: - if (reg & CCM_ANALOG_PLL_480_PFD1_DIV2_CLKGATE_MASK) - return 0; - reg = readl(&ccm_anatop->pfd_480a); - frac = (reg & CCM_ANALOG_PFD_480A_PFD1_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD1_FRAC_SHIFT; - div = 2; - break; - case PLL_SYS_PFD2_270M_CLK: - reg = readl(&ccm_anatop->pfd_480a); - if (reg & CCM_ANALOG_PFD_480A_PFD2_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT; - break; - case PLL_SYS_PFD2_135M_CLK: - if (reg & CCM_ANALOG_PLL_480_PFD2_DIV2_CLKGATE_MASK) - return 0; - reg = readl(&ccm_anatop->pfd_480a); - frac = (reg & CCM_ANALOG_PFD_480A_PFD2_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD2_FRAC_SHIFT; - div = 2; - break; - case PLL_SYS_PFD3_CLK: - reg = readl(&ccm_anatop->pfd_480a); - if (reg & CCM_ANALOG_PFD_480A_PFD3_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480A_PFD3_FRAC_MASK) >> - CCM_ANALOG_PFD_480A_PFD3_FRAC_SHIFT; - break; - case PLL_SYS_PFD4_CLK: - reg = readl(&ccm_anatop->pfd_480b); - if (reg & CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480B_PFD4_FRAC_MASK) >> - CCM_ANALOG_PFD_480B_PFD4_FRAC_SHIFT; - break; - case PLL_SYS_PFD5_CLK: - reg = readl(&ccm_anatop->pfd_480b); - if (reg & CCM_ANALOG_PFD_480B_PFD5_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480B_PFD5_FRAC_MASK) >> - CCM_ANALOG_PFD_480B_PFD5_FRAC_SHIFT; - break; - case PLL_SYS_PFD6_CLK: - reg = readl(&ccm_anatop->pfd_480b); - if (reg & CCM_ANALOG_PFD_480B_PFD6_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480B_PFD6_FRAC_MASK) >> - CCM_ANALOG_PFD_480B_PFD6_FRAC_SHIFT; - break; - case PLL_SYS_PFD7_CLK: - reg = readl(&ccm_anatop->pfd_480b); - if (reg & CCM_ANALOG_PFD_480B_PFD7_DIV1_CLKGATE_MASK) - return 0; - frac = (reg & CCM_ANALOG_PFD_480B_PFD7_FRAC_MASK) >> - CCM_ANALOG_PFD_480B_PFD7_FRAC_SHIFT; - break; - default: - printf("Error derived pll_sys clock %d\n", derive); - return 0; - } - - return ((freq / frac) * 18) / div; -} - -static u32 mxc_get_pll_enet_derive(int derive) -{ - u32 freq, reg; - - freq = decode_pll(PLL_ENET, MXC_HCLK); - reg = readl(&ccm_anatop->pll_enet); - - switch (derive) { - case PLL_ENET_MAIN_500M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK) - return freq / 2; - break; - case PLL_ENET_MAIN_250M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK) - return freq / 4; - break; - case PLL_ENET_MAIN_125M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK) - return freq / 8; - break; - case PLL_ENET_MAIN_100M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK) - return freq / 10; - break; - case PLL_ENET_MAIN_50M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK) - return freq / 20; - break; - case PLL_ENET_MAIN_40M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK) - return freq / 25; - break; - case PLL_ENET_MAIN_25M_CLK: - if (reg & CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK) - return freq / 40; - break; - default: - printf("Error derived pll_enet clock %d\n", derive); - break; - } - - return 0; -} - -static u32 mxc_get_pll_ddr_derive(int derive) -{ - u32 freq, reg; - - freq = decode_pll(PLL_DDR, MXC_HCLK); - reg = readl(&ccm_anatop->pll_ddr); - - switch (derive) { - case PLL_DRAM_MAIN_1066M_CLK: - return freq; - case PLL_DRAM_MAIN_533M_CLK: - if (reg & CCM_ANALOG_PLL_DDR_DIV2_ENABLE_CLK_MASK) - return freq / 2; - break; - default: - printf("Error derived pll_ddr clock %d\n", derive); - break; - } - - return 0; -} - -static u32 mxc_get_pll_derive(enum pll_clocks pll, int derive) -{ - switch (pll) { - case PLL_SYS: - return mxc_get_pll_sys_derive(derive); - case PLL_ENET: - return mxc_get_pll_enet_derive(derive); - case PLL_DDR: - return mxc_get_pll_ddr_derive(derive); - default: - printf("Error pll.\n"); - return 0; - } -} - -static u32 get_root_src_clk(enum clk_root_src root_src) -{ - switch (root_src) { - case OSC_24M_CLK: - return 24000000u; - case PLL_ARM_MAIN_800M_CLK: - return decode_pll(PLL_CORE, MXC_HCLK); - - case PLL_SYS_MAIN_480M_CLK: - case PLL_SYS_MAIN_240M_CLK: - case PLL_SYS_MAIN_120M_CLK: - case PLL_SYS_PFD0_392M_CLK: - case PLL_SYS_PFD0_196M_CLK: - case PLL_SYS_PFD1_332M_CLK: - case PLL_SYS_PFD1_166M_CLK: - case PLL_SYS_PFD2_270M_CLK: - case PLL_SYS_PFD2_135M_CLK: - case PLL_SYS_PFD3_CLK: - case PLL_SYS_PFD4_CLK: - case PLL_SYS_PFD5_CLK: - case PLL_SYS_PFD6_CLK: - case PLL_SYS_PFD7_CLK: - return mxc_get_pll_derive(PLL_SYS, root_src); - - case PLL_ENET_MAIN_500M_CLK: - case PLL_ENET_MAIN_250M_CLK: - case PLL_ENET_MAIN_125M_CLK: - case PLL_ENET_MAIN_100M_CLK: - case PLL_ENET_MAIN_50M_CLK: - case PLL_ENET_MAIN_40M_CLK: - case PLL_ENET_MAIN_25M_CLK: - return mxc_get_pll_derive(PLL_ENET, root_src); - - case PLL_DRAM_MAIN_1066M_CLK: - case PLL_DRAM_MAIN_533M_CLK: - return mxc_get_pll_derive(PLL_DDR, root_src); - - case PLL_AUDIO_MAIN_CLK: - return decode_pll(PLL_AUDIO, MXC_HCLK); - case PLL_VIDEO_MAIN_CLK: - return decode_pll(PLL_VIDEO, MXC_HCLK); - - case PLL_USB_MAIN_480M_CLK: - return decode_pll(PLL_USB, MXC_HCLK); - - case REF_1M_CLK: - return 1000000; - case OSC_32K_CLK: - return MXC_CLK32; - - case EXT_CLK_1: - case EXT_CLK_2: - case EXT_CLK_3: - case EXT_CLK_4: - printf("No EXT CLK supported??\n"); - break; - }; - - return 0; -} - -u32 get_root_clk(enum clk_root_index clock_id) -{ - enum clk_root_src root_src; - u32 post_podf, pre_podf, auto_podf, root_src_clk; - int auto_en; - - if (clock_root_enabled(clock_id) <= 0) - return 0; - - if (clock_get_prediv(clock_id, &pre_podf) < 0) - return 0; - - if (clock_get_postdiv(clock_id, &post_podf) < 0) - return 0; - - if (clock_get_autopostdiv(clock_id, &auto_podf, &auto_en) < 0) - return 0; - - if (auto_en == 0) - auto_podf = 0; - - if (clock_get_src(clock_id, &root_src) < 0) - return 0; - - root_src_clk = get_root_src_clk(root_src); - - /* - * bypass clk is ignored. - */ - - return root_src_clk / (post_podf + 1) / (pre_podf + 1) / - (auto_podf + 1); -} - -static u32 get_ddrc_clk(void) -{ - u32 reg, freq; - enum root_post_div post_div; - - reg = readl(&ccm_reg->root[DRAM_CLK_ROOT].target_root); - if (reg & CLK_ROOT_MUX_MASK) - /* DRAM_ALT_CLK_ROOT */ - freq = get_root_clk(DRAM_ALT_CLK_ROOT); - else - /* PLL_DRAM_MAIN_1066M_CLK */ - freq = mxc_get_pll_derive(PLL_DDR, PLL_DRAM_MAIN_1066M_CLK); - - post_div = reg & DRAM_CLK_ROOT_POST_DIV_MASK; - - return freq / (post_div + 1) / 2; -} - -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return get_root_clk(ARM_A7_CLK_ROOT); - case MXC_AXI_CLK: - return get_root_clk(MAIN_AXI_CLK_ROOT); - case MXC_AHB_CLK: - return get_root_clk(AHB_CLK_ROOT); - case MXC_IPG_CLK: - return get_ipg_clk(); - case MXC_I2C_CLK: - return get_root_clk(I2C1_CLK_ROOT); - case MXC_UART_CLK: - return get_root_clk(UART1_CLK_ROOT); - case MXC_CSPI_CLK: - return get_root_clk(ECSPI1_CLK_ROOT); - case MXC_DDR_CLK: - return get_ddrc_clk(); - case MXC_ESDHC_CLK: - return get_root_clk(USDHC1_CLK_ROOT); - case MXC_ESDHC2_CLK: - return get_root_clk(USDHC2_CLK_ROOT); - case MXC_ESDHC3_CLK: - return get_root_clk(USDHC3_CLK_ROOT); - default: - printf("Unsupported mxc_clock %d\n", clk); - break; - } - - return 0; -} - -#ifdef CONFIG_SYS_I2C_MXC -/* i2c_num can be 0 - 3 */ -int enable_i2c_clk(unsigned char enable, unsigned i2c_num) -{ - u32 target; - - if (i2c_num >= 4) - return -EINVAL; - - if (enable) { - clock_enable(CCGR_I2C1 + i2c_num, 0); - - /* Set i2c root clock to PLL_SYS_MAIN_120M_CLK */ - - target = CLK_ROOT_ON | - I2C1_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(I2C1_CLK_ROOT + i2c_num, target); - - clock_enable(CCGR_I2C1 + i2c_num, 1); - } else { - clock_enable(CCGR_I2C1 + i2c_num, 0); - } - - return 0; -} -#endif - -static void init_clk_esdhc(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_USDHC1, 0); - clock_enable(CCGR_USDHC2, 0); - clock_enable(CCGR_USDHC3, 0); - - /* 196: 392/2 */ - target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(USDHC1_CLK_ROOT, target); - - target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(USDHC2_CLK_ROOT, target); - - target = CLK_ROOT_ON | USDHC1_CLK_ROOT_FROM_PLL_SYS_PFD0_392M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(USDHC3_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_USDHC1, 1); - clock_enable(CCGR_USDHC2, 1); - clock_enable(CCGR_USDHC3, 1); -} - -static void init_clk_uart(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_UART1, 0); - clock_enable(CCGR_UART2, 0); - clock_enable(CCGR_UART3, 0); - clock_enable(CCGR_UART4, 0); - clock_enable(CCGR_UART5, 0); - clock_enable(CCGR_UART6, 0); - clock_enable(CCGR_UART7, 0); - - /* 24Mhz */ - target = CLK_ROOT_ON | UART1_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART1_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART2_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART2_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART3_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART3_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART4_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART4_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART5_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART5_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART6_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART6_CLK_ROOT, target); - - target = CLK_ROOT_ON | UART7_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(UART7_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_UART1, 1); - clock_enable(CCGR_UART2, 1); - clock_enable(CCGR_UART3, 1); - clock_enable(CCGR_UART4, 1); - clock_enable(CCGR_UART5, 1); - clock_enable(CCGR_UART6, 1); - clock_enable(CCGR_UART7, 1); -} - -static void init_clk_weim(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_WEIM, 0); - - /* 120Mhz */ - target = CLK_ROOT_ON | EIM_CLK_ROOT_FROM_PLL_SYS_MAIN_120M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(EIM_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_WEIM, 1); -} - -static void init_clk_ecspi(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_ECSPI1, 0); - clock_enable(CCGR_ECSPI2, 0); - clock_enable(CCGR_ECSPI3, 0); - clock_enable(CCGR_ECSPI4, 0); - - /* 60Mhz: 240/4 */ - target = CLK_ROOT_ON | ECSPI1_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ECSPI1_CLK_ROOT, target); - - target = CLK_ROOT_ON | ECSPI2_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ECSPI2_CLK_ROOT, target); - - target = CLK_ROOT_ON | ECSPI3_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ECSPI3_CLK_ROOT, target); - - target = CLK_ROOT_ON | ECSPI4_CLK_ROOT_FROM_PLL_SYS_MAIN_240M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ECSPI4_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_ECSPI1, 1); - clock_enable(CCGR_ECSPI2, 1); - clock_enable(CCGR_ECSPI3, 1); - clock_enable(CCGR_ECSPI4, 1); -} - -static void init_clk_wdog(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_WDOG1, 0); - clock_enable(CCGR_WDOG2, 0); - clock_enable(CCGR_WDOG3, 0); - clock_enable(CCGR_WDOG4, 0); - - /* 24Mhz */ - target = CLK_ROOT_ON | WDOG_CLK_ROOT_FROM_OSC_24M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(WDOG_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_WDOG1, 1); - clock_enable(CCGR_WDOG2, 1); - clock_enable(CCGR_WDOG3, 1); - clock_enable(CCGR_WDOG4, 1); -} - -#ifdef CONFIG_MXC_EPDC -static void init_clk_epdc(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_EPDC, 0); - - /* 24Mhz */ - target = CLK_ROOT_ON | EPDC_PIXEL_CLK_ROOT_FROM_PLL_SYS_MAIN_480M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV12); - clock_set_target_val(EPDC_PIXEL_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_EPDC, 1); -} -#endif - -static int enable_pll_enet(void) -{ - u32 reg; - s32 timeout = 100000; - - reg = readl(&ccm_anatop->pll_enet); - /* If pll_enet powered up, no need to set it again */ - if (reg & ANADIG_PLL_ENET_PWDN_MASK) { - reg &= ~ANADIG_PLL_ENET_PWDN_MASK; - writel(reg, &ccm_anatop->pll_enet); - - while (timeout--) { - if (readl(&ccm_anatop->pll_enet) & ANADIG_PLL_LOCK) - break; - } - - if (timeout <= 0) { - /* If timeout, we set pwdn for pll_enet. */ - reg |= ANADIG_PLL_ENET_PWDN_MASK; - return -ETIME; - } - } - - /* Clear bypass */ - writel(CCM_ANALOG_PLL_ENET_BYPASS_MASK, &ccm_anatop->pll_enet_clr); - - writel((CCM_ANALOG_PLL_ENET_ENABLE_CLK_500MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_250MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_125MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_100MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_50MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_40MHZ_MASK - | CCM_ANALOG_PLL_ENET_ENABLE_CLK_25MHZ_MASK), - &ccm_anatop->pll_enet_set); - - return 0; -} -static int enable_pll_video(u32 pll_div, u32 pll_num, u32 pll_denom, - u32 post_div) -{ - u32 reg = 0; - ulong start; - - debug("pll5 div = %d, num = %d, denom = %d\n", - pll_div, pll_num, pll_denom); - - /* Power up PLL5 video and disable its output */ - writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK | - CCM_ANALOG_PLL_VIDEO_CLR_POWERDOWN_MASK | - CCM_ANALOG_PLL_VIDEO_CLR_BYPASS_MASK | - CCM_ANALOG_PLL_VIDEO_CLR_DIV_SELECT_MASK | - CCM_ANALOG_PLL_VIDEO_CLR_POST_DIV_SEL_MASK | - CCM_ANALOG_PLL_VIDEO_CLR_TEST_DIV_SELECT_MASK, - &ccm_anatop->pll_video_clr); - - /* Set div, num and denom */ - switch (post_div) { - case 1: - writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | - CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x1) | - CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), - &ccm_anatop->pll_video_set); - break; - case 2: - writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | - CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | - CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), - &ccm_anatop->pll_video_set); - break; - case 3: - writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | - CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | - CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x1), - &ccm_anatop->pll_video_set); - break; - case 4: - writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | - CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x0) | - CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x3), - &ccm_anatop->pll_video_set); - break; - case 0: - default: - writel(CCM_ANALOG_PLL_VIDEO_SET_DIV_SELECT(pll_div) | - CCM_ANALOG_PLL_VIDEO_SET_TEST_DIV_SELECT(0x2) | - CCM_ANALOG_PLL_VIDEO_SET_POST_DIV_SEL(0x0), - &ccm_anatop->pll_video_set); - break; - } - - writel(CCM_ANALOG_PLL_VIDEO_NUM_A(pll_num), - &ccm_anatop->pll_video_num); - - writel(CCM_ANALOG_PLL_VIDEO_DENOM_B(pll_denom), - &ccm_anatop->pll_video_denom); - - /* Wait PLL5 lock */ - start = get_timer(0); /* Get current timestamp */ - - do { - reg = readl(&ccm_anatop->pll_video); - if (reg & CCM_ANALOG_PLL_VIDEO_LOCK_MASK) { - /* Enable PLL out */ - writel(CCM_ANALOG_PLL_VIDEO_CLR_ENABLE_CLK_MASK, - &ccm_anatop->pll_video_set); - return 0; - } - } while (get_timer(0) < (start + 10)); /* Wait 10ms */ - - printf("Lock PLL5 timeout\n"); - - return 1; -} - -int set_clk_qspi(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_QSPI, 0); - - /* 49M: 392/2/4 */ - target = CLK_ROOT_ON | QSPI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(QSPI_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_QSPI, 1); - - return 0; -} - -int set_clk_nand(void) -{ - u32 target; - - /* disable the clock gate first */ - clock_enable(CCGR_RAWNAND, 0); - - enable_pll_enet(); - /* 100: 500/5 */ - target = CLK_ROOT_ON | NAND_CLK_ROOT_FROM_PLL_ENET_MAIN_500M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV5); - clock_set_target_val(NAND_CLK_ROOT, target); - - /* enable the clock gate */ - clock_enable(CCGR_RAWNAND, 1); - - return 0; -} - -void mxs_set_lcdclk(uint32_t base_addr, uint32_t freq) -{ - u32 hck = MXC_HCLK/1000; - u32 min = hck * 27; - u32 max = hck * 54; - u32 temp, best = 0; - u32 i, j, pred = 1, postd = 1; - u32 pll_div, pll_num, pll_denom, post_div = 0; - u32 target; - - debug("mxs_set_lcdclk, freq = %d\n", freq); - - clock_enable(CCGR_LCDIF, 0); - - temp = (freq * 8 * 8); - if (temp < min) { - for (i = 1; i <= 4; i++) { - if ((temp * (1 << i)) > min) { - post_div = i; - freq = (freq * (1 << i)); - break; - } - } - - if (5 == i) { - printf("Fail to set rate to %dkhz", freq); - return; - } - } - - for (i = 1; i <= 8; i++) { - for (j = 1; j <= 8; j++) { - temp = freq * i * j; - if (temp > max || temp < min) - continue; - - if (best == 0 || temp < best) { - best = temp; - pred = i; - postd = j; - } - } - } - - if (best == 0) { - printf("Fail to set rate to %dkhz", freq); - return; - } - - debug("best %d, pred = %d, postd = %d\n", best, pred, postd); - - pll_div = best / hck; - pll_denom = 1000000; - pll_num = (best - hck * pll_div) * pll_denom / hck; - - if (enable_pll_video(pll_div, pll_num, pll_denom, post_div)) - return; - - target = CLK_ROOT_ON | LCDIF_PIXEL_CLK_ROOT_FROM_PLL_VIDEO_MAIN_CLK | - CLK_ROOT_PRE_DIV((pred - 1)) | CLK_ROOT_POST_DIV((postd - 1)); - clock_set_target_val(LCDIF_PIXEL_CLK_ROOT, target); - - clock_enable(CCGR_LCDIF, 1); -} - -#ifdef CONFIG_FEC_MXC -int set_clk_enet(enum enet_freq type) -{ - u32 target; - int ret; - u32 enet1_ref, enet2_ref; - - /* disable the clock first */ - clock_enable(CCGR_ENET1, 0); - clock_enable(CCGR_ENET2, 0); - - switch (type) { - case ENET_125MHz: - enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK; - enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_125M_CLK; - break; - case ENET_50MHz: - enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK; - enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_50M_CLK; - break; - case ENET_25MHz: - enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; - enet2_ref = ENET2_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; - break; - default: - return -EINVAL; - } - - ret = enable_pll_enet(); - if (ret != 0) - return ret; - - /* set enet axi clock 196M: 392/2 */ - target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_PLL_SYS_PFD4_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2); - clock_set_target_val(ENET_AXI_CLK_ROOT, target); - - target = CLK_ROOT_ON | enet1_ref | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(ENET1_REF_CLK_ROOT, target); - - target = CLK_ROOT_ON | ENET1_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ENET1_TIME_CLK_ROOT, target); - - target = CLK_ROOT_ON | enet2_ref | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(ENET2_REF_CLK_ROOT, target); - - target = CLK_ROOT_ON | ENET2_TIME_CLK_ROOT_FROM_PLL_ENET_MAIN_100M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV4); - clock_set_target_val(ENET2_TIME_CLK_ROOT, target); - -#ifdef CONFIG_FEC_MXC_25M_REF_CLK - target = CLK_ROOT_ON | - ENET_PHY_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK | - CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | - CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); - clock_set_target_val(ENET_PHY_REF_CLK_ROOT, target); -#endif - /* enable clock */ - clock_enable(CCGR_ENET1, 1); - clock_enable(CCGR_ENET2, 1); - - return 0; -} -#endif - -/* Configure PLL/PFD freq */ -void clock_init(void) -{ -/* Rom has enabled PLL_ARM, PLL_DDR, PLL_SYS, PLL_ENET - * In u-boot, we have to: - * 1. Configure PFD3- PFD7 for freq we needed in u-boot - * 2. Set clock root for peripherals (ip channel) used in u-boot but without set rate - * interface. The clocks for these peripherals are enabled after this intialization. - * 3. Other peripherals with set clock rate interface does not be set in this function. - */ - u32 reg; - - /* - * Configure PFD4 to 392M - * 480M * 18 / 0x16 = 392M - */ - reg = readl(&ccm_anatop->pfd_480b); - - reg &= ~(ANATOP_PFD480B_PFD4_FRAC_MASK | - CCM_ANALOG_PFD_480B_PFD4_DIV1_CLKGATE_MASK); - reg |= ANATOP_PFD480B_PFD4_FRAC_392M_VAL; - - writel(reg, &ccm_anatop->pfd_480b); - - init_clk_esdhc(); - init_clk_uart(); - init_clk_weim(); - init_clk_ecspi(); - init_clk_wdog(); -#ifdef CONFIG_MXC_EPDC - init_clk_epdc(); -#endif - - enable_usboh3_clk(1); - - clock_enable(CCGR_SNVS, 1); - -#ifdef CONFIG_NAND_MXS - clock_enable(CCGR_RAWNAND, 1); -#endif - - if (IS_ENABLED(CONFIG_IMX_RDC)) { - clock_enable(CCGR_RDC, 1); - clock_enable(CCGR_SEMA1, 1); - clock_enable(CCGR_SEMA2, 1); - } -} - -#ifdef CONFIG_SECURE_BOOT -void hab_caam_clock_enable(unsigned char enable) -{ - if (enable) - clock_enable(CCGR_CAAM, 1); - else - clock_enable(CCGR_CAAM, 0); -} -#endif - -#ifdef CONFIG_MXC_EPDC -void epdc_clock_enable(void) -{ - clock_enable(CCGR_EPDC, 1); -} -void epdc_clock_disable(void) -{ - clock_enable(CCGR_EPDC, 0); -} -#endif - -/* - * Dump some core clockes. - */ -int do_mx7_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 freq; - freq = decode_pll(PLL_CORE, MXC_HCLK); - printf("PLL_CORE %8d MHz\n", freq / 1000000); - freq = decode_pll(PLL_SYS, MXC_HCLK); - printf("PLL_SYS %8d MHz\n", freq / 1000000); - freq = decode_pll(PLL_ENET, MXC_HCLK); - printf("PLL_NET %8d MHz\n", freq / 1000000); - - printf("\n"); - - printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); - printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); -#ifdef CONFIG_MXC_SPI - printf("CSPI %8d kHz\n", mxc_get_clock(MXC_CSPI_CLK) / 1000); -#endif - printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); - printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000); - printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); - printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); - printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); - printf("USDHC3 %8d kHz\n", mxc_get_clock(MXC_ESDHC3_CLK) / 1000); - - return 0; -} - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_mx7_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/armv7/mx7/clock_slice.c b/arch/arm/cpu/armv7/mx7/clock_slice.c deleted file mode 100644 index 68a7005b2e..0000000000 --- a/arch/arm/cpu/armv7/mx7/clock_slice.c +++ /dev/null @@ -1,757 +0,0 @@ -/* - * Copyright (C) 2015 Freescale Semiconductor, Inc. - * - * Author: - * Peng Fan <Peng.Fan@freescale.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <linux/errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/crm_regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> - -struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; - -static struct clk_root_map root_array[] = { - {ARM_A7_CLK_ROOT, CCM_CORE_CHANNEL, - {OSC_24M_CLK, PLL_ARM_MAIN_800M_CLK, PLL_ENET_MAIN_500M_CLK, - PLL_DRAM_MAIN_1066M_CLK, PLL_SYS_MAIN_480M_CLK, - PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {ARM_M4_CLK_ROOT, CCM_BUS_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_250M_CLK, - PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {ARM_M0_CLK_ROOT, CCM_BUS_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_125M_CLK, - PLL_SYS_PFD2_135M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {MAIN_AXI_CLK_ROOT, CCM_BUS_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD5_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD7_CLK} - }, - {DISP_AXI_CLK_ROOT, CCM_BUS_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK, - PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} - }, - {ENET_AXI_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK} - }, - {NAND_USDHC_BUS_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_PFD6_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_AUDIO_MAIN_CLK} - }, - {AHB_CLK_ROOT, CCM_AHB_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_PFD0_392M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, - PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} - }, - {DRAM_PHYM_CLK_ROOT, CCM_DRAM_PHYM_CHANNEL, - {PLL_DRAM_MAIN_1066M_CLK, DRAM_PHYM_ALT_CLK_ROOT} - }, - {DRAM_CLK_ROOT, CCM_DRAM_CHANNEL, - {PLL_DRAM_MAIN_1066M_CLK, DRAM_ALT_CLK_ROOT} - }, - {DRAM_PHYM_ALT_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD7_CLK, - PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK} - }, - {DRAM_ALT_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_SYS_MAIN_480M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_ENET_MAIN_250M_CLK, - PLL_SYS_PFD0_392M_CLK, PLL_AUDIO_MAIN_CLK, PLL_SYS_PFD2_270M_CLK} - }, - {USB_HSIC_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_USB_MAIN_480M_CLK, - PLL_SYS_PFD3_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD5_CLK, - PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} - }, - {PCIE_CTRL_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_250M_CLK, PLL_SYS_MAIN_240M_CLK, - PLL_SYS_PFD2_270M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_SYS_PFD6_CLK} - }, - {PCIE_PHY_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_ENET_MAIN_500M_CLK, - EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, - EXT_CLK_4, PLL_SYS_PFD0_392M_CLK} - }, - {EPDC_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD1_332M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD6_CLK, - PLL_SYS_PFD7_CLK, PLL_VIDEO_MAIN_CLK} - }, - {LCDIF_PIXEL_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_DRAM_MAIN_533M_CLK, - EXT_CLK_3, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {MIPI_DSI_EXTSER_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD5_CLK, PLL_SYS_PFD3_CLK, - PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} - }, - {MIPI_CSI_WARP_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD3_CLK, - PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD0_196M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_VIDEO_MAIN_CLK, PLL_AUDIO_MAIN_CLK} - }, - {MIPI_DPHY_REF_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_PFD5_CLK, REF_1M_CLK, EXT_CLK_2, - PLL_VIDEO_MAIN_CLK, EXT_CLK_3} - }, - {SAI1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} - }, - {SAI2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_125M_CLK, EXT_CLK_2} - }, - {SAI3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} - }, - {SPDIF_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_125M_CLK, EXT_CLK_3} - }, - {ENET1_REF_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, EXT_CLK_4} - }, - {ENET1_TIME_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, - EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, - EXT_CLK_4, PLL_VIDEO_MAIN_CLK} - }, - {ENET2_REF_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_ENET_MAIN_25M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, EXT_CLK_4} - }, - {ENET2_TIME_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_AUDIO_MAIN_CLK, - EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, - EXT_CLK_4, PLL_VIDEO_MAIN_CLK} - }, - {ENET_PHY_REF_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_25M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_ENET_MAIN_125M_CLK, PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_SYS_PFD3_CLK} - }, - {EIM_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_SYS_PFD2_270M_CLK, PLL_SYS_PFD3_CLK, - PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK} - }, - {NAND_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_PFD0_392M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {QSPI_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD4_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD3_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} - }, - {USDHC1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} - }, - {USDHC2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} - }, - {USDHC3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD0_392M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD4_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_SYS_PFD6_CLK, PLL_SYS_PFD7_CLK} - }, - {CAN1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, - EXT_CLK_1, EXT_CLK_4} - }, - {CAN2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_SYS_MAIN_480M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_USB_MAIN_480M_CLK, - EXT_CLK_1, EXT_CLK_3} - }, - {I2C1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, - PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} - }, - {I2C2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, - PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} - }, - {I2C3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, - PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} - }, - {I2C4_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_120M_CLK, PLL_ENET_MAIN_50M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_AUDIO_MAIN_CLK, PLL_VIDEO_MAIN_CLK, - PLL_USB_MAIN_480M_CLK, PLL_SYS_PFD2_135M_CLK} - }, - {UART1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_4, PLL_USB_MAIN_480M_CLK} - }, - {UART2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_3, PLL_USB_MAIN_480M_CLK} - }, - {UART3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_4, PLL_USB_MAIN_480M_CLK} - }, - {UART4_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_3, PLL_USB_MAIN_480M_CLK} - }, - {UART5_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_4, PLL_USB_MAIN_480M_CLK} - }, - {UART6_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_3, PLL_USB_MAIN_480M_CLK} - }, - {UART7_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_480M_CLK, EXT_CLK_2, - EXT_CLK_4, PLL_USB_MAIN_480M_CLK} - }, - {ECSPI1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} - }, - {ECSPI2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} - }, - {ECSPI3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} - }, - {ECSPI4_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_ENET_MAIN_40M_CLK, - PLL_SYS_MAIN_120M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_PFD4_CLK, - PLL_ENET_MAIN_250M_CLK, PLL_USB_MAIN_480M_CLK} - }, - {PWM1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {PWM2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_1, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {PWM3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {PWM4_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_2, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {FLEXTIMER1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {FLEXTIMER2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_AUDIO_MAIN_CLK, EXT_CLK_3, - REF_1M_CLK, PLL_VIDEO_MAIN_CLK} - }, - {SIM1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} - }, - {SIM2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_USB_MAIN_480M_CLK, PLL_VIDEO_MAIN_CLK, - PLL_ENET_MAIN_125M_CLK, PLL_SYS_PFD7_CLK} - }, - {GPT1_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, - PLL_AUDIO_MAIN_CLK, EXT_CLK_1} - }, - {GPT2_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, - PLL_AUDIO_MAIN_CLK, EXT_CLK_2} - }, - {GPT3_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, - PLL_AUDIO_MAIN_CLK, EXT_CLK_3} - }, - {GPT4_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_100M_CLK, PLL_SYS_PFD0_392M_CLK, - PLL_ENET_MAIN_40M_CLK, PLL_VIDEO_MAIN_CLK, REF_1M_CLK, - PLL_AUDIO_MAIN_CLK, EXT_CLK_4} - }, - {TRACE_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, - EXT_CLK_1, EXT_CLK_3} - }, - {WDOG_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_USB_MAIN_480M_CLK, - REF_1M_CLK, PLL_SYS_PFD1_166M_CLK} - }, - {CSI_MCLK_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {AUDIO_MCLK_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_PFD2_135M_CLK, PLL_SYS_MAIN_120M_CLK, - PLL_DRAM_MAIN_533M_CLK, PLL_ENET_MAIN_125M_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, PLL_USB_MAIN_480M_CLK} - }, - {WRCLK_CLK_ROOT, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_ENET_MAIN_40M_CLK, PLL_DRAM_MAIN_533M_CLK, - PLL_USB_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD2_270M_CLK, - PLL_ENET_MAIN_500M_CLK, PLL_SYS_PFD7_CLK} - }, - {IPP_DO_CLKO1, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_480M_CLK, PLL_SYS_MAIN_240M_CLK, - PLL_SYS_PFD0_196M_CLK, PLL_SYS_PFD3_CLK, PLL_ENET_MAIN_500M_CLK, - PLL_DRAM_MAIN_533M_CLK, REF_1M_CLK} - }, - {IPP_DO_CLKO2, CCM_IP_CHANNEL, - {OSC_24M_CLK, PLL_SYS_MAIN_240M_CLK, PLL_SYS_PFD0_392M_CLK, - PLL_SYS_PFD1_166M_CLK, PLL_SYS_PFD4_CLK, PLL_AUDIO_MAIN_CLK, - PLL_VIDEO_MAIN_CLK, OSC_32K_CLK} - }, -}; - -/* select which entry of root_array */ -static int select(enum clk_root_index clock_id) -{ - int i, size; - struct clk_root_map *p = root_array; - - size = ARRAY_SIZE(root_array); - - for (i = 0; i < size; i++, p++) { - if (clock_id == p->entry) - return i; - } - - return -EINVAL; -} - -static int src_supported(int entry, enum clk_root_src clock_src) -{ - int i, size; - struct clk_root_map *p = &root_array[entry]; - - if ((p->type == CCM_DRAM_PHYM_CHANNEL) || (p->type == CCM_DRAM_CHANNEL)) - size = 2; - else - size = 8; - - for (i = 0; i < size; i++) { - if (p->src_mux[i] == clock_src) - return i; - } - - return -EINVAL; -} - -/* Set src for clock root slice. */ -int clock_set_src(enum clk_root_index clock_id, enum clk_root_src clock_src) -{ - int root_entry, src_entry; - u32 reg; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - src_entry = src_supported(root_entry, clock_src); - if (src_entry < 0) - return -EINVAL; - - reg = __raw_readl(&imx_ccm->root[clock_id].target_root); - reg &= ~CLK_ROOT_MUX_MASK; - reg |= src_entry << CLK_ROOT_MUX_SHIFT; - __raw_writel(reg, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -/* Get src of a clock root slice. */ -int clock_get_src(enum clk_root_index clock_id, enum clk_root_src *p_clock_src) -{ - u32 val; - int root_entry; - struct clk_root_map *p; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - val &= CLK_ROOT_MUX_MASK; - val >>= CLK_ROOT_MUX_SHIFT; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - *p_clock_src = p->src_mux[val]; - - return 0; -} - -int clock_set_prediv(enum clk_root_index clock_id, enum root_pre_div pre_div) -{ - int root_entry; - struct clk_root_map *p; - u32 reg; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - - if ((p->type == CCM_CORE_CHANNEL) || - (p->type == CCM_DRAM_PHYM_CHANNEL) || - (p->type == CCM_DRAM_CHANNEL)) { - if (pre_div != CLK_ROOT_PRE_DIV1) { - printf("Error pre div!\n"); - return -EINVAL; - } - } - - reg = __raw_readl(&imx_ccm->root[clock_id].target_root); - reg &= ~CLK_ROOT_PRE_DIV_MASK; - reg |= pre_div << CLK_ROOT_PRE_DIV_SHIFT; - __raw_writel(reg, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -int clock_get_prediv(enum clk_root_index clock_id, enum root_pre_div *pre_div) -{ - u32 val; - int root_entry; - struct clk_root_map *p; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - - if ((p->type == CCM_CORE_CHANNEL) || - (p->type == CCM_DRAM_PHYM_CHANNEL) || - (p->type == CCM_DRAM_CHANNEL)) { - *pre_div = 0; - return 0; - } - - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - val &= CLK_ROOT_PRE_DIV_MASK; - val >>= CLK_ROOT_PRE_DIV_SHIFT; - - *pre_div = val; - - return 0; -} - -int clock_set_postdiv(enum clk_root_index clock_id, enum root_post_div div) -{ - u32 reg; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - if (clock_id == DRAM_PHYM_CLK_ROOT) { - if (div != CLK_ROOT_POST_DIV1) { - printf("Error post div!\n"); - return -EINVAL; - } - } - - /* Only 3 bit post div. */ - if ((clock_id == DRAM_CLK_ROOT) && (div > CLK_ROOT_POST_DIV7)) { - printf("Error post div!\n"); - return -EINVAL; - } - - reg = __raw_readl(&imx_ccm->root[clock_id].target_root); - reg &= ~CLK_ROOT_POST_DIV_MASK; - reg |= div << CLK_ROOT_POST_DIV_SHIFT; - __raw_writel(reg, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -int clock_get_postdiv(enum clk_root_index clock_id, enum root_post_div *div) -{ - u32 val; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - if (clock_id == DRAM_PHYM_CLK_ROOT) { - *div = 0; - return 0; - } - - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - if (clock_id == DRAM_CLK_ROOT) - val &= DRAM_CLK_ROOT_POST_DIV_MASK; - else - val &= CLK_ROOT_POST_DIV_MASK; - val >>= CLK_ROOT_POST_DIV_SHIFT; - - *div = val; - - return 0; -} - -int clock_set_autopostdiv(enum clk_root_index clock_id, enum root_auto_div div, - int auto_en) -{ - u32 val; - int root_entry; - struct clk_root_map *p; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - - if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { - printf("Auto postdiv not supported.!\n"); - return -EINVAL; - } - - /* - * Each time only one filed can be changed, no use target_root_set. - */ - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - val &= ~CLK_ROOT_AUTO_DIV_MASK; - val |= (div << CLK_ROOT_AUTO_DIV_SHIFT); - - if (auto_en) - val |= CLK_ROOT_AUTO_EN; - else - val &= ~CLK_ROOT_AUTO_EN; - - __raw_writel(val, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -int clock_get_autopostdiv(enum clk_root_index clock_id, enum root_auto_div *div, - int *auto_en) -{ - u32 val; - int root_entry; - struct clk_root_map *p; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - - /* - * Only bus/ahb channel supports auto div. - * If unsupported, just set auto_en and div with 0. - */ - if ((p->type != CCM_BUS_CHANNEL) && (p->type != CCM_AHB_CHANNEL)) { - *auto_en = 0; - *div = 0; - return 0; - } - - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - if ((val & CLK_ROOT_AUTO_EN_MASK) == 0) - *auto_en = 0; - else - *auto_en = 1; - - val &= CLK_ROOT_AUTO_DIV_MASK; - val >>= CLK_ROOT_AUTO_DIV_SHIFT; - - *div = val; - - return 0; -} - -int clock_get_target_val(enum clk_root_index clock_id, u32 *val) -{ - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - *val = __raw_readl(&imx_ccm->root[clock_id].target_root); - - return 0; -} - -int clock_set_target_val(enum clk_root_index clock_id, u32 val) -{ - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - __raw_writel(val, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -/* Auto_div and auto_en is ignored, they are rarely used. */ -int clock_root_cfg(enum clk_root_index clock_id, enum root_pre_div pre_div, - enum root_post_div post_div, enum clk_root_src clock_src) -{ - u32 val; - int root_entry, src_entry; - struct clk_root_map *p; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - root_entry = select(clock_id); - if (root_entry < 0) - return -EINVAL; - - p = &root_array[root_entry]; - - if ((p->type == CCM_CORE_CHANNEL) || - (p->type == CCM_DRAM_PHYM_CHANNEL) || - (p->type == CCM_DRAM_CHANNEL)) { - if (pre_div != CLK_ROOT_PRE_DIV1) { - printf("Error pre div!\n"); - return -EINVAL; - } - } - - /* Only 3 bit post div. */ - if (p->type == CCM_DRAM_CHANNEL) { - if (post_div > CLK_ROOT_POST_DIV7) { - printf("Error post div!\n"); - return -EINVAL; - } - } - - if (p->type == CCM_DRAM_PHYM_CHANNEL) { - if (post_div != CLK_ROOT_POST_DIV1) { - printf("Error post div!\n"); - return -EINVAL; - } - } - - src_entry = src_supported(root_entry, clock_src); - if (src_entry < 0) - return -EINVAL; - - val = CLK_ROOT_ON | pre_div << CLK_ROOT_PRE_DIV_SHIFT | - post_div << CLK_ROOT_POST_DIV_SHIFT | - src_entry << CLK_ROOT_MUX_SHIFT; - - __raw_writel(val, &imx_ccm->root[clock_id].target_root); - - return 0; -} - -int clock_root_enabled(enum clk_root_index clock_id) -{ - u32 val; - - if (clock_id >= CLK_ROOT_MAX) - return -EINVAL; - - /* - * No enable bit for DRAM controller and PHY. Just return enabled. - */ - if ((clock_id == DRAM_PHYM_CLK_ROOT) || (clock_id == DRAM_CLK_ROOT)) - return 1; - - val = __raw_readl(&imx_ccm->root[clock_id].target_root); - - return (val & CLK_ROOT_ENABLE_MASK) ? 1 : 0; -} - -/* CCGR gate operation */ -int clock_enable(enum clk_ccgr_index index, bool enable) -{ - if (index >= CCGR_MAX) - return -EINVAL; - - if (enable) - __raw_writel(CCM_CLK_ON_MSK, - &imx_ccm->ccgr_array[index].ccgr_set); - else - __raw_writel(CCM_CLK_ON_MSK, - &imx_ccm->ccgr_array[index].ccgr_clr); - - return 0; -} diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c deleted file mode 100644 index 502552d171..0000000000 --- a/arch/arm/cpu/armv7/mx7/psci-mx7.c +++ /dev/null @@ -1,69 +0,0 @@ -#include <asm/io.h> -#include <asm/psci.h> -#include <asm/secure.h> -#include <asm/arch/imx-regs.h> -#include <common.h> - - -#define GPC_CPU_PGC_SW_PDN_REQ 0xfc -#define GPC_CPU_PGC_SW_PUP_REQ 0xf0 -#define GPC_PGC_C1 0x840 - -#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 - -/* below is for i.MX7D */ -#define SRC_GPR1_MX7D 0x074 -#define SRC_A7RCR0 0x004 -#define SRC_A7RCR1 0x008 - -#define BP_SRC_A7RCR0_A7_CORE_RESET0 0 -#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 - -static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) -{ - writel(enable, GPC_IPS_BASE_ADDR + offset); -} - -__secure void imx_gpcv2_set_core1_power(bool pdn) -{ - u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ; - u32 val; - - imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1); - - val = readl(GPC_IPS_BASE_ADDR + reg); - val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; - writel(val, GPC_IPS_BASE_ADDR + reg); - - while ((readl(GPC_IPS_BASE_ADDR + reg) & - BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0) - ; - - imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1); -} - -__secure void imx_enable_cpu_ca7(int cpu, bool enable) -{ - u32 mask, val; - - mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); - val = readl(SRC_BASE_ADDR + SRC_A7RCR1); - val = enable ? val | mask : val & ~mask; - writel(val, SRC_BASE_ADDR + SRC_A7RCR1); -} - -__secure int imx_cpu_on(int fn, int cpu, int pc) -{ - writel(pc, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D); - imx_gpcv2_set_core1_power(true); - imx_enable_cpu_ca7(cpu, true); - return 0; -} - -__secure int imx_cpu_off(int cpu) -{ - imx_enable_cpu_ca7(cpu, false); - imx_gpcv2_set_core1_power(false); - writel(0, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D + 4); - return 0; -} diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S deleted file mode 100644 index 96e88d6184..0000000000 --- a/arch/arm/cpu/armv7/mx7/psci.S +++ /dev/null @@ -1,39 +0,0 @@ -#include <config.h> -#include <linux/linkage.h> - -#include <asm/armv7.h> -#include <asm/arch-armv7/generictimer.h> -#include <asm/psci.h> - - .pushsection ._secure.text, "ax" - - .arch_extension sec - -.globl psci_cpu_on -psci_cpu_on: - push {r4, r5, lr} - - mov r4, r0 - mov r5, r1 - mov r0, r1 - mov r1, r2 - bl psci_save_target_pc - - mov r0, r4 - mov r1, r5 - ldr r2, =psci_cpu_entry - bl imx_cpu_on - - pop {r4, r5, pc} - -.globl psci_cpu_off -psci_cpu_off: - - bl psci_cpu_off_common - bl psci_get_cpu_id - bl imx_cpu_off - -1: wfi - b 1b - - .popsection diff --git a/arch/arm/cpu/armv7/mx7/soc.c b/arch/arm/cpu/armv7/mx7/soc.c deleted file mode 100644 index 8422f24573..0000000000 --- a/arch/arm/cpu/armv7/mx7/soc.c +++ /dev/null @@ -1,468 +0,0 @@ -/* - * Copyright (C) 2015 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> -#include <asm/imx-common/boot_mode.h> -#include <asm/imx-common/dma.h> -#include <asm/imx-common/hab.h> -#include <asm/imx-common/rdc-sema.h> -#include <asm/arch/imx-rdc.h> -#include <asm/arch/crm_regs.h> -#include <dm.h> -#include <imx_thermal.h> - -#if defined(CONFIG_IMX_THERMAL) -static const struct imx_thermal_plat imx7_thermal_plat = { - .regs = (void *)ANATOP_BASE_ADDR, - .fuse_bank = 3, - .fuse_word = 3, -}; - -U_BOOT_DEVICE(imx7_thermal) = { - .name = "imx_thermal", - .platdata = &imx7_thermal_plat, -}; -#endif - -#ifdef CONFIG_IMX_RDC -/* - * In current design, if any peripheral was assigned to both A7 and M4, - * it will receive ipg_stop or ipg_wait when any of the 2 platforms enter - * low power mode. So M4 sleep will cause some peripherals fail to work - * at A7 core side. At default, all resources are in domain 0 - 3. - * - * There are 26 peripherals impacted by this IC issue: - * SIM2(sim2/emvsim2) - * SIM1(sim1/emvsim1) - * UART1/UART2/UART3/UART4/UART5/UART6/UART7 - * SAI1/SAI2/SAI3 - * WDOG1/WDOG2/WDOG3/WDOG4 - * GPT1/GPT2/GPT3/GPT4 - * PWM1/PWM2/PWM3/PWM4 - * ENET1/ENET2 - * Software Workaround: - * Here we setup some resources to domain 0 where M4 codes will move - * the M4 out of this domain. Then M4 is not able to access them any longer. - * This is a workaround for ic issue. So the peripherals are not shared - * by them. This way requires the uboot implemented the RDC driver and - * set the 26 IPs above to domain 0 only. M4 code will assign resource - * to its own domain, if it want to use the resource. - */ -static rdc_peri_cfg_t const resources[] = { - (RDC_PER_SIM1 | RDC_DOMAIN(0)), - (RDC_PER_SIM2 | RDC_DOMAIN(0)), - (RDC_PER_UART1 | RDC_DOMAIN(0)), - (RDC_PER_UART2 | RDC_DOMAIN(0)), - (RDC_PER_UART3 | RDC_DOMAIN(0)), - (RDC_PER_UART4 | RDC_DOMAIN(0)), - (RDC_PER_UART5 | RDC_DOMAIN(0)), - (RDC_PER_UART6 | RDC_DOMAIN(0)), - (RDC_PER_UART7 | RDC_DOMAIN(0)), - (RDC_PER_SAI1 | RDC_DOMAIN(0)), - (RDC_PER_SAI2 | RDC_DOMAIN(0)), - (RDC_PER_SAI3 | RDC_DOMAIN(0)), - (RDC_PER_WDOG1 | RDC_DOMAIN(0)), - (RDC_PER_WDOG2 | RDC_DOMAIN(0)), - (RDC_PER_WDOG3 | RDC_DOMAIN(0)), - (RDC_PER_WDOG4 | RDC_DOMAIN(0)), - (RDC_PER_GPT1 | RDC_DOMAIN(0)), - (RDC_PER_GPT2 | RDC_DOMAIN(0)), - (RDC_PER_GPT3 | RDC_DOMAIN(0)), - (RDC_PER_GPT4 | RDC_DOMAIN(0)), - (RDC_PER_PWM1 | RDC_DOMAIN(0)), - (RDC_PER_PWM2 | RDC_DOMAIN(0)), - (RDC_PER_PWM3 | RDC_DOMAIN(0)), - (RDC_PER_PWM4 | RDC_DOMAIN(0)), - (RDC_PER_ENET1 | RDC_DOMAIN(0)), - (RDC_PER_ENET2 | RDC_DOMAIN(0)), -}; - -static void isolate_resource(void) -{ - imx_rdc_setup_peripherals(resources, ARRAY_SIZE(resources)); -} -#endif - -#if defined(CONFIG_SECURE_BOOT) -struct imx_sec_config_fuse_t const imx_sec_config_fuse = { - .bank = 1, - .word = 3, -}; -#endif - -/* - * OCOTP_TESTER3[9:8] (see Fusemap Description Table offset 0x440) - * defines a 2-bit SPEED_GRADING - */ -#define OCOTP_TESTER3_SPEED_SHIFT 8 -#define OCOTP_TESTER3_SPEED_800MHZ 0 -#define OCOTP_TESTER3_SPEED_500MHZ 1 -#define OCOTP_TESTER3_SPEED_1GHZ 2 -#define OCOTP_TESTER3_SPEED_1P2GHZ 3 - -u32 get_cpu_speed_grade_hz(void) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - uint32_t val; - - val = readl(&fuse->tester3); - val >>= OCOTP_TESTER3_SPEED_SHIFT; - val &= 0x3; - - switch(val) { - case OCOTP_TESTER3_SPEED_800MHZ: - return 800000000; - case OCOTP_TESTER3_SPEED_500MHZ: - return 500000000; - case OCOTP_TESTER3_SPEED_1GHZ: - return 1000000000; - case OCOTP_TESTER3_SPEED_1P2GHZ: - return 1200000000; - } - return 0; -} - -/* - * OCOTP_TESTER3[7:6] (see Fusemap Description Table offset 0x440) - * defines a 2-bit SPEED_GRADING - */ -#define OCOTP_TESTER3_TEMP_SHIFT 6 - -u32 get_cpu_temp_grade(int *minc, int *maxc) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - uint32_t val; - - val = readl(&fuse->tester3); - val >>= OCOTP_TESTER3_TEMP_SHIFT; - val &= 0x3; - - if (minc && maxc) { - if (val == TEMP_AUTOMOTIVE) { - *minc = -40; - *maxc = 125; - } else if (val == TEMP_INDUSTRIAL) { - *minc = -40; - *maxc = 105; - } else if (val == TEMP_EXTCOMMERCIAL) { - *minc = -20; - *maxc = 105; - } else { - *minc = 0; - *maxc = 95; - } - } - return val; -} - -static bool is_mx7d(void) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[1]; - struct fuse_bank1_regs *fuse = - (struct fuse_bank1_regs *)bank->fuse_regs; - int val; - - val = readl(&fuse->tester4); - if (val & 1) - return false; - else - return true; -} - -u32 get_cpu_rev(void) -{ - struct mxc_ccm_anatop_reg *ccm_anatop = (struct mxc_ccm_anatop_reg *) - ANATOP_BASE_ADDR; - u32 reg = readl(&ccm_anatop->digprog); - u32 type = (reg >> 16) & 0xff; - - if (!is_mx7d()) - type = MXC_CPU_MX7S; - - reg &= 0xff; - return (type << 12) | reg; -} - -#ifdef CONFIG_REVISION_TAG -u32 __weak get_board_rev(void) -{ - return get_cpu_rev(); -} -#endif - -/* enable all periherial can be accessed in nosec mode */ -static void init_csu(void) -{ - int i = 0; - for (i = 0; i < CSU_NUM_REGS; i++) - writel(CSU_INIT_SEC_LEVEL0, CSU_IPS_BASE_ADDR + i * 4); -} - -static void imx_enet_mdio_fixup(void) -{ - struct iomuxc_gpr_base_regs *gpr_regs = - (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; - - /* - * The management data input/output (MDIO) requires open-drain, - * i.MX7D TO1.0 ENET MDIO pin has no open drain, but TO1.1 supports - * this feature. So to TO1.1, need to enable open drain by setting - * bits GPR0[8:7]. - */ - - if (soc_rev() >= CHIP_REV_1_1) { - setbits_le32(&gpr_regs->gpr[0], - IOMUXC_GPR_GPR0_ENET_MDIO_OPEN_DRAIN_MASK); - } -} - -int arch_cpu_init(void) -{ - init_aips(); - - init_csu(); - /* Disable PDE bit of WMCR register */ - imx_set_wdog_powerdown(false); - - imx_enet_mdio_fixup(); - -#ifdef CONFIG_APBH_DMA - /* Start APBH DMA */ - mxs_dma_init(); -#endif - - if (IS_ENABLED(CONFIG_IMX_RDC)) - isolate_resource(); - - return 0; -} - -#ifdef CONFIG_ARCH_MISC_INIT -int arch_misc_init(void) -{ -#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG - if (is_mx7d()) - setenv("soc", "imx7d"); - else - setenv("soc", "imx7s"); -#endif - - return 0; -} -#endif - -#ifdef CONFIG_SERIAL_TAG -void get_board_serial(struct tag_serialnr *serialnr) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[0]; - struct fuse_bank0_regs *fuse = - (struct fuse_bank0_regs *)bank->fuse_regs; - - serialnr->low = fuse->tester0; - serialnr->high = fuse->tester1; -} -#endif - -#if defined(CONFIG_FEC_MXC) -void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) -{ - struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; - struct fuse_bank *bank = &ocotp->bank[9]; - struct fuse_bank9_regs *fuse = - (struct fuse_bank9_regs *)bank->fuse_regs; - - if (0 == dev_id) { - u32 value = readl(&fuse->mac_addr1); - mac[0] = (value >> 8); - mac[1] = value; - - value = readl(&fuse->mac_addr0); - mac[2] = value >> 24; - mac[3] = value >> 16; - mac[4] = value >> 8; - mac[5] = value; - } else { - u32 value = readl(&fuse->mac_addr2); - mac[0] = value >> 24; - mac[1] = value >> 16; - mac[2] = value >> 8; - mac[3] = value; - - value = readl(&fuse->mac_addr1); - mac[4] = value >> 24; - mac[5] = value >> 16; - } -} -#endif - -#ifdef CONFIG_IMX_BOOTAUX -int arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) -{ - u32 stack, pc; - struct src *src_reg = (struct src *)SRC_BASE_ADDR; - - if (!boot_private_data) - return 1; - - stack = *(u32 *)boot_private_data; - pc = *(u32 *)(boot_private_data + 4); - - /* Set the stack and pc to M4 bootROM */ - writel(stack, M4_BOOTROM_BASE_ADDR); - writel(pc, M4_BOOTROM_BASE_ADDR + 4); - - /* Enable M4 */ - clrsetbits_le32(&src_reg->m4rcr, SRC_M4RCR_M4C_NON_SCLR_RST_MASK, - SRC_M4RCR_ENABLE_M4_MASK); - - return 0; -} - -int arch_auxiliary_core_check_up(u32 core_id) -{ - uint32_t val; - struct src *src_reg = (struct src *)SRC_BASE_ADDR; - - val = readl(&src_reg->m4rcr); - if (val & 0x00000001) - return 0; /* assert in reset */ - - return 1; -} -#endif - -void set_wdog_reset(struct wdog_regs *wdog) -{ - u32 reg = readw(&wdog->wcr); - /* - * Output WDOG_B signal to reset external pmic or POR_B decided by - * the board desgin. Without external reset, the peripherals/DDR/ - * PMIC are not reset, that may cause system working abnormal. - */ - reg = readw(&wdog->wcr); - reg |= 1 << 3; - /* - * WDZST bit is write-once only bit. Align this bit in kernel, - * otherwise kernel code will have no chance to set this bit. - */ - reg |= 1 << 0; - writew(reg, &wdog->wcr); -} - -/* - * cfg_val will be used for - * Boot_cfg4[7:0]:Boot_cfg3[7:0]:Boot_cfg2[7:0]:Boot_cfg1[7:0] - * After reset, if GPR10[28] is 1, ROM will copy GPR9[25:0] - * to SBMR1, which will determine the boot device. - */ -const struct boot_mode soc_boot_modes[] = { - {"ecspi1:0", MAKE_CFGVAL(0x00, 0x60, 0x00, 0x00)}, - {"ecspi1:1", MAKE_CFGVAL(0x40, 0x62, 0x00, 0x00)}, - {"ecspi1:2", MAKE_CFGVAL(0x80, 0x64, 0x00, 0x00)}, - {"ecspi1:3", MAKE_CFGVAL(0xc0, 0x66, 0x00, 0x00)}, - - {"weim", MAKE_CFGVAL(0x00, 0x50, 0x00, 0x00)}, - {"qspi1", MAKE_CFGVAL(0x10, 0x40, 0x00, 0x00)}, - /* 4 bit bus width */ - {"usdhc1", MAKE_CFGVAL(0x10, 0x10, 0x00, 0x00)}, - {"usdhc2", MAKE_CFGVAL(0x10, 0x14, 0x00, 0x00)}, - {"usdhc3", MAKE_CFGVAL(0x10, 0x18, 0x00, 0x00)}, - {"mmc1", MAKE_CFGVAL(0x10, 0x20, 0x00, 0x00)}, - {"mmc2", MAKE_CFGVAL(0x10, 0x24, 0x00, 0x00)}, - {"mmc3", MAKE_CFGVAL(0x10, 0x28, 0x00, 0x00)}, - {NULL, 0}, -}; - -enum boot_device get_boot_device(void) -{ - struct bootrom_sw_info **p = - (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; - - enum boot_device boot_dev = SD1_BOOT; - u8 boot_type = (*p)->boot_dev_type; - u8 boot_instance = (*p)->boot_dev_instance; - - switch (boot_type) { - case BOOT_TYPE_SD: - boot_dev = boot_instance + SD1_BOOT; - break; - case BOOT_TYPE_MMC: - boot_dev = boot_instance + MMC1_BOOT; - break; - case BOOT_TYPE_NAND: - boot_dev = NAND_BOOT; - break; - case BOOT_TYPE_QSPI: - boot_dev = QSPI_BOOT; - break; - case BOOT_TYPE_WEIM: - boot_dev = WEIM_NOR_BOOT; - break; - case BOOT_TYPE_SPINOR: - boot_dev = SPI_NOR_BOOT; - break; - default: - break; - } - - return boot_dev; -} - -#ifdef CONFIG_ENV_IS_IN_MMC -__weak int board_mmc_get_env_dev(int devno) -{ - return CONFIG_SYS_MMC_ENV_DEV; -} - -int mmc_get_env_dev(void) -{ - struct bootrom_sw_info **p = - (struct bootrom_sw_info **)ROM_SW_INFO_ADDR; - int devno = (*p)->boot_dev_instance; - u8 boot_type = (*p)->boot_dev_type; - - /* If not boot from sd/mmc, use default value */ - if ((boot_type != BOOT_TYPE_SD) && (boot_type != BOOT_TYPE_MMC)) - return CONFIG_SYS_MMC_ENV_DEV; - - return board_mmc_get_env_dev(devno); -} -#endif - -void s_init(void) -{ -#if !defined CONFIG_SPL_BUILD - /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ - asm volatile( - "mrc p15, 0, r0, c1, c0, 1\n" - "orr r0, r0, #1 << 6\n" - "mcr p15, 0, r0, c1, c0, 1\n"); -#endif - /* clock configuration. */ - clock_init(); - - return; -} - -void reset_misc(void) -{ -#ifdef CONFIG_VIDEO_MXS - lcdif_power_down(); -#endif -} - diff --git a/arch/arm/cpu/armv7/mx7ulp/Kconfig b/arch/arm/cpu/armv7/mx7ulp/Kconfig deleted file mode 100644 index 1bdc85a9a0..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/Kconfig +++ /dev/null @@ -1,17 +0,0 @@ -if ARCH_MX7ULP - -config SYS_SOC - default "mx7ulp" - -choice - prompt "MX7ULP board select" - optional - -config TARGET_MX7ULP_EVK - bool "Support mx7ulp EVK board" - -endchoice - -source "board/freescale/mx7ulp_evk/Kconfig" - -endif diff --git a/arch/arm/cpu/armv7/mx7ulp/Makefile b/arch/arm/cpu/armv7/mx7ulp/Makefile deleted file mode 100644 index 0248ea85a3..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2016 Freescale Semiconductor, Inc. -# -# SPDX-License-Identifier: GPL-2.0+ -# -# - -obj-y := soc.o clock.o iomux.o pcc.o scg.o diff --git a/arch/arm/cpu/armv7/mx7ulp/clock.c b/arch/arm/cpu/armv7/mx7ulp/clock.c deleted file mode 100644 index 77b282addd..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/clock.c +++ /dev/null @@ -1,365 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <errno.h> -#include <asm/arch/clock.h> -#include <asm/arch/sys_proto.h> - -DECLARE_GLOBAL_DATA_PTR; - -int get_clocks(void) -{ -#ifdef CONFIG_FSL_ESDHC -#if CONFIG_SYS_FSL_ESDHC_ADDR == USDHC0_RBASE - gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK); -#elif CONFIG_SYS_FSL_ESDHC_ADDR == USDHC1_RBASE - gd->arch.sdhc_clk = mxc_get_clock(MXC_ESDHC2_CLK); -#endif -#endif - return 0; -} - -static u32 get_fast_plat_clk(void) -{ - return scg_clk_get_rate(SCG_NIC0_CLK); -} - -static u32 get_slow_plat_clk(void) -{ - return scg_clk_get_rate(SCG_NIC1_CLK); -} - -static u32 get_ipg_clk(void) -{ - return scg_clk_get_rate(SCG_NIC1_BUS_CLK); -} - -u32 get_lpuart_clk(void) -{ - int index = 0; - - const u32 lpuart_array[] = { - LPUART0_RBASE, - LPUART1_RBASE, - LPUART2_RBASE, - LPUART3_RBASE, - LPUART4_RBASE, - LPUART5_RBASE, - LPUART6_RBASE, - LPUART7_RBASE, - }; - - const enum pcc_clk lpuart_pcc_clks[] = { - PER_CLK_LPUART4, - PER_CLK_LPUART5, - PER_CLK_LPUART6, - PER_CLK_LPUART7, - }; - - for (index = 0; index < 8; index++) { - if (lpuart_array[index] == LPUART_BASE) - break; - } - - if (index < 4 || index > 7) - return 0; - - return pcc_clock_get_rate(lpuart_pcc_clks[index - 4]); -} - -#ifdef CONFIG_SYS_LPI2C_IMX -int enable_i2c_clk(unsigned char enable, unsigned i2c_num) -{ - /* Set parent to FIRC DIV2 clock */ - const enum pcc_clk lpi2c_pcc_clks[] = { - PER_CLK_LPI2C4, - PER_CLK_LPI2C5, - PER_CLK_LPI2C6, - PER_CLK_LPI2C7, - }; - - if (i2c_num < 4 || i2c_num > 7) - return -EINVAL; - - if (enable) { - pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4], false); - pcc_clock_sel(lpi2c_pcc_clks[i2c_num - 4], SCG_FIRC_DIV2_CLK); - pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4], true); - } else { - pcc_clock_enable(lpi2c_pcc_clks[i2c_num - 4], false); - } - return 0; -} - -u32 imx_get_i2cclk(unsigned i2c_num) -{ - const enum pcc_clk lpi2c_pcc_clks[] = { - PER_CLK_LPI2C4, - PER_CLK_LPI2C5, - PER_CLK_LPI2C6, - PER_CLK_LPI2C7, - }; - - if (i2c_num < 4 || i2c_num > 7) - return 0; - - return pcc_clock_get_rate(lpi2c_pcc_clks[i2c_num - 4]); -} -#endif - -unsigned int mxc_get_clock(enum mxc_clock clk) -{ - switch (clk) { - case MXC_ARM_CLK: - return scg_clk_get_rate(SCG_CORE_CLK); - case MXC_AXI_CLK: - return get_fast_plat_clk(); - case MXC_AHB_CLK: - return get_slow_plat_clk(); - case MXC_IPG_CLK: - return get_ipg_clk(); - case MXC_I2C_CLK: - return pcc_clock_get_rate(PER_CLK_LPI2C4); - case MXC_UART_CLK: - return get_lpuart_clk(); - case MXC_ESDHC_CLK: - return pcc_clock_get_rate(PER_CLK_USDHC0); - case MXC_ESDHC2_CLK: - return pcc_clock_get_rate(PER_CLK_USDHC1); - case MXC_DDR_CLK: - return scg_clk_get_rate(SCG_DDR_CLK); - default: - printf("Unsupported mxc_clock %d\n", clk); - break; - } - - return 0; -} - -void init_clk_usdhc(u32 index) -{ - switch (index) { - case 0: - /*Disable the clock before configure it */ - pcc_clock_enable(PER_CLK_USDHC0, false); - - /* 158MHz / 1 = 158MHz */ - pcc_clock_sel(PER_CLK_USDHC0, SCG_NIC1_CLK); - pcc_clock_div_config(PER_CLK_USDHC0, false, 1); - pcc_clock_enable(PER_CLK_USDHC0, true); - break; - case 1: - /*Disable the clock before configure it */ - pcc_clock_enable(PER_CLK_USDHC1, false); - - /* 158MHz / 1 = 158MHz */ - pcc_clock_sel(PER_CLK_USDHC1, SCG_NIC1_CLK); - pcc_clock_div_config(PER_CLK_USDHC1, false, 1); - pcc_clock_enable(PER_CLK_USDHC1, true); - break; - default: - printf("Invalid index for USDHC %d\n", index); - break; - } -} - -#ifdef CONFIG_MXC_OCOTP - -#define OCOTP_CTRL_PCC1_SLOT (38) -#define OCOTP_CTRL_HIGH4K_PCC1_SLOT (39) - -void enable_ocotp_clk(unsigned char enable) -{ - u32 val; - - /* - * Seems the OCOTP CLOCKs have been enabled at default, - * check its inuse flag - */ - - val = readl(PCC1_RBASE + 4 * OCOTP_CTRL_PCC1_SLOT); - if (!(val & PCC_INUSE_MASK)) - writel(PCC_CGC_MASK, (PCC1_RBASE + 4 * OCOTP_CTRL_PCC1_SLOT)); - - val = readl(PCC1_RBASE + 4 * OCOTP_CTRL_HIGH4K_PCC1_SLOT); - if (!(val & PCC_INUSE_MASK)) - writel(PCC_CGC_MASK, - (PCC1_RBASE + 4 * OCOTP_CTRL_HIGH4K_PCC1_SLOT)); -} -#endif - -void enable_usboh3_clk(unsigned char enable) -{ - if (enable) { - pcc_clock_enable(PER_CLK_USB0, false); - pcc_clock_sel(PER_CLK_USB0, SCG_NIC1_BUS_CLK); - pcc_clock_enable(PER_CLK_USB0, true); - -#ifdef CONFIG_USB_MAX_CONTROLLER_COUNT - if (CONFIG_USB_MAX_CONTROLLER_COUNT > 1) { - pcc_clock_enable(PER_CLK_USB1, false); - pcc_clock_sel(PER_CLK_USB1, SCG_NIC1_BUS_CLK); - pcc_clock_enable(PER_CLK_USB1, true); - } -#endif - - pcc_clock_enable(PER_CLK_USB_PHY, true); - pcc_clock_enable(PER_CLK_USB_PL301, true); - } else { - pcc_clock_enable(PER_CLK_USB0, false); - pcc_clock_enable(PER_CLK_USB1, false); - pcc_clock_enable(PER_CLK_USB_PHY, false); - pcc_clock_enable(PER_CLK_USB_PL301, false); - } -} - -static void lpuart_set_clk(uint32_t index, enum scg_clk clk) -{ - const enum pcc_clk lpuart_pcc_clks[] = { - PER_CLK_LPUART4, - PER_CLK_LPUART5, - PER_CLK_LPUART6, - PER_CLK_LPUART7, - }; - - if (index < 4 || index > 7) - return; - -#ifndef CONFIG_CLK_DEBUG - pcc_clock_enable(lpuart_pcc_clks[index - 4], false); -#endif - pcc_clock_sel(lpuart_pcc_clks[index - 4], clk); - pcc_clock_enable(lpuart_pcc_clks[index - 4], true); -} - -static void init_clk_lpuart(void) -{ - u32 index = 0, i; - - const u32 lpuart_array[] = { - LPUART0_RBASE, - LPUART1_RBASE, - LPUART2_RBASE, - LPUART3_RBASE, - LPUART4_RBASE, - LPUART5_RBASE, - LPUART6_RBASE, - LPUART7_RBASE, - }; - - for (i = 0; i < 8; i++) { - if (lpuart_array[i] == LPUART_BASE) { - index = i; - break; - } - } - - lpuart_set_clk(index, SCG_SOSC_DIV2_CLK); -} - -static void init_clk_rgpio2p(void) -{ - /*Enable RGPIO2P1 clock */ - pcc_clock_enable(PER_CLK_RGPIO2P1, true); - - /* - * Hard code to enable RGPIO2P0 clock since it is not - * in clock frame for A7 domain - */ - writel(PCC_CGC_MASK, (PCC0_RBASE + 0x3C)); -} - -/* Configure PLL/PFD freq */ -void clock_init(void) -{ - /* - * ROM has enabled clocks: - * A4 side: SIRC 16Mhz (DIV1-3 off), FIRC 48Mhz (DIV1-2 on), - * Non-LP-boot: SOSC, SPLL PFD0 (scs selected) - * A7 side: SPLL PFD0 (scs selected, 413Mhz), - * APLL PFD0 (352Mhz), DDRCLK, all NIC clocks - * A7 Plat0 (NIC0) = 176Mhz, Plat1 (NIC1) = 176Mhz, - * IP BUS (NIC1_BUS) = 58.6Mhz - * - * In u-boot: - * 1. Enable PFD1-3 of APLL for A7 side. Enable FIRC and DIVs. - * 2. Enable USB PLL - * 3. Init the clocks of peripherals used in u-boot bu - * without set rate interface.The clocks for these - * peripherals are enabled in this intialization. - * 4.Other peripherals with set clock rate interface - * does not be set in this function. - */ - - scg_a7_firc_init(); - - scg_a7_soscdiv_init(); - - /* APLL PFD1 = 270Mhz, PFD2=480Mhz, PFD3=800Mhz */ - scg_enable_pll_pfd(SCG_APLL_PFD1_CLK, 35); - scg_enable_pll_pfd(SCG_APLL_PFD2_CLK, 20); - scg_enable_pll_pfd(SCG_APLL_PFD3_CLK, 12); - - init_clk_lpuart(); - - init_clk_rgpio2p(); - - enable_usboh3_clk(1); -} - -#ifdef CONFIG_SECURE_BOOT -void hab_caam_clock_enable(unsigned char enable) -{ - if (enable) - pcc_clock_enable(PER_CLK_CAAM, true); - else - pcc_clock_enable(PER_CLK_CAAM, false); -} -#endif - -/* - * Dump some core clockes. - */ -int do_mx7_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) -{ - u32 addr = 0; - u32 freq; - freq = decode_pll(PLL_A7_SPLL); - printf("PLL_A7_SPLL %8d MHz\n", freq / 1000000); - - freq = decode_pll(PLL_A7_APLL); - printf("PLL_A7_APLL %8d MHz\n", freq / 1000000); - - freq = decode_pll(PLL_USB); - printf("PLL_USB %8d MHz\n", freq / 1000000); - - printf("\n"); - - printf("CORE %8d kHz\n", scg_clk_get_rate(SCG_CORE_CLK) / 1000); - printf("IPG %8d kHz\n", mxc_get_clock(MXC_IPG_CLK) / 1000); - printf("UART %8d kHz\n", mxc_get_clock(MXC_UART_CLK) / 1000); - printf("AHB %8d kHz\n", mxc_get_clock(MXC_AHB_CLK) / 1000); - printf("AXI %8d kHz\n", mxc_get_clock(MXC_AXI_CLK) / 1000); - printf("DDR %8d kHz\n", mxc_get_clock(MXC_DDR_CLK) / 1000); - printf("USDHC1 %8d kHz\n", mxc_get_clock(MXC_ESDHC_CLK) / 1000); - printf("USDHC2 %8d kHz\n", mxc_get_clock(MXC_ESDHC2_CLK) / 1000); - printf("I2C4 %8d kHz\n", mxc_get_clock(MXC_I2C_CLK) / 1000); - - addr = (u32) clock_init; - printf("[%s] addr = 0x%08X\r\n", __func__, addr); - scg_a7_info(); - - return 0; -} - -U_BOOT_CMD( - clocks, CONFIG_SYS_MAXARGS, 1, do_mx7_showclocks, - "display clocks", - "" -); diff --git a/arch/arm/cpu/armv7/mx7ulp/iomux.c b/arch/arm/cpu/armv7/mx7ulp/iomux.c deleted file mode 100644 index 1eba24e506..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/iomux.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <common.h> -#include <asm/io.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/iomux.h> - -static void *base = (void *)IOMUXC_BASE_ADDR; - -/* - * iomuxc0 base address. In imx7ulp-pins.h, - * the offsets of pins in iomuxc0 are from 0xD000, - * so we set the base address to (0x4103D000 - 0xD000 = 0x41030000) - */ -static void *base_mports = (void *)(AIPS0_BASE + 0x30000); - -/* - * configures a single pad in the iomuxer - */ -void mx7ulp_iomux_setup_pad(iomux_cfg_t pad) -{ - u32 mux_ctrl_ofs = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT; - u32 mux_mode = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT; - u32 sel_input_ofs = - (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT; - u32 sel_input = - (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT; - u32 pad_ctrl_ofs = mux_ctrl_ofs; - u32 pad_ctrl = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT; - - debug("[PAD CFG] = 0x%16llX \r\n\tmux_ctl = 0x%X(0x%X) sel_input = 0x%X(0x%X) pad_ctrl = 0x%X(0x%X)\r\n", - pad, mux_ctrl_ofs, mux_mode, sel_input_ofs, sel_input, - pad_ctrl_ofs, pad_ctrl); - - if (mux_mode & IOMUX_CONFIG_MPORTS) { - mux_mode &= ~IOMUX_CONFIG_MPORTS; - base = base_mports; - } else { - base = (void *)IOMUXC_BASE_ADDR; - } - - __raw_writel(((mux_mode << IOMUXC_PCR_MUX_ALT_SHIFT) & - IOMUXC_PCR_MUX_ALT_MASK), base + mux_ctrl_ofs); - - if (sel_input_ofs) - __raw_writel((sel_input << IOMUXC_PSMI_IMUX_ALT_SHIFT), - base + sel_input_ofs); - - if (!(pad_ctrl & NO_PAD_CTRL)) - __raw_writel(((mux_mode << IOMUXC_PCR_MUX_ALT_SHIFT) & - IOMUXC_PCR_MUX_ALT_MASK) | - (pad_ctrl & (~IOMUXC_PCR_MUX_ALT_MASK)), - base + pad_ctrl_ofs); -} - -/* configures a list of pads within declared with IOMUX_PADS macro */ -void mx7ulp_iomux_setup_multiple_pads(iomux_cfg_t const *pad_list, - unsigned count) -{ - iomux_cfg_t const *p = pad_list; - int i; - - for (i = 0; i < count; i++) { - mx7ulp_iomux_setup_pad(*p); - p++; - } -} diff --git a/arch/arm/cpu/armv7/mx7ulp/pcc.c b/arch/arm/cpu/armv7/mx7ulp/pcc.c deleted file mode 100644 index edd84e51b9..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/pcc.c +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/pcc.h> -#include <asm/arch/sys_proto.h> - -DECLARE_GLOBAL_DATA_PTR; - -#define PCC_CLKSRC_TYPES 2 -#define PCC_CLKSRC_NUM 7 - -static enum scg_clk pcc_clksrc[PCC_CLKSRC_TYPES][PCC_CLKSRC_NUM] = { - { SCG_NIC1_BUS_CLK, - SCG_NIC1_CLK, - SCG_DDR_CLK, - SCG_APLL_PFD2_CLK, - SCG_APLL_PFD1_CLK, - SCG_APLL_PFD0_CLK, - USB_PLL_OUT, - }, - { SCG_SOSC_DIV2_CLK, /* SOSC BUS clock */ - MIPI_PLL_OUT, - SCG_FIRC_DIV2_CLK, /* FIRC BUS clock */ - SCG_ROSC_CLK, - SCG_NIC1_BUS_CLK, - SCG_NIC1_CLK, - SCG_APLL_PFD3_CLK, - }, -}; - -static struct pcc_entry pcc_arrays[] = { - {PCC2_RBASE, DMA1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, RGPIO1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, FLEXBUS0_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, SEMA42_1_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, DMA1_CH_MUX0_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, SNVS_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, CAAM_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, LPTPM4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPTPM5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPIT1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPSPI2_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPSPI3_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPI2C4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPI2C5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPUART4_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, LPUART5_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, FLEXIO1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC2_RBASE, USBOTG0_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV}, - {PCC2_RBASE, USBOTG1_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV}, - {PCC2_RBASE, USBPHY_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, USB_PL301_PCC2_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC2_RBASE, USDHC0_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV}, - {PCC2_RBASE, USDHC1_PCC2_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV}, - {PCC2_RBASE, WDG1_PCC2_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV}, - {PCC2_RBASE, WDG2_PCC2_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV}, - - {PCC3_RBASE, LPTPM6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, LPTPM7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, LPI2C6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, LPI2C7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, LPUART6_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, LPUART7_PCC3_SLOT, CLKSRC_PER_BUS, PCC_NO_DIV}, - {PCC3_RBASE, VIU0_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, DSI0_PCC3_SLOT, CLKSRC_PER_BUS, PCC_HAS_DIV}, - {PCC3_RBASE, LCDIF0_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_HAS_DIV}, - {PCC3_RBASE, MMDC0_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, PORTC_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, PORTD_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, PORTE_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, PORTF_PCC3_SLOT, CLKSRC_NO_PCS, PCC_NO_DIV}, - {PCC3_RBASE, GPU3D_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_NO_DIV}, - {PCC3_RBASE, GPU2D_PCC3_SLOT, CLKSRC_PER_PLAT, PCC_NO_DIV}, -}; - -int pcc_clock_enable(enum pcc_clk clk, bool enable) -{ - u32 reg, val; - - if (clk >= ARRAY_SIZE(pcc_arrays)) - return -EINVAL; - - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - - val = readl(reg); - - clk_debug("pcc_clock_enable: clk %d, reg 0x%x, val 0x%x, enable %d\n", - clk, reg, val, enable); - - if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK)) - return -EPERM; - - if (enable) - val |= PCC_CGC_MASK; - else - val &= ~PCC_CGC_MASK; - - writel(val, reg); - - clk_debug("pcc_clock_enable: val 0x%x\n", val); - - return 0; -} - -/* The clock source select needs clock is disabled */ -int pcc_clock_sel(enum pcc_clk clk, enum scg_clk src) -{ - u32 reg, val, i, clksrc_type; - - if (clk >= ARRAY_SIZE(pcc_arrays)) - return -EINVAL; - - clksrc_type = pcc_arrays[clk].clksrc; - if (clksrc_type >= CLKSRC_NO_PCS) { - printf("No PCS field for the PCC %d, clksrc type %d\n", - clk, clksrc_type); - return -EPERM; - } - - for (i = 0; i < PCC_CLKSRC_NUM; i++) { - if (pcc_clksrc[clksrc_type][i] == src) { - /* Find the clock src, then set it to PCS */ - break; - } - } - - if (i == PCC_CLKSRC_NUM) { - printf("Not find the parent scg_clk in PCS of PCC %d, invalid scg_clk %d\n", clk, src); - return -EINVAL; - } - - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - - val = readl(reg); - - clk_debug("pcc_clock_sel: clk %d, reg 0x%x, val 0x%x, clksrc_type %d\n", - clk, reg, val, clksrc_type); - - if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK) || - (val & PCC_CGC_MASK)) { - printf("Not permit to select clock source val = 0x%x\n", val); - return -EPERM; - } - - val &= ~PCC_PCS_MASK; - val |= ((i + 1) << PCC_PCS_OFFSET); - - writel(val, reg); - - clk_debug("pcc_clock_sel: val 0x%x\n", val); - - return 0; -} - -int pcc_clock_div_config(enum pcc_clk clk, bool frac, u8 div) -{ - u32 reg, val; - - if (clk >= ARRAY_SIZE(pcc_arrays) || div > 8 || - (div == 1 && frac != 0)) - return -EINVAL; - - if (pcc_arrays[clk].div >= PCC_NO_DIV) { - printf("No DIV/FRAC field for the PCC %d\n", clk); - return -EPERM; - } - - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - - val = readl(reg); - - if (!(val & PCC_PR_MASK) || (val & PCC_INUSE_MASK) || - (val & PCC_CGC_MASK)) { - printf("Not permit to set div/frac val = 0x%x\n", val); - return -EPERM; - } - - if (frac) - val |= PCC_FRAC_MASK; - else - val &= ~PCC_FRAC_MASK; - - val &= ~PCC_PCD_MASK; - val |= (div - 1) & PCC_PCD_MASK; - - writel(val, reg); - - return 0; -} - -bool pcc_clock_is_enable(enum pcc_clk clk) -{ - u32 reg, val; - - if (clk >= ARRAY_SIZE(pcc_arrays)) - return -EINVAL; - - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - val = readl(reg); - - if ((val & PCC_INUSE_MASK) || (val & PCC_CGC_MASK)) - return true; - - return false; -} - -int pcc_clock_get_clksrc(enum pcc_clk clk, enum scg_clk *src) -{ - u32 reg, val, clksrc_type; - - if (clk >= ARRAY_SIZE(pcc_arrays)) - return -EINVAL; - - clksrc_type = pcc_arrays[clk].clksrc; - if (clksrc_type >= CLKSRC_NO_PCS) { - printf("No PCS field for the PCC %d, clksrc type %d\n", - clk, clksrc_type); - return -EPERM; - } - - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - - val = readl(reg); - - clk_debug("pcc_clock_get_clksrc: clk %d, reg 0x%x, val 0x%x, type %d\n", - clk, reg, val, clksrc_type); - - if (!(val & PCC_PR_MASK)) { - printf("This pcc slot is not present = 0x%x\n", val); - return -EPERM; - } - - val &= PCC_PCS_MASK; - val = (val >> PCC_PCS_OFFSET); - - if (!val) { - printf("Clock source is off\n"); - return -EIO; - } - - *src = pcc_clksrc[clksrc_type][val - 1]; - - clk_debug("pcc_clock_get_clksrc: parent scg clk %d\n", *src); - - return 0; -} - -u32 pcc_clock_get_rate(enum pcc_clk clk) -{ - u32 reg, val, rate, frac, div; - enum scg_clk parent; - int ret; - - ret = pcc_clock_get_clksrc(clk, &parent); - if (ret) - return 0; - - rate = scg_clk_get_rate(parent); - - clk_debug("pcc_clock_get_rate: parent rate %u\n", rate); - - if (pcc_arrays[clk].div == PCC_HAS_DIV) { - reg = pcc_arrays[clk].pcc_base + pcc_arrays[clk].pcc_slot * 4; - val = readl(reg); - - frac = (val & PCC_FRAC_MASK) >> PCC_FRAC_OFFSET; - div = (val & PCC_PCD_MASK) >> PCC_PCD_OFFSET; - - /* - * Theoretically don't have overflow in the calc, - * the rate won't exceed 2G - */ - rate = rate * (frac + 1) / (div + 1); - } - - clk_debug("pcc_clock_get_rate: rate %u\n", rate); - return rate; -} diff --git a/arch/arm/cpu/armv7/mx7ulp/scg.c b/arch/arm/cpu/armv7/mx7ulp/scg.c deleted file mode 100644 index c117af0a0e..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/scg.c +++ /dev/null @@ -1,1090 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <div64.h> -#include <asm/io.h> -#include <errno.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/pcc.h> -#include <asm/arch/sys_proto.h> - -DECLARE_GLOBAL_DATA_PTR; - -scg_p scg1_regs = (scg_p)SCG1_RBASE; - -static u32 scg_src_get_rate(enum scg_clk clksrc) -{ - u32 reg; - - switch (clksrc) { - case SCG_SOSC_CLK: - reg = readl(&scg1_regs->sosccsr); - if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK)) - return 0; - - return 24000000; - case SCG_FIRC_CLK: - reg = readl(&scg1_regs->firccsr); - if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK)) - return 0; - - return 48000000; - case SCG_SIRC_CLK: - reg = readl(&scg1_regs->sirccsr); - if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK)) - return 0; - - return 16000000; - case SCG_ROSC_CLK: - reg = readl(&scg1_regs->rtccsr); - if (!(reg & SCG_ROSC_CSR_ROSCVLD_MASK)) - return 0; - - return 32768; - default: - break; - } - - return 0; -} - -static u32 scg_sircdiv_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask; - - switch (clk) { - case SCG_SIRC_DIV1_CLK: - mask = SCG_SIRCDIV_DIV1_MASK; - shift = SCG_SIRCDIV_DIV1_SHIFT; - break; - case SCG_SIRC_DIV2_CLK: - mask = SCG_SIRCDIV_DIV2_MASK; - shift = SCG_SIRCDIV_DIV2_SHIFT; - break; - case SCG_SIRC_DIV3_CLK: - mask = SCG_SIRCDIV_DIV3_MASK; - shift = SCG_SIRCDIV_DIV3_SHIFT; - break; - default: - return 0; - } - - reg = readl(&scg1_regs->sirccsr); - if (!(reg & SCG_SIRC_CSR_SIRCVLD_MASK)) - return 0; - - reg = readl(&scg1_regs->sircdiv); - val = (reg & mask) >> shift; - - if (!val) /*clock disabled*/ - return 0; - - rate = scg_src_get_rate(SCG_SIRC_CLK); - rate = rate / (1 << (val - 1)); - - return rate; -} - -static u32 scg_fircdiv_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask; - - switch (clk) { - case SCG_FIRC_DIV1_CLK: - mask = SCG_FIRCDIV_DIV1_MASK; - shift = SCG_FIRCDIV_DIV1_SHIFT; - break; - case SCG_FIRC_DIV2_CLK: - mask = SCG_FIRCDIV_DIV2_MASK; - shift = SCG_FIRCDIV_DIV2_SHIFT; - break; - case SCG_FIRC_DIV3_CLK: - mask = SCG_FIRCDIV_DIV3_MASK; - shift = SCG_FIRCDIV_DIV3_SHIFT; - break; - default: - return 0; - } - - reg = readl(&scg1_regs->firccsr); - if (!(reg & SCG_FIRC_CSR_FIRCVLD_MASK)) - return 0; - - reg = readl(&scg1_regs->fircdiv); - val = (reg & mask) >> shift; - - if (!val) /*clock disabled*/ - return 0; - - rate = scg_src_get_rate(SCG_FIRC_CLK); - rate = rate / (1 << (val - 1)); - - return rate; -} - -static u32 scg_soscdiv_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask; - - switch (clk) { - case SCG_SOSC_DIV1_CLK: - mask = SCG_SOSCDIV_DIV1_MASK; - shift = SCG_SOSCDIV_DIV1_SHIFT; - break; - case SCG_SOSC_DIV2_CLK: - mask = SCG_SOSCDIV_DIV2_MASK; - shift = SCG_SOSCDIV_DIV2_SHIFT; - break; - case SCG_SOSC_DIV3_CLK: - mask = SCG_SOSCDIV_DIV3_MASK; - shift = SCG_SOSCDIV_DIV3_SHIFT; - break; - default: - return 0; - } - - reg = readl(&scg1_regs->sosccsr); - if (!(reg & SCG_SOSC_CSR_SOSCVLD_MASK)) - return 0; - - reg = readl(&scg1_regs->soscdiv); - val = (reg & mask) >> shift; - - if (!val) /*clock disabled*/ - return 0; - - rate = scg_src_get_rate(SCG_SOSC_CLK); - rate = rate / (1 << (val - 1)); - - return rate; -} - -static u32 scg_apll_pfd_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask, gate, valid; - - switch (clk) { - case SCG_APLL_PFD0_CLK: - gate = SCG_PLL_PFD0_GATE_MASK; - valid = SCG_PLL_PFD0_VALID_MASK; - mask = SCG_PLL_PFD0_FRAC_MASK; - shift = SCG_PLL_PFD0_FRAC_SHIFT; - break; - case SCG_APLL_PFD1_CLK: - gate = SCG_PLL_PFD1_GATE_MASK; - valid = SCG_PLL_PFD1_VALID_MASK; - mask = SCG_PLL_PFD1_FRAC_MASK; - shift = SCG_PLL_PFD1_FRAC_SHIFT; - break; - case SCG_APLL_PFD2_CLK: - gate = SCG_PLL_PFD2_GATE_MASK; - valid = SCG_PLL_PFD2_VALID_MASK; - mask = SCG_PLL_PFD2_FRAC_MASK; - shift = SCG_PLL_PFD2_FRAC_SHIFT; - break; - case SCG_APLL_PFD3_CLK: - gate = SCG_PLL_PFD3_GATE_MASK; - valid = SCG_PLL_PFD3_VALID_MASK; - mask = SCG_PLL_PFD3_FRAC_MASK; - shift = SCG_PLL_PFD3_FRAC_SHIFT; - break; - default: - return 0; - } - - reg = readl(&scg1_regs->apllpfd); - if (reg & gate || !(reg & valid)) - return 0; - - clk_debug("scg_apll_pfd_get_rate reg 0x%x\n", reg); - - val = (reg & mask) >> shift; - rate = decode_pll(PLL_A7_APLL); - - rate = rate / val * 18; - - clk_debug("scg_apll_pfd_get_rate rate %u\n", rate); - - return rate; -} - -static u32 scg_spll_pfd_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask, gate, valid; - - switch (clk) { - case SCG_SPLL_PFD0_CLK: - gate = SCG_PLL_PFD0_GATE_MASK; - valid = SCG_PLL_PFD0_VALID_MASK; - mask = SCG_PLL_PFD0_FRAC_MASK; - shift = SCG_PLL_PFD0_FRAC_SHIFT; - break; - case SCG_SPLL_PFD1_CLK: - gate = SCG_PLL_PFD1_GATE_MASK; - valid = SCG_PLL_PFD1_VALID_MASK; - mask = SCG_PLL_PFD1_FRAC_MASK; - shift = SCG_PLL_PFD1_FRAC_SHIFT; - break; - case SCG_SPLL_PFD2_CLK: - gate = SCG_PLL_PFD2_GATE_MASK; - valid = SCG_PLL_PFD2_VALID_MASK; - mask = SCG_PLL_PFD2_FRAC_MASK; - shift = SCG_PLL_PFD2_FRAC_SHIFT; - break; - case SCG_SPLL_PFD3_CLK: - gate = SCG_PLL_PFD3_GATE_MASK; - valid = SCG_PLL_PFD3_VALID_MASK; - mask = SCG_PLL_PFD3_FRAC_MASK; - shift = SCG_PLL_PFD3_FRAC_SHIFT; - break; - default: - return 0; - } - - reg = readl(&scg1_regs->spllpfd); - if (reg & gate || !(reg & valid)) - return 0; - - clk_debug("scg_spll_pfd_get_rate reg 0x%x\n", reg); - - val = (reg & mask) >> shift; - rate = decode_pll(PLL_A7_SPLL); - - rate = rate / val * 18; - - clk_debug("scg_spll_pfd_get_rate rate %u\n", rate); - - return rate; -} - -static u32 scg_apll_get_rate(void) -{ - u32 reg, val, rate; - - reg = readl(&scg1_regs->apllcfg); - val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT; - - if (!val) { - /* APLL clock after two dividers */ - rate = decode_pll(PLL_A7_APLL); - - val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >> - SCG_PLL_CFG_POSTDIV1_SHIFT; - rate = rate / (val + 1); - - val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >> - SCG_PLL_CFG_POSTDIV2_SHIFT; - rate = rate / (val + 1); - } else { - /* APLL PFD clock */ - val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >> - SCG_PLL_CFG_PFDSEL_SHIFT; - rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val); - } - - return rate; -} - -static u32 scg_spll_get_rate(void) -{ - u32 reg, val, rate; - - reg = readl(&scg1_regs->spllcfg); - val = (reg & SCG_PLL_CFG_PLLSEL_MASK) >> SCG_PLL_CFG_PLLSEL_SHIFT; - - clk_debug("scg_spll_get_rate reg 0x%x\n", reg); - - if (!val) { - /* APLL clock after two dividers */ - rate = decode_pll(PLL_A7_SPLL); - - val = (reg & SCG_PLL_CFG_POSTDIV1_MASK) >> - SCG_PLL_CFG_POSTDIV1_SHIFT; - rate = rate / (val + 1); - - val = (reg & SCG_PLL_CFG_POSTDIV2_MASK) >> - SCG_PLL_CFG_POSTDIV2_SHIFT; - rate = rate / (val + 1); - - clk_debug("scg_spll_get_rate SPLL %u\n", rate); - - } else { - /* APLL PFD clock */ - val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >> - SCG_PLL_CFG_PFDSEL_SHIFT; - rate = scg_spll_pfd_get_rate(SCG_SPLL_PFD0_CLK + val); - - clk_debug("scg_spll_get_rate PFD %u\n", rate); - } - - return rate; -} - -static u32 scg_ddr_get_rate(void) -{ - u32 reg, val, rate, div; - - reg = readl(&scg1_regs->ddrccr); - val = (reg & SCG_DDRCCR_DDRCS_MASK) >> SCG_DDRCCR_DDRCS_SHIFT; - div = (reg & SCG_DDRCCR_DDRDIV_MASK) >> SCG_DDRCCR_DDRDIV_SHIFT; - - if (!div) - return 0; - - if (!val) { - reg = readl(&scg1_regs->apllcfg); - val = (reg & SCG_PLL_CFG_PFDSEL_MASK) >> - SCG_PLL_CFG_PFDSEL_SHIFT; - rate = scg_apll_pfd_get_rate(SCG_APLL_PFD0_CLK + val); - } else { - rate = decode_pll(PLL_USB); - } - - rate = rate / (1 << (div - 1)); - return rate; -} - -static u32 scg_nic_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - u32 shift, mask; - - reg = readl(&scg1_regs->niccsr); - val = (reg & SCG_NICCSR_NICCS_MASK) >> SCG_NICCSR_NICCS_SHIFT; - - clk_debug("scg_nic_get_rate niccsr 0x%x\n", reg); - - if (!val) - rate = scg_src_get_rate(SCG_FIRC_CLK); - else - rate = scg_ddr_get_rate(); - - clk_debug("scg_nic_get_rate parent rate %u\n", rate); - - val = (reg & SCG_NICCSR_NIC0DIV_MASK) >> SCG_NICCSR_NIC0DIV_SHIFT; - - rate = rate / (val + 1); - - clk_debug("scg_nic_get_rate NIC0 rate %u\n", rate); - - switch (clk) { - case SCG_NIC0_CLK: - return rate; - case SCG_GPU_CLK: - mask = SCG_NICCSR_GPUDIV_MASK; - shift = SCG_NICCSR_GPUDIV_SHIFT; - break; - case SCG_NIC1_EXT_CLK: - case SCG_NIC1_BUS_CLK: - case SCG_NIC1_CLK: - mask = SCG_NICCSR_NIC1DIV_MASK; - shift = SCG_NICCSR_NIC1DIV_SHIFT; - break; - default: - return 0; - } - - val = (reg & mask) >> shift; - rate = rate / (val + 1); - - clk_debug("scg_nic_get_rate NIC1 rate %u\n", rate); - - switch (clk) { - case SCG_GPU_CLK: - case SCG_NIC1_CLK: - return rate; - case SCG_NIC1_EXT_CLK: - mask = SCG_NICCSR_NIC1EXTDIV_MASK; - shift = SCG_NICCSR_NIC1EXTDIV_SHIFT; - break; - case SCG_NIC1_BUS_CLK: - mask = SCG_NICCSR_NIC1BUSDIV_MASK; - shift = SCG_NICCSR_NIC1BUSDIV_SHIFT; - break; - default: - return 0; - } - - val = (reg & mask) >> shift; - rate = rate / (val + 1); - - clk_debug("scg_nic_get_rate NIC1 bus rate %u\n", rate); - return rate; -} - - -static enum scg_clk scg_scs_array[4] = { - SCG_SOSC_CLK, SCG_SIRC_CLK, SCG_FIRC_CLK, SCG_ROSC_CLK, -}; - -static u32 scg_sys_get_rate(enum scg_clk clk) -{ - u32 reg, val, rate; - - if (clk != SCG_CORE_CLK && clk != SCG_BUS_CLK) - return 0; - - reg = readl(&scg1_regs->csr); - val = (reg & SCG_CCR_SCS_MASK) >> SCG_CCR_SCS_SHIFT; - - clk_debug("scg_sys_get_rate reg 0x%x\n", reg); - - switch (val) { - case SCG_SCS_SYS_OSC: - case SCG_SCS_SLOW_IRC: - case SCG_SCS_FAST_IRC: - case SCG_SCS_RTC_OSC: - rate = scg_src_get_rate(scg_scs_array[val]); - break; - case 5: - rate = scg_apll_get_rate(); - break; - case 6: - rate = scg_spll_get_rate(); - break; - default: - return 0; - } - - clk_debug("scg_sys_get_rate parent rate %u\n", rate); - - val = (reg & SCG_CCR_DIVCORE_MASK) >> SCG_CCR_DIVCORE_SHIFT; - - rate = rate / (val + 1); - - if (clk == SCG_BUS_CLK) { - val = (reg & SCG_CCR_DIVBUS_MASK) >> SCG_CCR_DIVBUS_SHIFT; - rate = rate / (val + 1); - } - - return rate; -} - -u32 decode_pll(enum pll_clocks pll) -{ - u32 reg, pre_div, infreq, mult; - u32 num, denom; - - /* - * Alought there are four choices for the bypass src, - * we choose OSC_24M which is the default set in ROM. - */ - switch (pll) { - case PLL_A7_SPLL: - reg = readl(&scg1_regs->spllcsr); - - if (!(reg & SCG_SPLL_CSR_SPLLVLD_MASK)) - return 0; - - reg = readl(&scg1_regs->spllcfg); - - pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >> - SCG_PLL_CFG_PREDIV_SHIFT; - pre_div += 1; - - mult = (reg & SCG1_SPLL_CFG_MULT_MASK) >> - SCG_PLL_CFG_MULT_SHIFT; - - infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >> - SCG_PLL_CFG_CLKSRC_SHIFT; - if (!infreq) - infreq = scg_src_get_rate(SCG_SOSC_CLK); - else - infreq = scg_src_get_rate(SCG_FIRC_CLK); - - num = readl(&scg1_regs->spllnum); - denom = readl(&scg1_regs->splldenom); - - infreq = infreq / pre_div; - - return infreq * mult + infreq * num / denom; - - case PLL_A7_APLL: - reg = readl(&scg1_regs->apllcsr); - - if (!(reg & SCG_APLL_CSR_APLLVLD_MASK)) - return 0; - - reg = readl(&scg1_regs->apllcfg); - - pre_div = (reg & SCG_PLL_CFG_PREDIV_MASK) >> - SCG_PLL_CFG_PREDIV_SHIFT; - pre_div += 1; - - mult = (reg & SCG_APLL_CFG_MULT_MASK) >> - SCG_PLL_CFG_MULT_SHIFT; - - infreq = (reg & SCG_PLL_CFG_CLKSRC_MASK) >> - SCG_PLL_CFG_CLKSRC_SHIFT; - if (!infreq) - infreq = scg_src_get_rate(SCG_SOSC_CLK); - else - infreq = scg_src_get_rate(SCG_FIRC_CLK); - - num = readl(&scg1_regs->apllnum); - denom = readl(&scg1_regs->aplldenom); - - infreq = infreq / pre_div; - - return infreq * mult + infreq * num / denom; - - case PLL_USB: - reg = readl(&scg1_regs->upllcsr); - - if (!(reg & SCG_UPLL_CSR_UPLLVLD_MASK)) - return 0; - - return 480000000u; - - case PLL_MIPI: - return 480000000u; - default: - printf("Unsupported pll clocks %d\n", pll); - break; - } - - return 0; -} - -u32 scg_clk_get_rate(enum scg_clk clk) -{ - switch (clk) { - case SCG_SIRC_DIV1_CLK: - case SCG_SIRC_DIV2_CLK: - case SCG_SIRC_DIV3_CLK: - return scg_sircdiv_get_rate(clk); - - case SCG_FIRC_DIV1_CLK: - case SCG_FIRC_DIV2_CLK: - case SCG_FIRC_DIV3_CLK: - return scg_fircdiv_get_rate(clk); - - case SCG_SOSC_DIV1_CLK: - case SCG_SOSC_DIV2_CLK: - case SCG_SOSC_DIV3_CLK: - return scg_soscdiv_get_rate(clk); - - case SCG_CORE_CLK: - case SCG_BUS_CLK: - return scg_sys_get_rate(clk); - - case SCG_SPLL_PFD0_CLK: - case SCG_SPLL_PFD1_CLK: - case SCG_SPLL_PFD2_CLK: - case SCG_SPLL_PFD3_CLK: - return scg_spll_pfd_get_rate(clk); - - case SCG_APLL_PFD0_CLK: - case SCG_APLL_PFD1_CLK: - case SCG_APLL_PFD2_CLK: - case SCG_APLL_PFD3_CLK: - return scg_apll_pfd_get_rate(clk); - - case SCG_DDR_CLK: - return scg_ddr_get_rate(); - - case SCG_NIC0_CLK: - case SCG_GPU_CLK: - case SCG_NIC1_CLK: - case SCG_NIC1_BUS_CLK: - case SCG_NIC1_EXT_CLK: - return scg_nic_get_rate(clk); - - case USB_PLL_OUT: - return decode_pll(PLL_USB); - - case MIPI_PLL_OUT: - return decode_pll(PLL_MIPI); - - case SCG_SOSC_CLK: - case SCG_FIRC_CLK: - case SCG_SIRC_CLK: - case SCG_ROSC_CLK: - return scg_src_get_rate(clk); - default: - return 0; - } -} - -int scg_enable_pll_pfd(enum scg_clk clk, u32 frac) -{ - u32 reg; - u32 shift, mask, gate, valid; - u32 addr; - - if (frac < 12 || frac > 35) - return -EINVAL; - - switch (clk) { - case SCG_SPLL_PFD0_CLK: - case SCG_APLL_PFD0_CLK: - gate = SCG_PLL_PFD0_GATE_MASK; - valid = SCG_PLL_PFD0_VALID_MASK; - mask = SCG_PLL_PFD0_FRAC_MASK; - shift = SCG_PLL_PFD0_FRAC_SHIFT; - - if (clk == SCG_SPLL_PFD0_CLK) - addr = (u32)(&scg1_regs->spllpfd); - else - addr = (u32)(&scg1_regs->apllpfd); - break; - case SCG_SPLL_PFD1_CLK: - case SCG_APLL_PFD1_CLK: - gate = SCG_PLL_PFD1_GATE_MASK; - valid = SCG_PLL_PFD1_VALID_MASK; - mask = SCG_PLL_PFD1_FRAC_MASK; - shift = SCG_PLL_PFD1_FRAC_SHIFT; - - if (clk == SCG_SPLL_PFD1_CLK) - addr = (u32)(&scg1_regs->spllpfd); - else - addr = (u32)(&scg1_regs->apllpfd); - break; - case SCG_SPLL_PFD2_CLK: - case SCG_APLL_PFD2_CLK: - gate = SCG_PLL_PFD2_GATE_MASK; - valid = SCG_PLL_PFD2_VALID_MASK; - mask = SCG_PLL_PFD2_FRAC_MASK; - shift = SCG_PLL_PFD2_FRAC_SHIFT; - - if (clk == SCG_SPLL_PFD2_CLK) - addr = (u32)(&scg1_regs->spllpfd); - else - addr = (u32)(&scg1_regs->apllpfd); - break; - case SCG_SPLL_PFD3_CLK: - case SCG_APLL_PFD3_CLK: - gate = SCG_PLL_PFD3_GATE_MASK; - valid = SCG_PLL_PFD3_VALID_MASK; - mask = SCG_PLL_PFD3_FRAC_MASK; - shift = SCG_PLL_PFD3_FRAC_SHIFT; - - if (clk == SCG_SPLL_PFD3_CLK) - addr = (u32)(&scg1_regs->spllpfd); - else - addr = (u32)(&scg1_regs->apllpfd); - break; - default: - return -EINVAL; - } - - /* Gate the PFD */ - reg = readl(addr); - reg |= gate; - writel(reg, addr); - - /* Write Frac divider */ - reg &= ~mask; - reg |= (frac << shift) & mask; - writel(reg, addr); - - /* - * Un-gate the PFD - * (Need un-gate before checking valid, not align with RM) - */ - reg &= ~gate; - writel(reg, addr); - - /* Wait for PFD clock being valid */ - do { - reg = readl(addr); - } while (!(reg & valid)); - - return 0; -} - -#define SIM_MISC_CTRL0_USB_PLL_EN_MASK (0x1 << 2) -int scg_enable_usb_pll(bool usb_control) -{ - u32 sosc_rate; - s32 timeout = 1000000; - u32 reg; - - struct usbphy_regs *usbphy = - (struct usbphy_regs *)USBPHY_RBASE; - - sosc_rate = scg_src_get_rate(SCG_SOSC_CLK); - if (!sosc_rate) - return -EPERM; - - reg = readl(SIM0_RBASE + 0x3C); - if (usb_control) - reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK; - else - reg |= SIM_MISC_CTRL0_USB_PLL_EN_MASK; - writel(reg, SIM0_RBASE + 0x3C); - - if (!(readl(&usbphy->usb1_pll_480_ctrl) & PLL_USB_LOCK_MASK)) { - writel(0x1c00000, &usbphy->usb1_pll_480_ctrl_clr); - - switch (sosc_rate) { - case 24000000: - writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set); - break; - - case 30000000: - writel(0x800000, &usbphy->usb1_pll_480_ctrl_set); - break; - - case 19200000: - writel(0x1400000, &usbphy->usb1_pll_480_ctrl_set); - break; - - default: - writel(0xc00000, &usbphy->usb1_pll_480_ctrl_set); - break; - } - - /* Enable the regulator first */ - writel(PLL_USB_REG_ENABLE_MASK, - &usbphy->usb1_pll_480_ctrl_set); - - /* Wait at least 15us */ - udelay(15); - - /* Enable the power */ - writel(PLL_USB_PWR_MASK, &usbphy->usb1_pll_480_ctrl_set); - - /* Wait lock */ - while (timeout--) { - if (readl(&usbphy->usb1_pll_480_ctrl) & - PLL_USB_LOCK_MASK) - break; - } - - if (timeout <= 0) { - /* If timeout, we power down the pll */ - writel(PLL_USB_PWR_MASK, - &usbphy->usb1_pll_480_ctrl_clr); - return -ETIME; - } - } - - /* Clear the bypass */ - writel(PLL_USB_BYPASS_MASK, &usbphy->usb1_pll_480_ctrl_clr); - - /* Enable the PLL clock out to USB */ - writel((PLL_USB_EN_USB_CLKS_MASK | PLL_USB_ENABLE_MASK), - &usbphy->usb1_pll_480_ctrl_set); - - if (!usb_control) { - while (timeout--) { - if (readl(&scg1_regs->upllcsr) & - SCG_UPLL_CSR_UPLLVLD_MASK) - break; - } - - if (timeout <= 0) { - reg = readl(SIM0_RBASE + 0x3C); - reg &= ~SIM_MISC_CTRL0_USB_PLL_EN_MASK; - writel(reg, SIM0_RBASE + 0x3C); - return -ETIME; - } - } - - return 0; -} - - -/* A7 domain system clock source is SPLL */ -#define SCG1_RCCR_SCS_NUM ((SCG_SCS_SYS_PLL) << SCG_CCR_SCS_SHIFT) - -/* A7 Core clck = SPLL PFD0 / 1 = 500MHz / 1 = 500MHz */ -#define SCG1_RCCR_DIVCORE_NUM ((0x0) << SCG_CCR_DIVCORE_SHIFT) -#define SCG1_RCCR_CFG_MASK (SCG_CCR_SCS_MASK | SCG_CCR_DIVBUS_MASK) - -/* A7 Plat clck = A7 Core Clock / 2 = 250MHz / 1 = 250MHz */ -#define SCG1_RCCR_DIVBUS_NUM ((0x1) << SCG_CCR_DIVBUS_SHIFT) -#define SCG1_RCCR_CFG_NUM (SCG1_RCCR_SCS_NUM | SCG1_RCCR_DIVBUS_NUM) - -void scg_a7_rccr_init(void) -{ - u32 rccr_reg_val = 0; - - rccr_reg_val = readl(&scg1_regs->rccr); - - rccr_reg_val &= (~SCG1_RCCR_CFG_MASK); - rccr_reg_val |= (SCG1_RCCR_CFG_NUM); - - writel(rccr_reg_val, &scg1_regs->rccr); -} - -/* POSTDIV2 = 1 */ -#define SCG1_SPLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT) -/* POSTDIV1 = 1 */ -#define SCG1_SPLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT) - -/* MULT = 22 */ -#define SCG1_SPLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT) - -/* PFD0 output clock selected */ -#define SCG1_SPLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT) -/* PREDIV = 1 */ -#define SCG1_SPLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT) -/* SPLL output clocks (including PFD outputs) selected */ -#define SCG1_SPLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT) -/* SPLL PFD output clock selected */ -#define SCG1_SPLL_CFG_PLLSEL_NUM ((0x1) << SCG_PLL_CFG_PLLSEL_SHIFT) -/* Clock source is System OSC */ -#define SCG1_SPLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT) -#define SCG1_SPLL_CFG_NUM_24M_OSC (SCG1_SPLL_CFG_POSTDIV2_NUM | \ - SCG1_SPLL_CFG_POSTDIV1_NUM | \ - (22 << SCG_PLL_CFG_MULT_SHIFT) | \ - SCG1_SPLL_CFG_PFDSEL_NUM | \ - SCG1_SPLL_CFG_PREDIV_NUM | \ - SCG1_SPLL_CFG_BYPASS_NUM | \ - SCG1_SPLL_CFG_PLLSEL_NUM | \ - SCG1_SPLL_CFG_CLKSRC_NUM) -/*413Mhz = A7 SPLL(528MHz) * 18/23 */ -#define SCG1_SPLL_PFD0_FRAC_NUM ((23) << SCG_PLL_PFD0_FRAC_SHIFT) - -void scg_a7_spll_init(void) -{ - u32 val = 0; - - /* Disable A7 System PLL */ - val = readl(&scg1_regs->spllcsr); - val &= ~SCG_SPLL_CSR_SPLLEN_MASK; - writel(val, &scg1_regs->spllcsr); - - /* - * Per block guide, - * "When changing PFD values, it is recommneded PFDx clock - * gets gated first by writing a value of 1 to PFDx_CLKGATE register, - * then program the new PFD value, then poll the PFDx_VALID - * flag to set before writing a value of 0 to PFDx_CLKGATE - * to ungate the PFDx clock and allow PFDx clock to run" - */ - - /* Gate off A7 SPLL PFD0 ~ PDF4 */ - val = readl(&scg1_regs->spllpfd); - val |= (SCG_PLL_PFD3_GATE_MASK | - SCG_PLL_PFD2_GATE_MASK | - SCG_PLL_PFD1_GATE_MASK | - SCG_PLL_PFD0_GATE_MASK); - writel(val, &scg1_regs->spllpfd); - - /* ================ A7 SPLL Configuration Start ============== */ - - /* Configure A7 System PLL */ - writel(SCG1_SPLL_CFG_NUM_24M_OSC, &scg1_regs->spllcfg); - - /* Enable A7 System PLL */ - val = readl(&scg1_regs->spllcsr); - val |= SCG_SPLL_CSR_SPLLEN_MASK; - writel(val, &scg1_regs->spllcsr); - - /* Wait for A7 SPLL clock ready */ - while (!(readl(&scg1_regs->spllcsr) & SCG_SPLL_CSR_SPLLVLD_MASK)) - ; - - /* Configure A7 SPLL PFD0 */ - val = readl(&scg1_regs->spllpfd); - val &= ~SCG_PLL_PFD0_FRAC_MASK; - val |= SCG1_SPLL_PFD0_FRAC_NUM; - writel(val, &scg1_regs->spllpfd); - - /* Un-gate A7 SPLL PFD0 */ - val = readl(&scg1_regs->spllpfd); - val &= ~SCG_PLL_PFD0_GATE_MASK; - writel(val, &scg1_regs->spllpfd); - - /* Wait for A7 SPLL PFD0 clock being valid */ - while (!(readl(&scg1_regs->spllpfd) & SCG_PLL_PFD0_VALID_MASK)) - ; - - /* ================ A7 SPLL Configuration End ============== */ -} - -/* DDR clock source is APLL PFD0 (396MHz) */ -#define SCG1_DDRCCR_DDRCS_NUM ((0x0) << SCG_DDRCCR_DDRCS_SHIFT) -/* DDR clock = APLL PFD0 / 1 = 396MHz / 1 = 396MHz */ -#define SCG1_DDRCCR_DDRDIV_NUM ((0x1) << SCG_DDRCCR_DDRDIV_SHIFT) -/* DDR clock = APLL PFD0 / 2 = 396MHz / 2 = 198MHz */ -#define SCG1_DDRCCR_DDRDIV_LF_NUM ((0x2) << SCG_DDRCCR_DDRDIV_SHIFT) -#define SCG1_DDRCCR_CFG_NUM (SCG1_DDRCCR_DDRCS_NUM | \ - SCG1_DDRCCR_DDRDIV_NUM) -#define SCG1_DDRCCR_CFG_LF_NUM (SCG1_DDRCCR_DDRCS_NUM | \ - SCG1_DDRCCR_DDRDIV_LF_NUM) -void scg_a7_ddrclk_init(void) -{ - writel(SCG1_DDRCCR_CFG_NUM, &scg1_regs->ddrccr); -} - -/* SCG1(A7) APLLCFG configurations */ -/* divide by 1 <<28 */ -#define SCG1_APLL_CFG_POSTDIV2_NUM ((0x0) << SCG_PLL_CFG_POSTDIV2_SHIFT) -/* divide by 1 <<24 */ -#define SCG1_APLL_CFG_POSTDIV1_NUM ((0x0) << SCG_PLL_CFG_POSTDIV1_SHIFT) -/* MULT is 22 <<16 */ -#define SCG1_APLL_CFG_MULT_NUM ((22) << SCG_PLL_CFG_MULT_SHIFT) -/* PFD0 output clock selected <<14 */ -#define SCG1_APLL_CFG_PFDSEL_NUM ((0) << SCG_PLL_CFG_PFDSEL_SHIFT) -/* PREDIV = 1 <<8 */ -#define SCG1_APLL_CFG_PREDIV_NUM ((0x0) << SCG_PLL_CFG_PREDIV_SHIFT) -/* APLL output clocks (including PFD outputs) selected <<2 */ -#define SCG1_APLL_CFG_BYPASS_NUM ((0x0) << SCG_PLL_CFG_BYPASS_SHIFT) -/* APLL PFD output clock selected <<1 */ -#define SCG1_APLL_CFG_PLLSEL_NUM ((0x0) << SCG_PLL_CFG_PLLSEL_SHIFT) -/* Clock source is System OSC <<0 */ -#define SCG1_APLL_CFG_CLKSRC_NUM ((0x0) << SCG_PLL_CFG_CLKSRC_SHIFT) - -/* - * A7 APLL = 24MHz / 1 * 22 / 1 / 1 = 528MHz, - * system PLL is sourced from APLL, - * APLL clock source is system OSC (24MHz) - */ -#define SCG1_APLL_CFG_NUM_24M_OSC (SCG1_APLL_CFG_POSTDIV2_NUM | \ - SCG1_APLL_CFG_POSTDIV1_NUM | \ - (22 << SCG_PLL_CFG_MULT_SHIFT) | \ - SCG1_APLL_CFG_PFDSEL_NUM | \ - SCG1_APLL_CFG_PREDIV_NUM | \ - SCG1_APLL_CFG_BYPASS_NUM | \ - SCG1_APLL_CFG_PLLSEL_NUM | \ - SCG1_APLL_CFG_CLKSRC_NUM) - -/* PFD0 Freq = A7 APLL(528MHz) * 18 / 27 = 352MHz */ -#define SCG1_APLL_PFD0_FRAC_NUM (27) - - -void scg_a7_apll_init(void) -{ - u32 val = 0; - - /* Disable A7 Auxiliary PLL */ - val = readl(&scg1_regs->apllcsr); - val &= ~SCG_APLL_CSR_APLLEN_MASK; - writel(val, &scg1_regs->apllcsr); - - /* Gate off A7 APLL PFD0 ~ PDF4 */ - val = readl(&scg1_regs->apllpfd); - val |= 0x80808080; - writel(val, &scg1_regs->apllpfd); - - /* ================ A7 APLL Configuration Start ============== */ - /* Configure A7 Auxiliary PLL */ - writel(SCG1_APLL_CFG_NUM_24M_OSC, &scg1_regs->apllcfg); - - /* Enable A7 Auxiliary PLL */ - val = readl(&scg1_regs->apllcsr); - val |= SCG_APLL_CSR_APLLEN_MASK; - writel(val, &scg1_regs->apllcsr); - - /* Wait for A7 APLL clock ready */ - while (!(readl(&scg1_regs->apllcsr) & SCG_APLL_CSR_APLLVLD_MASK)) - ; - - /* Configure A7 APLL PFD0 */ - val = readl(&scg1_regs->apllpfd); - val &= ~SCG_PLL_PFD0_FRAC_MASK; - val |= SCG1_APLL_PFD0_FRAC_NUM; - writel(val, &scg1_regs->apllpfd); - - /* Un-gate A7 APLL PFD0 */ - val = readl(&scg1_regs->apllpfd); - val &= ~SCG_PLL_PFD0_GATE_MASK; - writel(val, &scg1_regs->apllpfd); - - /* Wait for A7 APLL PFD0 clock being valid */ - while (!(readl(&scg1_regs->apllpfd) & SCG_PLL_PFD0_VALID_MASK)) - ; -} - -/* SCG1(A7) FIRC DIV configurations */ -/* Disable FIRC DIV3 */ -#define SCG1_FIRCDIV_DIV3_NUM ((0x0) << SCG_FIRCDIV_DIV3_SHIFT) -/* FIRC DIV2 = 48MHz / 1 = 48MHz */ -#define SCG1_FIRCDIV_DIV2_NUM ((0x1) << SCG_FIRCDIV_DIV2_SHIFT) -/* Disable FIRC DIV1 */ -#define SCG1_FIRCDIV_DIV1_NUM ((0x0) << SCG_FIRCDIV_DIV1_SHIFT) - -void scg_a7_firc_init(void) -{ - /* Wait for FIRC clock ready */ - while (!(readl(&scg1_regs->firccsr) & SCG_FIRC_CSR_FIRCVLD_MASK)) - ; - - /* Configure A7 FIRC DIV1 ~ DIV3 */ - writel((SCG1_FIRCDIV_DIV3_NUM | - SCG1_FIRCDIV_DIV2_NUM | - SCG1_FIRCDIV_DIV1_NUM), &scg1_regs->fircdiv); -} - -/* SCG1(A7) NICCCR configurations */ -/* NIC clock source is DDR clock (396/198MHz) */ -#define SCG1_NICCCR_NICCS_NUM ((0x1) << SCG_NICCCR_NICCS_SHIFT) - -/* NIC0 clock = DDR Clock / 2 = 396MHz / 2 = 198MHz */ -#define SCG1_NICCCR_NIC0_DIV_NUM ((0x1) << SCG_NICCCR_NIC0_DIV_SHIFT) -/* NIC0 clock = DDR Clock / 1 = 198MHz / 1 = 198MHz */ -#define SCG1_NICCCR_NIC0_DIV_LF_NUM ((0x0) << SCG_NICCCR_NIC0_DIV_SHIFT) -/* NIC1 clock = NIC0 Clock / 1 = 198MHz / 2 = 198MHz */ -#define SCG1_NICCCR_NIC1_DIV_NUM ((0x0) << SCG_NICCCR_NIC1_DIV_SHIFT) -/* NIC1 bus clock = NIC1 Clock / 3 = 198MHz / 3 = 66MHz */ -#define SCG1_NICCCR_NIC1_DIVBUS_NUM ((0x2) << SCG_NICCCR_NIC1_DIVBUS_SHIFT) -#define SCG1_NICCCR_CFG_NUM (SCG1_NICCCR_NICCS_NUM | \ - SCG1_NICCCR_NIC0_DIV_NUM | \ - SCG1_NICCCR_NIC1_DIV_NUM | \ - SCG1_NICCCR_NIC1_DIVBUS_NUM) - -void scg_a7_nicclk_init(void) -{ - writel(SCG1_NICCCR_CFG_NUM, &scg1_regs->nicccr); -} - -/* SCG1(A7) FIRC DIV configurations */ -/* Enable FIRC DIV3 */ -#define SCG1_SOSCDIV_DIV3_NUM ((0x1) << SCG_SOSCDIV_DIV3_SHIFT) -/* FIRC DIV2 = 48MHz / 1 = 48MHz */ -#define SCG1_SOSCDIV_DIV2_NUM ((0x1) << SCG_SOSCDIV_DIV2_SHIFT) -/* Enable FIRC DIV1 */ -#define SCG1_SOSCDIV_DIV1_NUM ((0x1) << SCG_SOSCDIV_DIV1_SHIFT) - -void scg_a7_soscdiv_init(void) -{ - /* Wait for FIRC clock ready */ - while (!(readl(&scg1_regs->sosccsr) & SCG_SOSC_CSR_SOSCVLD_MASK)) - ; - - /* Configure A7 FIRC DIV1 ~ DIV3 */ - writel((SCG1_SOSCDIV_DIV3_NUM | SCG1_SOSCDIV_DIV2_NUM | - SCG1_SOSCDIV_DIV1_NUM), &scg1_regs->soscdiv); -} - -void scg_a7_sys_clk_sel(enum scg_sys_src clk) -{ - u32 rccr_reg_val = 0; - - clk_debug("%s: system clock selected as %s\n", "[SCG]", - clk == SCG_SCS_SYS_OSC ? "SYS_OSC" : - clk == SCG_SCS_SLOW_IRC ? "SLOW_IRC" : - clk == SCG_SCS_FAST_IRC ? "FAST_IRC" : - clk == SCG_SCS_RTC_OSC ? "RTC_OSC" : - clk == SCG_SCS_AUX_PLL ? "AUX_PLL" : - clk == SCG_SCS_SYS_PLL ? "SYS_PLL" : - clk == SCG_SCS_USBPHY_PLL ? "USBPHY_PLL" : - "Invalid source" - ); - - rccr_reg_val = readl(&scg1_regs->rccr); - rccr_reg_val &= ~SCG_CCR_SCS_MASK; - rccr_reg_val |= (clk << SCG_CCR_SCS_SHIFT); - writel(rccr_reg_val, &scg1_regs->rccr); -} - -void scg_a7_info(void) -{ - debug("SCG Version: 0x%x\n", readl(&scg1_regs->verid)); - debug("SCG Parameter: 0x%x\n", readl(&scg1_regs->param)); - debug("SCG RCCR Value: 0x%x\n", readl(&scg1_regs->rccr)); - debug("SCG Clock Status: 0x%x\n", readl(&scg1_regs->csr)); -} diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c deleted file mode 100644 index 4fd4c3a32f..0000000000 --- a/arch/arm/cpu/armv7/mx7ulp/soc.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2016 Freescale Semiconductor, Inc. - * - * SPDX-License-Identifier: GPL-2.0+ - */ -#include <asm/io.h> -#include <asm/arch/clock.h> -#include <asm/arch/imx-regs.h> -#include <asm/arch/sys_proto.h> -#include <asm/imx-common/hab.h> - -static char *get_reset_cause(char *); - -#if defined(CONFIG_SECURE_BOOT) -struct imx_sec_config_fuse_t const imx_sec_config_fuse = { - .bank = 29, - .word = 6, -}; -#endif - -u32 get_cpu_rev(void) -{ - /* Temporally hard code the CPU rev to 0x73, rev 1.0. Fix it later */ - return (MXC_CPU_MX7ULP << 12) | (1 << 4); -} - -#ifdef CONFIG_REVISION_TAG -u32 __weak get_board_rev(void) -{ - return get_cpu_rev(); -} -#endif - -enum bt_mode get_boot_mode(void) -{ - u32 bt0_cfg = 0; - - bt0_cfg = readl(CMC0_RBASE + 0x40); - bt0_cfg &= (BT0CFG_LPBOOT_MASK | BT0CFG_DUALBOOT_MASK); - - if (!(bt0_cfg & BT0CFG_LPBOOT_MASK)) { - /* No low power boot */ - if (bt0_cfg & BT0CFG_DUALBOOT_MASK) - return DUAL_BOOT; - else - return SINGLE_BOOT; - } - - return LOW_POWER_BOOT; -} - -int arch_cpu_init(void) -{ - return 0; -} - -#ifdef CONFIG_BOARD_POSTCLK_INIT -int board_postclk_init(void) -{ - return 0; -} -#endif - -#define UNLOCK_WORD0 0xC520 /* 1st unlock word */ -#define UNLOCK_WORD1 0xD928 /* 2nd unlock word */ -#define REFRESH_WORD0 0xA602 /* 1st refresh word */ -#define REFRESH_WORD1 0xB480 /* 2nd refresh word */ - -static void disable_wdog(u32 wdog_base) -{ - writel(UNLOCK_WORD0, (wdog_base + 0x04)); - writel(UNLOCK_WORD1, (wdog_base + 0x04)); - writel(0x0, (wdog_base + 0x0C)); /* Set WIN to 0 */ - writel(0x400, (wdog_base + 0x08)); /* Set timeout to default 0x400 */ - writel(0x120, (wdog_base + 0x00)); /* Disable it and set update */ - - writel(REFRESH_WORD0, (wdog_base + 0x04)); /* Refresh the CNT */ - writel(REFRESH_WORD1, (wdog_base + 0x04)); -} - -void init_wdog(void) -{ - /* - * ROM will configure WDOG1, disable it or enable it - * depending on FUSE. The update bit is set for reconfigurable. - * We have to use unlock sequence to reconfigure it. - * WDOG2 is not touched by ROM, so it will have default value - * which is enabled. We can directly configure it. - * To simplify the codes, we still use same reconfigure - * process as WDOG1. Because the update bit is not set for - * WDOG2, the unlock sequence won't take effect really. - * It actually directly configure the wdog. - * In this function, we will disable both WDOG1 and WDOG2, - * and set update bit for both. So that kernel can reconfigure them. - */ - disable_wdog(WDG1_RBASE); - disable_wdog(WDG2_RBASE); -} - - -void s_init(void) -{ - /* Disable wdog */ - init_wdog(); - - /* clock configuration. */ - clock_init(); - - return; -} - -#ifndef CONFIG_ULP_WATCHDOG -void reset_cpu(ulong addr) -{ - setbits_le32(SIM0_RBASE, SIM_SOPT1_A7_SW_RESET); - while (1) - ; -} -#endif - -#if defined(CONFIG_DISPLAY_CPUINFO) -const char *get_imx_type(u32 imxtype) -{ - return "7ULP"; -} - -int print_cpuinfo(void) -{ - u32 cpurev; - char cause[18]; - - cpurev = get_cpu_rev(); - - printf("CPU: Freescale i.MX%s rev%d.%d at %d MHz\n", - get_imx_type((cpurev & 0xFF000) >> 12), - (cpurev & 0x000F0) >> 4, (cpurev & 0x0000F) >> 0, - mxc_get_clock(MXC_ARM_CLK) / 1000000); - - printf("Reset cause: %s\n", get_reset_cause(cause)); - - printf("Boot mode: "); - switch (get_boot_mode()) { - case LOW_POWER_BOOT: - printf("Low power boot\n"); - break; - case DUAL_BOOT: - printf("Dual boot\n"); - break; - case SINGLE_BOOT: - default: - printf("Single boot\n"); - break; - } - - return 0; -} -#endif - -#define CMC_SRS_TAMPER (1 << 31) -#define CMC_SRS_SECURITY (1 << 30) -#define CMC_SRS_TZWDG (1 << 29) -#define CMC_SRS_JTAG_RST (1 << 28) -#define CMC_SRS_CORE1 (1 << 16) -#define CMC_SRS_LOCKUP (1 << 15) -#define CMC_SRS_SW (1 << 14) -#define CMC_SRS_WDG (1 << 13) -#define CMC_SRS_PIN_RESET (1 << 8) -#define CMC_SRS_WARM (1 << 4) -#define CMC_SRS_HVD (1 << 3) -#define CMC_SRS_LVD (1 << 2) -#define CMC_SRS_POR (1 << 1) -#define CMC_SRS_WUP (1 << 0) - -static u32 reset_cause = -1; - -static char *get_reset_cause(char *ret) -{ - u32 cause1, cause = 0, srs = 0; - u32 *reg_ssrs = (u32 *)(SRC_BASE_ADDR + 0x28); - u32 *reg_srs = (u32 *)(SRC_BASE_ADDR + 0x20); - - if (!ret) - return "null"; - - srs = readl(reg_srs); - cause1 = readl(reg_ssrs); - writel(cause1, reg_ssrs); - - reset_cause = cause1; - - cause = cause1 & (CMC_SRS_POR | CMC_SRS_WUP | CMC_SRS_WARM); - - switch (cause) { - case CMC_SRS_POR: - sprintf(ret, "%s", "POR"); - break; - case CMC_SRS_WUP: - sprintf(ret, "%s", "WUP"); - break; - case CMC_SRS_WARM: - cause = cause1 & (CMC_SRS_WDG | CMC_SRS_SW | - CMC_SRS_JTAG_RST); - switch (cause) { - case CMC_SRS_WDG: - sprintf(ret, "%s", "WARM-WDG"); - break; - case CMC_SRS_SW: - sprintf(ret, "%s", "WARM-SW"); - break; - case CMC_SRS_JTAG_RST: - sprintf(ret, "%s", "WARM-JTAG"); - break; - default: - sprintf(ret, "%s", "WARM-UNKN"); - break; - } - break; - default: - sprintf(ret, "%s-%X", "UNKN", cause1); - break; - } - - debug("[%X] SRS[%X] %X - ", cause1, srs, srs^cause1); - return ret; -} - -#ifdef CONFIG_ENV_IS_IN_MMC -__weak int board_mmc_get_env_dev(int devno) -{ - return CONFIG_SYS_MMC_ENV_DEV; -} - -int mmc_get_env_dev(void) -{ - int devno = 0; - u32 bt1_cfg = 0; - - /* If not boot from sd/mmc, use default value */ - if (get_boot_mode() == LOW_POWER_BOOT) - return CONFIG_SYS_MMC_ENV_DEV; - - bt1_cfg = readl(CMC1_RBASE + 0x40); - devno = (bt1_cfg >> 9) & 0x7; - - return board_mmc_get_env_dev(devno); -} -#endif diff --git a/arch/arm/cpu/armv7/vf610/generic.c b/arch/arm/cpu/armv7/vf610/generic.c index 0328096afd..ac2d8d1a3f 100644 --- a/arch/arm/cpu/armv7/vf610/generic.c +++ b/arch/arm/cpu/armv7/vf610/generic.c @@ -9,7 +9,7 @@ #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> #include <asm/arch/crm_regs.h> -#include <asm/imx-common/sys_proto.h> +#include <asm/mach-imx/sys_proto.h> #include <netdev.h> #ifdef CONFIG_FSL_ESDHC #include <fsl_esdhc.h> |