diff --git a/docs/plat/allwinner.rst b/docs/plat/allwinner.rst index a10e6dc9655acf54dcfa4464d3450b9d86e55e0e..825fded48eb68c61c79ec570ec6bca48f9ef58b2 100644 --- a/docs/plat/allwinner.rst +++ b/docs/plat/allwinner.rst @@ -4,9 +4,11 @@ Trusted Firmware-A for Allwinner ARMv8 SoCs Trusted Firmware-A (TF-A) implements the EL3 firmware layer for Allwinner SoCs with ARMv8 cores. Only BL31 is used to provide proper EL3 setup and PSCI runtime services. + U-Boot's SPL acts as a loader, loading both BL31 and BL33 (typically U-Boot). Loading is done from SD card, eMMC or SPI flash, also via an USB debug interface (FEL). + BL31 lives in SRAM A2, which is documented to be accessible from secure world only. diff --git a/maintainers.rst b/maintainers.rst index 94bb5d31821b018b25f797e72a559c183371de56..c01d97adfa0bae669f6ac9677d5b61e5f3a8296b 100644 --- a/maintainers.rst +++ b/maintainers.rst @@ -20,6 +20,8 @@ Allwinner ARMv8 platform port ----------------------------- :M: Andre Przywara <andre.przywara@arm.com> :G: `Andre-ARM`_ +:M: Samuel Holland <samuel@sholland.org> +:G: `smaeul`_ :F: docs/plat/allwinner.rst :F: plat/allwinner/ diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index 2752aa4d327bd1baf1d53b2b93ba7e04d7c61f93..d0391888dffd516098f17685b99568575e2806e1 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -39,7 +39,7 @@ #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_MAX_CPUS_PER_CLUSTER) #define PLATFORM_MAX_CPUS_PER_CLUSTER 4 -#define PLATFORM_MMAP_REGIONS 4 +#define PLATFORM_MMAP_REGIONS 3 #define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT) #ifndef SPD_none diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index f5f91e3186ba8a39ad8861196d9b34e8bc79d559..e910ee5491816e4bae4565aadf024aafbf1e8f8e 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -64,6 +64,22 @@ void bl31_plat_arch_setup(void) void bl31_platform_setup(void) { + const char *soc_name; + uint16_t soc_id = sunxi_read_soc_id(); + + switch (soc_id) { + case 0x1689: + soc_name = "A64/H64/R18"; + break; + case 0x1718: + soc_name = "H5"; + break; + default: + soc_name = "unknown"; + break; + } + NOTICE("BL31: Detected Allwinner %s SoC (%04x)\n", soc_name, soc_id); + generic_delay_timer_init(); /* Configure the interrupt controller */ diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index e36c8b0718e15bbc411907a6d50cf7427290c2e4..fc9bf20978fa1b588e5ac22d6dda6f499c7d166d 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -4,14 +4,15 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <mmio.h> #include <platform.h> #include <platform_def.h> #include <sunxi_def.h> #include <xlat_tables_v2.h> +#include "sunxi_private.h" + static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { - MAP_REGION_FLAT(SUNXI_ROM_BASE, SUNXI_ROM_SIZE, - MT_MEMORY | MT_RO | MT_SECURE), MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE, MT_MEMORY | MT_RW | MT_SECURE), MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, @@ -54,3 +55,19 @@ void sunxi_configure_mmu_el3(int flags) enable_mmu_el3(0); } + +#define SRAM_VER_REG (SUNXI_SYSCON_BASE + 0x24) +uint16_t sunxi_read_soc_id(void) +{ + uint32_t reg = mmio_read_32(SRAM_VER_REG); + + /* Set bit 15 to prepare for the SOCID read. */ + mmio_write_32(SRAM_VER_REG, reg | BIT(15)); + + reg = mmio_read_32(SRAM_VER_REG); + + /* deactivate the SOCID access again */ + mmio_write_32(SRAM_VER_REG, reg & ~BIT(15)); + + return reg >> 16; +} diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c index be72dee45e6c4b40461fd7b10f97e92256128d4e..aaee65c665cda038a864fa5b9c4a880a5f482d44 100644 --- a/plat/allwinner/common/sunxi_cpu_ops.c +++ b/plat/allwinner/common/sunxi_cpu_ops.c @@ -18,7 +18,7 @@ static void sunxi_cpu_disable_power(unsigned int cluster, unsigned int core) if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0xff) return; - INFO("PSCI: Disabling power to cluster %d core %d\n", cluster, core); + VERBOSE("PSCI: Disabling power to cluster %d core %d\n", cluster, core); mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xff); } @@ -28,7 +28,7 @@ static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) if (mmio_read_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core)) == 0) return; - INFO("PSCI: Enabling power to cluster %d core %d\n", cluster, core); + VERBOSE("PSCI: Enabling power to cluster %d core %d\n", cluster, core); /* Power enable sequence from original Allwinner sources */ mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0xfe); @@ -40,7 +40,7 @@ static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) void sunxi_cpu_off(unsigned int cluster, unsigned int core) { - INFO("PSCI: Powering off cluster %d core %d\n", cluster, core); + VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core); /* Deassert DBGPWRDUP */ mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); @@ -54,7 +54,7 @@ void sunxi_cpu_off(unsigned int cluster, unsigned int core) void sunxi_cpu_on(unsigned int cluster, unsigned int core) { - INFO("PSCI: Powering on cluster %d core %d\n", cluster, core); + VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core); /* Assert CPU core reset */ mmio_clrbits_32(SUNXI_CPUCFG_RST_CTRL_REG(cluster), BIT(core)); diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index fcab130cd04e029f2e99083939bc152599648e82..2a1f2231deb1f2460a423934d452746fabc4d068 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -76,8 +76,7 @@ static void __dead2 sunxi_system_reset(void) static int sunxi_validate_ns_entrypoint(uintptr_t ns_entrypoint) { /* The non-secure entry point must be in DRAM */ - if (ns_entrypoint >= SUNXI_DRAM_BASE && - ns_entrypoint < SUNXI_DRAM_BASE + SUNXI_DRAM_SIZE) + if (ns_entrypoint >= SUNXI_DRAM_BASE) return PSCI_E_SUCCESS; return PSCI_E_INVALID_ADDRESS; diff --git a/plat/allwinner/common/sunxi_private.h b/plat/allwinner/common/sunxi_private.h index b9f0fb41c24bae4210c2ef5cd783a26ef78f495b..e45f494ed289be00b5f22a0fbae05e23b5c0da15 100644 --- a/plat/allwinner/common/sunxi_private.h +++ b/plat/allwinner/common/sunxi_private.h @@ -12,6 +12,7 @@ void sunxi_cpu_off(unsigned int cluster, unsigned int core); void sunxi_cpu_on(unsigned int cluster, unsigned int core); void sunxi_disable_secondary_cpus(unsigned int primary_cpu); +uint16_t sunxi_read_soc_id(void); void sunxi_security_setup(void); #endif /* __SUNXI_PRIVATE_H__ */ diff --git a/plat/allwinner/common/sunxi_security.c b/plat/allwinner/common/sunxi_security.c index e76007285e684de28906c46d443ce49bc2b7d1a4..80fed6ad0de77427b0290f8405329df7d0fb3510 100644 --- a/plat/allwinner/common/sunxi_security.c +++ b/plat/allwinner/common/sunxi_security.c @@ -25,9 +25,9 @@ */ void sunxi_security_setup(void) { +#ifdef SUNXI_SPC_BASE int i; -#ifdef SUNXI_SPC_BASE INFO("Configuring SPC Controller\n"); /* SPC setup: set all devices to non-secure */ for (i = 0; i < 6; i++) diff --git a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h index cb202a8390a0bf29c5b2c5b3422f591619ece08c..7d46487dc70f92f3eb645e5ee5d9f44b77182ae2 100644 --- a/plat/allwinner/sun50i_a64/include/sunxi_mmap.h +++ b/plat/allwinner/sun50i_a64/include/sunxi_mmap.h @@ -27,7 +27,6 @@ #define SUNXI_CPU_MBIST_BASE 0x01502000 #define SUNXI_CPUCFG_BASE 0x01700000 #define SUNXI_SYSCON_BASE 0x01c00000 -#define SUNXI_SRAM_VER_REG (SUNXI_SYSCON_BASE + 0x24) #define SUNXI_DMA_BASE 0x01c02000 #define SUNXI_KEYMEM_BASE 0x01c0b000 #define SUNXI_SMHC0_BASE 0x01c0f000