mirror of https://gitee.com/openkylin/linux.git
firmware: tegra: Changes for v5.2-rc1
This set of changes includes improvements for Trusted Foundations and also moves the source files for this support into the standard location under drivers/firmware. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEiOrDCAFJzPfAjcif3SOs138+s6EFAly4jVETHHRyZWRpbmdA bnZpZGlhLmNvbQAKCRDdI6zXfz6zof9FD/wKq7/KMVDgv+Ja+MJz/nT5gqaTA29r d8n9KyrXMvSUJ73/uS9E9Sm97S22n5TaC1LBv3EnKVJMf4rRJRH5GuASSpWo1iJx Cv+WHjSbwGB3Glw76/KI6mq5RBJEU6BOEPUdypXPE2J+w8i0icXoRdNU70GSqjHW Pt3kaA6GKuUv4bnAxb9AZH1DaxuVuzIGs+XqolfGhs6NpNlfkZ63YJ2Ym/iRiWP0 Tqp5srZs57Zn43qgUf6zRKR+WCrsIZb2fiO7itCyIkY2Z5TiF1BXtKZNj+JsdAxI VVp6KNyperD1aU8y6qGUPFOBC/eR6QctKV3P1/06arizwPiaikobwNHnxX12VJMg G4ebPM0rhnxR73u1z/iZSXZub+X1gednSwDlq7qF9IdUDyFvnTAzxIPTBtVj5hxy VGLvJakaaeGLVe0QJqiZPPtssHXkRsp2CxJWSpEAvof6E1yvD040QRqGQdcJMzNJ QKwS2PBZMrXNs3lhd8QNk547uLAQDRv/oqaizM9J91yWDUicO+dWleya3l3kwrGq lEKUWvkUMi5bUT3frW66xRlhnv6yXqTvo9CqshcL59dQ8ZqIrEczxoR2dg7GL1c9 8i5Hqnor0j+9TlZMnw5hsbD8C2kuWI/nnZpfbiRJEMFIYe8lhF6onPMgAuiV3WRw 9EpzLPExTep0jg== =agCA -----END PGP SIGNATURE----- Merge tag 'tegra-for-5.2-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux into arm/soc firmware: tegra: Changes for v5.2-rc1 This set of changes includes improvements for Trusted Foundations and also moves the source files for this support into the standard location under drivers/firmware. * tag 'tegra-for-5.2-firmware' of git://git.kernel.org/pub/scm/linux/kernel/git/tegra/linux: firmware: Move Trusted Foundations support ARM: tegra: Sort dependencies alphabetically ARM: tegra: Add firmware calls required for suspend-resume on Tegra30 ARM: tegra: Always boot CPU in ARM-mode ARM: tegra: Don't apply CPU erratas in insecure mode ARM: tegra: Set up L2 cache using Trusted Foundations firmware ARM: trusted_foundations: Provide information about whether firmware is registered ARM: trusted_foundations: Make prepare_idle call to take mode argument ARM: trusted_foundations: Support L2 cache maintenance Signed-off-by: Olof Johansson <olof@lixom.net>
This commit is contained in:
commit
abfcba1c35
|
@ -900,8 +900,6 @@ config PLAT_PXA
|
|||
config PLAT_VERSATILE
|
||||
bool
|
||||
|
||||
source "arch/arm/firmware/Kconfig"
|
||||
|
||||
source "arch/arm/mm/Kconfig"
|
||||
|
||||
config IWMMXT
|
||||
|
|
|
@ -290,7 +290,6 @@ core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
|
|||
core-y += arch/arm/probes/
|
||||
core-y += arch/arm/net/
|
||||
core-y += arch/arm/crypto/
|
||||
core-y += arch/arm/firmware/
|
||||
core-y += $(machdirs) $(platdirs)
|
||||
|
||||
drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
|
||||
|
|
|
@ -1,29 +0,0 @@
|
|||
config ARCH_SUPPORTS_FIRMWARE
|
||||
bool
|
||||
|
||||
config ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
|
||||
bool
|
||||
select ARCH_SUPPORTS_FIRMWARE
|
||||
|
||||
menu "Firmware options"
|
||||
depends on ARCH_SUPPORTS_FIRMWARE
|
||||
|
||||
config TRUSTED_FOUNDATIONS
|
||||
bool "Trusted Foundations secure monitor support"
|
||||
depends on ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
|
||||
default y
|
||||
help
|
||||
Some devices (including most Tegra-based consumer devices on the
|
||||
market) are booted with the Trusted Foundations secure monitor
|
||||
active, requiring some core operations to be performed by the secure
|
||||
monitor instead of the kernel.
|
||||
|
||||
This option allows the kernel to invoke the secure monitor whenever
|
||||
required on devices using Trusted Foundations. See
|
||||
arch/arm/include/asm/trusted_foundations.h or the
|
||||
tlm,trusted-foundations device tree binding documentation for details
|
||||
on how to use it.
|
||||
|
||||
Say n if you don't know what this is about.
|
||||
|
||||
endmenu
|
|
@ -1,4 +0,0 @@
|
|||
obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
|
||||
|
||||
# tf_generic_smc() fails to build with -fsanitize-coverage=trace-pc
|
||||
KCOV_INSTRUMENT := n
|
|
@ -24,7 +24,7 @@ struct firmware_ops {
|
|||
/*
|
||||
* Inform the firmware we intend to enter CPU idle mode
|
||||
*/
|
||||
int (*prepare_idle)(void);
|
||||
int (*prepare_idle)(unsigned long mode);
|
||||
/*
|
||||
* Enters CPU idle mode
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
menuconfig ARCH_TEGRA
|
||||
bool "NVIDIA Tegra"
|
||||
depends on ARCH_MULTI_V7
|
||||
select ARCH_SUPPORTS_TRUSTED_FOUNDATIONS
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select ARM_AMBA
|
||||
select ARM_GIC
|
||||
select CLKSRC_MMIO
|
||||
|
@ -11,7 +11,6 @@ menuconfig ARCH_TEGRA
|
|||
select HAVE_ARM_TWD if SMP
|
||||
select PINCTRL
|
||||
select PM_OPP
|
||||
select ARCH_HAS_RESET_CONTROLLER
|
||||
select RESET_CONTROLLER
|
||||
select SOC_BUS
|
||||
select ZONE_DMA if ARM_LPAE
|
||||
|
|
|
@ -21,6 +21,8 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <asm/cpuidle.h>
|
||||
#include <asm/smp_plat.h>
|
||||
#include <asm/suspend.h>
|
||||
|
@ -46,7 +48,7 @@ static int tegra114_idle_power_down(struct cpuidle_device *dev,
|
|||
tegra_set_cpu_in_lp2();
|
||||
cpu_pm_enter();
|
||||
|
||||
call_firmware_op(prepare_idle);
|
||||
call_firmware_op(prepare_idle, TF_PM_MODE_LP2_NOFLUSH_L2);
|
||||
|
||||
/* Do suspend by ourselves if the firmware does not implement it */
|
||||
if (call_firmware_op(do_idle, 0) == -ENOSYS)
|
||||
|
|
|
@ -27,12 +27,15 @@
|
|||
#include <linux/spinlock.h>
|
||||
#include <linux/suspend.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <soc/tegra/flowctrl.h>
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/pm.h>
|
||||
#include <soc/tegra/pmc.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/idmap.h>
|
||||
#include <asm/proc-fns.h>
|
||||
#include <asm/smp_plat.h>
|
||||
|
@ -159,6 +162,28 @@ int tegra_cpu_do_idle(void)
|
|||
|
||||
static int tegra_sleep_cpu(unsigned long v2p)
|
||||
{
|
||||
/*
|
||||
* L2 cache disabling using kernel API only allowed when all
|
||||
* secondary CPU's are offline. Cache have to be disabled with
|
||||
* MMU-on if cache maintenance is done via Trusted Foundations
|
||||
* firmware. Note that CPUIDLE won't ever enter powergate on Tegra30
|
||||
* if any of secondary CPU's is online and this is the LP2-idle
|
||||
* code-path only for Tegra20/30.
|
||||
*/
|
||||
if (trusted_foundations_registered())
|
||||
outer_disable();
|
||||
|
||||
/*
|
||||
* Note that besides of setting up CPU reset vector this firmware
|
||||
* call may also do the following, depending on the FW version:
|
||||
* 1) Disable L2. But this doesn't matter since we already
|
||||
* disabled the L2.
|
||||
* 2) Disable D-cache. This need to be taken into account in
|
||||
* particular by the tegra_disable_clean_inv_dcache() which
|
||||
* shall avoid the re-disable.
|
||||
*/
|
||||
call_firmware_op(prepare_idle, TF_PM_MODE_LP2);
|
||||
|
||||
setup_mm_for_reboot();
|
||||
tegra_sleep_cpu_finish(v2p);
|
||||
|
||||
|
@ -197,6 +222,14 @@ void tegra_idle_lp2_last(void)
|
|||
|
||||
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, &tegra_sleep_cpu);
|
||||
|
||||
/*
|
||||
* Resume L2 cache if it wasn't re-enabled early during resume,
|
||||
* which is the case for Tegra30 that has to re-enable the cache
|
||||
* via firmware call. In other cases cache is already enabled and
|
||||
* hence re-enabling is a no-op. This is always a no-op on Tegra114+.
|
||||
*/
|
||||
outer_resume();
|
||||
|
||||
restore_cpu_complex();
|
||||
cpu_cluster_pm_exit();
|
||||
}
|
||||
|
@ -215,6 +248,15 @@ enum tegra_suspend_mode tegra_pm_validate_suspend_mode(
|
|||
|
||||
static int tegra_sleep_core(unsigned long v2p)
|
||||
{
|
||||
/*
|
||||
* Cache have to be disabled with MMU-on if cache maintenance is done
|
||||
* via Trusted Foundations firmware. This is a no-op on Tegra114+.
|
||||
*/
|
||||
if (trusted_foundations_registered())
|
||||
outer_disable();
|
||||
|
||||
call_firmware_op(prepare_idle, TF_PM_MODE_LP1);
|
||||
|
||||
setup_mm_for_reboot();
|
||||
tegra_sleep_core_finish(v2p);
|
||||
|
||||
|
@ -342,6 +384,14 @@ static int tegra_suspend_enter(suspend_state_t state)
|
|||
|
||||
cpu_suspend(PHYS_OFFSET - PAGE_OFFSET, tegra_sleep_func);
|
||||
|
||||
/*
|
||||
* Resume L2 cache if it wasn't re-enabled early during resume,
|
||||
* which is the case for Tegra30 that has to re-enable the cache
|
||||
* via firmware call. In other cases cache is already enabled and
|
||||
* hence re-enabling is a no-op.
|
||||
*/
|
||||
outer_resume();
|
||||
|
||||
switch (mode) {
|
||||
case TEGRA_SUSPEND_LP1:
|
||||
tegra_suspend_exit_lp1();
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#include <soc/tegra/flowctrl.h>
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include <asm/assembler.h>
|
||||
#include <asm/asm-offsets.h>
|
||||
#include <asm/cache.h>
|
||||
|
||||
|
@ -29,8 +30,6 @@
|
|||
|
||||
#define PMC_SCRATCH41 0x140
|
||||
|
||||
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
|
||||
|
||||
#ifdef CONFIG_PM_SLEEP
|
||||
/*
|
||||
* tegra_resume
|
||||
|
@ -78,6 +77,7 @@ ENTRY(tegra_resume)
|
|||
orr r1, r1, #1
|
||||
str r1, [r0]
|
||||
#endif
|
||||
bl tegra_resume_trusted_foundations
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
/* L2 cache resume & re-enable */
|
||||
|
@ -90,6 +90,30 @@ end_ca9_scu_l2_resume:
|
|||
|
||||
b cpu_resume
|
||||
ENDPROC(tegra_resume)
|
||||
|
||||
/*
|
||||
* tegra_resume_trusted_foundations
|
||||
*
|
||||
* Trusted Foundations firmware initialization.
|
||||
*
|
||||
* Doesn't return if firmware presents.
|
||||
* Corrupted registers: r1, r2
|
||||
*/
|
||||
ENTRY(tegra_resume_trusted_foundations)
|
||||
/* Check whether Trusted Foundations firmware presents. */
|
||||
mov32 r2, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
|
||||
ldr r1, =__tegra_cpu_reset_handler_data_offset + \
|
||||
RESET_DATA(TF_PRESENT)
|
||||
ldr r1, [r2, r1]
|
||||
cmp r1, #0
|
||||
reteq lr
|
||||
|
||||
.arch_extension sec
|
||||
/* First call after suspend wakes firmware. No arguments required. */
|
||||
smc #0
|
||||
|
||||
b cpu_resume
|
||||
ENDPROC(tegra_resume_trusted_foundations)
|
||||
#endif
|
||||
|
||||
.align L1_CACHE_SHIFT
|
||||
|
@ -115,12 +139,19 @@ ENTRY(__tegra_cpu_reset_handler_start)
|
|||
* must be position-independent.
|
||||
*/
|
||||
|
||||
.arm
|
||||
.align L1_CACHE_SHIFT
|
||||
ENTRY(__tegra_cpu_reset_handler)
|
||||
|
||||
cpsid aif, 0x13 @ SVC mode, interrupts disabled
|
||||
|
||||
tegra_get_soc_id TEGRA_APB_MISC_BASE, r6
|
||||
|
||||
adr r12, __tegra_cpu_reset_handler_data
|
||||
ldr r5, [r12, #RESET_DATA(TF_PRESENT)]
|
||||
cmp r5, #0
|
||||
bne after_errata
|
||||
|
||||
#ifdef CONFIG_ARCH_TEGRA_2x_SOC
|
||||
t20_check:
|
||||
cmp r6, #TEGRA20
|
||||
|
@ -155,7 +186,6 @@ after_errata:
|
|||
and r10, r10, #0x3 @ R10 = CPU number
|
||||
mov r11, #1
|
||||
mov r11, r11, lsl r10 @ R11 = CPU mask
|
||||
adr r12, __tegra_cpu_reset_handler_data
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* Does the OS know about this CPU? */
|
||||
|
@ -169,10 +199,9 @@ after_errata:
|
|||
cmp r6, #TEGRA20
|
||||
bne 1f
|
||||
/* If not CPU0, don't let CPU0 reset CPU1 now that CPU1 is coming up. */
|
||||
mov32 r5, TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET
|
||||
mov r0, #CPU_NOT_RESETTABLE
|
||||
cmp r10, #0
|
||||
strbne r0, [r5, #__tegra20_cpu1_resettable_status_offset]
|
||||
strbne r0, [r12, #RESET_DATA(RESETTABLE_STATUS)]
|
||||
1:
|
||||
#endif
|
||||
|
||||
|
@ -277,14 +306,13 @@ ENDPROC(__tegra_cpu_reset_handler)
|
|||
.align L1_CACHE_SHIFT
|
||||
.type __tegra_cpu_reset_handler_data, %object
|
||||
.globl __tegra_cpu_reset_handler_data
|
||||
__tegra_cpu_reset_handler_data:
|
||||
.rept TEGRA_RESET_DATA_SIZE
|
||||
.long 0
|
||||
.endr
|
||||
.globl __tegra20_cpu1_resettable_status_offset
|
||||
.equ __tegra20_cpu1_resettable_status_offset, \
|
||||
.globl __tegra_cpu_reset_handler_data_offset
|
||||
.equ __tegra_cpu_reset_handler_data_offset, \
|
||||
. - __tegra_cpu_reset_handler_start
|
||||
.byte 0
|
||||
__tegra_cpu_reset_handler_data:
|
||||
.rept TEGRA_RESET_DATA_SIZE
|
||||
.long 0
|
||||
.endr
|
||||
.align L1_CACHE_SHIFT
|
||||
|
||||
ENTRY(__tegra_cpu_reset_handler_end)
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <linux/init.h>
|
||||
#include <linux/io.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
|
||||
#include <asm/cacheflush.h>
|
||||
|
@ -89,6 +91,8 @@ static void __init tegra_cpu_reset_handler_enable(void)
|
|||
|
||||
void __init tegra_cpu_reset_handler_init(void)
|
||||
{
|
||||
__tegra_cpu_reset_handler_data[TEGRA_RESET_TF_PRESENT] =
|
||||
trusted_foundations_registered();
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
__tegra_cpu_reset_handler_data[TEGRA_RESET_MASK_PRESENT] =
|
||||
|
|
|
@ -25,7 +25,11 @@
|
|||
#define TEGRA_RESET_STARTUP_SECONDARY 3
|
||||
#define TEGRA_RESET_STARTUP_LP2 4
|
||||
#define TEGRA_RESET_STARTUP_LP1 5
|
||||
#define TEGRA_RESET_DATA_SIZE 6
|
||||
#define TEGRA_RESET_RESETTABLE_STATUS 6
|
||||
#define TEGRA_RESET_TF_PRESENT 7
|
||||
#define TEGRA_RESET_DATA_SIZE 8
|
||||
|
||||
#define RESET_DATA(x) ((TEGRA_RESET_##x)*4)
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
|
||||
|
@ -49,7 +53,8 @@ void __tegra_cpu_reset_handler_end(void);
|
|||
(u32)__tegra_cpu_reset_handler_start)))
|
||||
#define tegra20_cpu1_resettable_status \
|
||||
(IO_ADDRESS(TEGRA_IRAM_BASE + TEGRA_IRAM_RESET_HANDLER_OFFSET + \
|
||||
(u32)__tegra20_cpu1_resettable_status_offset))
|
||||
((u32)&__tegra_cpu_reset_handler_data[TEGRA_RESET_RESETTABLE_STATUS] - \
|
||||
(u32)__tegra_cpu_reset_handler_start)))
|
||||
#endif
|
||||
|
||||
#define tegra_cpu_reset_handler_offset \
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include <asm/cache.h>
|
||||
|
||||
#include "irammap.h"
|
||||
#include "reset.h"
|
||||
#include "sleep.h"
|
||||
|
||||
#define EMC_CFG 0xc
|
||||
|
@ -53,6 +54,9 @@
|
|||
#define APB_MISC_XM2CFGCPADCTRL2 0x8e4
|
||||
#define APB_MISC_XM2CFGDPADCTRL2 0x8e8
|
||||
|
||||
#define __tegra20_cpu1_resettable_status_offset \
|
||||
(__tegra_cpu_reset_handler_data_offset + RESET_DATA(RESETTABLE_STATUS))
|
||||
|
||||
.macro pll_enable, rd, r_car_base, pll_base
|
||||
ldr \rd, [\r_car_base, #\pll_base]
|
||||
tst \rd, #(1 << 30)
|
||||
|
|
|
@ -49,8 +49,9 @@ ENTRY(tegra_disable_clean_inv_dcache)
|
|||
|
||||
/* Disable the D-cache */
|
||||
mrc p15, 0, r2, c1, c0, 0
|
||||
tst r2, #CR_C @ see tegra_sleep_cpu()
|
||||
bic r2, r2, #CR_C
|
||||
mcr p15, 0, r2, c1, c0, 0
|
||||
mcrne p15, 0, r2, c1, c0, 0
|
||||
isb
|
||||
|
||||
/* Flush the D-cache */
|
||||
|
@ -132,10 +133,13 @@ ENTRY(tegra_shut_off_mmu)
|
|||
#ifdef CONFIG_CACHE_L2X0
|
||||
/* Disable L2 cache */
|
||||
check_cpu_part_num 0xc09, r9, r10
|
||||
movweq r2, #:lower16:(TEGRA_ARM_PERIF_BASE + 0x3000)
|
||||
movteq r2, #:upper16:(TEGRA_ARM_PERIF_BASE + 0x3000)
|
||||
moveq r3, #0
|
||||
streq r3, [r2, #L2X0_CTRL]
|
||||
retne r0
|
||||
|
||||
mov32 r2, TEGRA_ARM_PERIF_BASE + 0x3000
|
||||
ldr r3, [r2, #L2X0_CTRL]
|
||||
tst r3, #L2X0_CTRL_EN @ see tegra_sleep_cpu()
|
||||
mov r3, #0
|
||||
strne r3, [r2, #L2X0_CTRL]
|
||||
#endif
|
||||
ret r0
|
||||
ENDPROC(tegra_shut_off_mmu)
|
||||
|
|
|
@ -35,15 +35,17 @@
|
|||
#include <linux/sys_soc.h>
|
||||
#include <linux/usb/tegra_usb_phy.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <soc/tegra/fuse.h>
|
||||
#include <soc/tegra/pmc.h>
|
||||
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/mach/arch.h>
|
||||
#include <asm/mach/time.h>
|
||||
#include <asm/mach-types.h>
|
||||
#include <asm/setup.h>
|
||||
#include <asm/trusted_foundations.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "common.h"
|
||||
|
@ -74,6 +76,7 @@ static void __init tegra_init_early(void)
|
|||
{
|
||||
of_register_trusted_foundations();
|
||||
tegra_cpu_reset_handler_init();
|
||||
call_firmware_op(l2x0_init);
|
||||
}
|
||||
|
||||
static void __init tegra_dt_init_irq(void)
|
||||
|
|
|
@ -267,6 +267,22 @@ config TI_SCI_PROTOCOL
|
|||
This protocol library is used by client drivers to use the features
|
||||
provided by the system controller.
|
||||
|
||||
config TRUSTED_FOUNDATIONS
|
||||
bool "Trusted Foundations secure monitor support"
|
||||
depends on ARM
|
||||
help
|
||||
Some devices (including most early Tegra-based consumer devices on
|
||||
the market) are booted with the Trusted Foundations secure monitor
|
||||
active, requiring some core operations to be performed by the secure
|
||||
monitor instead of the kernel.
|
||||
|
||||
This option allows the kernel to invoke the secure monitor whenever
|
||||
required on devices using Trusted Foundations. See the functions and
|
||||
comments in linux/firmware/trusted_foundations.h or the device tree
|
||||
bindings for "tlm,trusted-foundations" for details on how to use it.
|
||||
|
||||
Choose N if you don't know what this is about.
|
||||
|
||||
config HAVE_ARM_SMCCC
|
||||
bool
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ obj-$(CONFIG_QCOM_SCM_64) += qcom_scm-64.o
|
|||
obj-$(CONFIG_QCOM_SCM_32) += qcom_scm-32.o
|
||||
CFLAGS_qcom_scm-32.o :=$(call as-instr,.arch armv7-a\n.arch_extension sec,-DREQUIRES_SEC=1) -march=armv7-a
|
||||
obj-$(CONFIG_TI_SCI_PROTOCOL) += ti_sci.o
|
||||
obj-$(CONFIG_TRUSTED_FOUNDATIONS) += trusted_foundations.o
|
||||
|
||||
obj-$(CONFIG_ARM_SCMI_PROTOCOL) += arm_scmi/
|
||||
obj-y += broadcom/
|
||||
|
|
|
@ -17,8 +17,17 @@
|
|||
#include <linux/kernel.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/firmware/trusted_foundations.h>
|
||||
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/trusted_foundations.h>
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/outercache.h>
|
||||
|
||||
#define TF_CACHE_MAINT 0xfffff100
|
||||
|
||||
#define TF_CACHE_ENABLE 1
|
||||
#define TF_CACHE_DISABLE 2
|
||||
|
||||
#define TF_SET_CPU_BOOT_ADDR_SMC 0xfffff200
|
||||
|
||||
|
@ -60,16 +69,75 @@ static int tf_set_cpu_boot_addr(int cpu, unsigned long boot_addr)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int tf_prepare_idle(void)
|
||||
static int tf_prepare_idle(unsigned long mode)
|
||||
{
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2, cpu_boot_addr);
|
||||
switch (mode) {
|
||||
case TF_PM_MODE_LP0:
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S3, cpu_boot_addr);
|
||||
break;
|
||||
|
||||
case TF_PM_MODE_LP1:
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S2, cpu_boot_addr);
|
||||
break;
|
||||
|
||||
case TF_PM_MODE_LP1_NO_MC_CLK:
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S2_NO_MC_CLK,
|
||||
cpu_boot_addr);
|
||||
break;
|
||||
|
||||
case TF_PM_MODE_LP2:
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1, cpu_boot_addr);
|
||||
break;
|
||||
|
||||
case TF_PM_MODE_LP2_NOFLUSH_L2:
|
||||
tf_generic_smc(TF_CPU_PM, TF_CPU_PM_S1_NOFLUSH_L2,
|
||||
cpu_boot_addr);
|
||||
break;
|
||||
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
static void tf_cache_write_sec(unsigned long val, unsigned int reg)
|
||||
{
|
||||
u32 l2x0_way_mask = 0xff;
|
||||
|
||||
switch (reg) {
|
||||
case L2X0_CTRL:
|
||||
if (l2x0_saved_regs.aux_ctrl & L310_AUX_CTRL_ASSOCIATIVITY_16)
|
||||
l2x0_way_mask = 0xffff;
|
||||
|
||||
if (val == L2X0_CTRL_EN)
|
||||
tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_ENABLE,
|
||||
l2x0_saved_regs.aux_ctrl);
|
||||
else
|
||||
tf_generic_smc(TF_CACHE_MAINT, TF_CACHE_DISABLE,
|
||||
l2x0_way_mask);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int tf_init_cache(void)
|
||||
{
|
||||
outer_cache.write_sec = tf_cache_write_sec;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_CACHE_L2X0 */
|
||||
|
||||
static const struct firmware_ops trusted_foundations_ops = {
|
||||
.set_cpu_boot_addr = tf_set_cpu_boot_addr,
|
||||
.prepare_idle = tf_prepare_idle,
|
||||
#ifdef CONFIG_CACHE_L2X0
|
||||
.l2x0_init = tf_init_cache,
|
||||
#endif
|
||||
};
|
||||
|
||||
void register_trusted_foundations(struct trusted_foundations_platform_data *pd)
|
||||
|
@ -101,3 +169,8 @@ void of_register_trusted_foundations(void)
|
|||
panic("Trusted Foundation: missing version-minor property\n");
|
||||
register_trusted_foundations(&pdata);
|
||||
}
|
||||
|
||||
bool trusted_foundations_registered(void)
|
||||
{
|
||||
return firmware_ops == &trusted_foundations_ops;
|
||||
}
|
|
@ -23,14 +23,24 @@
|
|||
* PSCI standard.
|
||||
*/
|
||||
|
||||
#ifndef __ASM_ARM_TRUSTED_FOUNDATIONS_H
|
||||
#define __ASM_ARM_TRUSTED_FOUNDATIONS_H
|
||||
#ifndef __FIRMWARE_TRUSTED_FOUNDATIONS_H
|
||||
#define __FIRMWARE_TRUSTED_FOUNDATIONS_H
|
||||
|
||||
#include <linux/printk.h>
|
||||
#include <linux/bug.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/types.h>
|
||||
|
||||
#include <asm/hardware/cache-l2x0.h>
|
||||
#include <asm/outercache.h>
|
||||
|
||||
#define TF_PM_MODE_LP0 0
|
||||
#define TF_PM_MODE_LP1 1
|
||||
#define TF_PM_MODE_LP1_NO_MC_CLK 2
|
||||
#define TF_PM_MODE_LP2 3
|
||||
#define TF_PM_MODE_LP2_NOFLUSH_L2 4
|
||||
|
||||
struct trusted_foundations_platform_data {
|
||||
unsigned int version_major;
|
||||
|
@ -41,8 +51,12 @@ struct trusted_foundations_platform_data {
|
|||
|
||||
void register_trusted_foundations(struct trusted_foundations_platform_data *pd);
|
||||
void of_register_trusted_foundations(void);
|
||||
bool trusted_foundations_registered(void);
|
||||
|
||||
#else /* CONFIG_TRUSTED_FOUNDATIONS */
|
||||
static inline void tf_dummy_write_sec(unsigned long val, unsigned int reg)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void register_trusted_foundations(
|
||||
struct trusted_foundations_platform_data *pd)
|
||||
|
@ -53,6 +67,10 @@ static inline void register_trusted_foundations(
|
|||
*/
|
||||
pr_err("No support for Trusted Foundations, continuing in degraded mode.\n");
|
||||
pr_err("Secondary processors as well as CPU PM will be disabled.\n");
|
||||
#if IS_ENABLED(CONFIG_CACHE_L2X0)
|
||||
pr_err("L2X0 cache will be kept disabled.\n");
|
||||
outer_cache.write_sec = tf_dummy_write_sec;
|
||||
#endif
|
||||
#if IS_ENABLED(CONFIG_SMP)
|
||||
setup_max_cpus = 0;
|
||||
#endif
|
||||
|
@ -68,6 +86,11 @@ static inline void of_register_trusted_foundations(void)
|
|||
if (of_find_compatible_node(NULL, NULL, "tlm,trusted-foundations"))
|
||||
register_trusted_foundations(NULL);
|
||||
}
|
||||
|
||||
static inline bool trusted_foundations_registered(void)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
#endif /* CONFIG_TRUSTED_FOUNDATIONS */
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue