diff options
author | Stefano Babic <sbabic@denx.de> | 2017-06-29 08:16:06 (GMT) |
---|---|---|
committer | Stefano Babic <sbabic@denx.de> | 2017-07-12 08:17:44 (GMT) |
commit | 552a848e4f75e224515269a84a1155c84b762bc7 (patch) | |
tree | abef72c4452bf6934525563520690119bb8d1301 /arch/arm/cpu/armv7/mx7ulp | |
parent | f34ccce50a1805a6fdb2d1604ec4e40d79302455 (diff) | |
download | u-boot-fsl-qoriq-552a848e4f75e224515269a84a1155c84b762bc7.tar.xz |
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/mx7ulp')
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/Kconfig | 17 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/clock.c | 365 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/iomux.c | 70 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/pcc.c | 286 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/scg.c | 1090 | ||||
-rw-r--r-- | arch/arm/cpu/armv7/mx7ulp/soc.c | 247 |
7 files changed, 0 insertions, 2083 deletions
diff --git a/arch/arm/cpu/armv7/mx7ulp/Kconfig b/arch/arm/cpu/armv7/mx7ulp/Kconfig deleted file mode 100644 index 1bdc85a..0000000 --- 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 0248ea8..0000000 --- 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 77b282a..0000000 --- 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 1eba24e..0000000 --- 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 edd84e5..0000000 --- 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 c117af0..0000000 --- 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 4fd4c3a..0000000 --- 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 |