
Hi Peng,
On 27/12/2016 11:04, Peng Fan wrote:
Implement soc level functions to get cpu rev, reset cause, enable cache, etc. We will disable the wdog and init clocks in s_init at very early u-boot phase.
Since the we are seeking the way to get chip id for mx7ulp, the get_cpu_rev is hard coded to a fixed value. This may change in future.
ok, understood, noted
Reuse some code in imx-common.
Signed-off-by: Peng Fan peng.fan@nxp.com Signed-off-by: Ye Li ye.li@nxp.com Cc: Stefano Babic sbabic@denx.de
V2: Reuse code in imx-common
arch/arm/Makefile | 2 +- arch/arm/cpu/armv7/mx7ulp/Makefile | 2 +- arch/arm/cpu/armv7/mx7ulp/soc.c | 274 +++++++++++++++++++++++++++ arch/arm/imx-common/Makefile | 4 + arch/arm/include/asm/arch-imx/cpu.h | 2 + arch/arm/include/asm/arch-mx7ulp/imx-regs.h | 5 + arch/arm/include/asm/arch-mx7ulp/sys_proto.h | 21 ++ 7 files changed, 308 insertions(+), 2 deletions(-) create mode 100644 arch/arm/cpu/armv7/mx7ulp/soc.c create mode 100644 arch/arm/include/asm/arch-mx7ulp/sys_proto.h
diff --git a/arch/arm/Makefile b/arch/arm/Makefile index ef4f69d..0921a66 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -99,7 +99,7 @@ ifneq (,$(CONFIG_MX23)$(CONFIG_MX28)$(CONFIG_MX35)$(filter $(SOC), mx25 mx27 mx5 libs-y += arch/arm/imx-common/ endif else -ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx31 mx35 mxs vf610)) +ifneq (,$(filter $(SOC), mx25 mx27 mx5 mx6 mx7 mx7ulp mx31 mx35 mxs vf610)) libs-y += arch/arm/imx-common/ endif endif diff --git a/arch/arm/cpu/armv7/mx7ulp/Makefile b/arch/arm/cpu/armv7/mx7ulp/Makefile index 6f37e8c..0248ea8 100644 --- a/arch/arm/cpu/armv7/mx7ulp/Makefile +++ b/arch/arm/cpu/armv7/mx7ulp/Makefile @@ -5,4 +5,4 @@ # #
-obj-y := clock.o iomux.o pcc.o scg.o +obj-y := soc.o clock.o iomux.o pcc.o scg.o diff --git a/arch/arm/cpu/armv7/mx7ulp/soc.c b/arch/arm/cpu/armv7/mx7ulp/soc.c new file mode 100644 index 0000000..d04edc5 --- /dev/null +++ b/arch/arm/cpu/armv7/mx7ulp/soc.c @@ -0,0 +1,274 @@ +/*
- 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>
+static char *get_reset_cause(char *);
+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) +{ +#ifdef CONFIG_MXC_OCOTP
- u8 uid[8];
- u32 val;
- struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
- struct fuse_bank *bank = &ocotp->bank[0];
- struct fuse_bank1_regs *fuse =
(struct fuse_bank1_regs *)bank->fuse_regs;
- val = readl(&fuse->cfg0);
- *uid = val & 0xFF;
- *(uid + 1) = (val & 0xFF00) >> 8;
- val = readl(&fuse->cfg1);
- *(uid + 2) = val & 0xFF;
- *(uid + 3) = (val & 0xFF00) >> 8;
- val = readl(&fuse->cfg2);
- *(uid + 4) = val & 0xFF;
- *(uid + 5) = (val & 0xFF00) >> 8;
- val = readl(&fuse->cfg3);
- *(uid + 6) = val & 0xFF;
- *(uid + 7) = (val & 0xFF00) >> 8;
I think it can be better described here, at least what you want to read for fuse->cfg0..cfg3.
- debug("UID = %02X %02X %02X %02X %02X %02X %02X %02X\r\n",
uid[0], uid[1], uid[2], uid[3], uid[4], uid[5], uid[6], uid[7]);
+#endif
- 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;
+}
+u32 get_imx_reset_cause(void) +{
- return reset_cause;
Why do you stored it ain a static variable ? Is it read just once from registers ?
+}
+#ifdef CONFIG_ENV_IS_IN_MMC +__weak int board_mmc_get_env_dev(int devno) +{
- return CONFIG_SYS_MMC_ENV_DEV;
+}
+int mmc_get_env_dev(void) +{
- int devno = 0;
- u32 bt1_cfg = 0;
- /* If not boot from sd/mmc, use default value */
- if (get_boot_mode() == LOW_POWER_BOOT)
return CONFIG_SYS_MMC_ENV_DEV;
- bt1_cfg = readl(CMC1_RBASE + 0x40);
- devno = (bt1_cfg >> 9) & 0x7;
- return board_mmc_get_env_dev(devno);
+} +#endif diff --git a/arch/arm/imx-common/Makefile b/arch/arm/imx-common/Makefile index 1873185..68ee60f 100644 --- a/arch/arm/imx-common/Makefile +++ b/arch/arm/imx-common/Makefile @@ -31,6 +31,10 @@ obj-$(CONFIG_IMX_RDC) += rdc-sema.o obj-$(CONFIG_IMX_BOOTAUX) += imx_bootaux.o obj-$(CONFIG_SECURE_BOOT) += hab.o endif +ifeq ($(SOC),$(filter $(SOC),mx7ulp)) +obj-y += cache.o +obj-$(CONFIG_SECURE_BOOT) += hab.o +endif ifeq ($(SOC),$(filter $(SOC),vf610)) obj-y += ddrmc-vf610.o endif diff --git a/arch/arm/include/asm/arch-imx/cpu.h b/arch/arm/include/asm/arch-imx/cpu.h index 8bd1421..b052406 100644 --- a/arch/arm/include/asm/arch-imx/cpu.h +++ b/arch/arm/include/asm/arch-imx/cpu.h @@ -25,10 +25,12 @@ #define MXC_CPU_MX6QP 0x69 #define MXC_CPU_MX7S 0x71 /* dummy ID */ #define MXC_CPU_MX7D 0x72 +#define MXC_CPU_MX7ULP 0x81 /* Temporally hard code */
ok
#define MXC_CPU_VF610 0xF6 /* dummy ID */
#define MXC_SOC_MX6 0x60 #define MXC_SOC_MX7 0x70 +#define MXC_SOC_MX7ULP 0x80 /* dummy */
#define CHIP_REV_1_0 0x10 #define CHIP_REV_1_1 0x11 diff --git a/arch/arm/include/asm/arch-mx7ulp/imx-regs.h b/arch/arm/include/asm/arch-mx7ulp/imx-regs.h index 30d0ba4..cdfbe2e 100644 --- a/arch/arm/include/asm/arch-mx7ulp/imx-regs.h +++ b/arch/arm/include/asm/arch-mx7ulp/imx-regs.h @@ -97,6 +97,11 @@ #define CORE_B_ROM_SIZE (SZ_32K + SZ_64K) #define CORE_B_ROM_BASE (0x00000000)
+#define ROMCP_ARB_BASE_ADDR CORE_B_ROM_BASE +#define ROMCP_ARB_END_ADDR CORE_B_ROM_SIZE +#define IRAM_BASE_ADDR OCRAM_0_BASE +#define IRAM_SIZE (SZ_128K + SZ_128K)
Why is it here and not in Patch 2/20 ?
#define IOMUXC_PCR_MUX_ALT0 (0<<8) #define IOMUXC_PCR_MUX_ALT1 (1<<8) #define IOMUXC_PCR_MUX_ALT2 (2<<8) diff --git a/arch/arm/include/asm/arch-mx7ulp/sys_proto.h b/arch/arm/include/asm/arch-mx7ulp/sys_proto.h new file mode 100644 index 0000000..d01748f --- /dev/null +++ b/arch/arm/include/asm/arch-mx7ulp/sys_proto.h @@ -0,0 +1,21 @@ +/*
- Copyright (C) 2016 Freescale Semiconductor, Inc.
- SPDX-License-Identifier: GPL-2.0+
- */
+#ifndef _SYS_PROTO_MX7ULP_H_ +#define _SYS_PROTO_MX7ULP_H_
+#include <asm/imx-common/sys_proto.h>
+#define BT0CFG_LPBOOT_MASK 0x1 +#define BT0CFG_DUALBOOT_MASK 0x2
+enum bt_mode {
- LOW_POWER_BOOT, /* LP_BT = 1 */
- DUAL_BOOT, /* LP_BT = 0, DUAL_BT = 1 */
- SINGLE_BOOT /* LP_BT = 0, DUAL_BT = 0 */
+};
+#endif
Best regards, Stefano Babic