u-boot/arch/arm/mach-stm32mp/cpu.c
Tom Rini 4549e789c1 SPDX: Convert all of our multiple license tags to Linux Kernel style
When U-Boot started using SPDX tags we were among the early adopters and
there weren't a lot of other examples to borrow from.  So we picked the
area of the file that usually had a full license text and replaced it
with an appropriate SPDX-License-Identifier: entry.  Since then, the
Linux Kernel has adopted SPDX tags and they place it as the very first
line in a file (except where shebangs are used, then it's second line)
and with slightly different comment styles than us.

In part due to community overlap, in part due to better tag visibility
and in part for other minor reasons, switch over to that style.

This commit changes all instances where we have multiple licenses (in
these cases, dual license) declared in the SPDX-License-Identifier tag.
In this case we change from listing "LICENSE-A LICENSE-B" or "LICENSE-A
or LICENSE-B" or "(LICENSE-A OR LICENSE-B)" to "LICENSE-A OR LICENSE-B"
as per the Linux Kernel style document.  Note that parenthesis are
allowed so when they were used before we continue to use them.

Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
Signed-off-by: Tom Rini <trini@konsulko.com>
2018-05-07 10:24:31 -04:00

270 lines
6.5 KiB
C

// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
/*
* Copyright (C) 2018, STMicroelectronics - All Rights Reserved
*/
#include <common.h>
#include <clk.h>
#include <asm/io.h>
#include <asm/arch/stm32.h>
#include <asm/arch/sys_proto.h>
#include <dm/uclass.h>
/* RCC register */
#define RCC_TZCR (STM32_RCC_BASE + 0x00)
#define RCC_DBGCFGR (STM32_RCC_BASE + 0x080C)
#define RCC_BDCR (STM32_RCC_BASE + 0x0140)
#define RCC_MP_APB5ENSETR (STM32_RCC_BASE + 0x0208)
#define RCC_BDCR_VSWRST BIT(31)
#define RCC_BDCR_RTCSRC GENMASK(17, 16)
#define RCC_DBGCFGR_DBGCKEN BIT(8)
/* Security register */
#define ETZPC_TZMA1_SIZE (STM32_ETZPC_BASE + 0x04)
#define ETZPC_DECPROT0 (STM32_ETZPC_BASE + 0x10)
#define TZC_GATE_KEEPER (STM32_TZC_BASE + 0x008)
#define TZC_REGION_ATTRIBUTE0 (STM32_TZC_BASE + 0x110)
#define TZC_REGION_ID_ACCESS0 (STM32_TZC_BASE + 0x114)
#define TAMP_CR1 (STM32_TAMP_BASE + 0x00)
#define PWR_CR1 (STM32_PWR_BASE + 0x00)
#define PWR_CR1_DBP BIT(8)
/* DBGMCU register */
#define DBGMCU_IDC (STM32_DBGMCU_BASE + 0x00)
#define DBGMCU_APB4FZ1 (STM32_DBGMCU_BASE + 0x2C)
#define DBGMCU_APB4FZ1_IWDG2 BIT(2)
#define DBGMCU_IDC_DEV_ID_MASK GENMASK(11, 0)
#define DBGMCU_IDC_DEV_ID_SHIFT 0
#define DBGMCU_IDC_REV_ID_MASK GENMASK(31, 16)
#define DBGMCU_IDC_REV_ID_SHIFT 16
/* boot interface from Bootrom
* - boot instance = bit 31:16
* - boot device = bit 15:0
*/
#define BOOTROM_PARAM_ADDR 0x2FFC0078
#define BOOTROM_MODE_MASK GENMASK(15, 0)
#define BOOTROM_MODE_SHIFT 0
#define BOOTROM_INSTANCE_MASK GENMASK(31, 16)
#define BOOTROM_INSTANCE_SHIFT 16
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
static void security_init(void)
{
/* Disable the backup domain write protection */
/* the protection is enable at each reset by hardware */
/* And must be disable by software */
setbits_le32(PWR_CR1, PWR_CR1_DBP);
while (!(readl(PWR_CR1) & PWR_CR1_DBP))
;
/* If RTC clock isn't enable so this is a cold boot then we need
* to reset the backup domain
*/
if (!(readl(RCC_BDCR) & RCC_BDCR_RTCSRC)) {
setbits_le32(RCC_BDCR, RCC_BDCR_VSWRST);
while (!(readl(RCC_BDCR) & RCC_BDCR_VSWRST))
;
clrbits_le32(RCC_BDCR, RCC_BDCR_VSWRST);
}
/* allow non secure access in Write/Read for all peripheral */
writel(GENMASK(25, 0), ETZPC_DECPROT0);
/* Open SYSRAM for no secure access */
writel(0x0, ETZPC_TZMA1_SIZE);
/* enable TZC1 TZC2 clock */
writel(BIT(11) | BIT(12), RCC_MP_APB5ENSETR);
/* Region 0 set to no access by default */
/* bit 0 / 16 => nsaid0 read/write Enable
* bit 1 / 17 => nsaid1 read/write Enable
* ...
* bit 15 / 31 => nsaid15 read/write Enable
*/
writel(0xFFFFFFFF, TZC_REGION_ID_ACCESS0);
/* bit 30 / 31 => Secure Global Enable : write/read */
/* bit 0 / 1 => Region Enable for filter 0/1 */
writel(BIT(0) | BIT(1) | BIT(30) | BIT(31), TZC_REGION_ATTRIBUTE0);
/* Enable Filter 0 and 1 */
setbits_le32(TZC_GATE_KEEPER, BIT(0) | BIT(1));
/* RCC trust zone deactivated */
writel(0x0, RCC_TZCR);
/* TAMP: deactivate the internal tamper
* Bit 23 ITAMP8E: monotonic counter overflow
* Bit 20 ITAMP5E: RTC calendar overflow
* Bit 19 ITAMP4E: HSE monitoring
* Bit 18 ITAMP3E: LSE monitoring
* Bit 16 ITAMP1E: RTC power domain supply monitoring
*/
writel(0x0, TAMP_CR1);
}
/*
* Debug init
*/
static void dbgmcu_init(void)
{
setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
/* Freeze IWDG2 if Cortex-A7 is in debug mode */
setbits_le32(DBGMCU_APB4FZ1, DBGMCU_APB4FZ1_IWDG2);
}
#endif /* !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD) */
static u32 get_bootmode(void)
{
u32 boot_mode;
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
u32 bootrom_itf = readl(BOOTROM_PARAM_ADDR);
u32 bootrom_device, bootrom_instance;
bootrom_device =
(bootrom_itf & BOOTROM_MODE_MASK) >> BOOTROM_MODE_SHIFT;
bootrom_instance =
(bootrom_itf & BOOTROM_INSTANCE_MASK) >> BOOTROM_INSTANCE_SHIFT;
boot_mode =
((bootrom_device << BOOT_TYPE_SHIFT) & BOOT_TYPE_MASK) |
((bootrom_instance << BOOT_INSTANCE_SHIFT) &
BOOT_INSTANCE_MASK);
/* save the boot mode in TAMP backup register */
clrsetbits_le32(TAMP_BOOT_CONTEXT,
TAMP_BOOT_MODE_MASK,
boot_mode << TAMP_BOOT_MODE_SHIFT);
#else
/* read TAMP backup register */
boot_mode = (readl(TAMP_BOOT_CONTEXT) & TAMP_BOOT_MODE_MASK) >>
TAMP_BOOT_MODE_SHIFT;
#endif
return boot_mode;
}
/*
* Early system init
*/
int arch_cpu_init(void)
{
/* early armv7 timer init: needed for polling */
timer_init();
#if !defined(CONFIG_SPL) || defined(CONFIG_SPL_BUILD)
dbgmcu_init();
security_init();
#endif
/* get bootmode from BootRom context: saved in TAMP register */
get_bootmode();
return 0;
}
void enable_caches(void)
{
/* Enable D-cache. I-cache is already enabled in start.S */
dcache_enable();
}
static u32 read_idc(void)
{
setbits_le32(RCC_DBGCFGR, RCC_DBGCFGR_DBGCKEN);
return readl(DBGMCU_IDC);
}
u32 get_cpu_rev(void)
{
return (read_idc() & DBGMCU_IDC_REV_ID_MASK) >> DBGMCU_IDC_REV_ID_SHIFT;
}
u32 get_cpu_type(void)
{
return (read_idc() & DBGMCU_IDC_DEV_ID_MASK) >> DBGMCU_IDC_DEV_ID_SHIFT;
}
#if defined(CONFIG_DISPLAY_CPUINFO)
int print_cpuinfo(void)
{
char *cpu_s, *cpu_r;
switch (get_cpu_type()) {
case CPU_STMP32MP15x:
cpu_s = "15x";
break;
default:
cpu_s = "?";
break;
}
switch (get_cpu_rev()) {
case CPU_REVA:
cpu_r = "A";
break;
case CPU_REVB:
cpu_r = "B";
break;
default:
cpu_r = "?";
break;
}
printf("CPU: STM32MP%s.%s\n", cpu_s, cpu_r);
return 0;
}
#endif /* CONFIG_DISPLAY_CPUINFO */
static void setup_boot_mode(void)
{
char cmd[60];
u32 boot_ctx = readl(TAMP_BOOT_CONTEXT);
u32 boot_mode =
(boot_ctx & TAMP_BOOT_MODE_MASK) >> TAMP_BOOT_MODE_SHIFT;
int instance = (boot_mode & TAMP_BOOT_INSTANCE_MASK) - 1;
pr_debug("%s: boot_ctx=0x%x => boot_mode=%x, instance=%d\n",
__func__, boot_ctx, boot_mode, instance);
switch (boot_mode & TAMP_BOOT_DEVICE_MASK) {
case BOOT_SERIAL_UART:
sprintf(cmd, "%d", instance);
env_set("boot_device", "uart");
env_set("boot_instance", cmd);
break;
case BOOT_SERIAL_USB:
env_set("boot_device", "usb");
env_set("boot_instance", "0");
break;
case BOOT_FLASH_SD:
case BOOT_FLASH_EMMC:
sprintf(cmd, "%d", instance);
env_set("boot_device", "mmc");
env_set("boot_instance", cmd);
break;
case BOOT_FLASH_NAND:
env_set("boot_device", "nand");
env_set("boot_instance", "0");
break;
case BOOT_FLASH_NOR:
env_set("boot_device", "nor");
env_set("boot_instance", "0");
break;
default:
pr_debug("unexpected boot mode = %x\n", boot_mode);
break;
}
}
int arch_misc_init(void)
{
setup_boot_mode();
return 0;
}