diff options
Diffstat (limited to 'arch/arm/mach-imx')
-rw-r--r-- | arch/arm/mach-imx/Makefile | 21 | ||||
-rw-r--r-- | arch/arm/mach-imx/cpu.c | 130 | ||||
-rw-r--r-- | arch/arm/mach-imx/imx_bootaux.c | 46 | ||||
-rw-r--r-- | arch/arm/mach-imx/mac.c | 61 | ||||
-rw-r--r-- | arch/arm/mach-imx/mmc_env.c | 30 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx5/Makefile | 5 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx5/mx53_dram.c | 45 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx6/soc.c | 72 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx7/psci-mx7.c | 33 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx7/psci.S | 14 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx7/soc.c | 200 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/Kconfig | 10 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/Makefile | 8 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/clock.c | 795 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/clock_slice.c | 742 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/lowlevel_init.S | 63 | ||||
-rw-r--r-- | arch/arm/mach-imx/mx8m/soc.c | 227 | ||||
-rw-r--r-- | arch/arm/mach-imx/sip.c | 23 | ||||
-rw-r--r-- | arch/arm/mach-imx/spl.c | 8 |
19 files changed, 2249 insertions, 284 deletions
diff --git a/arch/arm/mach-imx/Makefile b/arch/arm/mach-imx/Makefile index cf39d08bddf..95a542fa01f 100644 --- a/arch/arm/mach-imx/Makefile +++ b/arch/arm/mach-imx/Makefile @@ -7,30 +7,41 @@ # SPDX-License-Identifier: GPL-2.0+ # -ifeq ($(SOC),$(filter $(SOC),mx25 mx35 mx5 mx6 mx7 vf610)) +ifeq ($(SOC),$(filter $(SOC),mx25 mx35 mx5 mx6 mx7 mx8m vf610)) obj-y = iomux-v3.o endif + +ifeq ($(SOC),$(filter $(SOC),mx8m)) +obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o +obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o +obj-$(CONFIG_FEC_MXC) += mac.o +obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o +obj-y += cpu.o +endif + ifeq ($(SOC),$(filter $(SOC),mx5 mx6)) obj-y += cpu.o speed.o obj-$(CONFIG_GPT_TIMER) += timer.o obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o endif -ifeq ($(SOC),$(filter $(SOC),mx7 mx6 mxs)) +ifeq ($(SOC),$(filter $(SOC),mx7 mx6 mxs mx8m)) obj-y += misc.o obj-$(CONFIG_SPL_BUILD) += spl.o endif ifeq ($(SOC),$(filter $(SOC),mx7)) obj-y += cpu.o obj-$(CONFIG_SYS_I2C_MXC) += i2c-mxv7.o +obj-$(CONFIG_ENV_IS_IN_MMC) += mmc_env.o endif ifeq ($(SOC),$(filter $(SOC),mx6 mx7)) obj-y += cache.o init.o -obj-$(CONFIG_SATA) += sata.o +obj-$(CONFIG_FEC_MXC) += mac.o obj-$(CONFIG_IMX_VIDEO_SKIP) += video.o obj-$(CONFIG_IMX_RDC) += rdc-sema.o ifneq ($(CONFIG_SPL_BUILD),y) obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o endif +obj-$(CONFIG_SATA) += sata.o obj-$(CONFIG_SECURE_BOOT) += hab.o obj-$(CONFIG_SYSCOUNTER_TIMER) += syscounter.o endif @@ -124,8 +135,10 @@ spl/u-boot-nand-spl.imx: SPL FORCE targets += $(addprefix ../../../,$(IMX_CONFIG) SPL u-boot.uim spl/u-boot-nand-spl.imx) +obj-$(CONFIG_ARM64) += sip.o + obj-$(CONFIG_MX5) += mx5/ obj-$(CONFIG_MX6) += mx6/ obj-$(CONFIG_MX7) += mx7/ obj-$(CONFIG_ARCH_MX7ULP) += mx7ulp/ - +obj-$(CONFIG_MX8M) += mx8m/ diff --git a/arch/arm/mach-imx/cpu.c b/arch/arm/mach-imx/cpu.c index a32ab87e9b4..4d4d434906f 100644 --- a/arch/arm/mach-imx/cpu.c +++ b/arch/arm/mach-imx/cpu.c @@ -16,6 +16,7 @@ #include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> #include <asm/arch/crm_regs.h> +#include <asm/mach-imx/boot_mode.h> #include <imx_thermal.h> #include <ipu_pixfmt.h> #include <thermal.h> @@ -62,6 +63,11 @@ static char *get_reset_cause(void) return "WDOG4"; case 0x00200: return "TEMPSENSE"; +#elif defined(CONFIG_MX8M) + case 0x00100: + return "WDOG2"; + case 0x00200: + return "TEMPSENSE"; #else case 0x00100: return "TEMPSENSE"; @@ -137,6 +143,8 @@ unsigned imx_ddr_size(void) const char *get_imx_type(u32 imxtype) { switch (imxtype) { + case MXC_CPU_MX8MQ: + return "8MQ"; /* Quad-core version of the mx8m */ case MXC_CPU_MX7S: return "7S"; /* Single-core version of the mx7 */ case MXC_CPU_MX7D: @@ -259,7 +267,7 @@ int cpu_mmc_init(bd_t *bis) } #endif -#ifndef CONFIG_MX7 +#if !(defined(CONFIG_MX7) || defined(CONFIG_MX8M)) u32 get_ahb_clk(void) { struct mxc_ccm_reg *imx_ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; @@ -293,6 +301,7 @@ void arch_preboot_os(void) #endif } +#ifndef CONFIG_MX8M void set_chipselect_size(int const cs_size) { unsigned int reg; @@ -323,6 +332,125 @@ void set_chipselect_size(int const cs_size) writel(reg, &iomuxc_regs->gpr[1]); } +#endif + +#if defined(CONFIG_MX7) || defined(CONFIG_MX8M) +/* + * OCOTP_TESTER3[9:8] (see Fusemap Description Table offset 0x440) + * defines a 2-bit SPEED_GRADING + */ +#define OCOTP_TESTER3_SPEED_SHIFT 8 +enum cpu_speed { + OCOTP_TESTER3_SPEED_GRADE0, + OCOTP_TESTER3_SPEED_GRADE1, + OCOTP_TESTER3_SPEED_GRADE2, + OCOTP_TESTER3_SPEED_GRADE3, +}; + +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_GRADE0: + return 800000000; + case OCOTP_TESTER3_SPEED_GRADE1: + return is_mx7() ? 500000000 : 1000000000; + case OCOTP_TESTER3_SPEED_GRADE2: + return is_mx7() ? 1000000000 : 1300000000; + case OCOTP_TESTER3_SPEED_GRADE3: + return is_mx7() ? 1200000000 : 1500000000; + } + + 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; +} +#endif + +#if defined(CONFIG_MX7) || defined(CONFIG_MX8M) +enum boot_device get_boot_device(void) +{ + struct bootrom_sw_info **p = + (struct bootrom_sw_info **)(ulong)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; +#ifdef CONFIG_MX8M + case BOOT_TYPE_USB: + boot_dev = USB_BOOT; + break; +#endif + default: + break; + } + + return boot_dev; +} +#endif #ifdef CONFIG_NXP_BOARD_REVISION int nxp_board_rev(void) diff --git a/arch/arm/mach-imx/imx_bootaux.c b/arch/arm/mach-imx/imx_bootaux.c index b62dfbf6bf6..6256b3a778f 100644 --- a/arch/arm/mach-imx/imx_bootaux.c +++ b/arch/arm/mach-imx/imx_bootaux.c @@ -5,21 +5,51 @@ */ #include <common.h> +#include <asm/io.h> +#include <asm/mach-imx/sys_proto.h> #include <command.h> +#include <imx_sip.h> #include <linux/compiler.h> -/* Allow for arch specific config before we boot */ -int __weak arch_auxiliary_core_up(u32 core_id, u32 boot_private_data) +int arch_auxiliary_core_up(u32 core_id, ulong boot_private_data) { - /* please define platform specific arch_auxiliary_core_up() */ - return CMD_RET_FAILURE; + ulong stack, pc; + + if (!boot_private_data) + return -EINVAL; + + stack = *(ulong *)boot_private_data; + pc = *(ulong *)(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 */ +#ifdef CONFIG_MX8M + call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_START, 0, 0); +#else + clrsetbits_le32(SRC_BASE_ADDR + SRC_M4_REG_OFFSET, + SRC_M4C_NON_SCLR_RST_MASK, SRC_M4_ENABLE_MASK); +#endif + + return 0; } -/* Allow for arch specific config before we boot */ -int __weak arch_auxiliary_core_check_up(u32 core_id) +int arch_auxiliary_core_check_up(u32 core_id) { - /* please define platform specific arch_auxiliary_core_check_up() */ - return 0; +#ifdef CONFIG_MX8M + return call_imx_sip(IMX_SIP_SRC, IMX_SIP_SRC_M4_STARTED, 0, 0); +#else + unsigned int val; + + val = readl(SRC_BASE_ADDR + SRC_M4_REG_OFFSET); + + if (val & SRC_M4C_NON_SCLR_RST_MASK) + return 0; /* assert in reset */ + + return 1; +#endif } /* diff --git a/arch/arm/mach-imx/mac.c b/arch/arm/mach-imx/mac.c new file mode 100644 index 00000000000..dd7fd92d313 --- /dev/null +++ b/arch/arm/mach-imx/mac.c @@ -0,0 +1,61 @@ +/* + * Copyright 2017 NXP + * + * Peng Fan <peng.fan@nxp.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <errno.h> + +struct imx_mac_fuse { + u32 mac_addr0; + u32 rsvd0[3]; + u32 mac_addr1; + u32 rsvd1[3]; + u32 mac_addr2; + u32 rsvd2[7]; +}; + +#define MAC_FUSE_MX6_OFFSET 0x620 +#define MAC_FUSE_MX7_OFFSET 0x640 + +void imx_get_mac_from_fuse(int dev_id, unsigned char *mac) +{ + struct imx_mac_fuse *fuse; + u32 offset; + bool has_second_mac; + + offset = is_mx6() ? MAC_FUSE_MX6_OFFSET : MAC_FUSE_MX7_OFFSET; + fuse = (struct imx_mac_fuse *)(ulong)(OCOTP_BASE_ADDR + offset); + has_second_mac = is_mx7() || is_mx6sx() || is_mx6ul() || is_mx6ull(); + + if (has_second_mac && 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; + } +} diff --git a/arch/arm/mach-imx/mmc_env.c b/arch/arm/mach-imx/mmc_env.c new file mode 100644 index 00000000000..ccadd2c1e0d --- /dev/null +++ b/arch/arm/mach-imx/mmc_env.c @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/arch/sys_proto.h> +#include <asm/io.h> +#include <asm/mach-imx/boot_mode.h> + +__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 **)(ulong)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); +} diff --git a/arch/arm/mach-imx/mx5/Makefile b/arch/arm/mach-imx/mx5/Makefile index d021842f681..4e305e92cf5 100644 --- a/arch/arm/mach-imx/mx5/Makefile +++ b/arch/arm/mach-imx/mx5/Makefile @@ -9,3 +9,8 @@ obj-y := soc.o clock.o obj-y += lowlevel_init.o + +# common files for mx53 dram initialization +obj-$(CONFIG_TARGET_M53EVK) += mx53_dram.o +obj-$(CONFIG_TARGET_MX53CX9020) += mx53_dram.o +obj-$(CONFIG_TARGET_MX53LOCO) += mx53_dram.o diff --git a/arch/arm/mach-imx/mx5/mx53_dram.c b/arch/arm/mach-imx/mx5/mx53_dram.c new file mode 100644 index 00000000000..7e5fc42d1fd --- /dev/null +++ b/arch/arm/mach-imx/mx5/mx53_dram.c @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2017 Beckhoff Automation GmbH & Co. KG + * Patrick Bruenn <p.bruenn@beckhoff.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> + +DECLARE_GLOBAL_DATA_PTR; + +phys_size_t get_effective_memsize(void) +{ + /* + * WARNING: We must override get_effective_memsize() function here + * to report only the size of the first DRAM bank. This is to make + * U-Boot relocator place U-Boot into valid memory, that is, at the + * end of the first DRAM bank. If we did not override this function + * like so, U-Boot would be placed at the address of the first DRAM + * bank + total DRAM size - sizeof(uboot), which in the setup where + * each DRAM bank contains 512MiB of DRAM would result in placing + * U-Boot into invalid memory area close to the end of the first + * DRAM bank. + */ + return get_ram_size((void *)PHYS_SDRAM_1, 1 << 30); +} + +int dram_init(void) +{ + gd->ram_size = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30); + gd->ram_size += get_ram_size((void *)PHYS_SDRAM_2, 1 << 30); + + return 0; +} + +int dram_init_banksize(void) +{ + gd->bd->bi_dram[0].start = PHYS_SDRAM_1; + gd->bd->bi_dram[0].size = get_ram_size((void *)PHYS_SDRAM_1, 1 << 30); + + gd->bd->bi_dram[1].start = PHYS_SDRAM_2; + gd->bd->bi_dram[1].size = get_ram_size((void *)PHYS_SDRAM_2, 1 << 30); + + return 0; +} diff --git a/arch/arm/mach-imx/mx6/soc.c b/arch/arm/mach-imx/mx6/soc.c index 43cb58106b9..9b3d8f69b26 100644 --- a/arch/arm/mach-imx/mx6/soc.c +++ b/arch/arm/mach-imx/mx6/soc.c @@ -518,40 +518,6 @@ int board_postclk_init(void) 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 - #ifndef CONFIG_SPL_BUILD /* * cfg_val will be used for @@ -700,41 +666,3 @@ void gpr_init(void) writel(0x007F007F, &iomux->gpr[7]); } } - -#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/mach-imx/mx7/psci-mx7.c b/arch/arm/mach-imx/mx7/psci-mx7.c index 7f429b0a433..d5db51165f9 100644 --- a/arch/arm/mach-imx/mx7/psci-mx7.c +++ b/arch/arm/mach-imx/mx7/psci-mx7.c @@ -10,7 +10,7 @@ #include <asm/secure.h> #include <asm/arch/imx-regs.h> #include <common.h> - +#include <fsl_wdog.h> #define GPC_CPU_PGC_SW_PDN_REQ 0xfc #define GPC_CPU_PGC_SW_PUP_REQ 0xf0 @@ -26,6 +26,15 @@ #define BP_SRC_A7RCR0_A7_CORE_RESET0 0 #define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 +#define SNVS_LPCR 0x38 +#define BP_SNVS_LPCR_DP_EN 0x20 +#define BP_SNVS_LPCR_TOP 0x40 + +#define CCM_CCGR_SNVS 0x4250 + +#define CCM_ROOT_WDOG 0xbb80 +#define CCM_CCGR_WDOG1 0x49c0 + static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) { writel(enable, GPC_IPS_BASE_ADDR + offset); @@ -74,3 +83,25 @@ __secure int imx_cpu_off(int cpu) writel(0, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D + 4); return 0; } + +__secure void imx_system_reset(void) +{ + struct wdog_regs *wdog = (struct wdog_regs *)WDOG1_BASE_ADDR; + + /* make sure WDOG1 clock is enabled */ + writel(0x1 << 28, CCM_BASE_ADDR + CCM_ROOT_WDOG); + writel(0x3, CCM_BASE_ADDR + CCM_CCGR_WDOG1); + writew(WCR_WDE, &wdog->wcr); +} + +__secure void imx_system_off(void) +{ + u32 val; + + /* make sure SNVS clock is enabled */ + writel(0x3, CCM_BASE_ADDR + CCM_CCGR_SNVS); + + val = readl(SNVS_BASE_ADDR + SNVS_LPCR); + val |= BP_SNVS_LPCR_DP_EN | BP_SNVS_LPCR_TOP; + writel(val, SNVS_BASE_ADDR + SNVS_LPCR); +} diff --git a/arch/arm/mach-imx/mx7/psci.S b/arch/arm/mach-imx/mx7/psci.S index fc5eb34c889..bc2cd8ae9a5 100644 --- a/arch/arm/mach-imx/mx7/psci.S +++ b/arch/arm/mach-imx/mx7/psci.S @@ -43,4 +43,18 @@ psci_cpu_off: 1: wfi b 1b +.globl psci_system_reset +psci_system_reset: + bl imx_system_reset + +2: wfi + b 2b + +.globl psci_system_off +psci_system_off: + bl imx_system_off + +3: wfi + b 3b + .popsection diff --git a/arch/arm/mach-imx/mx7/soc.c b/arch/arm/mach-imx/mx7/soc.c index d160e80146d..d349676b811 100644 --- a/arch/arm/mach-imx/mx7/soc.c +++ b/arch/arm/mach-imx/mx7/soc.c @@ -17,6 +17,7 @@ #include <asm/arch/crm_regs.h> #include <dm.h> #include <imx_thermal.h> +#include <fsl_sec.h> #if defined(CONFIG_IMX_THERMAL) static const struct imx_thermal_plat imx7_thermal_plat = { @@ -97,77 +98,6 @@ struct imx_sec_config_fuse_t const imx_sec_config_fuse = { }; #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; @@ -262,6 +192,10 @@ int arch_misc_init(void) env_set("soc", "imx7s"); #endif +#ifdef CONFIG_FSL_CAAM + sec_init(); +#endif + return 0; } #endif @@ -279,74 +213,6 @@ void get_board_serial(struct tag_serialnr *serialnr) } #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); @@ -389,62 +255,6 @@ const struct boot_mode soc_boot_modes[] = { {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 diff --git a/arch/arm/mach-imx/mx8m/Kconfig b/arch/arm/mach-imx/mx8m/Kconfig new file mode 100644 index 00000000000..3a84c2f2b09 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/Kconfig @@ -0,0 +1,10 @@ +if ARCH_MX8M + +config MX8M + bool + select ROM_UNIFIED_SECTIONS + +config SYS_SOC + default "mx8m" + +endif diff --git a/arch/arm/mach-imx/mx8m/Makefile b/arch/arm/mach-imx/mx8m/Makefile new file mode 100644 index 00000000000..b1c5d74aab7 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/Makefile @@ -0,0 +1,8 @@ +# +# Copyright 2017 NXP +# +# SPDX-License-Identifier: GPL-2.0+ +# + +obj-y += lowlevel_init.o +obj-y += clock.o clock_slice.o soc.o diff --git a/arch/arm/mach-imx/mx8m/clock.c b/arch/arm/mach-imx/mx8m/clock.c new file mode 100644 index 00000000000..c56ba99d5c6 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/clock.c @@ -0,0 +1,795 @@ +/* + * Copyright 2017 NXP + * + * Peng Fan <peng.fan@nxp.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/io.h> +#include <asm/arch/sys_proto.h> +#include <errno.h> +#include <linux/iopoll.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; + +static u32 decode_frac_pll(enum clk_root_src frac_pll) +{ + u32 pll_cfg0, pll_cfg1, pllout; + u32 pll_refclk_sel, pll_refclk; + u32 divr_val, divq_val, divf_val, divff, divfi; + u32 pllout_div_shift, pllout_div_mask, pllout_div; + + switch (frac_pll) { + case ARM_PLL_CLK: + pll_cfg0 = readl(&ana_pll->arm_pll_cfg0); + pll_cfg1 = readl(&ana_pll->arm_pll_cfg1); + pllout_div_shift = HW_FRAC_ARM_PLL_DIV_SHIFT; + pllout_div_mask = HW_FRAC_ARM_PLL_DIV_MASK; + break; + default: + printf("Frac PLL %d not supporte\n", frac_pll); + return 0; + } + + pllout_div = readl(&ana_pll->frac_pllout_div_cfg); + pllout_div = (pllout_div & pllout_div_mask) >> pllout_div_shift; + + /* Power down */ + if (pll_cfg0 & FRAC_PLL_PD_MASK) + return 0; + + /* output not enabled */ + if ((pll_cfg0 & FRAC_PLL_CLKE_MASK) == 0) + return 0; + + pll_refclk_sel = pll_cfg0 & FRAC_PLL_REFCLK_SEL_MASK; + + if (pll_refclk_sel == FRAC_PLL_REFCLK_SEL_OSC_25M) + pll_refclk = 25000000u; + else if (pll_refclk_sel == FRAC_PLL_REFCLK_SEL_OSC_27M) + pll_refclk = 27000000u; + else if (pll_refclk_sel == FRAC_PLL_REFCLK_SEL_HDMI_PHY_27M) + pll_refclk = 27000000u; + else + pll_refclk = 0; + + if (pll_cfg0 & FRAC_PLL_BYPASS_MASK) + return pll_refclk; + + divr_val = (pll_cfg0 & FRAC_PLL_REFCLK_DIV_VAL_MASK) >> + FRAC_PLL_REFCLK_DIV_VAL_SHIFT; + divq_val = pll_cfg0 & FRAC_PLL_OUTPUT_DIV_VAL_MASK; + + divff = (pll_cfg1 & FRAC_PLL_FRAC_DIV_CTL_MASK) >> + FRAC_PLL_FRAC_DIV_CTL_SHIFT; + divfi = pll_cfg1 & FRAC_PLL_INT_DIV_CTL_MASK; + + divf_val = 1 + divfi + divff / (1 << 24); + + pllout = pll_refclk / (divr_val + 1) * 8 * divf_val / + ((divq_val + 1) * 2); + + return pllout / (pllout_div + 1); +} + +static u32 decode_sscg_pll(enum clk_root_src sscg_pll) +{ + u32 pll_cfg0, pll_cfg1, pll_cfg2; + u32 pll_refclk_sel, pll_refclk; + u32 divr1, divr2, divf1, divf2, divq, div; + u32 sse; + u32 pll_clke; + u32 pllout_div_shift, pllout_div_mask, pllout_div; + u32 pllout; + + switch (sscg_pll) { + case SYSTEM_PLL1_800M_CLK: + case SYSTEM_PLL1_400M_CLK: + case SYSTEM_PLL1_266M_CLK: + case SYSTEM_PLL1_200M_CLK: + case SYSTEM_PLL1_160M_CLK: + case SYSTEM_PLL1_133M_CLK: + case SYSTEM_PLL1_100M_CLK: + case SYSTEM_PLL1_80M_CLK: + case SYSTEM_PLL1_40M_CLK: + pll_cfg0 = readl(&ana_pll->sys_pll1_cfg0); + pll_cfg1 = readl(&ana_pll->sys_pll1_cfg1); + pll_cfg2 = readl(&ana_pll->sys_pll1_cfg2); + pllout_div_shift = HW_SSCG_SYSTEM_PLL1_DIV_SHIFT; + pllout_div_mask = HW_SSCG_SYSTEM_PLL1_DIV_MASK; + break; + case SYSTEM_PLL2_1000M_CLK: + case SYSTEM_PLL2_500M_CLK: + case SYSTEM_PLL2_333M_CLK: + case SYSTEM_PLL2_250M_CLK: + case SYSTEM_PLL2_200M_CLK: + case SYSTEM_PLL2_166M_CLK: + case SYSTEM_PLL2_125M_CLK: + case SYSTEM_PLL2_100M_CLK: + case SYSTEM_PLL2_50M_CLK: + pll_cfg0 = readl(&ana_pll->sys_pll2_cfg0); + pll_cfg1 = readl(&ana_pll->sys_pll2_cfg1); + pll_cfg2 = readl(&ana_pll->sys_pll2_cfg2); + pllout_div_shift = HW_SSCG_SYSTEM_PLL2_DIV_SHIFT; + pllout_div_mask = HW_SSCG_SYSTEM_PLL2_DIV_MASK; + break; + case SYSTEM_PLL3_CLK: + pll_cfg0 = readl(&ana_pll->sys_pll3_cfg0); + pll_cfg1 = readl(&ana_pll->sys_pll3_cfg1); + pll_cfg2 = readl(&ana_pll->sys_pll3_cfg2); + pllout_div_shift = HW_SSCG_SYSTEM_PLL3_DIV_SHIFT; + pllout_div_mask = HW_SSCG_SYSTEM_PLL3_DIV_MASK; + break; + case DRAM_PLL1_CLK: + pll_cfg0 = readl(&ana_pll->dram_pll_cfg0); + pll_cfg1 = readl(&ana_pll->dram_pll_cfg1); + pll_cfg2 = readl(&ana_pll->dram_pll_cfg2); + pllout_div_shift = HW_SSCG_DRAM_PLL_DIV_SHIFT; + pllout_div_mask = HW_SSCG_DRAM_PLL_DIV_MASK; + break; + default: + printf("sscg pll %d not supporte\n", sscg_pll); + return 0; + } + + switch (sscg_pll) { + case DRAM_PLL1_CLK: + pll_clke = SSCG_PLL_DRAM_PLL_CLKE_MASK; + div = 1; + break; + case SYSTEM_PLL3_CLK: + pll_clke = SSCG_PLL_PLL3_CLKE_MASK; + div = 1; + break; + case SYSTEM_PLL2_1000M_CLK: + case SYSTEM_PLL1_800M_CLK: + pll_clke = SSCG_PLL_CLKE_MASK; + div = 1; + break; + case SYSTEM_PLL2_500M_CLK: + case SYSTEM_PLL1_400M_CLK: + pll_clke = SSCG_PLL_DIV2_CLKE_MASK; + div = 2; + break; + case SYSTEM_PLL2_333M_CLK: + case SYSTEM_PLL1_266M_CLK: + pll_clke = SSCG_PLL_DIV3_CLKE_MASK; + div = 3; + break; + case SYSTEM_PLL2_250M_CLK: + case SYSTEM_PLL1_200M_CLK: + pll_clke = SSCG_PLL_DIV4_CLKE_MASK; + div = 4; + break; + case SYSTEM_PLL2_200M_CLK: + case SYSTEM_PLL1_160M_CLK: + pll_clke = SSCG_PLL_DIV5_CLKE_MASK; + div = 5; + break; + case SYSTEM_PLL2_166M_CLK: + case SYSTEM_PLL1_133M_CLK: + pll_clke = SSCG_PLL_DIV6_CLKE_MASK; + div = 6; + break; + case SYSTEM_PLL2_125M_CLK: + case SYSTEM_PLL1_100M_CLK: + pll_clke = SSCG_PLL_DIV8_CLKE_MASK; + div = 8; + break; + case SYSTEM_PLL2_100M_CLK: + case SYSTEM_PLL1_80M_CLK: + pll_clke = SSCG_PLL_DIV10_CLKE_MASK; + div = 10; + break; + case SYSTEM_PLL2_50M_CLK: + case SYSTEM_PLL1_40M_CLK: + pll_clke = SSCG_PLL_DIV20_CLKE_MASK; + div = 20; + break; + default: + printf("sscg pll %d not supporte\n", sscg_pll); + return 0; + } + + /* Power down */ + if (pll_cfg0 & SSCG_PLL_PD_MASK) + return 0; + + /* output not enabled */ + if ((pll_cfg0 & pll_clke) == 0) + return 0; + + pllout_div = readl(&ana_pll->sscg_pllout_div_cfg); + pllout_div = (pllout_div & pllout_div_mask) >> pllout_div_shift; + + pll_refclk_sel = pll_cfg0 & SSCG_PLL_REFCLK_SEL_MASK; + + if (pll_refclk_sel == SSCG_PLL_REFCLK_SEL_OSC_25M) + pll_refclk = 25000000u; + else if (pll_refclk_sel == SSCG_PLL_REFCLK_SEL_OSC_27M) + pll_refclk = 27000000u; + else if (pll_refclk_sel == SSCG_PLL_REFCLK_SEL_HDMI_PHY_27M) + pll_refclk = 27000000u; + else + pll_refclk = 0; + + /* We assume bypass1/2 are the same value */ + if ((pll_cfg0 & SSCG_PLL_BYPASS1_MASK) || + (pll_cfg0 & SSCG_PLL_BYPASS2_MASK)) + return pll_refclk; + + divr1 = (pll_cfg2 & SSCG_PLL_REF_DIVR1_MASK) >> + SSCG_PLL_REF_DIVR1_SHIFT; + divr2 = (pll_cfg2 & SSCG_PLL_REF_DIVR2_MASK) >> + SSCG_PLL_REF_DIVR2_SHIFT; + divf1 = (pll_cfg2 & SSCG_PLL_FEEDBACK_DIV_F1_MASK) >> + SSCG_PLL_FEEDBACK_DIV_F1_SHIFT; + divf2 = (pll_cfg2 & SSCG_PLL_FEEDBACK_DIV_F2_MASK) >> + SSCG_PLL_FEEDBACK_DIV_F2_SHIFT; + divq = (pll_cfg2 & SSCG_PLL_OUTPUT_DIV_VAL_MASK) >> + SSCG_PLL_OUTPUT_DIV_VAL_SHIFT; + sse = pll_cfg1 & SSCG_PLL_SSE_MASK; + + if (sse) + sse = 8; + else + sse = 2; + + pllout = pll_refclk / (divr1 + 1) * sse * (divf1 + 1) / + (divr2 + 1) * (divf2 + 1) / (divq + 1); + + return pllout / (pllout_div + 1) / div; +} + +static u32 get_root_src_clk(enum clk_root_src root_src) +{ + switch (root_src) { + case OSC_25M_CLK: + return 25000000; + case OSC_27M_CLK: + return 25000000; + case OSC_32K_CLK: + return 32000; + case ARM_PLL_CLK: + return decode_frac_pll(root_src); + case SYSTEM_PLL1_800M_CLK: + case SYSTEM_PLL1_400M_CLK: + case SYSTEM_PLL1_266M_CLK: + case SYSTEM_PLL1_200M_CLK: + case SYSTEM_PLL1_160M_CLK: + case SYSTEM_PLL1_133M_CLK: + case SYSTEM_PLL1_100M_CLK: + case SYSTEM_PLL1_80M_CLK: + case SYSTEM_PLL1_40M_CLK: + case SYSTEM_PLL2_1000M_CLK: + case SYSTEM_PLL2_500M_CLK: + case SYSTEM_PLL2_333M_CLK: + case SYSTEM_PLL2_250M_CLK: + case SYSTEM_PLL2_200M_CLK: + case SYSTEM_PLL2_166M_CLK: + case SYSTEM_PLL2_125M_CLK: + case SYSTEM_PLL2_100M_CLK: + case SYSTEM_PLL2_50M_CLK: + case SYSTEM_PLL3_CLK: + return decode_sscg_pll(root_src); + default: + return 0; + } + + return 0; +} + +static u32 get_root_clk(enum clk_root_index clock_id) +{ + enum clk_root_src root_src; + u32 post_podf, pre_podf, root_src_clk; + + 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_src(clock_id, &root_src) < 0) + return 0; + + root_src_clk = get_root_src_clk(root_src); + + return root_src_clk / (post_podf + 1) / (pre_podf + 1); +} + +#ifdef CONFIG_MXC_OCOTP +void enable_ocotp_clk(unsigned char enable) +{ + clock_enable(CCGR_OCOTP, !!enable); +} +#endif + +int enable_i2c_clk(unsigned char enable, unsigned int i2c_num) +{ + /* 0 - 3 is valid i2c num */ + if (i2c_num > 3) + return -EINVAL; + + clock_enable(CCGR_I2C1 + i2c_num, !!enable); + + return 0; +} + +unsigned int mxc_get_clock(enum clk_root_index clk) +{ + u32 val; + + if (clk >= CLK_ROOT_MAX) + return 0; + + if (clk == MXC_ARM_CLK) + return get_root_clk(ARM_A53_CLK_ROOT); + + if (clk == MXC_IPG_CLK) { + clock_get_target_val(IPG_CLK_ROOT, &val); + val = val & 0x3; + return get_root_clk(AHB_CLK_ROOT) / (val + 1); + } + + return get_root_clk(clk); +} + +u32 imx_get_uartclk(void) +{ + return mxc_get_clock(UART1_CLK_ROOT); +} + +void mxs_set_lcdclk(u32 base_addr, u32 freq) +{ + /* + * LCDIF_PIXEL_CLK: select 800MHz root clock, + * select pre divider 8, output is 100 MHz + */ + clock_set_target_val(LCDIF_PIXEL_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(4) | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV8)); +} + +void init_wdog_clk(void) +{ + clock_enable(CCGR_WDOG1, 0); + clock_enable(CCGR_WDOG2, 0); + clock_enable(CCGR_WDOG3, 0); + clock_set_target_val(WDOG_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_set_target_val(WDOG_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_set_target_val(WDOG_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_WDOG1, 1); + clock_enable(CCGR_WDOG2, 1); + clock_enable(CCGR_WDOG3, 1); +} + +void init_usb_clk(void) +{ + if (!is_usb_boot()) { + clock_enable(CCGR_USB_CTRL1, 0); + clock_enable(CCGR_USB_CTRL2, 0); + clock_enable(CCGR_USB_PHY1, 0); + clock_enable(CCGR_USB_PHY2, 0); + /* 500MHz */ + clock_set_target_val(USB_BUS_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + /* 100MHz */ + clock_set_target_val(USB_CORE_REF_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + /* 100MHz */ + clock_set_target_val(USB_PHY_REF_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + clock_enable(CCGR_USB_CTRL1, 1); + clock_enable(CCGR_USB_CTRL2, 1); + clock_enable(CCGR_USB_PHY1, 1); + clock_enable(CCGR_USB_PHY2, 1); + } +} + +void init_uart_clk(u32 index) +{ + /* Set uart clock root 25M OSC */ + switch (index) { + case 0: + clock_enable(CCGR_UART1, 0); + clock_set_target_val(UART1_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_UART1, 1); + return; + case 1: + clock_enable(CCGR_UART2, 0); + clock_set_target_val(UART2_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_UART2, 1); + return; + case 2: + clock_enable(CCGR_UART3, 0); + clock_set_target_val(UART3_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_UART3, 1); + return; + case 3: + clock_enable(CCGR_UART4, 0); + clock_set_target_val(UART4_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + clock_enable(CCGR_UART4, 1); + return; + default: + printf("Invalid uart index\n"); + return; + } +} + +void init_clk_usdhc(u32 index) +{ + /* + * set usdhc clock root + * sys pll1 400M + */ + switch (index) { + case 0: + clock_enable(CCGR_USDHC1, 0); + clock_set_target_val(USDHC1_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); + clock_enable(CCGR_USDHC1, 1); + return; + case 1: + clock_enable(CCGR_USDHC2, 0); + clock_set_target_val(USDHC2_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); + clock_enable(CCGR_USDHC2, 1); + return; + default: + printf("Invalid usdhc index\n"); + return; + } +} + +int set_clk_qspi(void) +{ + /* + * set qspi root + * sys pll1 100M + */ + clock_enable(CCGR_QSPI, 0); + clock_set_target_val(QSPI_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(7)); + clock_enable(CCGR_QSPI, 1); + + return 0; +} + +#ifdef CONFIG_FEC_MXC +int set_clk_enet(enum enet_freq type) +{ + u32 target; + u32 enet1_ref; + + switch (type) { + case ENET_125MHZ: + enet1_ref = ENET1_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; + break; + case ENET_25MHZ: + enet1_ref = ENET1_REF_CLK_ROOT_FROM_PLL_ENET_MAIN_25M_CLK; + break; + default: + return -EINVAL; + } + + /* disable the clock first */ + clock_enable(CCGR_ENET1, 0); + clock_enable(CCGR_SIM_ENET, 0); + + /* set enet axi clock 266Mhz */ + target = CLK_ROOT_ON | ENET_AXI_CLK_ROOT_FROM_SYS1_PLL_266M | + CLK_ROOT_PRE_DIV(CLK_ROOT_PRE_DIV1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1); + 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(ENET_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(ENET_TIMER_CLK_ROOT, target); + + /* enable clock */ + clock_enable(CCGR_SIM_ENET, 1); + clock_enable(CCGR_ENET1, 1); + + return 0; +} +#endif + +u32 imx_get_fecclk(void) +{ + return get_root_clk(ENET_AXI_CLK_ROOT); +} + +#ifdef CONFIG_SPL_BUILD +void dram_pll_init(void) +{ + struct src *src = (struct src *)SRC_BASE_ADDR; + void __iomem *pll_control_reg = &ana_pll->dram_pll_cfg0; + u32 pwdn_mask = 0, pll_clke = 0, bypass1 = 0, bypass2 = 0; + u32 val; + int ret; + + setbits_le32(GPC_BASE_ADDR + 0xEC, BIT(7)); + setbits_le32(GPC_BASE_ADDR + 0xF8, BIT(5)); + + pwdn_mask = SSCG_PLL_PD_MASK; + pll_clke = SSCG_PLL_DRAM_PLL_CLKE_MASK; + bypass1 = SSCG_PLL_BYPASS1_MASK; + bypass2 = SSCG_PLL_BYPASS2_MASK; + + /* Enable DDR1 and DDR2 domain */ + writel(SRC_DDR1_ENABLE_MASK, &src->ddr1_rcr); + writel(SRC_DDR1_ENABLE_MASK, &src->ddr2_rcr); + + /* Clear power down bit */ + clrbits_le32(pll_control_reg, pwdn_mask); + /* Eanble ARM_PLL/SYS_PLL */ + setbits_le32(pll_control_reg, pll_clke); + + /* Clear bypass */ + clrbits_le32(pll_control_reg, bypass1); + __udelay(100); + clrbits_le32(pll_control_reg, bypass2); + /* Wait lock */ + ret = readl_poll_timeout(pll_control_reg, val, + val & SSCG_PLL_LOCK_MASK, 1); + if (ret) + printf("%s timeout\n", __func__); +} + +int frac_pll_init(u32 pll, enum frac_pll_out_val val) +{ + void __iomem *pll_cfg0, __iomem *pll_cfg1; + u32 val_cfg0, val_cfg1; + int ret; + + switch (pll) { + case ANATOP_ARM_PLL: + pll_cfg0 = &ana_pll->arm_pll_cfg0; + pll_cfg1 = &ana_pll->arm_pll_cfg1; + + if (val == FRAC_PLL_OUT_1000M) + val_cfg1 = FRAC_PLL_INT_DIV_CTL_VAL(49); + else + val_cfg1 = FRAC_PLL_INT_DIV_CTL_VAL(79); + val_cfg0 = FRAC_PLL_CLKE_MASK | FRAC_PLL_REFCLK_SEL_OSC_25M | + FRAC_PLL_LOCK_SEL_MASK | FRAC_PLL_NEWDIV_VAL_MASK | + FRAC_PLL_REFCLK_DIV_VAL(4) | + FRAC_PLL_OUTPUT_DIV_VAL(0); + break; + default: + return -EINVAL; + } + + /* bypass the clock */ + setbits_le32(pll_cfg0, FRAC_PLL_BYPASS_MASK); + /* Set the value */ + writel(val_cfg1, pll_cfg1); + writel(val_cfg0 | FRAC_PLL_BYPASS_MASK, pll_cfg0); + val_cfg0 = readl(pll_cfg0); + /* unbypass the clock */ + clrbits_le32(pll_cfg0, FRAC_PLL_BYPASS_MASK); + ret = readl_poll_timeout(pll_cfg0, val_cfg0, + val_cfg0 & FRAC_PLL_LOCK_MASK, 1); + if (ret) + printf("%s timeout\n", __func__); + clrbits_le32(pll_cfg0, FRAC_PLL_NEWDIV_VAL_MASK); + + return 0; +} + +int sscg_pll_init(u32 pll) +{ + void __iomem *pll_cfg0, __iomem *pll_cfg1, __iomem *pll_cfg2; + u32 val_cfg0, val_cfg1, val_cfg2, val; + u32 bypass1_mask = 0x20, bypass2_mask = 0x10; + int ret; + + switch (pll) { + case ANATOP_SYSTEM_PLL1: + pll_cfg0 = &ana_pll->sys_pll1_cfg0; + pll_cfg1 = &ana_pll->sys_pll1_cfg1; + pll_cfg2 = &ana_pll->sys_pll1_cfg2; + /* 800MHz */ + val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) | + SSCG_PLL_FEEDBACK_DIV_F2_VAL(3); + val_cfg1 = 0; + val_cfg0 = SSCG_PLL_CLKE_MASK | SSCG_PLL_DIV2_CLKE_MASK | + SSCG_PLL_DIV3_CLKE_MASK | SSCG_PLL_DIV4_CLKE_MASK | + SSCG_PLL_DIV5_CLKE_MASK | SSCG_PLL_DIV6_CLKE_MASK | + SSCG_PLL_DIV8_CLKE_MASK | SSCG_PLL_DIV10_CLKE_MASK | + SSCG_PLL_DIV20_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK | + SSCG_PLL_REFCLK_SEL_OSC_25M; + break; + case ANATOP_SYSTEM_PLL2: + pll_cfg0 = &ana_pll->sys_pll2_cfg0; + pll_cfg1 = &ana_pll->sys_pll2_cfg1; + pll_cfg2 = &ana_pll->sys_pll2_cfg2; + /* 1000MHz */ + val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) | + SSCG_PLL_FEEDBACK_DIV_F2_VAL(4); + val_cfg1 = 0; + val_cfg0 = SSCG_PLL_CLKE_MASK | SSCG_PLL_DIV2_CLKE_MASK | + SSCG_PLL_DIV3_CLKE_MASK | SSCG_PLL_DIV4_CLKE_MASK | + SSCG_PLL_DIV5_CLKE_MASK | SSCG_PLL_DIV6_CLKE_MASK | + SSCG_PLL_DIV8_CLKE_MASK | SSCG_PLL_DIV10_CLKE_MASK | + SSCG_PLL_DIV20_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK | + SSCG_PLL_REFCLK_SEL_OSC_25M; + break; + case ANATOP_SYSTEM_PLL3: + pll_cfg0 = &ana_pll->sys_pll3_cfg0; + pll_cfg1 = &ana_pll->sys_pll3_cfg1; + pll_cfg2 = &ana_pll->sys_pll3_cfg2; + /* 800MHz */ + val_cfg2 = SSCG_PLL_FEEDBACK_DIV_F1_VAL(3) | + SSCG_PLL_FEEDBACK_DIV_F2_VAL(3); + val_cfg1 = 0; + val_cfg0 = SSCG_PLL_PLL3_CLKE_MASK | SSCG_PLL_LOCK_SEL_MASK | + SSCG_PLL_REFCLK_SEL_OSC_25M; + break; + default: + return -EINVAL; + } + + /*bypass*/ + setbits_le32(pll_cfg0, bypass1_mask | bypass2_mask); + /* set value */ + writel(val_cfg2, pll_cfg2); + writel(val_cfg1, pll_cfg1); + /*unbypass1 and wait 70us */ + writel(val_cfg0 | bypass2_mask, pll_cfg1); + + __udelay(70); + + /* unbypass2 and wait lock */ + writel(val_cfg0, pll_cfg1); + ret = readl_poll_timeout(pll_cfg0, val, val & SSCG_PLL_LOCK_MASK, 1); + if (ret) + printf("%s timeout\n", __func__); + + return ret; +} + +int clock_init(void) +{ + u32 grade; + + clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(0)); + + /* + * 8MQ only supports two grades: consumer and industrial. + * We set ARM clock to 1Ghz for consumer, 800Mhz for industrial + */ + grade = get_cpu_temp_grade(NULL, NULL); + if (!grade) { + frac_pll_init(ANATOP_ARM_PLL, FRAC_PLL_OUT_1000M); + clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV1)); + } else { + frac_pll_init(ANATOP_ARM_PLL, FRAC_PLL_OUT_1600M); + clock_set_target_val(ARM_A53_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1) | + CLK_ROOT_POST_DIV(CLK_ROOT_POST_DIV2)); + } + /* + * According to ANAMIX SPEC + * sys pll1 fixed at 800MHz + * sys pll2 fixed at 1GHz + * Here we only enable the outputs. + */ + setbits_le32(&ana_pll->sys_pll1_cfg0, SSCG_PLL_CLKE_MASK | + SSCG_PLL_DIV2_CLKE_MASK | SSCG_PLL_DIV3_CLKE_MASK | + SSCG_PLL_DIV4_CLKE_MASK | SSCG_PLL_DIV5_CLKE_MASK | + SSCG_PLL_DIV6_CLKE_MASK | SSCG_PLL_DIV8_CLKE_MASK | + SSCG_PLL_DIV10_CLKE_MASK | SSCG_PLL_DIV20_CLKE_MASK); + + setbits_le32(&ana_pll->sys_pll2_cfg0, SSCG_PLL_CLKE_MASK | + SSCG_PLL_DIV2_CLKE_MASK | SSCG_PLL_DIV3_CLKE_MASK | + SSCG_PLL_DIV4_CLKE_MASK | SSCG_PLL_DIV5_CLKE_MASK | + SSCG_PLL_DIV6_CLKE_MASK | SSCG_PLL_DIV8_CLKE_MASK | + SSCG_PLL_DIV10_CLKE_MASK | SSCG_PLL_DIV20_CLKE_MASK); + + clock_set_target_val(NAND_USDHC_BUS_CLK_ROOT, CLK_ROOT_ON | + CLK_ROOT_SOURCE_SEL(1)); + + init_wdog_clk(); + clock_enable(CCGR_TSENSOR, 1); + + return 0; +} +#endif + +/* + * Dump some clockes. + */ +#ifndef CONFIG_SPL_BUILD +int do_mx8m_showclocks(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + u32 freq; + + freq = decode_frac_pll(ARM_PLL_CLK); + printf("ARM_PLL %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_800M_CLK); + printf("SYS_PLL1_800 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_400M_CLK); + printf("SYS_PLL1_400 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_266M_CLK); + printf("SYS_PLL1_266 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_200M_CLK); + printf("SYS_PLL1_200 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_160M_CLK); + printf("SYS_PLL1_160 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_133M_CLK); + printf("SYS_PLL1_133 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_100M_CLK); + printf("SYS_PLL1_100 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_80M_CLK); + printf("SYS_PLL1_80 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL1_40M_CLK); + printf("SYS_PLL1_40 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_1000M_CLK); + printf("SYS_PLL2_1000 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_500M_CLK); + printf("SYS_PLL2_500 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_333M_CLK); + printf("SYS_PLL2_333 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_250M_CLK); + printf("SYS_PLL2_250 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_200M_CLK); + printf("SYS_PLL2_200 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_166M_CLK); + printf("SYS_PLL2_166 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_125M_CLK); + printf("SYS_PLL2_125 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_100M_CLK); + printf("SYS_PLL2_100 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL2_50M_CLK); + printf("SYS_PLL2_50 %8d MHz\n", freq / 1000000); + freq = decode_sscg_pll(SYSTEM_PLL3_CLK); + printf("SYS_PLL3 %8d MHz\n", freq / 1000000); + freq = mxc_get_clock(UART1_CLK_ROOT); + printf("UART1 %8d MHz\n", freq / 1000000); + freq = mxc_get_clock(USDHC1_CLK_ROOT); + printf("USDHC1 %8d MHz\n", freq / 1000000); + freq = mxc_get_clock(QSPI_CLK_ROOT); + printf("QSPI %8d MHz\n", freq / 1000000); + return 0; +} + +U_BOOT_CMD( + clocks, CONFIG_SYS_MAXARGS, 1, do_mx8m_showclocks, + "display clocks", + "" +); +#endif diff --git a/arch/arm/mach-imx/mx8m/clock_slice.c b/arch/arm/mach-imx/mx8m/clock_slice.c new file mode 100644 index 00000000000..e734498b947 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/clock_slice.c @@ -0,0 +1,742 @@ +/* + * Copyright 2017 NXP + * + * Peng Fan <peng.fan@nxp.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/clock.h> +#include <asm/arch/imx-regs.h> +#include <asm/io.h> +#include <errno.h> + +DECLARE_GLOBAL_DATA_PTR; + +static struct ccm_reg *ccm_reg = (struct ccm_reg *)CCM_BASE_ADDR; + +static struct clk_root_map root_array[] = { + {ARM_A53_CLK_ROOT, CORE_CLOCK_SLICE, 0, + {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL3_CLK} + }, + {ARM_M4_CLK_ROOT, CORE_CLOCK_SLICE, 1, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {VPU_A53_CLK_ROOT, CORE_CLOCK_SLICE, 2, + {OSC_25M_CLK, ARM_PLL_CLK, SYSTEM_PLL2_500M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VPU_PLL_CLK} + }, + {GPU_CORE_CLK_ROOT, CORE_CLOCK_SLICE, 3, + {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU_SHADER_CLK_ROOT, CORE_CLOCK_SLICE, 4, + {OSC_25M_CLK, GPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {MAIN_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 0, + {OSC_25M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL1_100M_CLK} + }, + {ENET_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 1, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, SYSTEM_PLL3_CLK} + }, + {NAND_USDHC_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 2, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_133M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL1_CLK} + }, + {VPU_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 3, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, VPU_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_100M_CLK} + }, + {DISPLAY_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 4, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_4} + }, + {DISPLAY_APB_CLK_ROOT, BUS_CLOCK_SLICE, 5, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, + EXT_CLK_1, EXT_CLK_3} + }, + {DISPLAY_RTRM_CLK_ROOT, BUS_CLOCK_SLICE, 6, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + EXT_CLK_2, EXT_CLK_3} + }, + {USB_BUS_CLK_ROOT, BUS_CLOCK_SLICE, 7, + {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {GPU_AXI_CLK_ROOT, BUS_CLOCK_SLICE, 8, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {GPU_AHB_CLK_ROOT, BUS_CLOCK_SLICE, 9, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, GPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_1000M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NOC_CLK_ROOT, BUS_CLOCK_SLICE, 10, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_500M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NOC_APB_CLK_ROOT, BUS_CLOCK_SLICE, 11, + {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_333M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_800M_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {AHB_CLK_ROOT, AHB_CLOCK_SLICE, 0, + {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL1_400M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {IPG_CLK_ROOT, IPG_CLOCK_SLICE, 0, + {} + }, + {AUDIO_AHB_CLK_ROOT, AHB_CLOCK_SLICE, 1, + {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL2_166M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_ESC_RX_CLK_ROOT, AHB_CLOCK_SLICE, 2, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL1_CLK }, + }, + {DRAM_ALT_CLK_ROOT, IP_CLOCK_SLICE, 0, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL1_CLK, SYSTEM_PLL1_266M_CLK} + }, + {DRAM_APB_CLK_ROOT, IP_CLOCK_SLICE, 1, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {VPU_G1_CLK_ROOT, IP_CLOCK_SLICE, 2, + {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} + }, + {VPU_G2_CLK_ROOT, IP_CLOCK_SLICE, 3, + {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_100M_CLK, + SYSTEM_PLL2_125M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK} + }, + {DISPLAY_DTRC_CLK_ROOT, IP_CLOCK_SLICE, 4, + {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} + }, + {DISPLAY_DC8000_CLK_ROOT, IP_CLOCK_SLICE, 5, + {OSC_25M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK} + }, + {PCIE1_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 6, + {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} + }, + {PCIE1_PHY_CLK_ROOT, IP_CLOCK_SLICE, 7, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, + SYSTEM_PLL1_400M_CLK} + }, + {PCIE1_AUX_CLK_ROOT, IP_CLOCK_SLICE, 8, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} + }, + {DC_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 9, + {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {LCDIF_PIXEL_CLK_ROOT, IP_CLOCK_SLICE, 10, + {OSC_25M_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK, + AUDIO_PLL1_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {SAI1_CLK_ROOT, IP_CLOCK_SLICE, 11, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2} + }, + {SAI2_CLK_ROOT, IP_CLOCK_SLICE, 12, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI3_CLK_ROOT, IP_CLOCK_SLICE, 13, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SAI4_CLK_ROOT, IP_CLOCK_SLICE, 14, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_1, EXT_CLK_2} + }, + {SAI5_CLK_ROOT, IP_CLOCK_SLICE, 15, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SAI6_CLK_ROOT, IP_CLOCK_SLICE, 16, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {SPDIF1_CLK_ROOT, IP_CLOCK_SLICE, 17, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_2, EXT_CLK_3} + }, + {SPDIF2_CLK_ROOT, IP_CLOCK_SLICE, 18, + {OSC_25M_CLK, AUDIO_PLL1_CLK, AUDIO_PLL2_CLK, + VIDEO_PLL_CLK, SYSTEM_PLL1_133M_CLK, + OSC_27M_CLK, EXT_CLK_3, EXT_CLK_4} + }, + {ENET_REF_CLK_ROOT, IP_CLOCK_SLICE, 19, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, EXT_CLK_4} + }, + {ENET_TIMER_CLK_ROOT, IP_CLOCK_SLICE, 20, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, AUDIO_PLL1_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, EXT_CLK_4, + VIDEO_PLL_CLK} + }, + {ENET_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 21, + {OSC_25M_CLK, SYSTEM_PLL2_50M_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_500M_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, AUDIO_PLL2_CLK} + }, + {NAND_CLK_ROOT, IP_CLOCK_SLICE, 22, + {OSC_25M_CLK, SYSTEM_PLL2_500M_CLK, AUDIO_PLL1_CLK, + SYSTEM_PLL1_400M_CLK, AUDIO_PLL2_CLK, SYSTEM_PLL3_CLK, + SYSTEM_PLL2_250M_CLK, VIDEO_PLL_CLK} + }, + {QSPI_CLK_ROOT, IP_CLOCK_SLICE, 23, + {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC1_CLK_ROOT, IP_CLOCK_SLICE, 24, + {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} + }, + {USDHC2_CLK_ROOT, IP_CLOCK_SLICE, 25, + {OSC_25M_CLK, SYSTEM_PLL1_400M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL3_CLK, SYSTEM_PLL1_100M_CLK} + }, + {I2C1_CLK_ROOT, IP_CLOCK_SLICE, 26, + {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C2_CLK_ROOT, IP_CLOCK_SLICE, 27, + {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C3_CLK_ROOT, IP_CLOCK_SLICE, 28, + {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {I2C4_CLK_ROOT, IP_CLOCK_SLICE, 29, + {OSC_25M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL1_CLK, VIDEO_PLL_CLK, + AUDIO_PLL2_CLK, SYSTEM_PLL1_133M_CLK} + }, + {UART1_CLK_ROOT, IP_CLOCK_SLICE, 30, + {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {UART2_CLK_ROOT, IP_CLOCK_SLICE, 31, + {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {UART3_CLK_ROOT, IP_CLOCK_SLICE, 32, + {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {UART4_CLK_ROOT, IP_CLOCK_SLICE, 33, + {OSC_25M_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL3_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {USB_CORE_REF_CLK_ROOT, IP_CLOCK_SLICE, 34, + {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {USB_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 35, + {OSC_25M_CLK, SYSTEM_PLL1_100M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_200M_CLK, + EXT_CLK_2, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {GIC_CLK_ROOT, IP_CLOCK_SLICE, 36, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_800M_CLK, + EXT_CLK_2, EXT_CLK_4, AUDIO_PLL2_CLK} + }, + {ECSPI1_CLK_ROOT, IP_CLOCK_SLICE, 37, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {ECSPI2_CLK_ROOT, IP_CLOCK_SLICE, 38, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {PWM1_CLK_ROOT, IP_CLOCK_SLICE, 39, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM2_CLK_ROOT, IP_CLOCK_SLICE, 40, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM3_CLK_ROOT, IP_CLOCK_SLICE, 41, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {PWM4_CLK_ROOT, IP_CLOCK_SLICE, 42, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_160M_CLK, + SYSTEM_PLL1_40M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_1, + SYSTEM_PLL1_80M_CLK, VIDEO_PLL_CLK} + }, + {GPT1_CLK_ROOT, IP_CLOCK_SLICE, 43, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT2_CLK_ROOT, IP_CLOCK_SLICE, 44, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT3_CLK_ROOT, IP_CLOCK_SLICE, 45, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {GPT4_CLK_ROOT, IP_CLOCK_SLICE, 46, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_1} + }, + {GPT5_CLK_ROOT, IP_CLOCK_SLICE, 47, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_2} + }, + {GPT6_CLK_ROOT, IP_CLOCK_SLICE, 48, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL1_40M_CLK, VIDEO_PLL_CLK, + SYSTEM_PLL1_80M_CLK, AUDIO_PLL1_CLK, EXT_CLK_3} + }, + {TRACE_CLK_ROOT, IP_CLOCK_SLICE, 49, + {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, + VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_1, EXT_CLK_3} + }, + {WDOG_CLK_ROOT, IP_CLOCK_SLICE, 50, + {OSC_25M_CLK, SYSTEM_PLL1_133M_CLK, SYSTEM_PLL1_160M_CLK, + VPU_PLL_CLK, SYSTEM_PLL2_125M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL1_80M_CLK, SYSTEM_PLL2_166M_CLK} + }, + {WRCLK_CLK_ROOT, IP_CLOCK_SLICE, 51, + {OSC_25M_CLK, SYSTEM_PLL1_40M_CLK, VPU_PLL_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_500M_CLK, SYSTEM_PLL1_100M_CLK} + }, + {IPP_DO_CLKO1, IP_CLOCK_SLICE, 52, + {OSC_25M_CLK, SYSTEM_PLL1_800M_CLK, OSC_27M_CLK, + SYSTEM_PLL1_200M_CLK, AUDIO_PLL2_CLK, + SYSTEM_PLL2_500M_CLK, VPU_PLL_CLK, SYSTEM_PLL1_80M_CLK} + }, + {IPP_DO_CLKO2, IP_CLOCK_SLICE, 53, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_400M_CLK, + SYSTEM_PLL2_166M_CLK, SYSTEM_PLL3_CLK, + AUDIO_PLL1_CLK, VIDEO_PLL_CLK, OSC_32K_CLK} + }, + {MIPI_DSI_CORE_CLK_ROOT, IP_CLOCK_SLICE, 54, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 55, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_DSI_DBI_CLK_ROOT, IP_CLOCK_SLICE, 56, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {OLD_MIPI_DSI_ESC_CLK_ROOT, IP_CLOCK_SLICE, 57, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {MIPI_CSI1_CORE_CLK_ROOT, IP_CLOCK_SLICE, 58, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI1_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 59, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI1_ESC_CLK_ROOT, IP_CLOCK_SLICE, 60, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {MIPI_CSI2_CORE_CLK_ROOT, IP_CLOCK_SLICE, 61, + {OSC_25M_CLK, SYSTEM_PLL1_266M_CLK, SYSTEM_PLL2_250M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_PHY_REF_CLK_ROOT, IP_CLOCK_SLICE, 62, + {OSC_25M_CLK, SYSTEM_PLL2_125M_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + EXT_CLK_2, AUDIO_PLL2_CLK, VIDEO_PLL_CLK} + }, + {MIPI_CSI2_ESC_CLK_ROOT, IP_CLOCK_SLICE, 63, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK} + }, + {PCIE2_CTRL_CLK_ROOT, IP_CLOCK_SLICE, 64, + {OSC_25M_CLK, SYSTEM_PLL2_250M_CLK, SYSTEM_PLL2_200M_CLK, + SYSTEM_PLL1_266M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_500M_CLK, SYSTEM_PLL2_333M_CLK, SYSTEM_PLL3_CLK} + }, + {PCIE2_PHY_CLK_ROOT, IP_CLOCK_SLICE, 65, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL2_500M_CLK, + EXT_CLK_1, EXT_CLK_2, EXT_CLK_3, + EXT_CLK_4, SYSTEM_PLL1_400M_CLK} + }, + {PCIE2_AUX_CLK_ROOT, IP_CLOCK_SLICE, 66, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL2_50M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_100M_CLK, + SYSTEM_PLL1_80M_CLK, SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_200M_CLK} + }, + {ECSPI3_CLK_ROOT, IP_CLOCK_SLICE, 67, + {OSC_25M_CLK, SYSTEM_PLL2_200M_CLK, SYSTEM_PLL1_40M_CLK, + SYSTEM_PLL1_160M_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL3_CLK, SYSTEM_PLL2_250M_CLK, AUDIO_PLL2_CLK} + }, + {OLD_MIPI_DSI_ESC_RX_ROOT, IP_CLOCK_SLICE, 68, + {OSC_25M_CLK, SYSTEM_PLL2_100M_CLK, SYSTEM_PLL1_80M_CLK, + SYSTEM_PLL1_800M_CLK, SYSTEM_PLL2_1000M_CLK, + SYSTEM_PLL3_CLK, EXT_CLK_3, AUDIO_PLL2_CLK}, + }, + {DISPLAY_HDMI_CLK_ROOT, IP_CLOCK_SLICE, 69, + {OSC_25M_CLK, SYSTEM_PLL1_200M_CLK, SYSTEM_PLL2_200M_CLK, + VPU_PLL_CLK, SYSTEM_PLL1_800M_CLK, + SYSTEM_PLL2_1000M_CLK, SYSTEM_PLL3_CLK, EXT_CLK_4} + }, + {DRAM_SEL_CFG, DRAM_SEL_CLOCK_SLICE, 0, + {DRAM_PLL1_CLK} + }, + {CORE_SEL_CFG, CORE_SEL_CLOCK_SLICE, 0, + {DRAM_PLL1_CLK} + }, +}; + +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 void __iomem *get_clk_root_target(enum clk_slice_type slice_type, + u32 slice_index) +{ + void __iomem *clk_root_target; + + switch (slice_type) { + case CORE_CLOCK_SLICE: + clk_root_target = + (void __iomem *)&ccm_reg->core_root[slice_index]; + break; + case BUS_CLOCK_SLICE: + clk_root_target = + (void __iomem *)&ccm_reg->bus_root[slice_index]; + break; + case IP_CLOCK_SLICE: + clk_root_target = + (void __iomem *)&ccm_reg->ip_root[slice_index]; + break; + case AHB_CLOCK_SLICE: + clk_root_target = + (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2]; + break; + case IPG_CLOCK_SLICE: + clk_root_target = + (void __iomem *)&ccm_reg->ahb_ipg_root[slice_index * 2 + 1]; + break; + case CORE_SEL_CLOCK_SLICE: + clk_root_target = (void __iomem *)&ccm_reg->core_sel; + break; + case DRAM_SEL_CLOCK_SLICE: + clk_root_target = (void __iomem *)&ccm_reg->dram_sel; + break; + default: + return NULL; + } + + return clk_root_target; +} + +int clock_get_target_val(enum clk_root_index clock_id, u32 *val) +{ + int root_entry; + struct clk_root_map *p; + void __iomem *clk_root_target; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); + if (!clk_root_target) + return -EINVAL; + + *val = readl(clk_root_target); + + return 0; +} + +int clock_set_target_val(enum clk_root_index clock_id, u32 val) +{ + int root_entry; + struct clk_root_map *p; + void __iomem *clk_root_target; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); + if (!clk_root_target) + return -EINVAL; + + writel(val, clk_root_target); + + return 0; +} + +int clock_root_enabled(enum clk_root_index clock_id) +{ + void __iomem *clk_root_target; + u32 slice_index, slice_type; + u32 val; + int root_entry; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + slice_type = root_array[root_entry].slice_type; + slice_index = root_array[root_entry].slice_index; + + if ((slice_type == IPG_CLOCK_SLICE) || + (slice_type == DRAM_SEL_CLOCK_SLICE) || + (slice_type == CORE_SEL_CLOCK_SLICE)) { + /* + * Not supported, from CCM doc + * TODO + */ + return 0; + } + + clk_root_target = get_clk_root_target(slice_type, slice_index); + if (!clk_root_target) + return -EINVAL; + + val = readl(clk_root_target); + + return (val & CLK_ROOT_ON) ? 1 : 0; +} + +/* CCGR CLK gate operation */ +int clock_enable(enum clk_ccgr_index index, bool enable) +{ + void __iomem *ccgr; + + if (index >= CCGR_MAX) + return -EINVAL; + + if (enable) + ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_set; + else + ccgr = (void __iomem *)&ccm_reg->ccgr_array[index].ccgr_clr; + + writel(CCGR_CLK_ON_MASK, ccgr); + + 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; + void __iomem *clk_root_target; + + 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->slice_type == CORE_CLOCK_SLICE) || + (p->slice_type == IPG_CLOCK_SLICE) || + (p->slice_type == CORE_SEL_CLOCK_SLICE) || + (p->slice_type == DRAM_SEL_CLOCK_SLICE)) { + *pre_div = 0; + return 0; + } + + clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); + if (!clk_root_target) + return -EINVAL; + + val = readl(clk_root_target); + val &= CLK_ROOT_PRE_DIV_MASK; + val >>= CLK_ROOT_PRE_DIV_SHIFT; + + *pre_div = val; + + return 0; +} + +int clock_get_postdiv(enum clk_root_index clock_id, + enum root_post_div *post_div) +{ + u32 val, mask; + int root_entry; + struct clk_root_map *p; + void __iomem *clk_root_target; + + 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->slice_type == CORE_SEL_CLOCK_SLICE) || + (p->slice_type == DRAM_SEL_CLOCK_SLICE)) { + *post_div = 0; + return 0; + } + + clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); + if (!clk_root_target) + return -EINVAL; + + if (p->slice_type == IPG_CLOCK_SLICE) + mask = CLK_ROOT_IPG_POST_DIV_MASK; + else if (p->slice_type == CORE_CLOCK_SLICE) + mask = CLK_ROOT_CORE_POST_DIV_MASK; + else + mask = CLK_ROOT_POST_DIV_MASK; + + val = readl(clk_root_target); + val &= mask; + val >>= CLK_ROOT_POST_DIV_SHIFT; + + *post_div = val; + + return 0; +} + +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; + void __iomem *clk_root_target; + + if (clock_id >= CLK_ROOT_MAX) + return -EINVAL; + + root_entry = select(clock_id); + if (root_entry < 0) + return -EINVAL; + + p = &root_array[root_entry]; + + clk_root_target = get_clk_root_target(p->slice_type, p->slice_index); + if (!clk_root_target) + return -EINVAL; + + val = readl(clk_root_target); + val &= CLK_ROOT_SRC_MUX_MASK; + val >>= CLK_ROOT_SRC_MUX_SHIFT; + + *p_clock_src = p->src_mux[val]; + + return 0; +} diff --git a/arch/arm/mach-imx/mx8m/lowlevel_init.S b/arch/arm/mach-imx/mx8m/lowlevel_init.S new file mode 100644 index 00000000000..d388f3ba956 --- /dev/null +++ b/arch/arm/mach-imx/mx8m/lowlevel_init.S @@ -0,0 +1,63 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <config.h> + +.align 8 +.global rom_pointer +rom_pointer: + .space 256 + +/* + * Routine: save_boot_params (called after reset from start.S) + */ + +.global save_boot_params +save_boot_params: + /* The firmware provided ATAG/FDT address can be found in r2/x0 */ + adr x0, rom_pointer + stp x1, x2, [x0], #16 + stp x3, x4, [x0], #16 + stp x5, x6, [x0], #16 + stp x7, x8, [x0], #16 + stp x9, x10, [x0], #16 + stp x11, x12, [x0], #16 + stp x13, x14, [x0], #16 + stp x15, x16, [x0], #16 + stp x17, x18, [x0], #16 + stp x19, x20, [x0], #16 + stp x21, x22, [x0], #16 + stp x23, x24, [x0], #16 + stp x25, x26, [x0], #16 + stp x27, x28, [x0], #16 + stp x29, x30, [x0], #16 + mov x30, sp + str x30, [x0], #8 + + /* Returns */ + b save_boot_params_ret + +.global restore_boot_params +restore_boot_params: + adr x0, rom_pointer + ldp x1, x2, [x0], #16 + ldp x3, x4, [x0], #16 + ldp x5, x6, [x0], #16 + ldp x7, x8, [x0], #16 + ldp x9, x10, [x0], #16 + ldp x11, x12, [x0], #16 + ldp x13, x14, [x0], #16 + ldp x15, x16, [x0], #16 + ldp x17, x18, [x0], #16 + ldp x19, x20, [x0], #16 + ldp x21, x22, [x0], #16 + ldp x23, x24, [x0], #16 + ldp x25, x26, [x0], #16 + ldp x27, x28, [x0], #16 + ldp x29, x30, [x0], #16 + ldr x0, [x0] + mov sp, x0 + ret diff --git a/arch/arm/mach-imx/mx8m/soc.c b/arch/arm/mach-imx/mx8m/soc.c new file mode 100644 index 00000000000..fe6c19c787d --- /dev/null +++ b/arch/arm/mach-imx/mx8m/soc.c @@ -0,0 +1,227 @@ +/* + * Copyright 2017 NXP + * + * Peng Fan <peng.fan@nxp.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/imx-regs.h> +#include <asm/io.h> +#include <asm/arch/clock.h> +#include <asm/arch/sys_proto.h> +#include <asm/mach-imx/hab.h> +#include <asm/mach-imx/boot_mode.h> +#include <asm/mach-imx/syscounter.h> +#include <asm/armv8/mmu.h> +#include <errno.h> +#include <fdt_support.h> +#include <fsl_wdog.h> +#include <imx_sip.h> + +DECLARE_GLOBAL_DATA_PTR; + +#if defined(CONFIG_SECURE_BOOT) +struct imx_sec_config_fuse_t const imx_sec_config_fuse = { + .bank = 1, + .word = 3, +}; +#endif + +int timer_init(void) +{ +#ifdef CONFIG_SPL_BUILD + struct sctr_regs *sctr = (struct sctr_regs *)SYSCNT_CTRL_BASE_ADDR; + unsigned long freq = readl(&sctr->cntfid0); + + /* Update with accurate clock frequency */ + asm volatile("msr cntfrq_el0, %0" : : "r" (freq) : "memory"); + + clrsetbits_le32(&sctr->cntcr, SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1, + SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG); +#endif + + gd->arch.tbl = 0; + gd->arch.tbu = 0; + + return 0; +} + +void enable_tzc380(void) +{ + struct iomuxc_gpr_base_regs *gpr = + (struct iomuxc_gpr_base_regs *)IOMUXC_GPR_BASE_ADDR; + + /* Enable TZASC and lock setting */ + setbits_le32(&gpr->gpr[10], GPR_TZASC_EN); + setbits_le32(&gpr->gpr[10], GPR_TZASC_EN_LOCK); +} + +void set_wdog_reset(struct wdog_regs *wdog) +{ + /* + * Output WDOG_B signal to reset external pmic or POR_B decided by + * the board design. Without external reset, the peripherals/DDR/ + * PMIC are not reset, that may cause system working abnormal. + * WDZST bit is write-once only bit. Align this bit in kernel, + * otherwise kernel code will have no chance to set this bit. + */ + setbits_le16(&wdog->wcr, WDOG_WDT_MASK | WDOG_WDZST_MASK); +} + +static struct mm_region imx8m_mem_map[] = { + { + /* ROM */ + .virt = 0x0UL, + .phys = 0x0UL, + .size = 0x100000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE + }, { + /* OCRAM */ + .virt = 0x900000UL, + .phys = 0x900000UL, + .size = 0x200000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE + }, { + /* AIPS */ + .virt = 0xB00000UL, + .phys = 0xB00000UL, + .size = 0x3f500000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) | + PTE_BLOCK_NON_SHARE | + PTE_BLOCK_PXN | PTE_BLOCK_UXN + }, { + /* DRAM1 */ + .virt = 0x40000000UL, + .phys = 0x40000000UL, + .size = 0xC0000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE + }, { + /* DRAM2 */ + .virt = 0x100000000UL, + .phys = 0x100000000UL, + .size = 0x040000000UL, + .attrs = PTE_BLOCK_MEMTYPE(MT_NORMAL) | + PTE_BLOCK_OUTER_SHARE + }, { + /* List terminator */ + 0, + } +}; + +struct mm_region *mem_map = imx8m_mem_map; + +u32 get_cpu_rev(void) +{ + struct anamix_pll *ana_pll = (struct anamix_pll *)ANATOP_BASE_ADDR; + u32 reg = readl(&ana_pll->digprog); + u32 type = (reg >> 16) & 0xff; + u32 rom_version; + + reg &= 0xff; + + if (reg == CHIP_REV_1_0) { + /* + * For B0 chip, the DIGPROG is not updated, still TO1.0. + * we have to check ROM version further + */ + rom_version = readl((void __iomem *)ROM_VERSION_A0); + if (rom_version != CHIP_REV_1_0) { + rom_version = readl((void __iomem *)ROM_VERSION_B0); + if (rom_version >= CHIP_REV_2_0) + reg = CHIP_REV_2_0; + } + } + + return (type << 12) | reg; +} + +static void imx_set_wdog_powerdown(bool enable) +{ + struct wdog_regs *wdog1 = (struct wdog_regs *)WDOG1_BASE_ADDR; + struct wdog_regs *wdog2 = (struct wdog_regs *)WDOG2_BASE_ADDR; + struct wdog_regs *wdog3 = (struct wdog_regs *)WDOG3_BASE_ADDR; + + /* Write to the PDE (Power Down Enable) bit */ + writew(enable, &wdog1->wmcr); + writew(enable, &wdog2->wmcr); + writew(enable, &wdog3->wmcr); +} + +int arch_cpu_init(void) +{ + /* + * Init timer at very early state, because sscg pll setting + * will use it + */ + timer_init(); + + if (IS_ENABLED(CONFIG_SPL_BUILD)) { + clock_init(); + imx_set_wdog_powerdown(false); + } + + return 0; +} + +bool is_usb_boot(void) +{ + return get_boot_device() == USB_BOOT; +} + +#ifdef CONFIG_OF_SYSTEM_SETUP +int ft_system_setup(void *blob, bd_t *bd) +{ + int i = 0; + int rc; + int nodeoff; + + /* Disable the CPU idle for A0 chip since the HW does not support it */ + if (is_soc_rev(CHIP_REV_1_0)) { + static const char * const nodes_path[] = { + "/cpus/cpu@0", + "/cpus/cpu@1", + "/cpus/cpu@2", + "/cpus/cpu@3", + }; + + for (i = 0; i < ARRAY_SIZE(nodes_path); i++) { + nodeoff = fdt_path_offset(blob, nodes_path[i]); + if (nodeoff < 0) + continue; /* Not found, skip it */ + + printf("Found %s node\n", nodes_path[i]); + + rc = fdt_delprop(blob, nodeoff, "cpu-idle-states"); + if (rc) { + printf("Unable to update property %s:%s, err=%s\n", + nodes_path[i], "status", fdt_strerror(rc)); + return rc; + } + + printf("Remove %s:%s\n", nodes_path[i], + "cpu-idle-states"); + } + } + + return 0; +} +#endif + +void reset_cpu(ulong addr) +{ + struct watchdog_regs *wdog = (struct watchdog_regs *)WDOG1_BASE_ADDR; + + /* Clear WDA to trigger WDOG_B immediately */ + writew((WCR_WDE | WCR_SRS), &wdog->wcr); + + while (1) { + /* + * spin for .5 seconds before reset + */ + } +} diff --git a/arch/arm/mach-imx/sip.c b/arch/arm/mach-imx/sip.c new file mode 100644 index 00000000000..b724330d358 --- /dev/null +++ b/arch/arm/mach-imx/sip.c @@ -0,0 +1,23 @@ +/* + * Copyright 2017 NXP + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <asm/arch/sys_proto.h> + +unsigned long call_imx_sip(unsigned long id, unsigned long reg0, + unsigned long reg1, unsigned long reg2) +{ + struct pt_regs regs; + + regs.regs[0] = id; + regs.regs[1] = reg0; + regs.regs[2] = reg1; + regs.regs[3] = reg2; + + smc_call(®s); + + return regs.regs[0]; +} diff --git a/arch/arm/mach-imx/spl.c b/arch/arm/mach-imx/spl.c index 6c16872f596..b2521b2101c 100644 --- a/arch/arm/mach-imx/spl.c +++ b/arch/arm/mach-imx/spl.c @@ -97,8 +97,8 @@ u32 spl_boot_device(void) return BOOT_DEVICE_NONE; } -#elif defined(CONFIG_MX7) -/* Translate iMX7 boot device to the SPL boot device enumeration */ +#elif defined(CONFIG_MX7) || defined(CONFIG_MX8M) +/* Translate iMX7/MX8M boot device to the SPL boot device enumeration */ u32 spl_boot_device(void) { enum boot_device boot_device_spl = get_boot_device(); @@ -115,11 +115,13 @@ u32 spl_boot_device(void) return BOOT_DEVICE_NAND; case SPI_NOR_BOOT: return BOOT_DEVICE_SPI; + case USB_BOOT: + return BOOT_DEVICE_USB; default: return BOOT_DEVICE_NONE; } } -#endif /* CONFIG_MX6 || CONFIG_MX7 */ +#endif /* CONFIG_MX6 || CONFIG_MX7 || CONFIG_MX8M */ #ifdef CONFIG_SPL_USB_GADGET_SUPPORT int g_dnl_bind_fixup(struct usb_device_descriptor *dev, const char *name) |