1. add basic psci support for imx7 chip. 2. support cpu_on and cpu_off. 3. switch to non-secure mode when boot linux kernel. 4. set csu allow accessing all peripherial register in non-secure mode. Signed-off-by: Frank Li <Frank.Li@freescale.com> Signed-off-by: Peng Fan <Peng.Fan@freescale.com> Cc: Stefano Babic <sbabic@denx.de> Cc: Fabio Estevam <fabio.estevam@freescale.com>master
parent
d47cb0b61a
commit
7de4703691
@ -0,0 +1,69 @@ |
||||
#include <asm/io.h> |
||||
#include <asm/psci.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 |
||||
#define GPC_PGC_C1 0x840 |
||||
|
||||
#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2 |
||||
|
||||
/* below is for i.MX7D */ |
||||
#define SRC_GPR1_MX7D 0x074 |
||||
#define SRC_A7RCR0 0x004 |
||||
#define SRC_A7RCR1 0x008 |
||||
|
||||
#define BP_SRC_A7RCR0_A7_CORE_RESET0 0 |
||||
#define BP_SRC_A7RCR1_A7_CORE1_ENABLE 1 |
||||
|
||||
static inline void imx_gpcv2_set_m_core_pgc(bool enable, u32 offset) |
||||
{ |
||||
writel(enable, GPC_IPS_BASE_ADDR + offset); |
||||
} |
||||
|
||||
__secure void imx_gpcv2_set_core1_power(bool pdn) |
||||
{ |
||||
u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ; |
||||
u32 val; |
||||
|
||||
imx_gpcv2_set_m_core_pgc(true, GPC_PGC_C1); |
||||
|
||||
val = readl(GPC_IPS_BASE_ADDR + reg); |
||||
val |= BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7; |
||||
writel(val, GPC_IPS_BASE_ADDR + reg); |
||||
|
||||
while ((readl(GPC_IPS_BASE_ADDR + reg) & |
||||
BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7) != 0) |
||||
; |
||||
|
||||
imx_gpcv2_set_m_core_pgc(false, GPC_PGC_C1); |
||||
} |
||||
|
||||
__secure void imx_enable_cpu_ca7(int cpu, bool enable) |
||||
{ |
||||
u32 mask, val; |
||||
|
||||
mask = 1 << (BP_SRC_A7RCR1_A7_CORE1_ENABLE + cpu - 1); |
||||
val = readl(SRC_BASE_ADDR + SRC_A7RCR1); |
||||
val = enable ? val | mask : val & ~mask; |
||||
writel(val, SRC_BASE_ADDR + SRC_A7RCR1); |
||||
} |
||||
|
||||
__secure int imx_cpu_on(int fn, int cpu, int pc) |
||||
{ |
||||
writel(pc, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D); |
||||
imx_gpcv2_set_core1_power(true); |
||||
imx_enable_cpu_ca7(cpu, true); |
||||
return 0; |
||||
} |
||||
|
||||
__secure int imx_cpu_off(int cpu) |
||||
{ |
||||
imx_enable_cpu_ca7(cpu, false); |
||||
imx_gpcv2_set_core1_power(false); |
||||
writel(0, SRC_BASE_ADDR + cpu * 8 + SRC_GPR1_MX7D + 4); |
||||
return 0; |
||||
} |
@ -0,0 +1,54 @@ |
||||
#include <config.h> |
||||
#include <linux/linkage.h> |
||||
|
||||
#include <asm/armv7.h> |
||||
#include <asm/arch-armv7/generictimer.h> |
||||
#include <asm/psci.h> |
||||
|
||||
.pushsection ._secure.text, "ax" |
||||
|
||||
.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} |
||||
|
||||
mov r0, r1 |
||||
bl psci_get_cpu_stack_top |
||||
str r2, [r0] |
||||
dsb |
||||
|
||||
ldr r2, =psci_cpu_entry |
||||
bl imx_cpu_on |
||||
|
||||
pop {pc} |
||||
|
||||
.globl psci_cpu_off
|
||||
psci_cpu_off: |
||||
|
||||
bl psci_cpu_off_common |
||||
bl psci_get_cpu_id |
||||
bl imx_cpu_off |
||||
|
||||
1: wfi |
||||
b 1b |
||||
|
||||
.globl psci_text_end
|
||||
psci_text_end: |
||||
.popsection |
Loading…
Reference in new issue