Commit 21473e16 authored by Olof Johansson's avatar Olof Johansson

Merge tag 'omap-for-v5.6/soc-smc-signed' of...

Merge tag 'omap-for-v5.6/soc-smc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into arm/soc

SMC related changes for omaps for v5.6 merge window

A series of changes to use optee SMC calls if optee is initialized by
the bootloader. Based on the discussions on LAKML in mailing list thread
"arm_smccc_smc as generic smc interface?" we don't want to add more quirk
handling to arm_smccc_smc() and want to handle it locally instead.

* tag 'omap-for-v5.6/soc-smc-signed' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap:
  ARM: OMAP2+: sleep43xx: Call secure suspend/resume handlers
  ARM: OMAP2+: Use ARM SMC Calling Convention when OP-TEE is available
  ARM: OMAP2+: Introduce check for OP-TEE in omap_secure_init()
  ARM: OMAP2+: Add omap_secure_init callback hook for secure initialization

Link: https://lore.kernel.org/r/pull-1579200367-372444@atomide.com-2Signed-off-by: default avatarOlof Johansson <olof@lixom.net>
parents e9d44015 8ab871f8
......@@ -255,7 +255,7 @@ extern void gic_dist_disable(void);
extern void gic_dist_enable(void);
extern bool gic_dist_disabled(void);
extern void gic_timer_retrigger(void);
extern void omap_smc1(u32 fn, u32 arg);
extern void _omap_smc1(u32 fn, u32 arg);
extern void omap4_sar_ram_init(void);
extern void __iomem *omap4_get_sar_ram_base(void);
extern void omap4_mpuss_early_init(void);
......
......@@ -51,6 +51,7 @@
#include "prm33xx.h"
#include "prm44xx.h"
#include "opp2xxx.h"
#include "omap-secure.h"
/*
* omap_clk_soc_init: points to a function that does the SoC-specific
......@@ -430,6 +431,7 @@ void __init omap2420_init_early(void)
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap2420_dt_clk_init;
rate_table = omap2420_rate_table;
omap_secure_init();
}
void __init omap2420_init_late(void)
......@@ -454,6 +456,7 @@ void __init omap2430_init_early(void)
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap2430_dt_clk_init;
rate_table = omap2430_rate_table;
omap_secure_init();
}
void __init omap2430_init_late(void)
......@@ -481,6 +484,7 @@ void __init omap3_init_early(void)
omap3xxx_clockdomains_init();
omap3xxx_hwmod_init();
omap_hwmod_init_postsetup();
omap_secure_init();
}
void __init omap3430_init_early(void)
......@@ -533,6 +537,7 @@ void __init ti814x_init_early(void)
dm814x_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dm814x_dt_clk_init;
omap_secure_init();
}
void __init ti816x_init_early(void)
......@@ -549,6 +554,7 @@ void __init ti816x_init_early(void)
dm816x_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dm816x_dt_clk_init;
omap_secure_init();
}
#endif
......@@ -566,6 +572,7 @@ void __init am33xx_init_early(void)
am33xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = am33xx_dt_clk_init;
omap_secure_init();
}
void __init am33xx_init_late(void)
......@@ -589,6 +596,7 @@ void __init am43xx_init_early(void)
omap_hwmod_init_postsetup();
omap_l2_cache_init();
omap_clk_soc_init = am43xx_dt_clk_init;
omap_secure_init();
}
void __init am43xx_init_late(void)
......@@ -617,6 +625,7 @@ void __init omap4430_init_early(void)
omap_hwmod_init_postsetup();
omap_l2_cache_init();
omap_clk_soc_init = omap4xxx_dt_clk_init;
omap_secure_init();
}
void __init omap4430_init_late(void)
......@@ -643,6 +652,7 @@ void __init omap5_init_early(void)
omap54xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = omap5xxx_dt_clk_init;
omap_secure_init();
}
void __init omap5_init_late(void)
......@@ -666,6 +676,7 @@ void __init dra7xx_init_early(void)
dra7xx_hwmod_init();
omap_hwmod_init_postsetup();
omap_clk_soc_init = dra7xx_dt_clk_init;
omap_secure_init();
}
void __init dra7xx_init_late(void)
......
......@@ -8,18 +8,42 @@
* Copyright (C) 2013 Pali Rohár <pali.rohar@gmail.com>
*/
#include <linux/arm-smccc.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/memblock.h>
#include <linux/of.h>
#include <asm/cacheflush.h>
#include <asm/memblock.h>
#include "common.h"
#include "omap-secure.h"
static phys_addr_t omap_secure_memblock_base;
bool optee_available;
#define OMAP_SIP_SMC_STD_CALL_VAL(func_num) \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_STD_CALL, ARM_SMCCC_SMC_32, \
ARM_SMCCC_OWNER_SIP, (func_num))
static void __init omap_optee_init_check(void)
{
struct device_node *np;
/*
* We only check that the OP-TEE node is present and available. The
* OP-TEE kernel driver is not needed for the type of interaction made
* with OP-TEE here so the driver's status is not checked.
*/
np = of_find_node_by_path("/firmware/optee");
if (np && of_device_is_available(np))
optee_available = true;
of_node_put(np);
}
/**
* omap_sec_dispatcher: Routine to dispatch low power secure
* service routines
......@@ -53,6 +77,27 @@ u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs, u32 arg1, u32 arg2,
return ret;
}
void omap_smccc_smc(u32 fn, u32 arg)
{
struct arm_smccc_res res;
arm_smccc_smc(OMAP_SIP_SMC_STD_CALL_VAL(fn), arg,
0, 0, 0, 0, 0, 0, &res);
WARN(res.a0, "Secure function call 0x%08x failed\n", fn);
}
void omap_smc1(u32 fn, u32 arg)
{
/*
* If this platform has OP-TEE installed we use ARM SMC calls
* otherwise fall back to the OMAP ROM style calls.
*/
if (optee_available)
omap_smccc_smc(fn, arg);
else
_omap_smc1(fn, arg);
}
/* Allocate the memory to save secure ram */
int __init omap_secure_ram_reserve_memblock(void)
{
......@@ -163,3 +208,8 @@ u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag)
NO_FLAG,
3, ptr, count, flag, 0);
}
void __init omap_secure_init(void)
{
omap_optee_init_check();
}
......@@ -10,6 +10,8 @@
#ifndef OMAP_ARCH_OMAP_SECURE_H
#define OMAP_ARCH_OMAP_SECURE_H
#include <linux/types.h>
/* Monitor error code */
#define API_HAL_RET_VALUE_NS2S_CONVERSION_ERROR 0xFFFFFFFE
#define API_HAL_RET_VALUE_SERVICE_UNKNWON 0xFFFFFFFF
......@@ -51,6 +53,9 @@
#define OMAP4_PPA_L2_POR_INDEX 0x23
#define OMAP4_PPA_CPU_ACTRL_SMP_INDEX 0x25
#define AM43xx_PPA_SVC_PM_SUSPEND 0x71
#define AM43xx_PPA_SVC_PM_RESUME 0x72
/* Secure RX-51 PPA (Primary Protected Application) APIs */
#define RX51_PPA_HWRNG 29
#define RX51_PPA_L2_INVAL 40
......@@ -60,6 +65,8 @@
extern u32 omap_secure_dispatcher(u32 idx, u32 flag, u32 nargs,
u32 arg1, u32 arg2, u32 arg3, u32 arg4);
extern void omap_smccc_smc(u32 fn, u32 arg);
extern void omap_smc1(u32 fn, u32 arg);
extern u32 omap_smc2(u32 id, u32 falg, u32 pargs);
extern u32 omap_smc3(u32 id, u32 process, u32 flag, u32 pargs);
extern phys_addr_t omap_secure_ram_mempool_base(void);
......@@ -72,6 +79,9 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
extern bool optee_available;
void omap_secure_init(void);
#ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
void set_cntfreq(void);
#else
......
......@@ -18,18 +18,18 @@
* the monitor API number. It uses few CPU registers
* internally and hence they need be backed up including
* link register "lr".
* Function signature : void omap_smc1(u32 fn, u32 arg)
* Function signature : void _omap_smc1(u32 fn, u32 arg)
*/
.arch armv7-a
.arch_extension sec
ENTRY(omap_smc1)
ENTRY(_omap_smc1)
stmfd sp!, {r2-r12, lr}
mov r12, r0
mov r0, r1
dsb
smc #0
ldmfd sp!, {r2-r12, pc}
ENDPROC(omap_smc1)
ENDPROC(_omap_smc1)
/**
* u32 omap_smc2(u32 id, u32 falg, u32 pargs)
......
......@@ -28,6 +28,7 @@
#include "prm33xx.h"
#include "soc.h"
#include "sram.h"
#include "omap-secure.h"
static struct powerdomain *cefuse_pwrdm, *gfx_pwrdm, *per_pwrdm, *mpu_pwrdm;
static struct clockdomain *gfx_l4ls_clkdm;
......@@ -166,6 +167,16 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
{
int ret = 0;
/* Suspend secure side on HS devices */
if (omap_type() != OMAP2_DEVICE_TYPE_GP) {
if (optee_available)
omap_smccc_smc(AM43xx_PPA_SVC_PM_SUSPEND, 0);
else
omap_secure_dispatcher(AM43xx_PPA_SVC_PM_SUSPEND,
FLAG_START_CRITICAL,
0, 0, 0, 0, 0);
}
amx3_pre_suspend_common();
scu_power_mode(scu_base, SCU_PM_POWEROFF);
ret = cpu_suspend(args, fn);
......@@ -174,6 +185,19 @@ static int am43xx_suspend(unsigned int state, int (*fn)(unsigned long),
if (!am43xx_check_off_mode_enable())
amx3_post_suspend_common();
/*
* Resume secure side on HS devices.
*
* Note that even on systems with OP-TEE available this resume call is
* issued to the ROM. This is because upon waking from suspend the ROM
* is restored as the secure monitor. On systems with OP-TEE ROM will
* restore OP-TEE during this call.
*/
if (omap_type() != OMAP2_DEVICE_TYPE_GP)
omap_secure_dispatcher(AM43xx_PPA_SVC_PM_RESUME,
FLAG_START_CRITICAL,
0, 0, 0, 0, 0);
return ret;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment