summaryrefslogtreecommitdiff
path: root/arch/arm/cpu/armv7
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/cpu/armv7')
-rw-r--r--arch/arm/cpu/armv7/Kconfig10
-rw-r--r--arch/arm/cpu/armv7/Makefile2
-rw-r--r--arch/arm/cpu/armv7/am33xx/config.mk1
-rw-r--r--arch/arm/cpu/armv7/am33xx/ddr.c24
-rw-r--r--arch/arm/cpu/armv7/cache_v7.c58
-rw-r--r--arch/arm/cpu/armv7/ls102xa/psci.S156
-rw-r--r--arch/arm/cpu/armv7/mx6/Kconfig18
-rw-r--r--arch/arm/cpu/armv7/mx6/clock.c6
-rw-r--r--arch/arm/cpu/armv7/mx7/Kconfig9
-rw-r--r--arch/arm/cpu/armv7/mx7/psci-mx7.c2
-rw-r--r--arch/arm/cpu/armv7/mx7/psci.S31
-rw-r--r--arch/arm/cpu/armv7/mx7/soc.c14
-rw-r--r--arch/arm/cpu/armv7/nonsec_virt.S7
-rw-r--r--arch/arm/cpu/armv7/omap-common/Makefile2
-rw-r--r--arch/arm/cpu/armv7/omap-common/clocks-common.c69
-rw-r--r--arch/arm/cpu/armv7/omap-common/config_secure.mk75
-rw-r--r--arch/arm/cpu/armv7/omap-common/emif-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/hwinit-common.c3
-rw-r--r--arch/arm/cpu/armv7/omap-common/lowlevel_init.S45
-rw-r--r--arch/arm/cpu/armv7/omap-common/mem-common.c156
-rw-r--r--arch/arm/cpu/armv7/omap-common/sec-common.c139
-rw-r--r--arch/arm/cpu/armv7/omap3/Kconfig25
-rw-r--r--arch/arm/cpu/armv7/omap3/spl_id_nand.c57
-rw-r--r--arch/arm/cpu/armv7/omap5/Kconfig1
-rw-r--r--arch/arm/cpu/armv7/omap5/config.mk3
-rw-r--r--arch/arm/cpu/armv7/omap5/hw_data.c4
-rw-r--r--arch/arm/cpu/armv7/psci-common.c39
-rw-r--r--arch/arm/cpu/armv7/psci.S133
-rw-r--r--arch/arm/cpu/armv7/sunxi/Makefile1
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci.c21
-rw-r--r--arch/arm/cpu/armv7/sunxi/psci_head.S66
-rw-r--r--arch/arm/cpu/armv7/virt-dt.c63
-rw-r--r--arch/arm/cpu/armv7/virt-v7.c4
33 files changed, 773 insertions, 474 deletions
diff --git a/arch/arm/cpu/armv7/Kconfig b/arch/arm/cpu/armv7/Kconfig
index afeaac8..41c6639 100644
--- a/arch/arm/cpu/armv7/Kconfig
+++ b/arch/arm/cpu/armv7/Kconfig
@@ -7,32 +7,32 @@ config CPU_V7_HAS_VIRT
bool
config ARMV7_NONSEC
- boolean "Enable support for booting in non-secure mode" if EXPERT
+ bool "Enable support for booting in non-secure mode" if EXPERT
depends on CPU_V7_HAS_NONSEC
default y
---help---
Say Y here to enable support for booting in non-secure / SVC mode.
config ARMV7_BOOT_SEC_DEFAULT
- boolean "Boot in secure mode by default" if EXPERT
+ bool "Boot in secure mode by default" if EXPERT
depends on ARMV7_NONSEC
default y if TEGRA
---help---
Say Y here to boot in secure mode by default even if non-secure mode
is supported. This option is useful to boot kernels which do not
suppport booting in non-secure mode. Only set this if you need it.
- This can be overriden at run-time by setting the bootm_boot_mode env.
+ This can be overridden at run-time by setting the bootm_boot_mode env.
variable to "sec" or "nonsec".
config ARMV7_VIRT
- boolean "Enable support for hardware virtualization" if EXPERT
+ bool "Enable support for hardware virtualization" if EXPERT
depends on CPU_V7_HAS_VIRT && ARMV7_NONSEC
default y
---help---
Say Y here to boot in hypervisor (HYP) mode when booting non-secure.
config ARMV7_LPAE
- boolean "Use LPAE page table format" if EXPERT
+ bool "Use LPAE page table format" if EXPERT
depends on CPU_V7
default n
---help---
diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile
index ddd8d12..0d4bfbc 100644
--- a/arch/arm/cpu/armv7/Makefile
+++ b/arch/arm/cpu/armv7/Makefile
@@ -19,7 +19,7 @@ endif
endif
obj-$(CONFIG_ARMV7_NONSEC) += nonsec_virt.o virt-v7.o virt-dt.o
-obj-$(CONFIG_ARMV7_PSCI) += psci.o
+obj-$(CONFIG_ARMV7_PSCI) += psci.o psci-common.o
obj-$(CONFIG_IPROC) += iproc-common/
obj-$(CONFIG_KONA) += kona-common/
diff --git a/arch/arm/cpu/armv7/am33xx/config.mk b/arch/arm/cpu/armv7/am33xx/config.mk
index 6d95d32..d4eb21c 100644
--- a/arch/arm/cpu/armv7/am33xx/config.mk
+++ b/arch/arm/cpu/armv7/am33xx/config.mk
@@ -26,6 +26,7 @@ endif
else
ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
ALL-$(CONFIG_QSPI_BOOT) += u-boot_HS_XIP_X-LOADER
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/am33xx/ddr.c b/arch/arm/cpu/armv7/am33xx/ddr.c
index 888cf1f..6acf30c 100644
--- a/arch/arm/cpu/armv7/am33xx/ddr.c
+++ b/arch/arm/cpu/armv7/am33xx/ddr.c
@@ -120,12 +120,15 @@ void config_sdram_emif4d5(const struct emif_regs *regs, int nr)
writel(regs->sdram_config, &emif_reg[nr]->emif_sdram_config);
writel(regs->sdram_config, &cstat->secure_emif_sdram_config);
+
+ /* Wait 1ms because of L3 timeout error */
+ udelay(1000);
+
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl);
writel(regs->ref_ctrl, &emif_reg[nr]->emif_sdram_ref_ctrl_shdw);
/* Perform hardware leveling for DDR3 */
if (emif_sdram_type(regs->sdram_config) == EMIF_SDRAM_TYPE_DDR3) {
- udelay(1000);
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36) |
0x100, &emif_reg[nr]->emif_ddr_ext_phy_ctrl_36);
writel(readl(&emif_reg[nr]->emif_ddr_ext_phy_ctrl_36_shdw) |
@@ -289,19 +292,14 @@ static void ext_phy_settings_hwlvl(const struct emif_regs *regs, int nr)
void config_ddr_phy(const struct emif_regs *regs, int nr)
{
/*
- * Disable initialization and refreshes for now until we
- * finish programming EMIF regs.
- * Also set time between rising edge of DDR_RESET to rising
- * edge of DDR_CKE to > 500us per memory spec.
+ * Disable initialization and refreshes for now until we finish
+ * programming EMIF regs and set time between rising edge of
+ * DDR_RESET to rising edge of DDR_CKE to > 500us per memory spec.
+ * We currently hardcode a value based on a max expected frequency
+ * of 400MHz.
*/
-#ifndef CONFIG_AM43XX
- setbits_le32(&emif_reg[nr]->emif_sdram_ref_ctrl,
- EMIF_REG_INITREF_DIS_MASK);
-#endif
- if (regs->zq_config)
- /* Set time between rising edge of DDR_RESET to rising
- * edge of DDR_CKE to > 500us per memory spec. */
- writel(0x00003100, &emif_reg[nr]->emif_sdram_ref_ctrl);
+ writel(EMIF_REG_INITREF_DIS_MASK | 0x3100,
+ &emif_reg[nr]->emif_sdram_ref_ctrl);
writel(regs->emif_ddr_phy_ctlr_1,
&emif_reg[nr]->emif_ddr_phy_ctrl_1);
diff --git a/arch/arm/cpu/armv7/cache_v7.c b/arch/arm/cpu/armv7/cache_v7.c
index dc309da..c4bbcc3 100644
--- a/arch/arm/cpu/armv7/cache_v7.c
+++ b/arch/arm/cpu/armv7/cache_v7.c
@@ -19,23 +19,6 @@
void v7_flush_dcache_all(void);
void v7_invalidate_dcache_all(void);
-static int check_cache_range(unsigned long start, unsigned long stop)
-{
- int ok = 1;
-
- if (start & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (stop & (CONFIG_SYS_CACHELINE_SIZE - 1))
- ok = 0;
-
- if (!ok)
- debug("CACHE: Misaligned operation at range [%08lx, %08lx]\n",
- start, stop);
-
- return ok;
-}
-
static u32 get_ccsidr(void)
{
u32 ccsidr;
@@ -61,27 +44,8 @@ static void v7_dcache_inval_range(u32 start, u32 stop, u32 line_len)
{
u32 mva;
- /*
- * If start address is not aligned to cache-line do not
- * invalidate the first cache-line
- */
- if (start & (line_len - 1)) {
- printf("ERROR: %s - start address is not aligned - 0x%08x\n",
- __func__, start);
- /* move to next cache line */
- start = (start + line_len - 1) & ~(line_len - 1);
- }
-
- /*
- * If stop address is not aligned to cache-line do not
- * invalidate the last cache-line
- */
- if (stop & (line_len - 1)) {
- printf("ERROR: %s - stop address is not aligned - 0x%08x\n",
- __func__, stop);
- /* align to the beginning of this cache line */
- stop &= ~(line_len - 1);
- }
+ if (!check_cache_range(start, stop))
+ return;
for (mva = start; mva < stop; mva = mva + line_len) {
/* DCIMVAC - Invalidate data cache by MVA to PoC */
@@ -111,7 +75,7 @@ static void v7_dcache_maint_range(u32 start, u32 stop, u32 range_op)
}
/* DSB to make sure the operation is complete */
- DSB;
+ dsb();
}
/* Invalidate TLB */
@@ -124,9 +88,9 @@ static void v7_inval_tlb(void)
/* Invalidate entire instruction TLB */
asm volatile ("mcr p15, 0, %0, c8, c5, 0" : : "r" (0));
/* Full system DSB - make sure that the invalidation is complete */
- DSB;
+ dsb();
/* Full system ISB - make sure the instruction stream sees it */
- ISB;
+ isb();
}
void invalidate_dcache_all(void)
@@ -195,6 +159,14 @@ void flush_dcache_all(void)
{
}
+void invalidate_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
+void flush_dcache_range(unsigned long start, unsigned long stop)
+{
+}
+
void arm_init_before_mmu(void)
{
}
@@ -222,10 +194,10 @@ void invalidate_icache_all(void)
asm volatile ("mcr p15, 0, %0, c7, c5, 6" : : "r" (0));
/* Full system DSB - make sure that the invalidation is complete */
- DSB;
+ dsb();
/* ISB - make sure the instruction stream sees it */
- ISB;
+ isb();
}
#else
void invalidate_icache_all(void)
diff --git a/arch/arm/cpu/armv7/ls102xa/psci.S b/arch/arm/cpu/armv7/ls102xa/psci.S
index cf5cd48..8f38680 100644
--- a/arch/arm/cpu/armv7/ls102xa/psci.S
+++ b/arch/arm/cpu/armv7/ls102xa/psci.S
@@ -12,33 +12,118 @@
#include <asm/arch-armv7/generictimer.h>
#include <asm/psci.h>
+#define RCPM_TWAITSR 0x04C
+
#define SCFG_CORE0_SFT_RST 0x130
#define SCFG_CORESRENCR 0x204
-#define DCFG_CCSR_BRR 0x0E4
-#define DCFG_CCSR_SCRATCHRW1 0x200
+#define DCFG_CCSR_RSTCR 0x0B0
+#define DCFG_CCSR_RSTCR_RESET_REQ 0x2
+#define DCFG_CCSR_BRR 0x0E4
+#define DCFG_CCSR_SCRATCHRW1 0x200
+
+#define PSCI_FN_PSCI_VERSION_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_SUSPEND_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_CPU_ON_FEATURE_MASK 0x0
+#define PSCI_FN_AFFINITY_INFO_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_OFF_FEATURE_MASK 0x0
+#define PSCI_FN_SYSTEM_RESET_FEATURE_MASK 0x0
.pushsection ._secure.text, "ax"
.arch_extension sec
+ .align 5
+
#define ONE_MS (GENERIC_TIMER_CLK / 1000)
#define RESET_WAIT (30 * ONE_MS)
+.globl psci_version
+psci_version:
+ movw r0, #0
+ movt r0, #1
+
+ bx lr
+
+_ls102x_psci_supported_table:
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word PSCI_FN_PSCI_VERSION_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word PSCI_FN_CPU_SUSPEND_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word PSCI_FN_CPU_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word PSCI_FN_CPU_ON_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word PSCI_FN_AFFINITY_INFO_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word PSCI_FN_SYSTEM_OFF_FEATURE_MASK
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word PSCI_FN_SYSTEM_RESET_FEATURE_MASK
+ .word 0
+ .word ARM_PSCI_RET_NI
+
+.globl psci_features
+psci_features:
+ adr r2, _ls102x_psci_supported_table
+1: ldr r3, [r2]
+ cmp r3, #0
+ beq out_psci_features
+ cmp r1, r3
+ addne r2, r2, #8
+ bne 1b
+
+out_psci_features:
+ ldr r0, [r2, #4]
+ bx lr
+
+@ r0: return value ARM_PSCI_RET_SUCCESS or ARM_PSCI_RET_INVAL
+@ r1: input target CPU ID in MPIDR format, original value in r1 may be dropped
+@ r4: output validated CPU ID if ARM_PSCI_RET_SUCCESS returns, meaningless for
+@ ARM_PSCI_RET_INVAL,suppose caller saves r4 before calling
+LENTRY(psci_check_target_cpu_id)
+ @ Get the real CPU number
+ and r4, r1, #0xff
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Bit[31:24], bits must be zero.
+ tst r1, #0xff000000
+ bxne lr
+
+ @ Affinity level 2 - Cluster: only one cluster in LS1021xa.
+ tst r1, #0xff0000
+ bxne lr
+
+ @ Affinity level 1 - Processors: should be in 0xf00 format.
+ lsr r1, r1, #8
+ teq r1, #0xf
+ bxne lr
+
+ @ Affinity level 0 - CPU: only 0, 1 are valid in LS1021xa.
+ cmp r4, #2
+ bxge lr
+
+ mov r0, #ARM_PSCI_RET_SUCCESS
+ bx lr
+ENDPROC(psci_check_target_cpu_id)
+
@ r1 = target CPU
@ r2 = target PC
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, r6, lr}
@ Clear and Get the correct CPU number
@ r1 = 0xf01
- and r1, r1, #0xff
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_psci_cpu_on
- mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r0, r4
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r1, r4
@ Get DCFG base address
movw r4, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
@@ -101,7 +186,8 @@ holdoff_release:
@ Return
mov r0, #ARM_PSCI_RET_SUCCESS
- pop {lr}
+out_psci_cpu_on:
+ pop {r4, r5, r6, lr}
bx lr
.globl psci_cpu_off
@@ -111,16 +197,50 @@ psci_cpu_off:
1: wfi
b 1b
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
+.globl psci_affinity_info
+psci_affinity_info:
+ push {lr}
+
+ mov r0, #ARM_PSCI_RET_INVAL
+
+ @ Verify Affinity level
+ cmp r2, #0
+ bne out_affinity_info
+
+ bl psci_check_target_cpu_id
+ cmp r0, #ARM_PSCI_RET_INVAL
+ beq out_affinity_info
+ mov r1, r4
+
+ @ Get RCPM base address
+ movw r4, #(CONFIG_SYS_FSL_RCPM_ADDR & 0xffff)
+ movt r4, #(CONFIG_SYS_FSL_RCPM_ADDR >> 16)
+
+ mov r0, #PSCI_AFFINITY_LEVEL_ON
+
+ @ Detect target CPU state
+ ldr r2, [r4, #RCPM_TWAITSR]
+ rev r2, r2
+ lsr r2, r2, r1
+ ands r2, r2, #1
+ beq out_affinity_info
+
+ mov r0, #PSCI_AFFINITY_LEVEL_OFF
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
+out_affinity_info:
+ pop {pc}
+
+.globl psci_system_reset
+psci_system_reset:
+ @ Get DCFG base address
+ movw r1, #(CONFIG_SYS_FSL_GUTS_ADDR & 0xffff)
+ movt r1, #(CONFIG_SYS_FSL_GUTS_ADDR >> 16)
- bx r6
+ mov r2, #DCFG_CCSR_RSTCR_RESET_REQ
+ rev r2, r2
+ str r2, [r1, #DCFG_CCSR_RSTCR]
+
+1: wfi
+ b 1b
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/mx6/Kconfig b/arch/arm/cpu/armv7/mx6/Kconfig
index 663f970..78383f0 100644
--- a/arch/arm/cpu/armv7/mx6/Kconfig
+++ b/arch/arm/cpu/armv7/mx6/Kconfig
@@ -148,6 +148,10 @@ config TARGET_PLATINUM_TITANIUM
bool "platinum-titanium"
select SUPPORT_SPL
+config TARGET_PCM058
+ bool "Phytec PCM058 i.MX6 Quad"
+ select SUPPORT_SPL
+
config TARGET_SECOMX6
bool "secomx6 boards"
@@ -178,6 +182,18 @@ config TARGET_XPRESS
select DM_THERMAL
select SUPPORT_SPL
+config TARGET_ZC5202
+ bool "zc5202"
+ select SUPPORT_SPL
+ select DM
+ select DM_THERMAL
+
+config TARGET_ZC5601
+ bool "zc5601"
+ select SUPPORT_SPL
+ select DM
+ select DM_THERMAL
+
endchoice
config SYS_SOC
@@ -192,6 +208,7 @@ source "board/boundary/nitrogen6x/Kconfig"
source "board/ccv/xpress/Kconfig"
source "board/compulab/cm_fx6/Kconfig"
source "board/congatec/cgtqmx6eval/Kconfig"
+source "board/el/el6x/Kconfig"
source "board/embest/mx6boards/Kconfig"
source "board/freescale/mx6qarm2/Kconfig"
source "board/freescale/mx6qsabreauto/Kconfig"
@@ -200,6 +217,7 @@ source "board/freescale/mx6slevk/Kconfig"
source "board/freescale/mx6sxsabresd/Kconfig"
source "board/freescale/mx6sxsabreauto/Kconfig"
source "board/freescale/mx6ul_14x14_evk/Kconfig"
+source "board/phytec/pcm058/Kconfig"
source "board/gateworks/gw_ventana/Kconfig"
source "board/kosagi/novena/Kconfig"
source "board/seco/Kconfig"
diff --git a/arch/arm/cpu/armv7/mx6/clock.c b/arch/arm/cpu/armv7/mx6/clock.c
index ff932aa..b3c9dcc 100644
--- a/arch/arm/cpu/armv7/mx6/clock.c
+++ b/arch/arm/cpu/armv7/mx6/clock.c
@@ -281,7 +281,7 @@ static u32 mxc_get_pll_pfd(enum pll_clocks pll, int pfd_num)
case PLL_BUS:
if (!is_mx6ul()) {
if (pfd_num == 3) {
- /* No PFD3 on PPL2 */
+ /* No PFD3 on PLL2 */
return 0;
}
}
@@ -433,9 +433,9 @@ static u32 get_axi_clk(void)
if (cbcdr & MXC_CCM_CBCDR_AXI_SEL) {
if (cbcdr & MXC_CCM_CBCDR_AXI_ALT_SEL)
- root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
- else
root_freq = mxc_get_pll_pfd(PLL_USBOTG, 1);
+ else
+ root_freq = mxc_get_pll_pfd(PLL_BUS, 2);
} else
root_freq = get_periph_clk();
diff --git a/arch/arm/cpu/armv7/mx7/Kconfig b/arch/arm/cpu/armv7/mx7/Kconfig
index ecfa4a2..5fdc8dd 100644
--- a/arch/arm/cpu/armv7/mx7/Kconfig
+++ b/arch/arm/cpu/armv7/mx7/Kconfig
@@ -3,6 +3,8 @@ if ARCH_MX7
config MX7
bool
select ROM_UNIFIED_SECTIONS
+ select CPU_V7_HAS_VIRT
+ select CPU_V7_HAS_NONSEC
default y
config MX7D
@@ -25,12 +27,19 @@ config TARGET_WARP7
select DM
select DM_THERMAL
+config TARGET_COLIBRI_IMX7
+ bool "Support Colibri iMX7S/iMX7D modules"
+ select DM
+ select DM_SERIAL
+ select DM_THERMAL
+
endchoice
config SYS_SOC
default "mx7"
source "board/freescale/mx7dsabresd/Kconfig"
+source "board/toradex/colibri_imx7/Kconfig"
source "board/warp7/Kconfig"
endif
diff --git a/arch/arm/cpu/armv7/mx7/psci-mx7.c b/arch/arm/cpu/armv7/mx7/psci-mx7.c
index 9a33047..502552d 100644
--- a/arch/arm/cpu/armv7/mx7/psci-mx7.c
+++ b/arch/arm/cpu/armv7/mx7/psci-mx7.c
@@ -1,9 +1,9 @@
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/arch/imx-regs.h>
#include <common.h>
-#define __secure __attribute__((section("._secure.text")))
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
diff --git a/arch/arm/cpu/armv7/mx7/psci.S b/arch/arm/cpu/armv7/mx7/psci.S
index 34c6ab3..96e88d6 100644
--- a/arch/arm/cpu/armv7/mx7/psci.S
+++ b/arch/arm/cpu/armv7/mx7/psci.S
@@ -9,35 +9,22 @@
.arch_extension sec
- @ r1 = target CPU
- @ r2 = target PC
-
-.globl psci_arch_init
-psci_arch_init:
- mov r6, lr
-
- bl psci_get_cpu_id
- bl psci_get_cpu_stack_top
- mov sp, r0
-
- bx r6
-
- @ r1 = target CPU
- @ r2 = target PC
-
.globl psci_cpu_on
psci_cpu_on:
- push {lr}
+ push {r4, r5, lr}
+ mov r4, r0
+ mov r5, r1
mov r0, r1
- bl psci_get_cpu_stack_top
- str r2, [r0]
- dsb
+ mov r1, r2
+ bl psci_save_target_pc
+ mov r0, r4
+ mov r1, r5
ldr r2, =psci_cpu_entry
bl imx_cpu_on
- pop {pc}
+ pop {r4, r5, pc}
.globl psci_cpu_off
psci_cpu_off:
@@ -49,6 +36,4 @@ psci_cpu_off:
1: wfi
b 1b
- .globl psci_text_end
-psci_text_end:
.popsection
diff --git a/arch/arm/cpu/armv7/mx7/soc.c b/arch/arm/cpu/armv7/mx7/soc.c
index ef46c92..dead1d3 100644
--- a/arch/arm/cpu/armv7/mx7/soc.c
+++ b/arch/arm/cpu/armv7/mx7/soc.c
@@ -248,6 +248,20 @@ int arch_cpu_init(void)
return 0;
}
+#ifdef CONFIG_ARCH_MISC_INIT
+int arch_misc_init(void)
+{
+#ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG
+ if (is_mx7d())
+ setenv("soc", "imx7d");
+ else
+ setenv("soc", "imx7s");
+#endif
+
+ return 0;
+}
+#endif
+
#ifdef CONFIG_SERIAL_TAG
void get_board_serial(struct tag_serialnr *serialnr)
{
diff --git a/arch/arm/cpu/armv7/nonsec_virt.S b/arch/arm/cpu/armv7/nonsec_virt.S
index b7563ed..95ce938 100644
--- a/arch/arm/cpu/armv7/nonsec_virt.S
+++ b/arch/arm/cpu/armv7/nonsec_virt.S
@@ -49,8 +49,13 @@ _secure_monitor:
mcr p15, 0, r5, c12, c0, 1
isb
- @ Obtain a secure stack, and configure the PSCI backend
+ @ Obtain a secure stack
+ bl psci_stack_setup
+
+ @ Configure the PSCI backend
+ push {r0, r1, r2, ip}
bl psci_arch_init
+ pop {r0, r1, r2, ip}
#endif
#ifdef CONFIG_ARM_ERRATA_773022
diff --git a/arch/arm/cpu/armv7/omap-common/Makefile b/arch/arm/cpu/armv7/omap-common/Makefile
index 87a7ac0..3172bae 100644
--- a/arch/arm/cpu/armv7/omap-common/Makefile
+++ b/arch/arm/cpu/armv7/omap-common/Makefile
@@ -36,3 +36,5 @@ obj-y += boot-common.o
obj-y += lowlevel_init.o
obj-y += mem-common.o
+
+obj-$(CONFIG_TI_SECURE_DEVICE) += sec-common.o
diff --git a/arch/arm/cpu/armv7/omap-common/clocks-common.c b/arch/arm/cpu/armv7/omap-common/clocks-common.c
index 2de9935..9b97583 100644
--- a/arch/arm/cpu/armv7/omap-common/clocks-common.c
+++ b/arch/arm/cpu/armv7/omap-common/clocks-common.c
@@ -443,15 +443,12 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
{
u32 offset_code;
u32 offset = volt_mv;
-#ifndef CONFIG_DRA7XX
int ret = 0;
-#endif
if (!volt_mv)
return;
pmic->pmic_bus_init();
-#ifndef CONFIG_DRA7XX
/* See if we can first get the GPIO if needed */
if (pmic->gpio_en)
ret = gpio_request(pmic->gpio, "PMIC_GPIO");
@@ -465,7 +462,7 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
/* Pull the GPIO low to select SET0 register, while we program SET1 */
if (pmic->gpio_en)
gpio_direction_output(pmic->gpio, 0);
-#endif
+
/* convert to uV for better accuracy in the calculations */
offset *= 1000;
@@ -476,10 +473,8 @@ void do_scale_vcore(u32 vcore_reg, u32 volt_mv, struct pmic_data *pmic)
if (pmic->pmic_write(pmic->i2c_slave_addr, vcore_reg, offset_code))
printf("Scaling voltage failed for 0x%x\n", vcore_reg);
-#ifndef CONFIG_DRA7XX
if (pmic->gpio_en)
gpio_direction_output(pmic->gpio, 1);
-#endif
}
static u32 optimize_vcore_voltage(struct volts const *v)
@@ -534,7 +529,6 @@ void __weak recalibrate_iodelay(void)
*/
void scale_vcores(struct vcores_data const *vcores)
{
-#if defined(CONFIG_DRA7XX)
int i;
struct volts *pv = (struct volts *)vcores;
struct volts *px;
@@ -594,7 +588,16 @@ void scale_vcores(struct vcores_data const *vcores)
vcores->mpu.abb_tx_done_mask,
OMAP_ABB_FAST_OPP);
- /* The .mm member is not used for the DRA7xx */
+ debug("mm: %d\n", vcores->mm.value);
+ do_scale_vcore(vcores->mm.addr, vcores->mm.value, vcores->mm.pmic);
+ /* Configure MM ABB LDO after scale */
+ abb_setup(vcores->mm.efuse.reg,
+ (*ctrl)->control_wkup_ldovbb_mm_voltage_ctrl,
+ (*prcm)->prm_abbldo_mm_setup,
+ (*prcm)->prm_abbldo_mm_ctrl,
+ (*prcm)->prm_irqstatus_mpu,
+ vcores->mm.abb_tx_done_mask,
+ OMAP_ABB_FAST_OPP);
debug("gpu: %d\n", vcores->gpu.value);
do_scale_vcore(vcores->gpu.addr, vcores->gpu.value, vcores->gpu.pmic);
@@ -626,56 +629,6 @@ void scale_vcores(struct vcores_data const *vcores)
(*prcm)->prm_irqstatus_mpu,
vcores->iva.abb_tx_done_mask,
OMAP_ABB_FAST_OPP);
- /* Might need udelay(1000) here if debug is enabled to see all prints */
-#else
- u32 val;
-
- val = optimize_vcore_voltage(&vcores->core);
- do_scale_vcore(vcores->core.addr, val, vcores->core.pmic);
-
- /*
- * IO delay recalibration should be done immediately after
- * adjusting AVS voltages for VDD_CORE_L.
- * Respective boards should call __recalibrate_iodelay()
- * with proper mux, virtual and manual mode configurations.
- */
-#ifdef CONFIG_IODELAY_RECALIBRATION
- recalibrate_iodelay();
-#endif
-
- val = optimize_vcore_voltage(&vcores->mpu);
- do_scale_vcore(vcores->mpu.addr, val, vcores->mpu.pmic);
-
- /* Configure MPU ABB LDO after scale */
- abb_setup(vcores->mpu.efuse.reg,
- (*ctrl)->control_wkup_ldovbb_mpu_voltage_ctrl,
- (*prcm)->prm_abbldo_mpu_setup,
- (*prcm)->prm_abbldo_mpu_ctrl,
- (*prcm)->prm_irqstatus_mpu_2,
- vcores->mpu.abb_tx_done_mask,
- OMAP_ABB_FAST_OPP);
-
- val = optimize_vcore_voltage(&vcores->mm);
- do_scale_vcore(vcores->mm.addr, val, vcores->mm.pmic);
-
- /* Configure MM ABB LDO after scale */
- abb_setup(vcores->mm.efuse.reg,
- (*ctrl)->control_wkup_ldovbb_mm_voltage_ctrl,
- (*prcm)->prm_abbldo_mm_setup,
- (*prcm)->prm_abbldo_mm_ctrl,
- (*prcm)->prm_irqstatus_mpu,
- vcores->mm.abb_tx_done_mask,
- OMAP_ABB_FAST_OPP);
-
- val = optimize_vcore_voltage(&vcores->gpu);
- do_scale_vcore(vcores->gpu.addr, val, vcores->gpu.pmic);
-
- val = optimize_vcore_voltage(&vcores->eve);
- do_scale_vcore(vcores->eve.addr, val, vcores->eve.pmic);
-
- val = optimize_vcore_voltage(&vcores->iva);
- do_scale_vcore(vcores->iva.addr, val, vcores->iva.pmic);
-#endif
}
static inline void enable_clock_domain(u32 const clkctrl_reg, u32 enable_mode)
diff --git a/arch/arm/cpu/armv7/omap-common/config_secure.mk b/arch/arm/cpu/armv7/omap-common/config_secure.mk
index c7bb101..1122439 100644
--- a/arch/arm/cpu/armv7/omap-common/config_secure.mk
+++ b/arch/arm/cpu/armv7/omap-common/config_secure.mk
@@ -12,8 +12,8 @@ cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
$(if $(KBUILD_VERBOSE:1=), >/dev/null)
else
cmd_mkomapsecimg = $(TI_SECURE_DEV_PKG)/scripts/create-boot-image.sh \
- $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
- $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+ $(patsubst u-boot_HS_%,%,$(@F)) $< $@ $(CONFIG_ISW_ENTRY_ADDR) \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
endif
else
cmd_mkomapsecimg = echo "WARNING:" \
@@ -25,14 +25,33 @@ cmd_mkomapsecimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
"variable must be defined for TI secure devices. $@ was NOT created!"
endif
+ifdef CONFIG_SPL_LOAD_FIT
+quiet_cmd_omapsecureimg = SECURE $@
+ifneq ($(TI_SECURE_DEV_PKG),)
+ifneq ($(wildcard $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh),)
+cmd_omapsecureimg = $(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh \
+ $< $@ \
+ $(if $(KBUILD_VERBOSE:1=), >/dev/null)
+else
+cmd_omapsecureimg = echo "WARNING:" \
+ "$(TI_SECURE_DEV_PKG)/scripts/secure-binary-image.sh not found." \
+ "$@ was NOT created!"; cp $< $@
+endif
+else
+cmd_omapsecureimg = echo "WARNING: TI_SECURE_DEV_PKG environment" \
+ "variable must be defined for TI secure devices." \
+ "$@ was NOT created!"; cp $< $@
+endif
+endif
+
+
# Standard X-LOADER target (QPSI, NOR flash)
u-boot-spl_HS_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For MLO targets (SD card boot) the final file name
-# that is copied to the SD card fAT partition must
-# be MLO, so we make a copy of the output file to a
-# new file with that name
+# For MLO targets (SD card boot) the final file name that is copied to the SD
+# card FAT partition must be MLO, so we make a copy of the output file to a new
+# file with that name
u-boot-spl_HS_MLO: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
@if [ -f $@ ]; then \
@@ -51,16 +70,44 @@ u-boot-spl_HS_ULO: $(obj)/u-boot-spl.bin
u-boot-spl_HS_ISSW: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For SPI flash on AM335x and AM43xx, these
-# require special byte swap handling so we use
-# the SPI_X-LOADER target instead of X-LOADER
-# and let the create-boot-image.sh script handle
-# that
+# For SPI flash on AM335x and AM43xx, these require special byte swap handling
+# so we use the SPI_X-LOADER target instead of X-LOADER and let the
+# create-boot-image.sh script handle that
u-boot-spl_HS_SPI_X-LOADER: $(obj)/u-boot-spl.bin
$(call if_changed,mkomapsecimg)
-# For supporting single stage XiP QSPI on AM43xx, the
-# image is a full u-boot file, not an SPL. In this case
-# the mkomapsecimg command looks for a u-boot-HS_* prefix
+# For supporting single stage XiP QSPI on AM43xx, the image is a full u-boot
+# file, not an SPL. In this case the mkomapsecimg command looks for a
+# u-boot-HS_* prefix
u-boot_HS_XIP_X-LOADER: $(obj)/u-boot.bin
$(call if_changed,mkomapsecimg)
+
+# For supporting the SPL loading and interpreting of FIT images whose
+# components are pre-processed before being integrated into the FIT image in
+# order to secure them in some way
+ifdef CONFIG_SPL_LOAD_FIT
+
+MKIMAGEFLAGS_u-boot_HS.img = -f auto -A $(ARCH) -T firmware -C none -O u-boot \
+ -a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
+ -n "U-Boot $(UBOOTRELEASE) for $(BOARD) board" -E \
+ $(patsubst %,-b arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+
+OF_LIST_TARGETS = $(patsubst %,arch/$(ARCH)/dts/%.dtb,$(subst ",,$(CONFIG_OF_LIST)))
+$(OF_LIST_TARGETS): dtbs
+
+%_HS.dtb: %.dtb
+ $(call if_changed,omapsecureimg)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ $<; \
+ fi
+
+u-boot-nodtb_HS.bin: u-boot-nodtb.bin
+ $(call if_changed,omapsecureimg)
+
+u-boot_HS.img: u-boot-nodtb_HS.bin u-boot.img $(patsubst %.dtb,%_HS.dtb,$(OF_LIST_TARGETS))
+ $(call if_changed,mkimage)
+ $(Q)if [ -f $@ ]; then \
+ cp -f $@ u-boot.img; \
+ fi
+
+endif
diff --git a/arch/arm/cpu/armv7/omap-common/emif-common.c b/arch/arm/cpu/armv7/omap-common/emif-common.c
index 9a9c764..2b79010 100644
--- a/arch/arm/cpu/armv7/omap-common/emif-common.c
+++ b/arch/arm/cpu/armv7/omap-common/emif-common.c
@@ -37,7 +37,8 @@ void set_lpmode_selfrefresh(u32 base)
void force_emif_self_refresh()
{
set_lpmode_selfrefresh(EMIF1_BASE);
- set_lpmode_selfrefresh(EMIF2_BASE);
+ if (!is_dra72x())
+ set_lpmode_selfrefresh(EMIF2_BASE);
}
inline u32 emif_num(u32 base)
diff --git a/arch/arm/cpu/armv7/omap-common/hwinit-common.c b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
index 2f9693f..f317293 100644
--- a/arch/arm/cpu/armv7/omap-common/hwinit-common.c
+++ b/arch/arm/cpu/armv7/omap-common/hwinit-common.c
@@ -147,8 +147,7 @@ void early_system_init(void)
hw_data_init();
#ifdef CONFIG_SPL_BUILD
- if (warm_reset() &&
- (is_omap44xx() || (omap_revision() == OMAP5430_ES1_0)))
+ if (warm_reset())
force_emif_self_refresh();
#endif
watchdog_init();
diff --git a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
index 5283135..66a3b3d 100644
--- a/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
+++ b/arch/arm/cpu/armv7/omap-common/lowlevel_init.S
@@ -16,9 +16,10 @@
#include <asm/arch/spl.h>
#include <linux/linkage.h>
+.arch_extension sec
+
#ifdef CONFIG_SPL
ENTRY(save_boot_params)
-
ldr r1, =OMAP_SRAM_SCRATCH_BOOT_PARAMS
str r0, [r1]
b save_boot_params_ret
@@ -26,14 +27,40 @@ ENDPROC(save_boot_params)
#endif
ENTRY(omap_smc1)
- PUSH {r4-r12, lr} @ save registers - ROM code may pollute
+ push {r4-r12, lr} @ save registers - ROM code may pollute
@ our registers
- MOV r12, r0 @ Service
- MOV r0, r1 @ Argument
- DSB
- DMB
- .word 0xe1600070 @ SMC #0 - hand assembled for GCC versions
- @ call ROM Code API for the service requested
+ mov r12, r0 @ Service
+ mov r0, r1 @ Argument
- POP {r4-r12, pc}
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+ @ call ROM Code API for the service requested
+ pop {r4-r12, pc}
ENDPROC(omap_smc1)
+
+ENTRY(omap_smc_sec)
+ push {r4-r12, lr} @ save registers - ROM code may pollute
+ @ our registers
+ mov r6, #0xFF @ Indicate new Task call
+ mov r12, #0x00 @ Secure Service ID in R12
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+ b omap_smc_sec_end @ exit at end of the service execution
+ nop
+
+ @ In case of IRQ happening in Secure, then ARM will branch here.
+ @ At that moment, IRQ will be pending and ARM will jump to Non Secure
+ @ IRQ handler
+ mov r12, #0xFE
+
+ dsb
+ dmb
+ smc 0 @ SMC #0 to enter monitor mode
+
+omap_smc_sec_end:
+ pop {r4-r12, pc}
+ENDPROC(omap_smc_sec)
diff --git a/arch/arm/cpu/armv7/omap-common/mem-common.c b/arch/arm/cpu/armv7/omap-common/mem-common.c
index fc4290c..d72e82e 100644
--- a/arch/arm/cpu/armv7/omap-common/mem-common.c
+++ b/arch/arm/cpu/armv7/omap-common/mem-common.c
@@ -20,8 +20,19 @@
#include <asm/arch/sys_proto.h>
#include <command.h>
#include <linux/mtd/omap_gpmc.h>
+#include <jffs2/load_kernel.h>
-struct gpmc *gpmc_cfg;
+const struct gpmc *gpmc_cfg = (struct gpmc *)GPMC_BASE;
+
+#if defined(CONFIG_NOR)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NOR;
+#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_NAND;
+#elif defined(CONFIG_CMD_ONENAND)
+char gpmc_cs0_flash = MTD_DEV_TYPE_ONENAND;
+#else
+char gpmc_cs0_flash = -1;
+#endif
#if defined(CONFIG_OMAP34XX)
/********************************************************
@@ -50,8 +61,8 @@ u32 mem_ok(u32 cs)
}
#endif
-void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
- u32 size)
+void enable_gpmc_cs_config(const u32 *gpmc_config, const struct gpmc_cs *cs,
+ u32 base, u32 size)
{
writel(0, &cs->config7);
sdelay(1000);
@@ -68,6 +79,81 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
sdelay(2000);
}
+void set_gpmc_cs0(int flash_type)
+{
+ const u32 *gpmc_regs;
+ u32 base, size;
+#if defined(CONFIG_NOR)
+ const u32 gpmc_regs_nor[GPMC_MAX_REG] = {
+ STNOR_GPMC_CONFIG1,
+ STNOR_GPMC_CONFIG2,
+ STNOR_GPMC_CONFIG3,
+ STNOR_GPMC_CONFIG4,
+ STNOR_GPMC_CONFIG5,
+ STNOR_GPMC_CONFIG6,
+ STNOR_GPMC_CONFIG7
+ };
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+ const u32 gpmc_regs_nand[GPMC_MAX_REG] = {
+ M_NAND_GPMC_CONFIG1,
+ M_NAND_GPMC_CONFIG2,
+ M_NAND_GPMC_CONFIG3,
+ M_NAND_GPMC_CONFIG4,
+ M_NAND_GPMC_CONFIG5,
+ M_NAND_GPMC_CONFIG6,
+ 0
+ };
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+ const u32 gpmc_regs_onenand[GPMC_MAX_REG] = {
+ ONENAND_GPMC_CONFIG1,
+ ONENAND_GPMC_CONFIG2,
+ ONENAND_GPMC_CONFIG3,
+ ONENAND_GPMC_CONFIG4,
+ ONENAND_GPMC_CONFIG5,
+ ONENAND_GPMC_CONFIG6,
+ 0
+ };
+#endif
+
+ switch (flash_type) {
+#if defined(CONFIG_NOR)
+ case MTD_DEV_TYPE_NOR:
+ gpmc_regs = gpmc_regs_nor;
+ base = CONFIG_SYS_FLASH_BASE;
+ size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M :
+ ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M :
+ GPMC_SIZE_16M)));
+ break;
+#endif
+#if defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
+ case MTD_DEV_TYPE_NAND:
+ gpmc_regs = gpmc_regs_nand;
+ base = CONFIG_SYS_NAND_BASE;
+ size = GPMC_SIZE_16M;
+ break;
+#endif
+#if defined(CONFIG_CMD_ONENAND)
+ case MTD_DEV_TYPE_ONENAND:
+ gpmc_regs = gpmc_regs_onenand;
+ base = CONFIG_SYS_ONENAND_BASE;
+ size = GPMC_SIZE_128M;
+ break;
+#endif
+ default:
+ /* disable the GPMC0 config set by ROM code */
+ writel(0, &gpmc_cfg->cs[0].config7);
+ sdelay(1000);
+ return;
+ }
+
+ /* enable chip-select specific configurations */
+ enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+}
+
/*****************************************************
* gpmc_init(): init gpmc bus
* Init GPMC for x16, MuxMode (SDRAM in x32).
@@ -75,70 +161,14 @@ void enable_gpmc_cs_config(const u32 *gpmc_config, struct gpmc_cs *cs, u32 base,
*****************************************************/
void gpmc_init(void)
{
- /* putting a blanket check on GPMC based on ZeBu for now */
- gpmc_cfg = (struct gpmc *)GPMC_BASE;
-#if defined(CONFIG_NOR)
-/* configure GPMC for NOR */
- const u32 gpmc_regs[GPMC_MAX_REG] = { STNOR_GPMC_CONFIG1,
- STNOR_GPMC_CONFIG2,
- STNOR_GPMC_CONFIG3,
- STNOR_GPMC_CONFIG4,
- STNOR_GPMC_CONFIG5,
- STNOR_GPMC_CONFIG6,
- STNOR_GPMC_CONFIG7
- };
- u32 base = CONFIG_SYS_FLASH_BASE;
- u32 size = (CONFIG_SYS_FLASH_SIZE > 0x08000000) ? GPMC_SIZE_256M :
- /* > 64MB */ ((CONFIG_SYS_FLASH_SIZE > 0x04000000) ? GPMC_SIZE_128M :
- /* > 32MB */ ((CONFIG_SYS_FLASH_SIZE > 0x02000000) ? GPMC_SIZE_64M :
- /* > 16MB */ ((CONFIG_SYS_FLASH_SIZE > 0x01000000) ? GPMC_SIZE_32M :
- /* min 16MB */ GPMC_SIZE_16M)));
-#elif defined(CONFIG_NAND) || defined(CONFIG_CMD_NAND)
-/* configure GPMC for NAND */
- const u32 gpmc_regs[GPMC_MAX_REG] = { M_NAND_GPMC_CONFIG1,
- M_NAND_GPMC_CONFIG2,
- M_NAND_GPMC_CONFIG3,
- M_NAND_GPMC_CONFIG4,
- M_NAND_GPMC_CONFIG5,
- M_NAND_GPMC_CONFIG6,
- 0
- };
- u32 base = CONFIG_SYS_NAND_BASE;
- u32 size = GPMC_SIZE_16M;
-
-#elif defined(CONFIG_CMD_ONENAND)
- const u32 gpmc_regs[GPMC_MAX_REG] = { ONENAND_GPMC_CONFIG1,
- ONENAND_GPMC_CONFIG2,
- ONENAND_GPMC_CONFIG3,
- ONENAND_GPMC_CONFIG4,
- ONENAND_GPMC_CONFIG5,
- ONENAND_GPMC_CONFIG6,
- 0
- };
- u32 size = GPMC_SIZE_128M;
- u32 base = CONFIG_SYS_ONENAND_BASE;
-#else
- const u32 gpmc_regs[GPMC_MAX_REG] = { 0, 0, 0, 0, 0, 0, 0 };
- u32 size = 0;
- u32 base = 0;
-#endif
/* global settings */
writel(0x00000008, &gpmc_cfg->sysconfig);
writel(0x00000000, &gpmc_cfg->irqstatus);
writel(0x00000000, &gpmc_cfg->irqenable);
/* disable timeout, set a safe reset value */
writel(0x00001ff0, &gpmc_cfg->timeout_control);
-#ifdef CONFIG_NOR
- writel(0x00000200, &gpmc_cfg->config);
-#else
- writel(0x00000012, &gpmc_cfg->config);
-#endif
- /*
- * Disable the GPMC0 config set by ROM code
- */
- writel(0, &gpmc_cfg->cs[0].config7);
- sdelay(1000);
- /* enable chip-select specific configurations */
- if (base != 0)
- enable_gpmc_cs_config(gpmc_regs, &gpmc_cfg->cs[0], base, size);
+ writel(gpmc_cs0_flash == MTD_DEV_TYPE_NOR ?
+ 0x00000200 : 0x00000012, &gpmc_cfg->config);
+
+ set_gpmc_cs0(gpmc_cs0_flash);
}
diff --git a/arch/arm/cpu/armv7/omap-common/sec-common.c b/arch/arm/cpu/armv7/omap-common/sec-common.c
new file mode 100644
index 0000000..246a239
--- /dev/null
+++ b/arch/arm/cpu/armv7/omap-common/sec-common.c
@@ -0,0 +1,139 @@
+/*
+ *
+ * Common security related functions for OMAP devices
+ *
+ * (C) Copyright 2016
+ * Texas Instruments, <www.ti.com>
+ *
+ * Daniel Allred <d-allred@ti.com>
+ * Andreas Dannenberg <dannenberg@ti.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <stdarg.h>
+
+#include <asm/arch/sys_proto.h>
+#include <asm/omap_common.h>
+#include <asm/omap_sec_common.h>
+#include <asm/spl.h>
+#include <spl.h>
+
+/* Index for signature verify ROM API */
+#define API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX (0x0000000E)
+
+static uint32_t secure_rom_call_args[5] __aligned(ARCH_DMA_MINALIGN);
+
+u32 secure_rom_call(u32 service, u32 proc_id, u32 flag, ...)
+{
+ int i;
+ u32 num_args;
+ va_list ap;
+
+ va_start(ap, flag);
+
+ num_args = va_arg(ap, u32);
+
+ if (num_args > 4)
+ return 1;
+
+ /* Copy args to aligned args structure */
+ for (i = 0; i < num_args; i++)
+ secure_rom_call_args[i + 1] = va_arg(ap, u32);
+
+ secure_rom_call_args[0] = num_args;
+
+ va_end(ap);
+
+ /* if data cache is enabled, flush the aligned args structure */
+ flush_dcache_range(
+ (unsigned int)&secure_rom_call_args[0],
+ (unsigned int)&secure_rom_call_args[0] +
+ roundup(sizeof(secure_rom_call_args), ARCH_DMA_MINALIGN));
+
+ return omap_smc_sec(service, proc_id, flag, secure_rom_call_args);
+}
+
+static u32 find_sig_start(char *image, size_t size)
+{
+ char *image_end = image + size;
+ char *sig_start_magic = "CERT_";
+ int magic_str_len = strlen(sig_start_magic);
+ char *ch;
+
+ while (--image_end > image) {
+ if (*image_end == '_') {
+ ch = image_end - magic_str_len + 1;
+ if (!strncmp(ch, sig_start_magic, magic_str_len))
+ return (u32)ch;
+ }
+ }
+ return 0;
+}
+
+int secure_boot_verify_image(void **image, size_t *size)
+{
+ int result = 1;
+ u32 cert_addr, sig_addr;
+ size_t cert_size;
+
+ /* Perform cache writeback on input buffer */
+ flush_dcache_range(
+ (u32)*image,
+ (u32)*image + roundup(*size, ARCH_DMA_MINALIGN));
+
+ cert_addr = (uint32_t)*image;
+ sig_addr = find_sig_start((char *)*image, *size);
+
+ if (sig_addr == 0) {
+ printf("No signature found in image!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ *size = sig_addr - cert_addr; /* Subtract out the signature size */
+ cert_size = *size;
+
+ /* Check if image load address is 32-bit aligned */
+ if (!IS_ALIGNED(cert_addr, 4)) {
+ printf("Image is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Image size also should be multiple of 4 */
+ if (!IS_ALIGNED(cert_size, 4)) {
+ printf("Image size is not 4-byte aligned!\n");
+ result = 1;
+ goto auth_exit;
+ }
+
+ /* Call ROM HAL API to verify certificate signature */
+ debug("%s: load_addr = %x, size = %x, sig_addr = %x\n", __func__,
+ cert_addr, cert_size, sig_addr);
+
+ result = secure_rom_call(
+ API_HAL_KM_VERIFYCERTIFICATESIGNATURE_INDEX, 0, 0,
+ 4, cert_addr, cert_size, sig_addr, 0xFFFFFFFF);
+auth_exit:
+ if (result != 0) {
+ printf("Authentication failed!\n");
+ printf("Return Value = %08X\n", result);
+ hang();
+ }
+
+ /*
+ * Output notification of successful authentication as well the name of
+ * the signing certificate used to re-assure the user that the secure
+ * code is being processed as expected. However suppress any such log
+ * output in case of building for SPL and booting via YMODEM. This is
+ * done to avoid disturbing the YMODEM serial protocol transactions.
+ */
+ if (!(IS_ENABLED(CONFIG_SPL_BUILD) &&
+ IS_ENABLED(CONFIG_SPL_YMODEM_SUPPORT) &&
+ spl_boot_device() == BOOT_DEVICE_UART))
+ printf("Authentication passed: %s\n", (char *)sig_addr);
+
+ return result;
+}
diff --git a/arch/arm/cpu/armv7/omap3/Kconfig b/arch/arm/cpu/armv7/omap3/Kconfig
index 85d6436..99a25f9 100644
--- a/arch/arm/cpu/armv7/omap3/Kconfig
+++ b/arch/arm/cpu/armv7/omap3/Kconfig
@@ -6,55 +6,39 @@ choice
config TARGET_AM3517_EVM
bool "AM3517 EVM"
- select SUPPORT_SPL
config TARGET_MT_VENTOUX
bool "TeeJet Mt.Ventoux"
- select SUPPORT_SPL
config TARGET_OMAP3_BEAGLE
bool "TI OMAP3 BeagleBoard"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
config TARGET_CM_T35
bool "CompuLab CM-T3530 and CM-T3730 boards"
- select SUPPORT_SPL
config TARGET_CM_T3517
bool "CompuLab CM-T3517 boards"
config TARGET_DEVKIT8000
bool "TimLL OMAP3 Devkit8000"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
config TARGET_OMAP3_EVM
bool "TI OMAP3 EVM"
- select SUPPORT_SPL
-
-config TARGET_OMAP3_EVM_QUICK_MMC
- bool "TI OMAP3 EVM Quick MMC"
- select SUPPORT_SPL
-
-config TARGET_OMAP3_EVM_QUICK_NAND
- bool "TI OMAP3 EVM Quick NAND"
- select SUPPORT_SPL
config TARGET_OMAP3_IGEP00X0
bool "IGEP"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
config TARGET_OMAP3_OVERO
bool "OMAP35xx Gumstix Overo"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
@@ -67,51 +51,42 @@ config TARGET_OMAP3_ZOOM1
config TARGET_AM3517_CRANE
bool "am3517_crane"
- select SUPPORT_SPL
config TARGET_OMAP3_PANDORA
bool "OMAP3 Pandora"
config TARGET_ECO5PK
bool "ECO5PK"
- select SUPPORT_SPL
config TARGET_TRICORDER
bool "Tricorder"
- select SUPPORT_SPL
config TARGET_MCX
bool "MCX"
- select SUPPORT_SPL
config TARGET_OMAP3_LOGIC
bool "OMAP3 Logic"
select DM
select DM_SERIAL
select DM_GPIO
- select SUPPORT_SPL
config TARGET_NOKIA_RX51
bool "Nokia RX51"
config TARGET_TAO3530
bool "TAO3530"
- select SUPPORT_SPL
config TARGET_TWISTER
bool "Twister"
- select SUPPORT_SPL
config TARGET_OMAP3_CAIRO
bool "QUIPOS CAIRO"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
config TARGET_SNIPER
bool "LG Optimus Black"
- select SUPPORT_SPL
select DM
select DM_SERIAL
select DM_GPIO
diff --git a/arch/arm/cpu/armv7/omap3/spl_id_nand.c b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
index db6de09..0e2f0a2 100644
--- a/arch/arm/cpu/armv7/omap3/spl_id_nand.c
+++ b/arch/arm/cpu/armv7/omap3/spl_id_nand.c
@@ -13,62 +13,45 @@
*/
#include <common.h>
+#include <jffs2/load_kernel.h>
#include <linux/mtd/nand.h>
+#include <linux/mtd/omap_gpmc.h>
#include <asm/io.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/mem.h>
-static struct gpmc *gpmc_config = (struct gpmc *)GPMC_BASE;
-
-/* nand_command: Send a flash command to the flash chip */
-static void nand_command(u8 command)
-{
- writeb(command, &gpmc_config->cs[0].nand_cmd);
-
- if (command == NAND_CMD_RESET) {
- unsigned char ret_val;
- writeb(NAND_CMD_STATUS, &gpmc_config->cs[0].nand_cmd);
- do {
- /* Wait until ready */
- ret_val = readl(&gpmc_config->cs[0].nand_dat);
- } while ((ret_val & NAND_STATUS_READY) != NAND_STATUS_READY);
- }
-}
-
/*
* Many boards will want to know the results of the NAND_CMD_READID command
* in order to decide what to do about DDR initialization. This function
* allows us to do that very early and to pass those results back to the
* board so it can make whatever decisions need to be made.
*/
-void identify_nand_chip(int *mfr, int *id)
+int identify_nand_chip(int *mfr, int *id)
{
- /* Make sure that we have setup GPMC for NAND correctly. */
- writel(M_NAND_GPMC_CONFIG1, &gpmc_config->cs[0].config1);
- writel(M_NAND_GPMC_CONFIG2, &gpmc_config->cs[0].config2);
- writel(M_NAND_GPMC_CONFIG3, &gpmc_config->cs[0].config3);
- writel(M_NAND_GPMC_CONFIG4, &gpmc_config->cs[0].config4);
- writel(M_NAND_GPMC_CONFIG5, &gpmc_config->cs[0].config5);
- writel(M_NAND_GPMC_CONFIG6, &gpmc_config->cs[0].config6);
+ int loops = 1000;
- /*
- * Enable the config. The CS size goes in bits 11:8. We set
- * bit 6 to enable the CS and the base address goes into bits 5:0.
- */
- writel((GPMC_SIZE_128M << 8) | (GPMC_CS_ENABLE << 6) |
- ((NAND_BASE >> 24) & GPMC_BASEADDR_MASK),
- &gpmc_config->cs[0].config7);
+ /* Make sure that we have setup GPMC for NAND correctly. */
+ set_gpmc_cs0(MTD_DEV_TYPE_NAND);
sdelay(2000);
/* Issue a RESET and then READID */
- nand_command(NAND_CMD_RESET);
- nand_command(NAND_CMD_READID);
+ writeb(NAND_CMD_RESET, &gpmc_cfg->cs[0].nand_cmd);
+ writeb(NAND_CMD_STATUS, &gpmc_cfg->cs[0].nand_cmd);
+ while ((readl(&gpmc_cfg->cs[0].nand_dat) & NAND_STATUS_READY)
+ != NAND_STATUS_READY) {
+ sdelay(100);
+ if (--loops == 0)
+ return 1;
+ }
+ writeb(NAND_CMD_READID, &gpmc_cfg->cs[0].nand_cmd);
/* Set the address to read to 0x0 */
- writeb(0x0, &gpmc_config->cs[0].nand_adr);
+ writeb(0x0, &gpmc_cfg->cs[0].nand_adr);
/* Read off the manufacturer and device id. */
- *mfr = readb(&gpmc_config->cs[0].nand_dat);
- *id = readb(&gpmc_config->cs[0].nand_dat);
+ *mfr = readb(&gpmc_cfg->cs[0].nand_dat);
+ *id = readb(&gpmc_cfg->cs[0].nand_dat);
+
+ return 0;
}
diff --git a/arch/arm/cpu/armv7/omap5/Kconfig b/arch/arm/cpu/armv7/omap5/Kconfig
index 4fb5ef9..a8600b1 100644
--- a/arch/arm/cpu/armv7/omap5/Kconfig
+++ b/arch/arm/cpu/armv7/omap5/Kconfig
@@ -13,6 +13,7 @@ config TARGET_OMAP5_UEVM
config TARGET_DRA7XX_EVM
bool "TI DRA7XX"
select TI_I2C_BOARD_DETECT
+ select PHYS_64BIT
config TARGET_AM57XX_EVM
bool "AM57XX"
diff --git a/arch/arm/cpu/armv7/omap5/config.mk b/arch/arm/cpu/armv7/omap5/config.mk
index a7e55a5..286ca86 100644
--- a/arch/arm/cpu/armv7/omap5/config.mk
+++ b/arch/arm/cpu/armv7/omap5/config.mk
@@ -15,5 +15,8 @@ else
ALL-y += MLO
endif
else
+ifeq ($(CONFIG_TI_SECURE_DEVICE),y)
+ALL-$(CONFIG_SPL_LOAD_FIT) += u-boot_HS.img
+endif
ALL-y += u-boot.img
endif
diff --git a/arch/arm/cpu/armv7/omap5/hw_data.c b/arch/arm/cpu/armv7/omap5/hw_data.c
index 62dd275..fc99135 100644
--- a/arch/arm/cpu/armv7/omap5/hw_data.c
+++ b/arch/arm/cpu/armv7/omap5/hw_data.c
@@ -160,7 +160,7 @@ static const struct dpll_params per_dpll_params_768mhz_es2[NUM_SYS_CLKS] = {
static const struct dpll_params per_dpll_params_768mhz_dra7xx[NUM_SYS_CLKS] = {
{32, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 12 MHz */
- {96, 4, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 20 MHz */
+ {96, 4, 4, 1, 3, 4, 10, 2, -1, -1, -1, -1}, /* 20 MHz */
{160, 6, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 16.8 MHz */
{20, 0, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 19.2 MHz */
{192, 12, 4, 1, 3, 4, 4, 2, -1, -1, -1, -1}, /* 26 MHz */
@@ -318,6 +318,7 @@ struct pmic_data palmas = {
.i2c_slave_addr = SMPS_I2C_SLAVE_ADDR,
.pmic_bus_init = sri2c_init,
.pmic_write = omap_vc_bypass_send_value,
+ .gpio_en = 0,
};
/* The TPS659038 and TPS65917 are software-compatible, use common struct */
@@ -332,6 +333,7 @@ struct pmic_data tps659038 = {
.i2c_slave_addr = TPS659038_I2C_SLAVE_ADDR,
.pmic_bus_init = gpi2c_init,
.pmic_write = palmas_i2c_write_u8,
+ .gpio_en = 0,
};
struct vcores_data omap5430_volts = {
diff --git a/arch/arm/cpu/armv7/psci-common.c b/arch/arm/cpu/armv7/psci-common.c
new file mode 100644
index 0000000..8cb4107
--- /dev/null
+++ b/arch/arm/cpu/armv7/psci-common.c
@@ -0,0 +1,39 @@
+/*
+ * Common PSCI functions
+ *
+ * Copyright (C) 2016 Chen-Yu Tsai
+ * Author: Chen-Yu Tsai <wens@csie.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <config.h>
+#include <asm/armv7.h>
+#include <asm/macro.h>
+#include <asm/psci.h>
+#include <asm/secure.h>
+#include <linux/linkage.h>
+
+static u32 psci_target_pc[CONFIG_ARMV7_PSCI_NR_CPUS] __secure_data = { 0 };
+
+void __secure psci_save_target_pc(int cpu, u32 pc)
+{
+ psci_target_pc[cpu] = pc;
+ dsb();
+}
+
+u32 __secure psci_get_target_pc(int cpu)
+{
+ return psci_target_pc[cpu];
+}
+
diff --git a/arch/arm/cpu/armv7/psci.S b/arch/arm/cpu/armv7/psci.S
index ab40837..f80f6e2 100644
--- a/arch/arm/cpu/armv7/psci.S
+++ b/arch/arm/cpu/armv7/psci.S
@@ -46,20 +46,62 @@ ENTRY(default_psci_vector)
ENDPROC(default_psci_vector)
.weak default_psci_vector
+ENTRY(psci_version)
ENTRY(psci_cpu_suspend)
ENTRY(psci_cpu_off)
ENTRY(psci_cpu_on)
+ENTRY(psci_affinity_info)
ENTRY(psci_migrate)
+ENTRY(psci_migrate_info_type)
+ENTRY(psci_migrate_info_up_cpu)
+ENTRY(psci_system_off)
+ENTRY(psci_system_reset)
+ENTRY(psci_features)
+ENTRY(psci_cpu_freeze)
+ENTRY(psci_cpu_default_suspend)
+ENTRY(psci_node_hw_state)
+ENTRY(psci_system_suspend)
+ENTRY(psci_set_suspend_mode)
+ENTRY(psi_stat_residency)
+ENTRY(psci_stat_count)
mov r0, #ARM_PSCI_RET_NI @ Return -1 (Not Implemented)
mov pc, lr
+ENDPROC(psci_stat_count)
+ENDPROC(psi_stat_residency)
+ENDPROC(psci_set_suspend_mode)
+ENDPROC(psci_system_suspend)
+ENDPROC(psci_node_hw_state)
+ENDPROC(psci_cpu_default_suspend)
+ENDPROC(psci_cpu_freeze)
+ENDPROC(psci_features)
+ENDPROC(psci_system_reset)
+ENDPROC(psci_system_off)
+ENDPROC(psci_migrate_info_up_cpu)
+ENDPROC(psci_migrate_info_type)
ENDPROC(psci_migrate)
+ENDPROC(psci_affinity_info)
ENDPROC(psci_cpu_on)
ENDPROC(psci_cpu_off)
ENDPROC(psci_cpu_suspend)
+ENDPROC(psci_version)
+.weak psci_version
.weak psci_cpu_suspend
.weak psci_cpu_off
.weak psci_cpu_on
+.weak psci_affinity_info
.weak psci_migrate
+.weak psci_migrate_info_type
+.weak psci_migrate_info_up_cpu
+.weak psci_system_off
+.weak psci_system_reset
+.weak psci_features
+.weak psci_cpu_freeze
+.weak psci_cpu_default_suspend
+.weak psci_node_hw_state
+.weak psci_system_suspend
+.weak psci_set_suspend_mode
+.weak psi_stat_residency
+.weak psci_stat_count
_psci_table:
.word ARM_PSCI_FN_CPU_SUSPEND
@@ -70,6 +112,42 @@ _psci_table:
.word psci_cpu_on
.word ARM_PSCI_FN_MIGRATE
.word psci_migrate
+ .word ARM_PSCI_0_2_FN_PSCI_VERSION
+ .word psci_version
+ .word ARM_PSCI_0_2_FN_CPU_SUSPEND
+ .word psci_cpu_suspend
+ .word ARM_PSCI_0_2_FN_CPU_OFF
+ .word psci_cpu_off
+ .word ARM_PSCI_0_2_FN_CPU_ON
+ .word psci_cpu_on
+ .word ARM_PSCI_0_2_FN_AFFINITY_INFO
+ .word psci_affinity_info
+ .word ARM_PSCI_0_2_FN_MIGRATE
+ .word psci_migrate
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE
+ .word psci_migrate_info_type
+ .word ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU
+ .word psci_migrate_info_up_cpu
+ .word ARM_PSCI_0_2_FN_SYSTEM_OFF
+ .word psci_system_off
+ .word ARM_PSCI_0_2_FN_SYSTEM_RESET
+ .word psci_system_reset
+ .word ARM_PSCI_1_0_FN_PSCI_FEATURES
+ .word psci_features
+ .word ARM_PSCI_1_0_FN_CPU_FREEZE
+ .word psci_cpu_freeze
+ .word ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND
+ .word psci_cpu_default_suspend
+ .word ARM_PSCI_1_0_FN_NODE_HW_STATE
+ .word psci_node_hw_state
+ .word ARM_PSCI_1_0_FN_SYSTEM_SUSPEND
+ .word psci_system_suspend
+ .word ARM_PSCI_1_0_FN_SET_SUSPEND_MODE
+ .word psci_set_suspend_mode
+ .word ARM_PSCI_1_0_FN_STAT_RESIDENCY
+ .word psi_stat_residency
+ .word ARM_PSCI_1_0_FN_STAT_COUNT
+ .word psci_stat_count
.word 0
.word 0
@@ -196,29 +274,56 @@ ENTRY(psci_cpu_off_common)
bx lr
ENDPROC(psci_cpu_off_common)
-@ expects CPU ID in r0 and returns stack top in r0
-ENTRY(psci_get_cpu_stack_top)
- mov r3, #0x400 @ 1kB of stack per CPU
- mul r0, r0, r3
-
- ldr r3, =psci_text_end @ end of monitor text
- add r3, r3, #0x2000 @ Skip two pages
- lsr r3, r3, #12 @ Align to start of page
- lsl r3, r3, #12
- sub r3, r3, #4 @ reserve 1 word for target PC
- sub r0, r3, r0 @ here's our stack!
-
+@ The stacks are allocated in reverse order, i.e.
+@ the stack for CPU0 has the highest memory address.
+@
+@ -------------------- __secure_stack_end
+@ | CPU0 target PC |
+@ |------------------|
+@ | |
+@ | CPU0 stack |
+@ | |
+@ |------------------| __secure_stack_end - 1KB
+@ | . |
+@ | . |
+@ | . |
+@ | . |
+@ -------------------- __secure_stack_start
+@
+@ This expects CPU ID in r0 and returns stack top in r0
+LENTRY(psci_get_cpu_stack_top)
+ @ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
+ ldr r3, =__secure_stack_end
+ sub r0, r3, r0, LSL #ARM_PSCI_STACK_SHIFT
+ sub r0, r0, #4 @ Save space for target PC
bx lr
ENDPROC(psci_get_cpu_stack_top)
+@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
+@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
+@ this function.
+ENTRY(psci_stack_setup)
+ mov r6, lr
+ mov r7, r0
+ bl psci_get_cpu_id @ CPU ID => r0
+ bl psci_get_cpu_stack_top @ stack top => r0
+ mov sp, r0
+ mov r0, r7
+ bx r6
+ENDPROC(psci_stack_setup)
+
+ENTRY(psci_arch_init)
+ mov pc, lr
+ENDPROC(psci_arch_init)
+.weak psci_arch_init
+
ENTRY(psci_cpu_entry)
bl psci_enable_smp
bl _nonsec_init
bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- ldr r0, [r0] @ target PC at stack top
+ bl psci_get_target_pc @ target PC => r0
b _do_nonsec_entry
ENDPROC(psci_cpu_entry)
diff --git a/arch/arm/cpu/armv7/sunxi/Makefile b/arch/arm/cpu/armv7/sunxi/Makefile
index c208510..b35b9df 100644
--- a/arch/arm/cpu/armv7/sunxi/Makefile
+++ b/arch/arm/cpu/armv7/sunxi/Makefile
@@ -14,7 +14,6 @@ obj-$(CONFIG_MACH_SUN8I_H3) += tzpc.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_ARMV7_PSCI) += psci.o
-obj-$(CONFIG_ARMV7_PSCI) += psci_head.o
endif
ifdef CONFIG_SPL_BUILD
diff --git a/arch/arm/cpu/armv7/sunxi/psci.c b/arch/arm/cpu/armv7/sunxi/psci.c
index a118e9d..766b8c7 100644
--- a/arch/arm/cpu/armv7/sunxi/psci.c
+++ b/arch/arm/cpu/armv7/sunxi/psci.c
@@ -17,11 +17,11 @@
#include <asm/gic.h>
#include <asm/io.h>
#include <asm/psci.h>
+#include <asm/secure.h>
#include <asm/system.h>
#include <linux/bitops.h>
-#define __secure __attribute__ ((section ("._secure.text")))
#define __irq __attribute__ ((interrupt ("IRQ")))
#define GICD_BASE (SUNXI_GIC400_BASE + GIC_DIST_OFFSET)
@@ -53,16 +53,16 @@ static void __secure __mdelay(u32 ms)
u32 reg = ONE_MS * ms;
cp15_write_cntp_tval(reg);
- ISB;
+ isb();
cp15_write_cntp_ctl(3);
do {
- ISB;
+ isb();
reg = cp15_read_cntp_ctl();
} while (!(reg & BIT(2)));
cp15_write_cntp_ctl(0);
- ISB;
+ isb();
}
static void __secure clamp_release(u32 __maybe_unused *clamp)
@@ -164,7 +164,7 @@ static u32 __secure cp15_read_scr(void)
static void __secure cp15_write_scr(u32 scr)
{
asm volatile ("mcr p15, 0, %0, c1, c1, 0" : : "r" (scr));
- ISB;
+ isb();
}
/*
@@ -190,7 +190,7 @@ void __secure __irq psci_fiq_enter(void)
/* End of interrupt */
writel(reg, GICC_BASE + GICC_EOIR);
- DSB;
+ dsb();
/* Get CPU number */
cpu = (reg >> 10) & 0x7;
@@ -209,9 +209,8 @@ int __secure psci_cpu_on(u32 __always_unused unused, u32 mpidr, u32 pc)
(struct sunxi_cpucfg_reg *)SUNXI_CPUCFG_BASE;
u32 cpu = (mpidr & 0x3);
- /* store target PC at target CPU stack top */
- writel(pc, psci_get_cpu_stack_top(cpu));
- DSB;
+ /* store target PC */
+ psci_save_target_pc(cpu, pc);
/* Set secondary core power on PC */
writel((u32)&psci_cpu_entry, &cpucfg->priv0);
@@ -243,14 +242,14 @@ void __secure psci_cpu_off(void)
/* Ask CPU0 via SGI15 to pull the rug... */
writel(BIT(16) | 15, GICD_BASE + GICD_SGIR);
- DSB;
+ dsb();
/* Wait to be turned off */
while (1)
wfi();
}
-void __secure sunxi_gic_init(void)
+void __secure psci_arch_init(void)
{
u32 reg;
diff --git a/arch/arm/cpu/armv7/sunxi/psci_head.S b/arch/arm/cpu/armv7/sunxi/psci_head.S
deleted file mode 100644
index 8fa823d..0000000
--- a/arch/arm/cpu/armv7/sunxi/psci_head.S
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Copyright (C) 2013 - ARM Ltd
- * Author: Marc Zyngier <marc.zyngier@arm.com>
- *
- * Based on code by Carl van Schaik <carl@ok-labs.com>.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include <config.h>
-#include <linux/linkage.h>
-
-#include <asm/arch-armv7/generictimer.h>
-#include <asm/gic.h>
-#include <asm/macro.h>
-#include <asm/psci.h>
-#include <asm/arch/cpu.h>
-
-/*
- * Memory layout:
- *
- * SECURE_RAM to text_end :
- * ._secure_text section
- * text_end to ALIGN_PAGE(text_end):
- * nothing
- * ALIGN_PAGE(text_end) to ALIGN_PAGE(text_end) + 0x1000)
- * 1kB of stack per CPU (4 CPUs max).
- */
-
- .pushsection ._secure.text, "ax"
-
- .arch_extension sec
-
-#define GICD_BASE (SUNXI_GIC400_BASE + 0x1000)
-#define GICC_BASE (SUNXI_GIC400_BASE + 0x2000)
-
-@ {r0, r1, r2, ip} from _do_nonsec_entry(kernel_entry, 0, machid, r2) in
-@ arch/arm/lib/bootm.c:boot_jump_linux() must remain unchanged across
-@ this function.
-ENTRY(psci_arch_init)
- mov r6, lr
- mov r7, r0
- bl psci_get_cpu_id @ CPU ID => r0
- bl psci_get_cpu_stack_top @ stack top => r0
- sub r0, r0, #4 @ Save space for target PC
- mov sp, r0
- mov r0, r7
- mov lr, r6
-
- push {r0, r1, r2, ip, lr}
- bl sunxi_gic_init
- pop {r0, r1, r2, ip, pc}
-ENDPROC(psci_arch_init)
-
-ENTRY(psci_text_end)
- .popsection
diff --git a/arch/arm/cpu/armv7/virt-dt.c b/arch/arm/cpu/armv7/virt-dt.c
index 32c368f..707dad4 100644
--- a/arch/arm/cpu/armv7/virt-dt.c
+++ b/arch/arm/cpu/armv7/virt-dt.c
@@ -26,69 +26,6 @@
#include <asm/armv7.h>
#include <asm/psci.h>
-static int fdt_psci(void *fdt)
-{
-#ifdef CONFIG_ARMV7_PSCI
- int nodeoff;
- int tmp;
-
- nodeoff = fdt_path_offset(fdt, "/cpus");
- if (nodeoff < 0) {
- printf("couldn't find /cpus\n");
- return nodeoff;
- }
-
- /* add 'enable-method = "psci"' to each cpu node */
- for (tmp = fdt_first_subnode(fdt, nodeoff);
- tmp >= 0;
- tmp = fdt_next_subnode(fdt, tmp)) {
- const struct fdt_property *prop;
- int len;
-
- prop = fdt_get_property(fdt, tmp, "device_type", &len);
- if (!prop)
- continue;
- if (len < 4)
- continue;
- if (strcmp(prop->data, "cpu"))
- continue;
-
- fdt_setprop_string(fdt, tmp, "enable-method", "psci");
- }
-
- nodeoff = fdt_path_offset(fdt, "/psci");
- if (nodeoff < 0) {
- nodeoff = fdt_path_offset(fdt, "/");
- if (nodeoff < 0)
- return nodeoff;
-
- nodeoff = fdt_add_subnode(fdt, nodeoff, "psci");
- if (nodeoff < 0)
- return nodeoff;
- }
-
- tmp = fdt_setprop_string(fdt, nodeoff, "compatible", "arm,psci");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_string(fdt, nodeoff, "method", "smc");
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_suspend", ARM_PSCI_FN_CPU_SUSPEND);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_off", ARM_PSCI_FN_CPU_OFF);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "cpu_on", ARM_PSCI_FN_CPU_ON);
- if (tmp)
- return tmp;
- tmp = fdt_setprop_u32(fdt, nodeoff, "migrate", ARM_PSCI_FN_MIGRATE);
- if (tmp)
- return tmp;
-#endif
- return 0;
-}
-
int armv7_apply_memory_carveout(u64 *start, u64 *size)
{
#ifdef CONFIG_ARMV7_SECURE_RESERVE_SIZE
diff --git a/arch/arm/cpu/armv7/virt-v7.c b/arch/arm/cpu/armv7/virt-v7.c
index 9c53306..d33e5c6 100644
--- a/arch/arm/cpu/armv7/virt-v7.c
+++ b/arch/arm/cpu/armv7/virt-v7.c
@@ -54,10 +54,12 @@ static void relocate_secure_section(void)
{
#ifdef CONFIG_ARMV7_SECURE_BASE
size_t sz = __secure_end - __secure_start;
+ unsigned long szflush = ALIGN(sz + 1, CONFIG_SYS_CACHELINE_SIZE);
memcpy((void *)CONFIG_ARMV7_SECURE_BASE, __secure_start, sz);
+
flush_dcache_range(CONFIG_ARMV7_SECURE_BASE,
- CONFIG_ARMV7_SECURE_BASE + sz + 1);
+ CONFIG_ARMV7_SECURE_BASE + szflush);
protect_secure_section();
invalidate_icache_all();
#endif