summaryrefslogtreecommitdiff
path: root/arch/arm/cpu
diff options
context:
space:
mode:
authorAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-09-05 11:15:26 +0200
committerAlbert ARIBAUD <albert.u.boot@aribaud.net>2013-09-05 11:15:26 +0200
commit19d829fa60fc4e6df514a046142faaaf9fc8185d (patch)
tree295c75b0d9f3c7180f23ec131442286cf91db5b1 /arch/arm/cpu
parente62d5fb0da76ef168e90cae9bbbda80349aaf137 (diff)
parent8467faef7fce8c5faad7224b7737a58e16c52186 (diff)
downloadu-boot-imx-19d829fa60fc4e6df514a046142faaaf9fc8185d.zip
u-boot-imx-19d829fa60fc4e6df514a046142faaaf9fc8185d.tar.gz
u-boot-imx-19d829fa60fc4e6df514a046142faaaf9fc8185d.tar.bz2
Merge branch 'u-boot-imx/master' into 'u-boot-arm/master'
Conflicts: drivers/serial/serial.c The conflict above was a trivial case of adding one init function in each branch, and manually resolved in merge.
Diffstat (limited to 'arch/arm/cpu')
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg6
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg8
-rw-r--r--arch/arm/cpu/arm926ejs/mxs/spl_power_init.c9
-rw-r--r--arch/arm/cpu/armv7/mx6/Makefile7
-rw-r--r--arch/arm/cpu/armv7/mx6/hab.c104
-rw-r--r--arch/arm/cpu/armv7/mx6/soc.c28
6 files changed, 153 insertions, 9 deletions
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
new file mode 100644
index 0000000..8118767
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx23.cfg
@@ -0,0 +1,6 @@
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x0 spl/u-boot-spl.bin
+ CALL 0x14 0x0
+ LOAD 0x40000100 u-boot.bin
+ CALL 0x40000100 0x0
diff --git a/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
new file mode 100644
index 0000000..ea772f0
--- /dev/null
+++ b/arch/arm/cpu/arm926ejs/mxs/mxsimage.mx28.cfg
@@ -0,0 +1,8 @@
+SECTION 0x0 BOOTABLE
+ TAG LAST
+ LOAD 0x0 spl/u-boot-spl.bin
+ LOAD IVT 0x8000 0x14
+ CALL HAB 0x8000 0x0
+ LOAD 0x40000100 u-boot.bin
+ LOAD IVT 0x8000 0x40000100
+ CALL HAB 0x8000 0x0
diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
index e3b6cd9..f357959 100644
--- a/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
+++ b/arch/arm/cpu/arm926ejs/mxs/spl_power_init.c
@@ -36,7 +36,7 @@ static void mxs_power_clock2pll(void)
CLKCTRL_CLKSEQ_BYPASS_CPU);
}
-static void mxs_power_clear_auto_restart(void)
+static void mxs_power_set_auto_restart(void)
{
struct mxs_rtc_regs *rtc_regs =
(struct mxs_rtc_regs *)MXS_RTC_BASE;
@@ -49,10 +49,7 @@ static void mxs_power_clear_auto_restart(void)
while (readl(&rtc_regs->hw_rtc_ctrl) & RTC_CTRL_CLKGATE)
;
- /*
- * Due to the hardware design bug of mx28 EVK-A
- * we need to set the AUTO_RESTART bit.
- */
+ /* Do nothing if flag already set */
if (readl(&rtc_regs->hw_rtc_persistent0) & RTC_PERSISTENT0_AUTO_RESTART)
return;
@@ -911,7 +908,7 @@ void mxs_power_init(void)
mxs_ungate_power();
mxs_power_clock2xtal();
- mxs_power_clear_auto_restart();
+ mxs_power_set_auto_restart();
mxs_power_set_linreg();
mxs_power_setup_5v_detect();
diff --git a/arch/arm/cpu/armv7/mx6/Makefile b/arch/arm/cpu/armv7/mx6/Makefile
index c5e9858..6d73617 100644
--- a/arch/arm/cpu/armv7/mx6/Makefile
+++ b/arch/arm/cpu/armv7/mx6/Makefile
@@ -11,10 +11,11 @@ include $(TOPDIR)/config.mk
LIB = $(obj)lib$(SOC).o
-COBJS = soc.o clock.o
+COBJS-y = soc.o clock.o
+COBJS-$(CONFIG_SECURE_BOOT) += hab.o
-SRCS := $(SOBJS:.o=.S) $(COBJS:.o=.c)
-OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS))
+SRCS := $(SOBJS:.o=.S) $(COBJS-y:.o=.c)
+OBJS := $(addprefix $(obj),$(SOBJS) $(COBJS-y))
all: $(obj).depend $(LIB)
diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c
new file mode 100644
index 0000000..5187775
--- /dev/null
+++ b/arch/arm/cpu/armv7/mx6/hab.c
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2010-2013 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/arch/hab.h>
+
+/* -------- start of HAB API updates ------------*/
+#define hab_rvt_report_event ((hab_rvt_report_event_t *)HAB_RVT_REPORT_EVENT)
+#define hab_rvt_report_status ((hab_rvt_report_status_t *)HAB_RVT_REPORT_STATUS)
+#define hab_rvt_authenticate_image \
+ ((hab_rvt_authenticate_image_t *)HAB_RVT_AUTHENTICATE_IMAGE)
+#define hab_rvt_entry ((hab_rvt_entry_t *)HAB_RVT_ENTRY)
+#define hab_rvt_exit ((hab_rvt_exit_t *)HAB_RVT_EXIT)
+#define hab_rvt_clock_init HAB_RVT_CLOCK_INIT
+
+bool is_hab_enabled(void)
+{
+ struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR;
+ struct fuse_bank *bank = &ocotp->bank[0];
+ struct fuse_bank0_regs *fuse =
+ (struct fuse_bank0_regs *)bank->fuse_regs;
+ uint32_t reg = readl(&fuse->cfg5);
+
+ return (reg & 0x2) == 0x2;
+}
+
+void display_event(uint8_t *event_data, size_t bytes)
+{
+ uint32_t i;
+
+ if (!(event_data && bytes > 0))
+ return;
+
+ for (i = 0; i < bytes; i++) {
+ if (i == 0)
+ printf("\t0x%02x", event_data[i]);
+ else if ((i % 8) == 0)
+ printf("\n\t0x%02x", event_data[i]);
+ else
+ printf(" 0x%02x", event_data[i]);
+ }
+}
+
+int get_hab_status(void)
+{
+ uint32_t index = 0; /* Loop index */
+ uint8_t event_data[128]; /* Event data buffer */
+ size_t bytes = sizeof(event_data); /* Event size in bytes */
+ enum hab_config config = 0;
+ enum hab_state state = 0;
+
+ if (is_hab_enabled())
+ puts("\nSecure boot enabled\n");
+ else
+ puts("\nSecure boot disabled\n");
+
+ /* Check HAB status */
+ if (hab_rvt_report_status(&config, &state) != HAB_SUCCESS) {
+ printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+ config, state);
+
+ /* Display HAB Error events */
+ while (hab_rvt_report_event(HAB_FAILURE, index, event_data,
+ &bytes) == HAB_SUCCESS) {
+ puts("\n");
+ printf("--------- HAB Event %d -----------------\n",
+ index + 1);
+ puts("event data:\n");
+ display_event(event_data, bytes);
+ puts("\n");
+ bytes = sizeof(event_data);
+ index++;
+ }
+ }
+ /* Display message if no HAB events are found */
+ else {
+ printf("\nHAB Configuration: 0x%02x, HAB State: 0x%02x\n",
+ config, state);
+ puts("No HAB Events Found!\n\n");
+ }
+ return 0;
+}
+
+int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
+{
+ if ((argc != 1)) {
+ cmd_usage(cmdtp);
+ return 1;
+ }
+
+ get_hab_status();
+
+ return 0;
+}
+
+U_BOOT_CMD(
+ hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status,
+ "display HAB status",
+ ""
+ );
diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c
index 8150bff..a390296 100644
--- a/arch/arm/cpu/armv7/mx6/soc.c
+++ b/arch/arm/cpu/armv7/mx6/soc.c
@@ -213,6 +213,34 @@ const struct boot_mode soc_boot_modes[] = {
void s_init(void)
{
+ struct anatop_regs *anatop = (struct anatop_regs *)ANATOP_BASE_ADDR;
+ int is_6q = is_cpu_type(MXC_CPU_MX6Q);
+ u32 mask480;
+ u32 mask528;
+
+ /* Due to hardware limitation, on MX6Q we need to gate/ungate all PFDs
+ * to make sure PFD is working right, otherwise, PFDs may
+ * not output clock after reset, MX6DL and MX6SL have added 396M pfd
+ * workaround in ROM code, as bus clock need it
+ */
+
+ mask480 = ANATOP_PFD_CLKGATE_MASK(0) |
+ ANATOP_PFD_CLKGATE_MASK(1) |
+ ANATOP_PFD_CLKGATE_MASK(2) |
+ ANATOP_PFD_CLKGATE_MASK(3);
+ mask528 = ANATOP_PFD_CLKGATE_MASK(0) |
+ ANATOP_PFD_CLKGATE_MASK(1) |
+ ANATOP_PFD_CLKGATE_MASK(3);
+
+ /*
+ * Don't reset PFD2 on DL/S
+ */
+ if (is_6q)
+ mask528 |= ANATOP_PFD_CLKGATE_MASK(2);
+ writel(mask480, &anatop->pfd_480_set);
+ writel(mask528, &anatop->pfd_528_set);
+ writel(mask480, &anatop->pfd_480_clr);
+ writel(mask528, &anatop->pfd_528_clr);
}
#ifdef CONFIG_IMX_HDMI