From 3be2246332395d5053dd0223e70c3d8ef639c344 Mon Sep 17 00:00:00 2001 From: Jianhong Chen Date: Tue, 27 Oct 2015 16:25:11 +0800 Subject: [PATCH] ARM: rockchip: psci support arch32 and arch64 smc call Change-Id: I736c6c15cbb41d52aa9ef1e98cb9ebdd6ac9ebfc Signed-off-by: Jianhong Chen --- arch/arm/mach-rockchip/Makefile | 1 + arch/arm/mach-rockchip/psci.c | 153 +++++++++++++++++++++++++------- include/linux/rockchip/psci.h | 34 +++---- 3 files changed, 142 insertions(+), 46 deletions(-) diff --git a/arch/arm/mach-rockchip/Makefile b/arch/arm/mach-rockchip/Makefile index c175b1da10c2..d8a0484b97aa 100755 --- a/arch/arm/mach-rockchip/Makefile +++ b/arch/arm/mach-rockchip/Makefile @@ -6,6 +6,7 @@ obj-y += rk3126b.o obj-y += rk3188.o obj-y += rk3288.o obj-y += rk3228.o +obj-$(CONFIG_ARM_PSCI) += psci.o ifneq ($(CONFIG_ARM_TRUSTZONE),y) obj-y += ddr_freq.o endif diff --git a/arch/arm/mach-rockchip/psci.c b/arch/arm/mach-rockchip/psci.c index 66d4905e0930..82293468e3c9 100644 --- a/arch/arm/mach-rockchip/psci.c +++ b/arch/arm/mach-rockchip/psci.c @@ -20,9 +20,77 @@ #include #include #include +#ifdef CONFIG_ARM +#include +#endif -static u32 reg_rd_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2, - u64 *val) +/* + * SMC32 id call made from arch32 or arch64 + */ +static u32 reg_rd_fn_smc(u32 function_id, u32 arg0, u32 arg1, + u32 arg2, u32 *val) +{ + asm volatile( +#ifdef CONFIG_ARM + __asmeq("%0", "r0") + __asmeq("%1", "r1") + __asmeq("%2", "r2") + __asmeq("%3", "r3") + __SMC(0) +#else + __asmeq("%w0", "w0") + __asmeq("%w1", "w1") + __asmeq("%w2", "w2") + __asmeq("%w3", "w3") + "smc #0\n" +#endif + : "+r" (function_id), "+r" (arg0) + : "r" (arg1), "r" (arg2)); + + + if (val) + *val = arg0; + + return function_id; +} + +/* + * SMC32 id call made from arch32 or arch64 + */ +static u32 reg_wr_fn_smc(u32 function_id, u32 arg0, + u32 arg1, u32 arg2) +{ + asm volatile( +#ifdef CONFIG_ARM + __asmeq("%0", "r0") + __asmeq("%1", "r1") + __asmeq("%2", "r2") + __asmeq("%3", "r3") + __SMC(0) +#else + __asmeq("%w0", "w0") + __asmeq("%w1", "w1") + __asmeq("%w2", "w2") + __asmeq("%w3", "w3") + "smc #0\n" +#endif + : "+r" (function_id), "+r" (arg0) + : "r" (arg1), "r" (arg2)); + + return function_id; +} + +static u32 (*reg_wr_fn)(u32, u32, u32, u32) = reg_wr_fn_smc; +static u32 (*reg_rd_fn)(u32, u32, u32, u32, u32 *) = reg_rd_fn_smc; + + +#ifdef CONFIG_ARM64 + +/* + * SMC64 id call only made from arch64 + */ +static u32 reg_rd_fn_smc64(u64 function_id, u64 arg0, u64 arg1, u64 arg2, + u64 *val) { asm volatile( __asmeq("%0", "x0") @@ -39,7 +107,10 @@ static u32 reg_rd_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2, return function_id; } -static u32 reg_wr_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) +/* + * SMC64 id call only made from Arch64 + */ +static u32 reg_wr_fn_smc64(u64 function_id, u64 arg0, u64 arg1, u64 arg2) { asm volatile( __asmeq("%0", "x0") @@ -53,37 +124,59 @@ static u32 reg_wr_fn_smc(u64 function_id, u64 arg0, u64 arg1, u64 arg2) return function_id; } -static u32 (*reg_wr_fn)(u64, u64, u64, u64) = reg_wr_fn_smc; -static u32 (*reg_rd_fn)(u64, u64, u64, u64, u64 *) = reg_rd_fn_smc; +static u32 (*reg_wr_fn64)(u64, u64, u64, u64) = reg_wr_fn_smc64; +static u32 (*reg_rd_fn64)(u64, u64, u64, u64, u64 *) = reg_rd_fn_smc64; -/* - * u64 *val: another return value - */ -u32 rockchip_psci_smc_read(u64 function_id, u64 arg0, u64 arg1, u64 arg2, - u64 *val) +u32 rockchip_psci_smc_read64(u64 function_id, u64 arg0, u64 arg1, u64 arg2, + u64 *val) +{ + return reg_rd_fn64(function_id, arg0, arg1, arg2, val); +} + +u32 rockchip_psci_smc_write64(u64 function_id, u64 arg0, u64 arg1, u64 arg2) +{ + return reg_wr_fn64(function_id, arg0, arg1, arg2); +} + +u64 rockchip_secure_reg_read64(u64 addr_phy) +{ + u64 val; + + reg_rd_fn64(PSCI_SIP_ACCESS_REG64, 0, addr_phy, SEC_REG_RD, &val); + + return val; +} + +u32 rockchip_secure_reg_write64(u64 addr_phy, u64 val) +{ + return reg_wr_fn64(PSCI_SIP_ACCESS_REG64, val, addr_phy, SEC_REG_WR); +} + +#endif /*CONFIG_ARM64*/ + +u32 rockchip_psci_smc_read(u32 function_id, u32 arg0, u32 arg1, u32 arg2, + u32 *val) { return reg_rd_fn(function_id, arg0, arg1, arg2, val); } -u32 rockchip_psci_smc_write(u64 function_id, u64 arg0, u64 arg1, u64 arg2) +u32 rockchip_psci_smc_write(u32 function_id, u32 arg0, u32 arg1, u32 arg2) { return reg_wr_fn(function_id, arg0, arg1, arg2); } -u32 rockchip_secure_reg_read32(u64 addr_phy) +u32 rockchip_secure_reg_read(u32 addr_phy) { - u64 val = 0; + u32 val = 0; - reg_rd_fn(PSCI_SIP_ACCESS_REG, 0, addr_phy, SEC_REG_RD_32, &val); + reg_rd_fn(PSCI_SIP_ACCESS_REG, 0, addr_phy, SEC_REG_RD, &val); return val; } -u32 rockchip_secure_reg_write32(u64 addr_phy, u32 val) +u32 rockchip_secure_reg_write(u32 addr_phy, u32 val) { - u64 val_64 = val; - - return reg_wr_fn(PSCI_SIP_ACCESS_REG, val_64, addr_phy, SEC_REG_WR_32); + return reg_wr_fn(PSCI_SIP_ACCESS_REG, val, addr_phy, SEC_REG_WR); } /* @@ -95,6 +188,7 @@ u32 rockchip_psci_smc_get_tf_ver(void) } /*************************** fiq debug *****************************/ +#ifdef CONFIG_ARM64 static u64 ft_fiq_mem_phy; static void __iomem *ft_fiq_mem_base; static void (*psci_fiq_debugger_uart_irq_tf)(void *reg_base, u64 sp_el1); @@ -102,32 +196,31 @@ static void (*psci_fiq_debugger_uart_irq_tf)(void *reg_base, u64 sp_el1); void psci_fiq_debugger_uart_irq_tf_cb(u64 sp_el1, u64 offset) { psci_fiq_debugger_uart_irq_tf((char *)ft_fiq_mem_base + offset, sp_el1); - - reg_wr_fn(PSCI_SIP_UARTDBG_CFG, 0, 0, UARTDBG_CFG_OSHDL_TO_OS); + reg_wr_fn64(PSCI_SIP_UARTDBG_CFG64, 0, 0, UARTDBG_CFG_OSHDL_TO_OS); } void psci_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback) { psci_fiq_debugger_uart_irq_tf = callback; - - ft_fiq_mem_phy = reg_wr_fn(PSCI_SIP_UARTDBG_CFG, irq_id, - (u64)psci_fiq_debugger_uart_irq_tf_cb, - UARTDBG_CFG_INIT); + ft_fiq_mem_phy = reg_wr_fn64(PSCI_SIP_UARTDBG_CFG64, irq_id, + (u64)psci_fiq_debugger_uart_irq_tf_cb, + UARTDBG_CFG_INIT); ft_fiq_mem_base = ioremap(ft_fiq_mem_phy, 8 * 1024); } u32 psci_fiq_debugger_switch_cpu(u32 cpu) { - return reg_wr_fn(PSCI_SIP_UARTDBG_CFG, cpu_logical_map(cpu), - 0, UARTDBG_CFG_OSHDL_CPUSW); + return reg_wr_fn64(PSCI_SIP_UARTDBG_CFG64, cpu_logical_map(cpu), + 0, UARTDBG_CFG_OSHDL_CPUSW); } void psci_fiq_debugger_enable_debug(bool val) { if (val) - reg_wr_fn(PSCI_SIP_UARTDBG_CFG, 0, - 0, UARTDBG_CFG_OSHDL_DEBUG_ENABLE); + reg_wr_fn64(PSCI_SIP_UARTDBG_CFG64, 0, + 0, UARTDBG_CFG_OSHDL_DEBUG_ENABLE); else - reg_wr_fn(PSCI_SIP_UARTDBG_CFG, 0, - 0, UARTDBG_CFG_OSHDL_DEBUG_DISABLE); + reg_wr_fn64(PSCI_SIP_UARTDBG_CFG64, 0, + 0, UARTDBG_CFG_OSHDL_DEBUG_DISABLE); } +#endif diff --git a/include/linux/rockchip/psci.h b/include/linux/rockchip/psci.h index 93c7c827a69f..5a2111031e52 100644 --- a/include/linux/rockchip/psci.h +++ b/include/linux/rockchip/psci.h @@ -1,19 +1,9 @@ #ifndef __ROCKCHIP_PSCI_H #define __ROCKCHIP_PSCI_H -#define SEC_REG_RW_SHT (0x0) #define SEC_REG_RD (0x0) #define SEC_REG_WR (0x1) -#define SEC_REG_BITS_SHT (0x1) -#define SEC_REG_32 (0x0) -#define SEC_REG_64 (0x2) - -#define SEC_REG_RD_32 (SEC_REG_RD | SEC_REG_32) -#define SEC_REG_RD_64 (SEC_REG_RD | SEC_REG_64) -#define SEC_REG_WR_32 (SEC_REG_WR | SEC_REG_32) -#define SEC_REG_WR_64 (SEC_REG_WR | SEC_REG_64) - /* * trust firmware verison */ @@ -25,9 +15,11 @@ */ #define PSCI_SIP_RKTF_VER (0x82000001) #define PSCI_SIP_ACCESS_REG (0x82000002) +#define PSCI_SIP_ACCESS_REG64 (0xc2000002) #define PSCI_SIP_SUSPEND_WR_CTRBITS (0x82000003) #define PSCI_SIP_PENDING_CPUS (0x82000004) #define PSCI_SIP_UARTDBG_CFG (0x82000005) +#define PSCI_SIP_UARTDBG_CFG64 (0xc2000005) #define PSCI_SIP_EL3FIQ_CFG (0x82000006) /* @@ -47,16 +39,26 @@ /* * rockchip psci function call interface */ -u32 rockchip_psci_smc_read(u64 function_id, u64 arg0, u64 arg1, u64 arg2, - u64 *val); -u32 rockchip_psci_smc_write(u64 function_id, u64 arg0, u64 arg1, u64 arg2); + +u32 rockchip_psci_smc_read(u32 function_id, u32 arg0, u32 arg1, u32 arg2, + u32 *val); +u32 rockchip_psci_smc_write(u32 function_id, u32 arg0, u32 arg1, u32 arg2); u32 rockchip_psci_smc_get_tf_ver(void); -u32 rockchip_secure_reg_read32(u64 addr_phy); -u32 rockchip_secure_reg_write32(u64 addr_phy, u32 val); +u32 rockchip_secure_reg_read(u32 addr_phy); +u32 rockchip_secure_reg_write(u32 addr_phy, u32 val); + +#ifdef CONFIG_ARM64 +u32 rockchip_psci_smc_write64(u64 function_id, u64 arg0, u64 arg1, u64 arg2); +u32 rockchip_psci_smc_read64(u64 function_id, u64 arg0, u64 arg1, u64 arg2, + u64 *val); +u64 rockchip_secure_reg_read64(u64 addr_phy); +u32 rockchip_secure_reg_write64(u64 addr_phy, u64 val); -u32 psci_fiq_debugger_switch_cpu(u32 cpu); void psci_fiq_debugger_uart_irq_tf_cb(u64 sp_el1, u64 offset); +#endif + +u32 psci_fiq_debugger_switch_cpu(u32 cpu); void psci_fiq_debugger_uart_irq_tf_init(u32 irq_id, void *callback); void psci_fiq_debugger_enable_debug(bool val); -- 2.34.1