From 93a0ea501e1eca1ae5d7d2624906b656c765e5e8 Mon Sep 17 00:00:00 2001 From: Andrew Ruder <andrew.ruder@elecsyscorp.com> Date: Tue, 12 Aug 2014 09:26:00 -0500 Subject: arm: mx31: use common timer functions This patch moves mx31 to the common timer functions added in commit 8dfafdd - Introduce common timer functions <Rob Herring> The (removed) mx31 timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locks the processor. Rather than patch the specific mx31 issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com> Cc: Marek Vasut <marex@denx.de> Cc: Linus Walleij <linus.walleij@linaro.org> Cc: Wolfgang Denk <wd@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com> Cc: Helmut Raiger <helmut.raiger@hale.at> --- arch/arm/cpu/arm1136/mx31/timer.c | 104 +----------------------------- arch/arm/include/asm/arch-mx31/imx-regs.h | 10 +++ 2 files changed, 12 insertions(+), 102 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/arm1136/mx31/timer.c b/arch/arm/cpu/arm1136/mx31/timer.c index f111242..3a81ce4 100644 --- a/arch/arm/cpu/arm1136/mx31/timer.c +++ b/arch/arm/cpu/arm1136/mx31/timer.c @@ -7,9 +7,6 @@ #include <common.h> #include <asm/arch/imx-regs.h> -#include <asm/arch/clock.h> -#include <div64.h> -#include <watchdog.h> #include <asm/io.h> #define TIMER_BASE 0x53f90000 /* General purpose timer 1 */ @@ -28,57 +25,6 @@ DECLARE_GLOBAL_DATA_PTR; -/* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ - -#ifdef CONFIG_MX31_TIMER_HIGH_PRECISION -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, MXC_CLK32); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - time *= MXC_CLK32; - do_div(time, CONFIG_SYS_HZ); - return time; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * MXC_CLK32 + 999999; - do_div(us, 1000000); - return us; -} -#else -/* ~2% error */ -#define TICK_PER_TIME ((MXC_CLK32 + CONFIG_SYS_HZ / 2) / CONFIG_SYS_HZ) -#define US_PER_TICK (1000000 / MXC_CLK32) - -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - do_div(tick, TICK_PER_TIME); - return tick; -} - -static inline unsigned long long time_to_tick(unsigned long long time) -{ - return time * TICK_PER_TIME; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us += US_PER_TICK - 1; - do_div(us, US_PER_TICK); - return us; -} -#endif - /* The 32768Hz 32-bit timer overruns in 131072 seconds */ int timer_init(void) { @@ -95,53 +41,7 @@ int timer_init(void) return 0; } -unsigned long long get_ticks(void) -{ - ulong now = GPTCNT; /* current tick value */ - - if (now >= gd->arch.lastinc) /* normal mode (non roll) */ - /* move stamp forward with absolut diff ticks */ - gd->arch.tbl += (now - gd->arch.lastinc); - else /* we have rollover of incrementer */ - gd->arch.tbl += (0xFFFFFFFF - gd->arch.lastinc) + now; - gd->arch.lastinc = now; - return gd->arch.tbl; -} - -ulong get_timer_masked(void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds AND preserve advance timestamp value */ -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) +unsigned long timer_read_counter(void) { - return MXC_CLK32; + return GPTCNT; } diff --git a/arch/arm/include/asm/arch-mx31/imx-regs.h b/arch/arm/include/asm/arch-mx31/imx-regs.h index f23350e..71ebd24 100644 --- a/arch/arm/include/asm/arch-mx31/imx-regs.h +++ b/arch/arm/include/asm/arch-mx31/imx-regs.h @@ -909,9 +909,19 @@ struct esdc_regs { #define MXC_CSPIPERIOD_32KHZ (1 << 15) #define MAX_SPI_BYTES 4 + #define MXC_SPI_BASE_ADDRESSES \ 0x43fa4000, \ 0x50010000, \ 0x53f84000, +/* + * Generic timer support + */ +#ifdef CONFIG_MX31_CLK32 +#define CONFIG_SYS_TIMER_RATE CONFIG_MX31_CLK32 +#else +#define CONFIG_SYS_TIMER_RATE 32768 +#endif + #endif /* __ASM_ARCH_MX31_IMX_REGS_H */ -- cgit v1.1 From 816264fc6672dbb7c7b22ad9e67b8d0056873394 Mon Sep 17 00:00:00 2001 From: Andrew Ruder <andrew.ruder@elecsyscorp.com> Date: Tue, 12 Aug 2014 09:26:01 -0500 Subject: arm: mx35: use common timer functions This patch moves mx35 to the common timer functions added in commit 8dfafdd - Introduce common timer functions <Rob Herring> The (removed) mx35 timer code (specifically __udelay()) could deadlock at the 32-bit boundary of get_ticks(). get_ticks() returned a 32-bit value cast up to a 64-bit value. If get_ticks() + tmo in __udelay() crossed the 32-bit boundary, the while condition became unconditionally true and locks the processor. Rather than patch the specific mx35 issues, simply move everything over to the common code. Signed-off-by: Andrew Ruder <andrew.ruder@elecsyscorp.com> Cc: Marek Vasut <marex@denx.de> Cc: Stefano Babic <sbabic@denx.de> --- arch/arm/cpu/arm1136/mx35/timer.c | 83 ------------------------------- arch/arm/include/asm/arch-mx35/imx-regs.h | 12 +++++ 2 files changed, 12 insertions(+), 83 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/arm1136/mx35/timer.c b/arch/arm/cpu/arm1136/mx35/timer.c index cc6166f..4edf533 100644 --- a/arch/arm/cpu/arm1136/mx35/timer.c +++ b/arch/arm/cpu/arm1136/mx35/timer.c @@ -9,16 +9,11 @@ #include <common.h> #include <asm/io.h> -#include <div64.h> #include <asm/arch/imx-regs.h> #include <asm/arch/crm_regs.h> -#include <asm/arch/clock.h> DECLARE_GLOBAL_DATA_PTR; -#define timestamp (gd->arch.tbl) -#define lastinc (gd->arch.lastinc) - /* General purpose timers bitfields */ #define GPTCR_SWR (1<<15) /* Software reset */ #define GPTCR_FRR (1<<9) /* Freerun / restart */ @@ -26,27 +21,6 @@ DECLARE_GLOBAL_DATA_PTR; #define GPTCR_TEN (1) /* Timer enable */ /* - * "time" is measured in 1 / CONFIG_SYS_HZ seconds, - * "tick" is internal timer period - */ -/* ~0.4% error - measured with stop-watch on 100s boot-delay */ -static inline unsigned long long tick_to_time(unsigned long long tick) -{ - tick *= CONFIG_SYS_HZ; - do_div(tick, MXC_CLK32); - - return tick; -} - -static inline unsigned long long us_to_tick(unsigned long long us) -{ - us = us * MXC_CLK32 + 999999; - do_div(us, 1000000); - - return us; -} - -/* * nothing really to do with interrupts, just starts up a counter. * The 32KHz 32-bit timer overruns in 134217 seconds */ @@ -71,60 +45,3 @@ int timer_init(void) return 0; } - -unsigned long long get_ticks(void) -{ - struct gpt_regs *gpt = (struct gpt_regs *)GPT1_BASE_ADDR; - ulong now = readl(&gpt->counter); /* current tick value */ - - if (now >= lastinc) { - /* - * normal mode (non roll) - * move stamp forward with absolut diff ticks - */ - timestamp += (now - lastinc); - } else { - /* we have rollover of incrementer */ - timestamp += (0xFFFFFFFF - lastinc) + now; - } - lastinc = now; - return timestamp; -} - -ulong get_timer_masked(void) -{ - /* - * get_ticks() returns a long long (64 bit), it wraps in - * 2^64 / MXC_CLK32 = 2^64 / 2^15 = 2^49 ~ 5 * 10^14 (s) ~ - * 5 * 10^9 days... and get_ticks() * CONFIG_SYS_HZ wraps in - * 5 * 10^6 days - long enough. - */ - return tick_to_time(get_ticks()); -} - -ulong get_timer(ulong base) -{ - return get_timer_masked() - base; -} - -/* delay x useconds AND preserve advance timstamp value */ -void __udelay(unsigned long usec) -{ - unsigned long long tmp; - ulong tmo; - - tmo = us_to_tick(usec); - tmp = get_ticks() + tmo; /* get current timestamp */ - - while (get_ticks() < tmp) /* loop till event */ - /*NOP*/; -} - -/* - * This function is derived from PowerPC code (timebase clock frequency). - * On ARM it returns the number of timer ticks per second. - */ -ulong get_tbclk(void) -{ - return MXC_CLK32; -} diff --git a/arch/arm/include/asm/arch-mx35/imx-regs.h b/arch/arm/include/asm/arch-mx35/imx-regs.h index b530029..28a47ed 100644 --- a/arch/arm/include/asm/arch-mx35/imx-regs.h +++ b/arch/arm/include/asm/arch-mx35/imx-regs.h @@ -372,4 +372,16 @@ struct aips_regs { #define CCM_RCSR_NF_16BIT_SEL (1 << 14) #endif + +/* + * Generic timer support + */ +#ifdef CONFIG_MX35_CLK32 +#define CONFIG_SYS_TIMER_RATE CONFIG_MX35_CLK32 +#else +#define CONFIG_SYS_TIMER_RATE 32768 +#endif + +#define CONFIG_SYS_TIMER_COUNTER (GPT1_BASE_ADDR+36) + #endif /* __ASM_ARCH_MX35_H */ -- cgit v1.1 From 36c1ca4d46ef11ac7b3c0afb5c42dadb4e8773f3 Mon Sep 17 00:00:00 2001 From: Nitin Garg <nitin.garg@freescale.com> Date: Tue, 16 Sep 2014 13:33:25 -0500 Subject: imx: Support i.MX6 High Assurance Boot authentication When CONFIG_SECURE_BOOT is enabled, the signed images like kernel and dtb can be authenticated using iMX6 CAAM. The added command hab_auth_img can be used for HAB authentication of images. The command takes the image DDR location, IVT (Image Vector Table) offset inside image as parameters. Detailed info about signing images can be found in Freescale AppNote AN4581. Signed-off-by: Nitin Garg <nitin.garg@freescale.com> --- arch/arm/cpu/armv7/mx6/clock.c | 27 ++++++ arch/arm/cpu/armv7/mx6/hab.c | 169 +++++++++++++++++++++++++++++++++- arch/arm/cpu/armv7/mx6/soc.c | 15 +++ arch/arm/include/asm/arch-mx6/clock.h | 1 + 4 files changed, 211 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c index 336e557..d200531 100644 --- a/arch/arm/cpu/armv7/mx6/clock.c +++ b/arch/arm/cpu/armv7/mx6/clock.c @@ -642,6 +642,33 @@ int enable_pcie_clock(void) BM_ANADIG_PLL_ENET_ENABLE_PCIE); } +#ifdef CONFIG_SECURE_BOOT +void hab_caam_clock_enable(unsigned char enable) +{ + u32 reg; + + /* CG4 ~ CG6, CAAM clocks */ + reg = __raw_readl(&imx_ccm->CCGR0); + if (enable) + reg |= (MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); + else + reg &= ~(MXC_CCM_CCGR0_CAAM_WRAPPER_IPG_MASK | + MXC_CCM_CCGR0_CAAM_WRAPPER_ACLK_MASK | + MXC_CCM_CCGR0_CAAM_SECURE_MEM_MASK); + __raw_writel(reg, &imx_ccm->CCGR0); + + /* EMI slow clk */ + reg = __raw_readl(&imx_ccm->CCGR6); + if (enable) + reg |= MXC_CCM_CCGR6_EMI_SLOW_MASK; + else + reg &= ~MXC_CCM_CCGR6_EMI_SLOW_MASK; + __raw_writel(reg, &imx_ccm->CCGR6); +} +#endif + unsigned int mxc_get_clock(enum mxc_clock clk) { switch (clk) { diff --git a/arch/arm/cpu/armv7/mx6/hab.c b/arch/arm/cpu/armv7/mx6/hab.c index f6810a6..8dee595 100644 --- a/arch/arm/cpu/armv7/mx6/hab.c +++ b/arch/arm/cpu/armv7/mx6/hab.c @@ -1,12 +1,14 @@ /* - * Copyright (C) 2010-2013 Freescale Semiconductor, Inc. + * Copyright (C) 2010-2014 Freescale Semiconductor, Inc. * * SPDX-License-Identifier: GPL-2.0+ */ #include <common.h> #include <asm/io.h> +#include <asm/system.h> #include <asm/arch/hab.h> +#include <asm/arch/clock.h> #include <asm/arch/sys_proto.h> /* -------- start of HAB API updates ------------*/ @@ -71,6 +73,44 @@ ((hab_rvt_exit_t *)HAB_RVT_EXIT) \ ) +#define IVT_SIZE 0x20 +#define ALIGN_SIZE 0x1000 +#define CSF_PAD_SIZE 0x2000 +#define MX6DQ_PU_IROM_MMU_EN_VAR 0x009024a8 +#define MX6DLS_PU_IROM_MMU_EN_VAR 0x00901dd0 +#define MX6SL_PU_IROM_MMU_EN_VAR 0x00900a18 + +/* + * +------------+ 0x0 (DDR_UIMAGE_START) - + * | Header | | + * +------------+ 0x40 | + * | | | + * | | | + * | | | + * | | | + * | Image Data | | + * . | | + * . | > Stuff to be authenticated ----+ + * . | | | + * | | | | + * | | | | + * +------------+ | | + * | | | | + * | Fill Data | | | + * | | | | + * +------------+ Align to ALIGN_SIZE | | + * | IVT | | | + * +------------+ + IVT_SIZE - | + * | | | + * | CSF DATA | <---------------------------------------------------------+ + * | | + * +------------+ + * | | + * | Fill Data | + * | | + * +------------+ + CSF_PAD_SIZE + */ + bool is_hab_enabled(void) { struct ocotp_regs *ocotp = (struct ocotp_regs *)OCOTP_BASE_ADDR; @@ -144,6 +184,108 @@ int get_hab_status(void) return 0; } +uint32_t authenticate_image(uint32_t ddr_start, uint32_t image_size) +{ + uint32_t load_addr = 0; + size_t bytes; + ptrdiff_t ivt_offset = 0; + int result = 0; + ulong start; + hab_rvt_authenticate_image_t *hab_rvt_authenticate_image; + hab_rvt_entry_t *hab_rvt_entry; + hab_rvt_exit_t *hab_rvt_exit; + + hab_rvt_authenticate_image = hab_rvt_authenticate_image_p; + hab_rvt_entry = hab_rvt_entry_p; + hab_rvt_exit = hab_rvt_exit_p; + + if (is_hab_enabled()) { + printf("\nAuthenticate image from DDR location 0x%x...\n", + ddr_start); + + hab_caam_clock_enable(1); + + if (hab_rvt_entry() == HAB_SUCCESS) { + /* If not already aligned, Align to ALIGN_SIZE */ + ivt_offset = (image_size + ALIGN_SIZE - 1) & + ~(ALIGN_SIZE - 1); + + start = ddr_start; + bytes = ivt_offset + IVT_SIZE + CSF_PAD_SIZE; +#ifdef DEBUG + printf("\nivt_offset = 0x%x, ivt addr = 0x%x\n", + ivt_offset, ddr_start + ivt_offset); + puts("Dumping IVT\n"); + print_buffer(ddr_start + ivt_offset, + (void *)(ddr_start + ivt_offset), + 4, 0x8, 0); + + puts("Dumping CSF Header\n"); + print_buffer(ddr_start + ivt_offset+IVT_SIZE, + (void *)(ddr_start + ivt_offset+IVT_SIZE), + 4, 0x10, 0); + + get_hab_status(); + + puts("\nCalling authenticate_image in ROM\n"); + printf("\tivt_offset = 0x%x\n", ivt_offset); + printf("\tstart = 0x%08lx\n", start); + printf("\tbytes = 0x%x\n", bytes); +#endif + /* + * If the MMU is enabled, we have to notify the ROM + * code, or it won't flush the caches when needed. + * This is done, by setting the "pu_irom_mmu_enabled" + * word to 1. You can find its address by looking in + * the ROM map. This is critical for + * authenticate_image(). If MMU is enabled, without + * setting this bit, authentication will fail and may + * crash. + */ + /* Check MMU enabled */ + if (get_cr() & CR_M) { + if (is_cpu_type(MXC_CPU_MX6Q) || + is_cpu_type(MXC_CPU_MX6D)) { + /* + * This won't work on Rev 1.0.0 of + * i.MX6Q/D, since their ROM doesn't + * do cache flushes. don't think any + * exist, so we ignore them. + */ + writel(1, MX6DQ_PU_IROM_MMU_EN_VAR); + } else if (is_cpu_type(MXC_CPU_MX6DL) || + is_cpu_type(MXC_CPU_MX6SOLO)) { + writel(1, MX6DLS_PU_IROM_MMU_EN_VAR); + } else if (is_cpu_type(MXC_CPU_MX6SL)) { + writel(1, MX6SL_PU_IROM_MMU_EN_VAR); + } + } + + load_addr = (uint32_t)hab_rvt_authenticate_image( + HAB_CID_UBOOT, + ivt_offset, (void **)&start, + (size_t *)&bytes, NULL); + if (hab_rvt_exit() != HAB_SUCCESS) { + puts("hab exit function fail\n"); + load_addr = 0; + } + } else { + puts("hab entry function fail\n"); + } + + hab_caam_clock_enable(0); + + get_hab_status(); + } else { + puts("hab fuse not enabled\n"); + } + + if ((!is_hab_enabled()) || (load_addr != 0)) + result = 1; + + return result; +} + int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { if ((argc != 1)) { @@ -156,8 +298,33 @@ int do_hab_status(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) return 0; } +static int do_authenticate_image(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[]) +{ + ulong addr, ivt_offset; + int rcode = 0; + + if (argc < 3) + return CMD_RET_USAGE; + + addr = simple_strtoul(argv[1], NULL, 16); + ivt_offset = simple_strtoul(argv[2], NULL, 16); + + rcode = authenticate_image(addr, ivt_offset); + + return rcode; +} + U_BOOT_CMD( hab_status, CONFIG_SYS_MAXARGS, 1, do_hab_status, "display HAB status", "" ); + +U_BOOT_CMD( + hab_auth_img, 3, 0, do_authenticate_image, + "authenticate image via HAB", + "addr ivt_offset\n" + "addr - image hex address\n" + "ivt_offset - hex offset of IVT in the image" + ); diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index ba21cfe..05683a3 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -273,10 +273,25 @@ int board_postclk_init(void) #ifndef CONFIG_SYS_DCACHE_OFF void enable_caches(void) { +#if defined(CONFIG_SYS_ARM_CACHE_WRITETHROUGH) + enum dcache_option option = DCACHE_WRITETHROUGH; +#else + enum dcache_option option = DCACHE_WRITEBACK; +#endif + /* Avoid random hang when download by usb */ invalidate_dcache_all(); + /* Enable D-cache. I-cache is already enabled in start.S */ dcache_enable(); + + /* Enable caching on OCRAM and ROM */ + mmu_set_region_dcache_behaviour(ROMCP_ARB_BASE_ADDR, + ROMCP_ARB_END_ADDR, + option); + mmu_set_region_dcache_behaviour(IRAM_BASE_ADDR, + IRAM_SIZE, + option); } #endif diff --git a/arch/arm/include/asm/arch-mx6/clock.h b/arch/arm/include/asm/arch-mx6/clock.h index c11674f..3c58a0a 100644 --- a/arch/arm/include/asm/arch-mx6/clock.h +++ b/arch/arm/include/asm/arch-mx6/clock.h @@ -53,6 +53,7 @@ u32 imx_get_uartclk(void); u32 imx_get_fecclk(void); unsigned int mxc_get_clock(enum mxc_clock clk); void setup_gpmi_io_clk(u32 cfg); +void hab_caam_clock_enable(unsigned char enable); void enable_ocotp_clk(unsigned char enable); void enable_usboh3_clk(unsigned char enable); void enable_uart_clk(unsigned char enable); -- cgit v1.1 From be0ecdbed5efc7833275701ebdb1ff8ef7ffd4c0 Mon Sep 17 00:00:00 2001 From: Marek Vasut <marex@denx.de> Date: Mon, 28 Apr 2014 03:38:40 +0200 Subject: arm: mxs: Wait when disabling VDDMEM current limiter According to i.MX23 datasheet Table 32-17, we must wait for the supply to settle before disabling the current limiter. Indeed, not waiting a little here causes the system to crash at times. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Stefano Babic <sbabic@denx.de> --- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index 3baf4dd..de8841a 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -240,9 +240,14 @@ static void mx23_mem_setup_vddmem(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)MXS_POWER_BASE; + /* We must wait before and after disabling the current limiter! */ + early_delay(10000); + clrbits_le32(&power_regs->hw_power_vddmemctrl, POWER_VDDMEMCTRL_ENABLE_ILIMIT); + early_delay(10000); + } static void mx23_mem_init(void) -- cgit v1.1 From 7c604e98c2213619af6a8c3064418af9b689cf56 Mon Sep 17 00:00:00 2001 From: Marek Vasut <marex@denx.de> Date: Mon, 28 Apr 2014 03:38:41 +0200 Subject: arm: mxs: Wait for DRAM to start Instead of waiting for a fixed period of time and hoping for the best that the DRAM will start, read back an EMI status register which tells us exactly when the DRAM started. Signed-off-by: Marek Vasut <marex@denx.de> Cc: Stefano Babic <sbabic@denx.de> --- arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c index de8841a..97ef67d 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_mem_init.c @@ -274,7 +274,13 @@ static void mx23_mem_init(void) setbits_le32(MXS_DRAM_BASE + 0x20, 1 << 16); clrbits_le32(MXS_DRAM_BASE + 0x40, 1 << 17); - early_delay(20000); + + /* Wait for EMI_STAT bit DRAM_HALTED */ + for (;;) { + if (!(readl(MXS_EMI_BASE + 0x10) & (1 << 1))) + break; + early_delay(1000); + } /* Adjust EMI port priority. */ clrsetbits_le32(0x80020000, 0x1f << 16, 0x2); -- cgit v1.1 From 9293d7fd502ce29302fadb8b4ccb9231ec0bcc66 Mon Sep 17 00:00:00 2001 From: "Ye.Li" <B37916@freescale.com> Date: Tue, 9 Sep 2014 10:17:00 +0800 Subject: imx: mx6: Checking PLL2 PFD0 and PFD2 for periph_clk before PFD reset Checking the pre_periph_clk_sel and pre_periph2_clk of CCM CBCMR register, if the PLL2 PFD0 or PLL2 PFD2 is used for the clock source, do not reset this PFD to avoid system hang. Customers may set this in DDR script or use BT_FREQ to select low freq boot. Signed-off-by: Ye.Li <B37916@freescale.com> --- arch/arm/cpu/armv7/mx6/soc.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/cpu/armv7/mx6/soc.c b/arch/arm/cpu/armv7/mx6/soc.c index 05683a3..6352422 100644 --- a/arch/arm/cpu/armv7/mx6/soc.c +++ b/arch/arm/cpu/armv7/mx6/soc.c @@ -354,10 +354,10 @@ 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); + struct mxc_ccm_reg *ccm = (struct mxc_ccm_reg *)CCM_BASE_ADDR; u32 mask480; u32 mask528; - + u32 reg, periph1, periph2; if (is_cpu_type(MXC_CPU_MX6SX)) return; @@ -372,15 +372,23 @@ void s_init(void) 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) | + mask528 = ANATOP_PFD_CLKGATE_MASK(1) | ANATOP_PFD_CLKGATE_MASK(3); - /* - * Don't reset PFD2 on DL/S - */ - if (is_6q) + reg = readl(&ccm->cbcmr); + periph2 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_MASK) + >> MXC_CCM_CBCMR_PRE_PERIPH2_CLK_SEL_OFFSET); + periph1 = ((reg & MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_MASK) + >> MXC_CCM_CBCMR_PRE_PERIPH_CLK_SEL_OFFSET); + + /* Checking if PLL2 PFD0 or PLL2 PFD2 is using for periph clock */ + if ((periph2 != 0x2) && (periph1 != 0x2)) + mask528 |= ANATOP_PFD_CLKGATE_MASK(0); + + if ((periph2 != 0x1) && (periph1 != 0x1) && + (periph2 != 0x3) && (periph1 != 0x3)) mask528 |= ANATOP_PFD_CLKGATE_MASK(2); + writel(mask480, &anatop->pfd_480_set); writel(mask528, &anatop->pfd_528_set); writel(mask480, &anatop->pfd_480_clr); -- cgit v1.1 From 5546ad0734bb5eed2b3cd6333dbcec51ae45185a Mon Sep 17 00:00:00 2001 From: "Ye.Li" <B37916@freescale.com> Date: Mon, 15 Sep 2014 17:23:14 +0800 Subject: usb: ehci-mx6: Rename the USB register base address The mx6sl/mx6sx has 2 OTG and 1 host. So they have name "USBO2H_USB_BASE_ADDR" in imx-regs.h. The driver hard codes the USB base address name to "USBOH3", which causes the driver failed to build for mx6sl/mx6sx. This patch uniform the address name to "USB_BASE_ADDR" for all mx6 series. Signed-off-by: Ye.Li <B37916@freescale.com> --- arch/arm/include/asm/arch-mx6/imx-regs.h | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-mx6/imx-regs.h b/arch/arm/include/asm/arch-mx6/imx-regs.h index 22614fc..a159309 100644 --- a/arch/arm/include/asm/arch-mx6/imx-regs.h +++ b/arch/arm/include/asm/arch-mx6/imx-regs.h @@ -215,13 +215,8 @@ #define AIPS2_OFF_BASE_ADDR (ATZ2_BASE_ADDR + 0x80000) #define CAAM_BASE_ADDR (ATZ2_BASE_ADDR) #define ARM_BASE_ADDR (ATZ2_BASE_ADDR + 0x40000) -#ifdef CONFIG_MX6SL -#define USBO2H_PL301_IPS_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) -#define USBO2H_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) -#else -#define USBOH3_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) -#define USBOH3_USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) -#endif +#define USB_PL301_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x0000) +#define USB_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x4000) #define ENET_BASE_ADDR (AIPS2_OFF_BASE_ADDR + 0x8000) #ifdef CONFIG_MX6SL -- cgit v1.1 From 13bc86037e832f547dacda81339d74177f2e569d Mon Sep 17 00:00:00 2001 From: Nitin Garg <nitin.garg@freescale.com> Date: Tue, 30 Sep 2014 11:39:29 -0500 Subject: imx6sx: Fix i.MX6SX HAB api function table offset i.MX6SX ROM implements unified table sections. The HAB function table is at offset 0x100. Update the HAB function pointers accordingly. Signed-off-by: Nitin Garg <nitin.garg@freescale.com> Tested-by: Fabio Estevam <fabio.estevam@freescale.com> --- arch/arm/include/asm/arch-mx6/hab.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch/arm') diff --git a/arch/arm/include/asm/arch-mx6/hab.h b/arch/arm/include/asm/arch-mx6/hab.h index 1f12695..c9e5318 100644 --- a/arch/arm/include/asm/arch-mx6/hab.h +++ b/arch/arm/include/asm/arch-mx6/hab.h @@ -53,11 +53,17 @@ typedef void *hab_rvt_authenticate_image_t(uint8_t, ptrdiff_t, void **, size_t *, hab_loader_callback_f_t); typedef void hapi_clock_init_t(void); -#define HAB_RVT_REPORT_EVENT (*(uint32_t *)0x000000B4) -#define HAB_RVT_REPORT_STATUS (*(uint32_t *)0x000000B8) -#define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)0x000000A4) -#define HAB_RVT_ENTRY (*(uint32_t *)0x00000098) -#define HAB_RVT_EXIT (*(uint32_t *)0x0000009C) +#ifdef CONFIG_MX6SX +#define HAB_RVT_BASE 0x00000100 +#else +#define HAB_RVT_BASE 0x00000094 +#endif + +#define HAB_RVT_ENTRY (*(uint32_t *)(HAB_RVT_BASE + 0x04)) +#define HAB_RVT_EXIT (*(uint32_t *)(HAB_RVT_BASE + 0x08)) +#define HAB_RVT_AUTHENTICATE_IMAGE (*(uint32_t *)(HAB_RVT_BASE + 0x10)) +#define HAB_RVT_REPORT_EVENT (*(uint32_t *)(HAB_RVT_BASE + 0x20)) +#define HAB_RVT_REPORT_STATUS (*(uint32_t *)(HAB_RVT_BASE + 0x24)) #define HAB_RVT_REPORT_EVENT_NEW (*(uint32_t *)0x000000B8) #define HAB_RVT_REPORT_STATUS_NEW (*(uint32_t *)0x000000BC) -- cgit v1.1 From 39d0973300b83c08f3f5047245ebf1de883b31f2 Mon Sep 17 00:00:00 2001 From: Christian Gmeiner <christian.gmeiner@gmail.com> Date: Thu, 2 Oct 2014 13:33:46 +0200 Subject: imx6: add Bachmann OT1200 board This patch adds support for the OT1200 series of devices. Following components are used in u-boot: + ethernet + i2c + emmc + gpio For more details see README. Changes v1 > v2 - make use of enable_cspi_clock(..) - fix usage of OUTPUT_40OHM define - added README Changes v2 > v3 - improve spelling in README - added own copy of mx6q_4x_mt41j128.cfg Signed-off-by: Christian Gmeiner <christian.gmeiner@gmail.com> --- arch/arm/Kconfig | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/arm') diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 106aed9..8face21 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -414,6 +414,9 @@ config TARGET_HUMMINGBOARD config TARGET_TQMA6 bool "TQ Systems TQMa6 board" +config TARGET_OT1200 + bool "Bachmann OT1200" + config OMAP34XX bool "OMAP34XX SoC" @@ -577,6 +580,7 @@ source "board/atmel/at91sam9rlek/Kconfig" source "board/atmel/at91sam9x5ek/Kconfig" source "board/atmel/sama5d3_xplained/Kconfig" source "board/atmel/sama5d3xek/Kconfig" +source "board/bachmann/ot1200/Kconfig" source "board/balloon3/Kconfig" source "board/barco/titanium/Kconfig" source "board/bluegiga/apx4devkit/Kconfig" -- cgit v1.1