diff options
Diffstat (limited to 'plat')
486 files changed, 24025 insertions, 7621 deletions
diff --git a/plat/allwinner/common/allwinner-common.mk b/plat/allwinner/common/allwinner-common.mk index 6866bd65a..98bcf3e22 100644 --- a/plat/allwinner/common/allwinner-common.mk +++ b/plat/allwinner/common/allwinner-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -8,8 +8,7 @@ include lib/xlat_tables_v2/xlat_tables.mk AW_PLAT := plat/allwinner -PLAT_INCLUDES := -Iinclude/plat/arm/common \ - -Iinclude/plat/arm/common/aarch64 \ +PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64 \ -I${AW_PLAT}/common/include \ -I${AW_PLAT}/${PLAT}/include @@ -20,7 +19,8 @@ PLAT_BL_COMMON_SOURCES := drivers/ti/uart/${ARCH}/16550_console.S \ ${AW_PLAT}/common/plat_helpers.S \ ${AW_PLAT}/common/sunxi_common.c -BL31_SOURCES += drivers/arm/gic/common/gic_common.c \ +BL31_SOURCES += drivers/allwinner/axp/common.c \ + drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/delay_timer/delay_timer.c \ @@ -55,11 +55,11 @@ PROGRAMMABLE_RESET_ADDRESS := 1 # Allow mapping read-only data as execute-never. SEPARATE_CODE_AND_RODATA := 1 +# Put NOBITS memory in SRAM A1, overwriting U-Boot's SPL. +SEPARATE_NOBITS_REGION := 1 + # BL31 gets loaded alongside BL33 (U-Boot) by U-Boot's SPL RESET_TO_BL31 := 1 -# We are short on memory, so save 3.5KB by not having an extra coherent page. -USE_COHERENT_MEM := 0 - # This platform is single-cluster and does not require coherency setup. WARMBOOT_ENABLE_DCACHE_EARLY := 1 diff --git a/plat/allwinner/common/include/platform_def.h b/plat/allwinner/common/include/platform_def.h index ede3881a7..32a7c0408 100644 --- a/plat/allwinner/common/include/platform_def.h +++ b/plat/allwinner/common/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,6 +16,10 @@ #define BL31_BASE SUNXI_SRAM_A2_BASE #define BL31_LIMIT (SUNXI_SRAM_A2_BASE + SUNXI_SRAM_A2_SIZE) +/* Overwrite U-Boot SPL, but reserve the first page for the SPL header. */ +#define BL31_NOBITS_BASE (SUNXI_SRAM_A1_BASE + 0x1000) +#define BL31_NOBITS_LIMIT (SUNXI_SRAM_A1_BASE + SUNXI_SRAM_A1_SIZE) + /* The traditional U-Boot load address is 160MB into DRAM, so at 0x4a000000 */ #define PLAT_SUNXI_NS_IMAGE_OFFSET (SUNXI_DRAM_BASE + (160U << 20)) @@ -36,17 +40,17 @@ #define PLAT_MAX_OFF_STATE U(2) #define PLAT_MAX_PWR_LVL U(2) -#define PLAT_NUM_PWR_DOMAINS (1 + \ +#define PLAT_NUM_PWR_DOMAINS (U(1) + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 28) -#define PLATFORM_CLUSTER_COUNT 1 +#define PLATFORM_CLUSTER_COUNT U(1) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_MAX_CPUS_PER_CLUSTER) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_MMAP_REGIONS 4 #define PLATFORM_STACK_SIZE (0x1000 / PLATFORM_CORE_COUNT) diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h index 11668797b..dcf3dc965 100644 --- a/plat/allwinner/common/include/sunxi_private.h +++ b/plat/allwinner/common/include/sunxi_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,7 +12,7 @@ void sunxi_configure_mmu_el3(int flags); void sunxi_cpu_on(u_register_t mpidr); void sunxi_cpu_off(u_register_t mpidr); void sunxi_disable_secondary_cpus(u_register_t primary_mpidr); -void __dead2 sunxi_power_down(void); +void sunxi_power_down(void); int sunxi_pmic_setup(uint16_t socid, const void *fdt); void sunxi_security_setup(void); @@ -20,7 +20,6 @@ void sunxi_security_setup(void); uint16_t sunxi_read_soc_id(void); void sunxi_set_gpio_out(char port, int pin, bool level_high); int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb); -void sunxi_execute_arisc_code(uint32_t *code, size_t size, - int patch_offset, uint16_t param); +void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param); #endif /* SUNXI_PRIVATE_H */ diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 3b44aab68..3759c285e 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -20,15 +20,15 @@ static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE, - MT_MEMORY | MT_RW | MT_SECURE), + MT_RW_DATA | MT_SECURE), MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, - MT_DEVICE | MT_RW | MT_SECURE), + MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE, - MT_MEMORY | MT_RW | MT_SECURE), + MT_RW_DATA | MT_SECURE), MAP_REGION(PLAT_SUNXI_NS_IMAGE_OFFSET, SUNXI_DRAM_VIRT_BASE + SUNXI_DRAM_SEC_SIZE, SUNXI_DRAM_MAP_SIZE, - MT_MEMORY | MT_RO | MT_NS), + MT_RO_DATA | MT_NS), {}, }; @@ -48,15 +48,16 @@ uintptr_t plat_get_ns_image_entrypoint(void) void sunxi_configure_mmu_el3(int flags) { - mmap_add_region(BL31_BASE, BL31_BASE, - BL31_LIMIT - BL31_BASE, - MT_MEMORY | MT_RW | MT_SECURE); mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_SECURE); mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE, MT_RO_DATA | MT_SECURE); + mmap_add_region(BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER); + mmap_add(sunxi_mmap); init_xlat_tables(); @@ -150,16 +151,16 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) /* set both pins to pull-up */ mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U); - /* assert, then de-assert reset of I2C/RSB controller */ - mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); - mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); - /* un-gate clock */ if (socid != SUNXI_SOC_H6) mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit); else mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0)); + /* assert, then de-assert reset of I2C/RSB controller */ + mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); + mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); + return 0; } @@ -172,8 +173,7 @@ DEFINE_BAKERY_LOCK(arisc_lock); * in SRAM, put the address of that into the reset vector and release the * arisc reset line. The SCP will execute that code and pull the line up again. */ -void sunxi_execute_arisc_code(uint32_t *code, size_t size, - int patch_offset, uint16_t param) +void sunxi_execute_arisc_code(uint32_t *code, size_t size, uint16_t param) { uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE - 0x4000 + 0x100; @@ -187,8 +187,7 @@ void sunxi_execute_arisc_code(uint32_t *code, size_t size, } while (1); /* Patch up the code to feed in an input parameter. */ - if (patch_offset >= 0 && patch_offset <= (size - 4)) - code[patch_offset] = (code[patch_offset] & ~0xffff) | param; + code[0] = (code[0] & ~0xffff) | param; clean_dcache_range((uintptr_t)code, size); /* diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c index b4c9fcc18..6e29b69bf 100644 --- a/plat/allwinner/common/sunxi_cpu_ops.c +++ b/plat/allwinner/common/sunxi_cpu_ops.c @@ -78,7 +78,7 @@ void sunxi_cpu_off(u_register_t mpidr) * patched into the first instruction. */ sunxi_execute_arisc_code(arisc_core_off, sizeof(arisc_core_off), - 0, BIT_32(core)); + BIT_32(core)); } void sunxi_cpu_on(u_register_t mpidr) diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index 13e135325..9b074d2ac 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -65,6 +65,11 @@ static void __dead2 sunxi_system_off(void) sunxi_disable_secondary_cpus(read_mpidr()); sunxi_power_down(); + + udelay(1000); + ERROR("PSCI: Cannot turn off system, halting\n"); + wfi(); + panic(); } static void __dead2 sunxi_system_reset(void) diff --git a/plat/allwinner/sun50i_a64/platform.mk b/plat/allwinner/sun50i_a64/platform.mk index b46fbc2d1..f6d5aa9f8 100644 --- a/plat/allwinner/sun50i_a64/platform.mk +++ b/plat/allwinner/sun50i_a64/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,4 +7,5 @@ # The differences between the platform are covered by the include files. include plat/allwinner/common/allwinner-common.mk -PLAT_BL_COMMON_SOURCES += drivers/allwinner/sunxi_rsb.c +BL31_SOURCES += drivers/allwinner/axp/axp803.c \ + drivers/allwinner/sunxi_rsb.c diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c index 07a37167f..5b7d76ae9 100644 --- a/plat/allwinner/sun50i_a64/sunxi_power.c +++ b/plat/allwinner/sun50i_a64/sunxi_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io> * * SPDX-License-Identifier: BSD-3-Clause @@ -7,14 +7,11 @@ #include <errno.h> -#include <libfdt.h> - #include <platform_def.h> -#include <arch_helpers.h> #include <common/debug.h> +#include <drivers/allwinner/axp.h> #include <drivers/allwinner/sunxi_rsb.h> -#include <drivers/delay_timer.h> #include <lib/mmio.h> #include <sunxi_def.h> @@ -22,6 +19,7 @@ #include <sunxi_private.h> static enum pmic_type { + UNKNOWN, GENERIC_H5, GENERIC_A64, REF_DESIGN_H5, /* regulators controlled by GPIO pins on port L */ @@ -38,7 +36,7 @@ static enum pmic_type { * disabled. * This function only cares about peripherals. */ -void sunxi_turn_off_soc(uint16_t socid) +static void sunxi_turn_off_soc(uint16_t socid) { int i; @@ -113,174 +111,22 @@ static int rsb_init(void) return ret; /* Associate the 8-bit runtime address with the 12-bit bus address. */ - return rsb_assign_runtime_address(AXP803_HW_ADDR, - AXP803_RT_ADDR); -} - -static int axp_write(uint8_t reg, uint8_t val) -{ - return rsb_write(AXP803_RT_ADDR, reg, val); -} - -static int axp_clrsetbits(uint8_t reg, uint8_t clr_mask, uint8_t set_mask) -{ - uint8_t regval; - int ret; - - ret = rsb_read(AXP803_RT_ADDR, reg); - if (ret < 0) + ret = rsb_assign_runtime_address(AXP803_HW_ADDR, + AXP803_RT_ADDR); + if (ret) return ret; - regval = (ret & ~clr_mask) | set_mask; - - return rsb_write(AXP803_RT_ADDR, reg, regval); + return axp_check_id(); } -#define axp_clrbits(reg, clr_mask) axp_clrsetbits(reg, clr_mask, 0) -#define axp_setbits(reg, set_mask) axp_clrsetbits(reg, 0, set_mask) - -static bool should_enable_regulator(const void *fdt, int node) +int axp_read(uint8_t reg) { - if (fdt_getprop(fdt, node, "phandle", NULL) != NULL) - return true; - if (fdt_getprop(fdt, node, "regulator-always-on", NULL) != NULL) - return true; - return false; + return rsb_read(AXP803_RT_ADDR, reg); } -/* - * Retrieve the voltage from a given regulator DTB node. - * Both the regulator-{min,max}-microvolt properties must be present and - * have the same value. Return that value in millivolts. - */ -static int fdt_get_regulator_millivolt(const void *fdt, int node) -{ - const fdt32_t *prop; - uint32_t min_volt; - - prop = fdt_getprop(fdt, node, "regulator-min-microvolt", NULL); - if (prop == NULL) - return -EINVAL; - min_volt = fdt32_to_cpu(*prop); - - prop = fdt_getprop(fdt, node, "regulator-max-microvolt", NULL); - if (prop == NULL) - return -EINVAL; - - if (fdt32_to_cpu(*prop) != min_volt) - return -EINVAL; - - return min_volt / 1000; -} - -#define NO_SPLIT 0xff - -static const struct axp_regulator { - char *dt_name; - uint16_t min_volt; - uint16_t max_volt; - uint16_t step; - unsigned char split; - unsigned char volt_reg; - unsigned char switch_reg; - unsigned char switch_bit; -} regulators[] = { - {"dcdc1", 1600, 3400, 100, NO_SPLIT, 0x20, 0x10, 0}, - {"dcdc5", 800, 1840, 10, 32, 0x24, 0x10, 4}, - {"dcdc6", 600, 1520, 10, 50, 0x25, 0x10, 5}, - {"dldo1", 700, 3300, 100, NO_SPLIT, 0x15, 0x12, 3}, - {"dldo2", 700, 4200, 100, 27, 0x16, 0x12, 4}, - {"dldo3", 700, 3300, 100, NO_SPLIT, 0x17, 0x12, 5}, - {"fldo1", 700, 1450, 50, NO_SPLIT, 0x1c, 0x13, 2}, - {} -}; - -static int setup_regulator(const void *fdt, int node, - const struct axp_regulator *reg) +int axp_write(uint8_t reg, uint8_t val) { - int mvolt; - uint8_t regval; - - if (!should_enable_regulator(fdt, node)) - return -ENOENT; - - mvolt = fdt_get_regulator_millivolt(fdt, node); - if (mvolt < reg->min_volt || mvolt > reg->max_volt) - return -EINVAL; - - regval = (mvolt / reg->step) - (reg->min_volt / reg->step); - if (regval > reg->split) - regval = ((regval - reg->split) / 2) + reg->split; - - axp_write(reg->volt_reg, regval); - if (reg->switch_reg < 0xff) - axp_setbits(reg->switch_reg, BIT(reg->switch_bit)); - - INFO("PMIC: AXP803: %s voltage: %d.%03dV\n", reg->dt_name, - mvolt / 1000, mvolt % 1000); - - return 0; -} - -static void setup_axp803_rails(const void *fdt) -{ - int node; - bool dc1sw = false; - - /* locate the PMIC DT node, bail out if not found */ - node = fdt_node_offset_by_compatible(fdt, -1, "x-powers,axp803"); - if (node < 0) { - WARN("BL31: PMIC: Cannot find AXP803 DT node, skipping initial setup.\n"); - return; - } - - if (fdt_getprop(fdt, node, "x-powers,drive-vbus-en", NULL)) { - axp_clrbits(0x8f, BIT(4)); - axp_setbits(0x30, BIT(2)); - INFO("PMIC: AXP803: Enabling DRIVEVBUS\n"); - } - - /* descend into the "regulators" subnode */ - node = fdt_subnode_offset(fdt, node, "regulators"); - if (node < 0) { - WARN("BL31: PMIC: Cannot find regulators subnode, skipping initial setup.\n"); - return; - } - - /* iterate over all regulators to find used ones */ - for (node = fdt_first_subnode(fdt, node); - node >= 0; - node = fdt_next_subnode(fdt, node)) { - const struct axp_regulator *reg; - const char *name; - int length; - - /* We only care if it's always on or referenced. */ - if (!should_enable_regulator(fdt, node)) - continue; - - name = fdt_get_name(fdt, node, &length); - for (reg = regulators; reg->dt_name; reg++) { - if (!strncmp(name, reg->dt_name, length)) { - setup_regulator(fdt, node, reg); - break; - } - } - - if (!strncmp(name, "dc1sw", length)) { - /* Delay DC1SW enablement to avoid overheating. */ - dc1sw = true; - continue; - } - } - /* - * If DLDO2 is enabled after DC1SW, the PMIC overheats and shuts - * down. So always enable DC1SW as the very last regulator. - */ - if (dc1sw) { - INFO("PMIC: AXP803: Enabling DC1SW\n"); - axp_setbits(0x12, BIT(7)); - } + return rsb_write(AXP803_RT_ADDR, reg, val); } int sunxi_pmic_setup(uint16_t socid, const void *fdt) @@ -289,11 +135,16 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt) switch (socid) { case SUNXI_SOC_H5: + NOTICE("PMIC: Assuming H5 reference regulator design\n"); + pmic = REF_DESIGN_H5; - NOTICE("BL31: PMIC: Defaulting to PortL GPIO according to H5 reference design.\n"); + break; case SUNXI_SOC_A64: pmic = GENERIC_A64; + + INFO("PMIC: Probing AXP803 on RSB\n"); + ret = sunxi_init_platform_r_twi(socid, true); if (ret) return ret; @@ -303,20 +154,16 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt) return ret; pmic = AXP803_RSB; - NOTICE("BL31: PMIC: Detected AXP803 on RSB.\n"); - - if (fdt) - setup_axp803_rails(fdt); + axp_setup_regulators(fdt); break; default: - NOTICE("BL31: PMIC: No support for Allwinner %x SoC.\n", socid); return -ENODEV; } return 0; } -void __dead2 sunxi_power_down(void) +void sunxi_power_down(void) { switch (pmic) { case GENERIC_H5: @@ -354,16 +201,10 @@ void __dead2 sunxi_power_down(void) /* (Re-)init RSB in case the rich OS has disabled it. */ sunxi_init_platform_r_twi(SUNXI_SOC_A64, true); rsb_init(); - - /* Set "power disable control" bit */ - axp_setbits(0x32, BIT(7)); + axp_power_off(); break; default: break; } - udelay(1000); - ERROR("PSCI: Cannot turn off system, halting.\n"); - wfi(); - panic(); } diff --git a/plat/allwinner/sun50i_h6/platform.mk b/plat/allwinner/sun50i_h6/platform.mk index 5c21eadb2..4ecc57cf0 100644 --- a/plat/allwinner/sun50i_h6/platform.mk +++ b/plat/allwinner/sun50i_h6/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,4 +7,5 @@ # The differences between the platform are covered by the include files. include plat/allwinner/common/allwinner-common.mk -PLAT_BL_COMMON_SOURCES += drivers/mentor/i2c/mi2cv.c +BL31_SOURCES += drivers/allwinner/axp/axp805.c \ + drivers/mentor/i2c/mi2cv.c diff --git a/plat/allwinner/sun50i_h6/sunxi_power.c b/plat/allwinner/sun50i_h6/sunxi_power.c index 5b5bad177..443015bac 100644 --- a/plat/allwinner/sun50i_h6/sunxi_power.c +++ b/plat/allwinner/sun50i_h6/sunxi_power.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2018, Icenowy Zheng <icenowy@aosc.io> * * SPDX-License-Identifier: BSD-3-Clause @@ -10,6 +10,7 @@ #include <arch_helpers.h> #include <common/debug.h> +#include <drivers/allwinner/axp.h> #include <drivers/delay_timer.h> #include <drivers/mentor/mi2cv.h> #include <lib/mmio.h> @@ -19,53 +20,51 @@ #include <sunxi_private.h> #define AXP805_ADDR 0x36 -#define AXP805_ID 0x03 -enum pmic_type { - NO_PMIC, +static enum pmic_type { + UNKNOWN, AXP805, -}; +} pmic; -enum pmic_type pmic; - -int axp_i2c_read(uint8_t chip, uint8_t reg, uint8_t *val) +int axp_read(uint8_t reg) { + uint8_t val; int ret; - ret = i2c_write(chip, 0, 0, ®, 1); - if (ret) + ret = i2c_write(AXP805_ADDR, 0, 0, ®, 1); + if (ret == 0) + ret = i2c_read(AXP805_ADDR, 0, 0, &val, 1); + if (ret) { + ERROR("PMIC: Cannot read AXP805 register %02x\n", reg); return ret; + } - return i2c_read(chip, 0, 0, val, 1); + return val; } -int axp_i2c_write(uint8_t chip, uint8_t reg, uint8_t val) +int axp_write(uint8_t reg, uint8_t val) { - return i2c_write(chip, reg, 1, &val, 1); + int ret; + + ret = i2c_write(AXP805_ADDR, reg, 1, &val, 1); + if (ret) + ERROR("PMIC: Cannot write AXP805 register %02x\n", reg); + + return ret; } static int axp805_probe(void) { int ret; - uint8_t val; - ret = axp_i2c_write(AXP805_ADDR, 0xff, 0x0); - if (ret) { - ERROR("PMIC: Cannot put AXP805 to master mode.\n"); - return -EPERM; - } - - ret = axp_i2c_read(AXP805_ADDR, AXP805_ID, &val); + /* Switch the AXP805 to master/single-PMIC mode. */ + ret = axp_write(0xff, 0x0); + if (ret) + return ret; - if (!ret && ((val & 0xcf) == 0x40)) - NOTICE("PMIC: AXP805 detected\n"); - else if (ret) { - ERROR("PMIC: Cannot communicate with AXP805.\n"); - return -EPERM; - } else { - ERROR("PMIC: Non-AXP805 chip attached at AXP805's address.\n"); - return -EINVAL; - } + ret = axp_check_id(); + if (ret) + return ret; return 0; } @@ -74,41 +73,36 @@ int sunxi_pmic_setup(uint16_t socid, const void *fdt) { int ret; - sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); + INFO("PMIC: Probing AXP805 on I2C\n"); + + ret = sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); + if (ret) + return ret; + /* initialise mi2cv driver */ i2c_init((void *)SUNXI_R_I2C_BASE); - NOTICE("PMIC: Probing AXP805\n"); - pmic = AXP805; - ret = axp805_probe(); if (ret) - pmic = NO_PMIC; - else - pmic = AXP805; + return ret; + + pmic = AXP805; + axp_setup_regulators(fdt); return 0; } -void __dead2 sunxi_power_down(void) +void sunxi_power_down(void) { - uint8_t val; - switch (pmic) { case AXP805: /* Re-initialise after rich OS might have used it. */ sunxi_init_platform_r_twi(SUNXI_SOC_H6, false); /* initialise mi2cv driver */ i2c_init((void *)SUNXI_R_I2C_BASE); - axp_i2c_read(AXP805_ADDR, 0x32, &val); - axp_i2c_write(AXP805_ADDR, 0x32, val | 0x80); + axp_power_off(); break; default: break; } - - udelay(1000); - ERROR("PSCI: Cannot communicate with PMIC, halting\n"); - wfi(); - panic(); } diff --git a/plat/meson/gxl/aarch64/gxl_helpers.S b/plat/amlogic/common/aarch64/aml_helpers.S index 760d6c46d..39bff0833 100644 --- a/plat/meson/gxl/aarch64/gxl_helpers.S +++ b/plat/amlogic/common/aarch64/aml_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,7 @@ .globl plat_is_my_cpu_primary .globl plat_my_core_pos .globl plat_reset_handler - .globl plat_gxbb_calc_core_pos + .globl plat_calc_core_pos /* ----------------------------------------------------- * unsigned int plat_my_core_pos(void); @@ -24,17 +24,17 @@ */ func plat_my_core_pos mrs x0, mpidr_el1 - b plat_gxbb_calc_core_pos + b plat_calc_core_pos endfunc plat_my_core_pos /* ----------------------------------------------------- - * unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr); + * unsigned int plat_calc_core_pos(u_register_t mpidr); * ----------------------------------------------------- */ -func plat_gxbb_calc_core_pos +func plat_calc_core_pos and x0, x0, #MPIDR_CPU_MASK ret -endfunc plat_gxbb_calc_core_pos +endfunc plat_calc_core_pos /* ----------------------------------------------------- * unsigned int plat_is_my_cpu_primary(void); @@ -43,7 +43,7 @@ endfunc plat_gxbb_calc_core_pos func plat_is_my_cpu_primary mrs x0, mpidr_el1 and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #GXBB_PRIMARY_CPU + cmp x0, #AML_PRIMARY_CPU cset w0, eq ret endfunc plat_is_my_cpu_primary @@ -61,9 +61,9 @@ endfunc platform_mem_init * --------------------------------------------- */ func plat_crash_console_init - mov_imm x0, GXBB_UART0_AO_BASE - mov_imm x1, GXBB_UART0_AO_CLK_IN_HZ - mov_imm x2, GXBB_UART_BAUDRATE + mov_imm x0, AML_UART0_AO_BASE + mov_imm x1, AML_UART0_AO_CLK_IN_HZ + mov_imm x2, AML_UART_BAUDRATE b console_meson_init endfunc plat_crash_console_init @@ -73,7 +73,7 @@ endfunc plat_crash_console_init * --------------------------------------------- */ func plat_crash_console_putc - mov_imm x1, GXBB_UART0_AO_BASE + mov_imm x1, AML_UART0_AO_BASE b console_meson_core_putc endfunc plat_crash_console_putc @@ -84,7 +84,7 @@ endfunc plat_crash_console_putc * --------------------------------------------- */ func plat_crash_console_flush - mov_imm x0, GXBB_UART0_AO_BASE + mov_imm x0, AML_UART0_AO_BASE b console_meson_core_flush endfunc plat_crash_console_flush diff --git a/plat/amlogic/common/aml_console.c b/plat/amlogic/common/aml_console.c new file mode 100644 index 000000000..352279b6c --- /dev/null +++ b/plat/amlogic/common/aml_console.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019, Carlo Caione <ccaione@baylibre.com> + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <meson_console.h> +#include <platform_def.h> + +/******************************************************************************* + * Function that sets up the console + ******************************************************************************/ +static console_meson_t aml_console; + +void aml_console_init(void) +{ + int rc = console_meson_register(AML_UART0_AO_BASE, + AML_UART0_AO_CLK_IN_HZ, + AML_UART_BAUDRATE, + &aml_console); + if (rc == 0) { + /* + * The crash console doesn't use the multi console API, it uses + * the core console functions directly. It is safe to call panic + * and let it print debug information. + */ + panic(); + } + + console_set_scope(&aml_console.console, + CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); +} diff --git a/plat/amlogic/common/aml_efuse.c b/plat/amlogic/common/aml_efuse.c new file mode 100644 index 000000000..00884ebd5 --- /dev/null +++ b/plat/amlogic/common/aml_efuse.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <stdint.h> + +#include "aml_private.h" + +#define EFUSE_BASE 0x140 +#define EFUSE_SIZE 0xC0 + +uint64_t aml_efuse_read(void *dst, uint32_t offset, uint32_t size) +{ + if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE) + return 0; + + return aml_scpi_efuse_read(dst, offset + EFUSE_BASE, size); +} + +uint64_t aml_efuse_user_max(void) +{ + return EFUSE_SIZE; +} diff --git a/plat/amlogic/common/aml_mhu.c b/plat/amlogic/common/aml_mhu.c new file mode 100644 index 000000000..001686af0 --- /dev/null +++ b/plat/amlogic/common/aml_mhu.c @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/bakery_lock.h> +#include <lib/mmio.h> +#include <platform_def.h> + +static DEFINE_BAKERY_LOCK(mhu_lock); + +void aml_mhu_secure_message_start(void) +{ + bakery_lock_get(&mhu_lock); + + while (mmio_read_32(AML_HIU_MAILBOX_STAT_3) != 0) + ; +} + +void aml_mhu_secure_message_send(uint32_t msg) +{ + mmio_write_32(AML_HIU_MAILBOX_SET_3, msg); + + while (mmio_read_32(AML_HIU_MAILBOX_STAT_3) != 0) + ; +} + +uint32_t aml_mhu_secure_message_wait(void) +{ + uint32_t val; + + do { + val = mmio_read_32(AML_HIU_MAILBOX_STAT_0); + } while (val == 0); + + return val; +} + +void aml_mhu_secure_message_end(void) +{ + mmio_write_32(AML_HIU_MAILBOX_CLR_0, 0xFFFFFFFF); + + bakery_lock_release(&mhu_lock); +} + +void aml_mhu_secure_init(void) +{ + bakery_lock_init(&mhu_lock); + + mmio_write_32(AML_HIU_MAILBOX_CLR_3, 0xFFFFFFFF); +} diff --git a/plat/amlogic/common/aml_scpi.c b/plat/amlogic/common/aml_scpi.c new file mode 100644 index 000000000..c8a6772c0 --- /dev/null +++ b/plat/amlogic/common/aml_scpi.c @@ -0,0 +1,234 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <crypto/sha_dma.h> +#include <lib/mmio.h> +#include <plat/common/platform.h> +#include <platform_def.h> +#include <string.h> + +#include "aml_private.h" + +#define SIZE_SHIFT 20 +#define SIZE_MASK 0x1FF +#define SIZE_FWBLK 0x200UL + +/* + * Note: The Amlogic SCP firmware uses the legacy SCPI protocol. + */ +#define SCPI_CMD_SET_CSS_POWER_STATE 0x04 +#define SCPI_CMD_SET_SYS_POWER_STATE 0x08 + +#define SCPI_CMD_JTAG_SET_STATE 0xC0 +#define SCPI_CMD_EFUSE_READ 0xC2 +#define SCPI_CMD_CHIP_ID 0xC6 + +#define SCPI_CMD_COPY_FW 0xd4 +#define SCPI_CMD_SET_FW_ADDR 0xd3 +#define SCPI_CMD_FW_SIZE 0xd2 + +static inline uint32_t aml_scpi_cmd(uint32_t command, uint32_t size) +{ + return command | (size << SIZE_SHIFT); +} + +static void aml_scpi_secure_message_send(uint32_t command, uint32_t size) +{ + aml_mhu_secure_message_send(aml_scpi_cmd(command, size)); +} + +static uint32_t aml_scpi_secure_message_receive(void **message_out, size_t *size_out) +{ + uint32_t response = aml_mhu_secure_message_wait(); + + size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; + + response &= ~(SIZE_MASK << SIZE_SHIFT); + + if (size_out != NULL) + *size_out = size; + + if (message_out != NULL) + *message_out = (void *)AML_MHU_SECURE_SCP_TO_AP_PAYLOAD; + + return response; +} + +void aml_scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, + uint32_t cluster_state, uint32_t css_state) +{ + uint32_t state = (mpidr & 0x0F) | /* CPU ID */ + ((mpidr & 0xF00) >> 4) | /* Cluster ID */ + (cpu_state << 8) | + (cluster_state << 12) | + (css_state << 16); + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, state); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_sys_power_state(uint64_t system_state) +{ + uint32_t *response; + size_t size; + + aml_mhu_secure_message_start(); + mmio_write_8(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1)); + aml_scpi_secure_message_receive((void *)&response, &size); + aml_mhu_secure_message_end(); + + return *response; +} + +void aml_scpi_jtag_set_state(uint32_t state, uint8_t select) +{ + assert(state <= AML_JTAG_STATE_OFF); + + if (select > AML_JTAG_A53_EE) { + WARN("BL31: Invalid JTAG select (0x%x).\n", select); + return; + } + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, + (state << 8) | (uint32_t)select); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_efuse_read(void *dst, uint32_t base, uint32_t size) +{ + uint32_t *response; + size_t resp_size; + + if (size > 0x1FC) + return 0; + + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, base); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_EFUSE_READ, 8)); + aml_scpi_secure_message_receive((void *)&response, &resp_size); + aml_mhu_secure_message_end(); + + /* + * response[0] is the size of the response message. + * response[1 ... N] are the contents. + */ + if (*response != 0) + memcpy(dst, response + 1, *response); + + return *response; +} + +void aml_scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, + uint32_t arg2, uint32_t arg3) +{ + aml_mhu_secure_message_start(); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2); + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3); + aml_mhu_secure_message_send(aml_scpi_cmd(0xC3, 16)); + aml_mhu_secure_message_wait(); + aml_mhu_secure_message_end(); +} + +uint32_t aml_scpi_get_chip_id(uint8_t *obuff, uint32_t osize) +{ + uint32_t *response; + size_t resp_size; + + if ((osize != 16) && (osize != 12)) + return 0; + + aml_mhu_secure_message_start(); + aml_mhu_secure_message_send(aml_scpi_cmd(SCPI_CMD_CHIP_ID, osize)); + aml_scpi_secure_message_receive((void *)&response, &resp_size); + aml_mhu_secure_message_end(); + + if (!((resp_size == 16) && (osize == 16)) && + !((resp_size == 0) && (osize == 12))) + return 0; + + memcpy((void *)obuff, (const void *)response, osize); + + return osize; +} + +static inline void aml_scpi_copy_scp_data(uint8_t *data, size_t len) +{ + void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + size_t sz; + + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); + aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); + aml_mhu_secure_message_wait(); + + for (sz = 0; sz < len; sz += SIZE_FWBLK) { + memcpy(dst, data + sz, MIN(SIZE_FWBLK, len - sz)); + aml_mhu_secure_message_send(SCPI_CMD_COPY_FW); + } +} + +static inline void aml_scpi_set_scp_addr(uint64_t addr, size_t len) +{ + volatile uint64_t *dst = (uint64_t *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + + /* + * It is ok as AML_MHU_SECURE_AP_TO_SCP_PAYLOAD is mapped as + * non cachable + */ + *dst = addr; + aml_scpi_secure_message_send(SCPI_CMD_SET_FW_ADDR, sizeof(addr)); + aml_mhu_secure_message_wait(); + + mmio_write_32(AML_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); + aml_scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); + aml_mhu_secure_message_wait(); +} + +static inline void aml_scpi_send_fw_hash(uint8_t hash[], size_t len) +{ + void *dst = (void *)AML_MHU_SECURE_AP_TO_SCP_PAYLOAD; + + memcpy(dst, hash, len); + aml_mhu_secure_message_send(0xd0); + aml_mhu_secure_message_send(0xd1); + aml_mhu_secure_message_send(0xd5); + aml_mhu_secure_message_end(); +} + +/** + * Upload a FW to SCP. + * + * @param addr: firmware data address + * @param size: size of firmware + * @param send: If set, actually copy the firmware in SCP memory otherwise only + * send the firmware address. + */ +void aml_scpi_upload_scp_fw(uintptr_t addr, size_t size, int send) +{ + struct asd_ctx ctx; + + asd_sha_init(&ctx, ASM_SHA256); + asd_sha_update(&ctx, (void *)addr, size); + asd_sha_finalize(&ctx); + + aml_mhu_secure_message_start(); + if (send == 0) + aml_scpi_set_scp_addr(addr, size); + else + aml_scpi_copy_scp_data((void *)addr, size); + + aml_scpi_send_fw_hash(ctx.digest, sizeof(ctx.digest)); +} diff --git a/plat/amlogic/common/aml_sip_svc.c b/plat/amlogic/common/aml_sip_svc.c new file mode 100644 index 000000000..ab4c01563 --- /dev/null +++ b/plat/amlogic/common/aml_sip_svc.c @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <common/runtime_svc.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <stdint.h> +#include <string.h> + +#include "aml_private.h" + +struct aml_cpu_info { + uint32_t version; + uint8_t chip_id[16]; +}; + +static int aml_sip_get_chip_id(uint64_t version) +{ + struct aml_cpu_info *info = (void *)AML_SHARE_MEM_OUTPUT_BASE; + uint32_t size; + + if (version > 2) + return -1; + + memset(info, 0, sizeof(struct aml_cpu_info)); + + if (version == 2) { + info->version = 2; + size = 16; + } else { + info->version = 1; + size = 12; + } + + if (aml_scpi_get_chip_id(info->chip_id, size) == 0) + return -1; + + return 0; +} + +/******************************************************************************* + * This function is responsible for handling all SiP calls + ******************************************************************************/ +static uintptr_t aml_sip_handler(uint32_t smc_fid, + u_register_t x1, u_register_t x2, + u_register_t x3, u_register_t x4, + void *cookie, void *handle, + u_register_t flags) +{ + switch (smc_fid) { + + case AML_SM_GET_SHARE_MEM_INPUT_BASE: + SMC_RET1(handle, AML_SHARE_MEM_INPUT_BASE); + + case AML_SM_GET_SHARE_MEM_OUTPUT_BASE: + SMC_RET1(handle, AML_SHARE_MEM_OUTPUT_BASE); + + case AML_SM_EFUSE_READ: + { + void *dst = (void *)AML_SHARE_MEM_OUTPUT_BASE; + uint64_t ret = aml_efuse_read(dst, (uint32_t)x1, x2); + + SMC_RET1(handle, ret); + } + case AML_SM_EFUSE_USER_MAX: + SMC_RET1(handle, aml_efuse_user_max()); + + case AML_SM_JTAG_ON: + aml_scpi_jtag_set_state(AML_JTAG_STATE_ON, x1); + SMC_RET1(handle, 0); + + case AML_SM_JTAG_OFF: + aml_scpi_jtag_set_state(AML_JTAG_STATE_OFF, x1); + SMC_RET1(handle, 0); + + case AML_SM_GET_CHIP_ID: + SMC_RET1(handle, aml_sip_get_chip_id(x1)); + + default: + ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid); + break; + } + + SMC_RET1(handle, SMC_UNK); +} + +DECLARE_RT_SVC( + aml_sip_handler, + + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + aml_sip_handler +); diff --git a/plat/meson/gxbb/gxbb_thermal.c b/plat/amlogic/common/aml_thermal.c index b6048eee4..53ed10323 100644 --- a/plat/meson/gxbb/gxbb_thermal.c +++ b/plat/amlogic/common/aml_thermal.c @@ -1,27 +1,27 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <stdint.h> -#include "gxbb_private.h" +#include "aml_private.h" static int32_t modules_initialized = -1; /******************************************************************************* * Unknown commands related to something thermal-related ******************************************************************************/ -void gxbb_thermal_unknown(void) +void aml_thermal_unknown(void) { uint16_t ret; if (modules_initialized == -1) { - scpi_efuse_read(&ret, 0, 2); + aml_scpi_efuse_read(&ret, 0, 2); modules_initialized = ret; } - scpi_unknown_thermal(10, 2, /* thermal */ - 13, 1); /* thermalver */ + aml_scpi_unknown_thermal(10, 2, /* thermal */ + 13, 1); /* thermalver */ } diff --git a/plat/meson/gxl/gxl_topology.c b/plat/amlogic/common/aml_topology.c index cca3ead50..0a04c1105 100644 --- a/plat/meson/gxl/gxl_topology.c +++ b/plat/amlogic/common/aml_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,7 +8,7 @@ #include <platform_def.h> #include <stdint.h> -#include "gxl_private.h" +#include "aml_private.h" /* The power domain tree descriptor */ static unsigned char power_domain_tree_desc[] = { @@ -49,5 +49,5 @@ int plat_core_pos_by_mpidr(u_register_t mpidr) if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) return -1; - return plat_gxbb_calc_core_pos(mpidr); + return plat_calc_core_pos(mpidr); } diff --git a/plat/amlogic/common/include/aml_private.h b/plat/amlogic/common/include/aml_private.h new file mode 100644 index 000000000..724f382fb --- /dev/null +++ b/plat/amlogic/common/include/aml_private.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef AML_PRIVATE_H +#define AML_PRIVATE_H + +#include <stddef.h> +#include <stdint.h> + +/* Utility functions */ +unsigned int plat_calc_core_pos(u_register_t mpidr); +void aml_console_init(void); +void aml_setup_page_tables(void); + +/* MHU functions */ +void aml_mhu_secure_message_start(void); +void aml_mhu_secure_message_send(uint32_t msg); +uint32_t aml_mhu_secure_message_wait(void); +void aml_mhu_secure_message_end(void); +void aml_mhu_secure_init(void); + +/* SCPI functions */ +void aml_scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, + uint32_t cluster_state, uint32_t css_state); +uint32_t aml_scpi_sys_power_state(uint64_t system_state); +void aml_scpi_jtag_set_state(uint32_t state, uint8_t select); +uint32_t aml_scpi_efuse_read(void *dst, uint32_t base, uint32_t size); +void aml_scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, + uint32_t arg2, uint32_t arg3); +void aml_scpi_upload_scp_fw(uintptr_t addr, size_t size, int send); +uint32_t aml_scpi_get_chip_id(uint8_t *obuff, uint32_t osize); + +/* Peripherals */ +void aml_thermal_unknown(void); +uint64_t aml_efuse_read(void *dst, uint32_t offset, uint32_t size); +uint64_t aml_efuse_user_max(void); + +#endif /* AML_PRIVATE_H */ diff --git a/plat/meson/gxl/include/plat_macros.S b/plat/amlogic/common/include/plat_macros.S index c721c21b6..d620fcfba 100644 --- a/plat/meson/gxl/include/plat_macros.S +++ b/plat/amlogic/common/include/plat_macros.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -33,7 +33,7 @@ spacer: /* GICC registers */ - mov_imm x17, GXBB_GICC_BASE + mov_imm x17, AML_GICC_BASE adr x6, gicc_regs ldr w8, [x17, #GICC_HPPIR] @@ -43,7 +43,7 @@ spacer: /* GICD registers */ - mov_imm x16, GXBB_GICD_BASE + mov_imm x16, AML_GICD_BASE add x7, x16, #GICD_ISPENDR adr x4, gicd_pend_reg diff --git a/plat/amlogic/g12a/g12a_bl31_setup.c b/plat/amlogic/g12a/g12a_bl31_setup.c new file mode 100644 index 000000000..77057a17f --- /dev/null +++ b/plat/amlogic/g12a/g12a_bl31_setup.c @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/bl_common.h> +#include <common/interrupt_props.h> +#include <drivers/arm/gicv2.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +/* + * Placeholder variables for copying the arguments that have been passed to + * BL31 from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; +static image_info_t bl30_image_info; +static image_info_t bl301_image_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + next_image_info = (type == NON_SECURE) ? + &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images can have 0x0 as the entrypoint. */ + if (next_image_info->pc != 0U) + return next_image_info; + + return NULL; +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +struct g12a_bl31_param { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; + image_info_t *scp_image_info[]; +}; + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + struct g12a_bl31_param *from_bl2; + + /* Initialize the console to provide early debug support */ + aml_console_init(); + + from_bl2 = (struct g12a_bl31_param *)arg0; + + /* Check params passed from BL2 are not NULL. */ + assert(from_bl2 != NULL); + assert(from_bl2->h.type == PARAM_BL31); + assert(from_bl2->h.version >= VERSION_1); + + /* + * Copy BL32 and BL33 entry point information. It is stored in Secure + * RAM, in BL2's address space. + */ + bl32_image_ep_info = *from_bl2->bl32_ep_info; + bl33_image_ep_info = *from_bl2->bl33_ep_info; + + if (bl33_image_ep_info.pc == 0U) { + ERROR("BL31: BL33 entrypoint not obtained from BL2\n"); + panic(); + } + + bl30_image_info = *from_bl2->scp_image_info[0]; + bl301_image_info = *from_bl2->scp_image_info[1]; +} + +void bl31_plat_arch_setup(void) +{ + aml_setup_page_tables(); + + enable_mmu_el3(0); +} + +/******************************************************************************* + * GICv2 driver setup information + ******************************************************************************/ +static const interrupt_prop_t g12a_interrupt_props[] = { + INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), + INTR_PROP_DESC(IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL) +}; + +static const gicv2_driver_data_t g12a_gic_data = { + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, + .interrupt_props = g12a_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(g12a_interrupt_props) +}; + +void bl31_platform_setup(void) +{ + aml_mhu_secure_init(); + + gicv2_driver_init(&g12a_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} diff --git a/plat/amlogic/g12a/g12a_common.c b/plat/amlogic/g12a/g12a_common.c new file mode 100644 index 000000000..e74ed0466 --- /dev/null +++ b/plat/amlogic/g12a/g12a_common.c @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <bl31/interrupt_mgmt.h> +#include <common/bl_common.h> +#include <common/ep_info.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <platform_def.h> +#include <stdint.h> + +/******************************************************************************* + * Platform memory map regions + ******************************************************************************/ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_NS_SHARE_MEM MAP_REGION_FLAT(AML_NS_SHARE_MEM_BASE, \ + AML_NS_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define MAP_SEC_SHARE_MEM MAP_REGION_FLAT(AML_SEC_SHARE_MEM_BASE, \ + AML_SEC_SHARE_MEM_SIZE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ + MT_DEVICE | MT_RW) + +#define MAP_HDCP_RX MAP_REGION_FLAT(AML_HDCP_RX_BASE, \ + AML_HDCP_RX_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_HDCP_TX MAP_REGION_FLAT(AML_HDCP_TX_BASE, \ + AML_HDCP_TX_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_GIC_DEVICE MAP_REGION_FLAT(AML_GIC_DEVICE_BASE, \ + AML_GIC_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +static const mmap_region_t g12a_mmap[] = { + MAP_NSDRAM0, + MAP_NS_SHARE_MEM, + MAP_SEC_SHARE_MEM, + MAP_SEC_DEVICE0, + MAP_HDCP_RX, + MAP_HDCP_TX, + MAP_GIC_DEVICE, + MAP_SEC_DEVICE1, + MAP_SEC_DEVICE2, + MAP_TZRAM, + {0} +}; + +/******************************************************************************* + * Per-image regions + ******************************************************************************/ +#define MAP_BL31 MAP_REGION_FLAT(BL31_BASE, \ + BL31_END - BL31_BASE, \ + MT_MEMORY | MT_RW | MT_SECURE) + +#define MAP_BL_CODE MAP_REGION_FLAT(BL_CODE_BASE, \ + BL_CODE_END - BL_CODE_BASE, \ + MT_CODE | MT_SECURE) + +#define MAP_BL_RO_DATA MAP_REGION_FLAT(BL_RO_DATA_BASE, \ + BL_RO_DATA_END - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) + +#define MAP_BL_COHERENT MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, \ + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +/******************************************************************************* + * Function that sets up the translation tables. + ******************************************************************************/ +void aml_setup_page_tables(void) +{ +#if IMAGE_BL31 + const mmap_region_t g12a_bl_mmap[] = { + MAP_BL31, + MAP_BL_CODE, + MAP_BL_RO_DATA, +#if USE_COHERENT_MEM + MAP_BL_COHERENT, +#endif + {0} + }; +#endif + + mmap_add(g12a_bl_mmap); + + mmap_add(g12a_mmap); + + init_xlat_tables(); +} + +/******************************************************************************* + * Function that returns the system counter frequency + ******************************************************************************/ +unsigned int plat_get_syscnt_freq2(void) +{ + mmio_clrbits_32(AML_SYS_CPU_CFG7, ~0xFDFFFFFF); + mmio_clrbits_32(AML_AO_TIMESTAMP_CNTL, ~0xFFFFFE00); + + return AML_OSC24M_CLK_IN_HZ; +} diff --git a/plat/amlogic/g12a/g12a_def.h b/plat/amlogic/g12a/g12a_def.h new file mode 100644 index 000000000..d032815f6 --- /dev/null +++ b/plat/amlogic/g12a/g12a_def.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef G12A_DEF_H +#define G12A_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_HDCP_RX_BASE UL(0xFFE0D000) +#define AML_HDCP_RX_SIZE UL(0x00002000) + +#define AML_HDCP_TX_BASE UL(0xFFE01000) +#define AML_HDCP_TX_SIZE UL(0x00001000) + +#define AML_NS_SHARE_MEM_BASE UL(0x05000000) +#define AML_NS_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_SEC_SHARE_MEM_BASE UL(0x05200000) +#define AML_SEC_SHARE_MEM_SIZE UL(0x00100000) + +#define AML_GIC_DEVICE_BASE UL(0xFFC00000) +#define AML_GIC_DEVICE_SIZE UL(0x00008000) + +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define BL31_BASE UL(0x05100000) +#define BL31_SIZE UL(0x00100000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xFFD00000) +#define AML_SEC_DEVICE0_SIZE UL(0x00026000) + +#define AML_SEC_DEVICE1_BASE UL(0xFF800000) +#define AML_SEC_DEVICE1_SIZE UL(0x0000A000) + +#define AML_TZRAM_BASE UL(0xFFFA0000) +#define AML_TZRAM_SIZE UL(0x00048000) + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xFFFE7800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xFFFE7A00) +#define AML_PSCI_MAILBOX_BASE UL(0xFFFE7F00) + +#define AML_SEC_DEVICE2_BASE UL(0xFF620000) +#define AML_SEC_DEVICE2_SIZE UL(0x00028000) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xFFC01000) +#define AML_GICC_BASE UL(0xFFC02000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 +#define IRQ_SEC_SGI_8 16 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xFF803000) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xFF8000B4) + +#define AML_SYS_CPU_CFG7 UL(0xFF634664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xFF80001C) +#define AML_AO_RTI_SCP_STAT UL(0xFF80023C) +#define AML_AO_RTI_SCP_READY_OFF U(0x14) +#define AML_A0_RTI_SCP_READY_MASK U(3) +#define AML_AO_RTI_SCP_IS_READY(v) \ + ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \ + AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK) + +#define AML_HIU_MAILBOX_SET_0 UL(0xFF63C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xFF63C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xFF63C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xFF63C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xFF63C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xFF63C430) + +#define AML_SHA_DMA_BASE UL(0xFF63E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x28) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* G12A_DEF_H */ diff --git a/plat/amlogic/g12a/g12a_pm.c b/plat/amlogic/g12a/g12a_pm.c new file mode 100644 index 000000000..c9fe3e977 --- /dev/null +++ b/plat/amlogic/g12a/g12a_pm.c @@ -0,0 +1,215 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <assert.h> +#include <common/debug.h> +#include <drivers/arm/gicv2.h> +#include <drivers/console.h> +#include <errno.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +#include "aml_private.h" + +#define SCPI_POWER_ON 0 +#define SCPI_POWER_RETENTION 1 +#define SCPI_POWER_OFF 3 + +#define SCPI_SYSTEM_SHUTDOWN 0 +#define SCPI_SYSTEM_REBOOT 1 + +static uintptr_t g12a_sec_entrypoint; +static volatile uint32_t g12a_cpu0_go; + +static void g12a_pm_set_reset_addr(u_register_t mpidr, uint64_t value) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); + + mmio_write_64(cpu_mailbox_addr, value); +} + +static void g12a_pm_reset(u_register_t mpidr) +{ + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8; + + mmio_write_32(cpu_mailbox_addr, 0); +} + +static void __dead2 g12a_system_reset(void) +{ + INFO("BL31: PSCI_SYSTEM_RESET\n"); + + u_register_t mpidr = read_mpidr_el1(); + uint32_t status = mmio_read_32(AML_AO_RTI_STATUS_REG3); + int ret; + + NOTICE("BL31: Reboot reason: 0x%x\n", status); + + status &= 0xFFFF0FF0; + + console_flush(); + + mmio_write_32(AML_AO_RTI_STATUS_REG3, status); + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret); + panic(); + } + + g12a_pm_reset(mpidr); + + wfi(); + + ERROR("BL31: PSCI_SYSTEM_RESET: Operation not handled\n"); + panic(); +} + +static void __dead2 g12a_system_off(void) +{ + INFO("BL31: PSCI_SYSTEM_OFF\n"); + + u_register_t mpidr = read_mpidr_el1(); + int ret; + + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + + if (ret != 0) { + ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret); + panic(); + } + + g12a_pm_set_reset_addr(mpidr, 0); + g12a_pm_reset(mpidr); + + wfi(); + + ERROR("BL31: PSCI_SYSTEM_OFF: Operation not handled\n"); + panic(); +} + +static int32_t g12a_pwr_domain_on(u_register_t mpidr) +{ + unsigned int core = plat_calc_core_pos(mpidr); + + /* CPU0 can't be turned OFF */ + if (core == AML_PRIMARY_CPU) { + VERBOSE("BL31: Releasing CPU0 from wait loop...\n"); + + g12a_cpu0_go = 1; + flush_dcache_range((uintptr_t)&g12a_cpu0_go, + sizeof(g12a_cpu0_go)); + dsb(); + isb(); + + sev(); + + return PSCI_E_SUCCESS; + } + + g12a_pm_set_reset_addr(mpidr, g12a_sec_entrypoint); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + dmbsy(); + sev(); + + return PSCI_E_SUCCESS; +} + +static void g12a_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + unsigned int core = plat_calc_core_pos(read_mpidr_el1()); + + assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == + PLAT_LOCAL_STATE_OFF); + + if (core == AML_PRIMARY_CPU) { + g12a_cpu0_go = 0; + flush_dcache_range((uintptr_t)&g12a_cpu0_go, + sizeof(g12a_cpu0_go)); + dsb(); + isb(); + } + + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +static void g12a_pwr_domain_off(const psci_power_state_t *target_state) +{ + u_register_t mpidr = read_mpidr_el1(); + unsigned int core = plat_calc_core_pos(mpidr); + + gicv2_cpuif_disable(); + + /* CPU0 can't be turned OFF */ + if (core == AML_PRIMARY_CPU) + return; + + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, SCPI_POWER_ON, + SCPI_POWER_ON); +} + +static void __dead2 g12a_pwr_domain_pwr_down_wfi(const psci_power_state_t + *target_state) +{ + u_register_t mpidr = read_mpidr_el1(); + unsigned int core = plat_calc_core_pos(mpidr); + + /* CPU0 can't be turned OFF, emulate it with a WFE loop */ + if (core == AML_PRIMARY_CPU) { + VERBOSE("BL31: CPU0 entering wait loop...\n"); + + while (g12a_cpu0_go == 0) + wfe(); + + VERBOSE("BL31: CPU0 resumed.\n"); + + /* + * Because setting CPU0's warm reset entrypoint through PSCI + * mailbox and/or mmio mapped RVBAR (0xda834650) does not seem + * to work, jump to it manually. + * In order to avoid an assert, MMU has to be disabled. + */ + disable_mmu_el3(); + ((void(*)(void))g12a_sec_entrypoint)(); + } + + dsbsy(); + g12a_pm_set_reset_addr(mpidr, 0); + g12a_pm_reset(mpidr); + + for (;;) + wfi(); +} + +/******************************************************************************* + * Platform handlers and setup function. + ******************************************************************************/ +static const plat_psci_ops_t g12a_ops = { + .pwr_domain_on = g12a_pwr_domain_on, + .pwr_domain_on_finish = g12a_pwr_domain_on_finish, + .pwr_domain_off = g12a_pwr_domain_off, + .pwr_domain_pwr_down_wfi = g12a_pwr_domain_pwr_down_wfi, + .system_off = g12a_system_off, + .system_reset = g12a_system_reset +}; + +int plat_setup_psci_ops(uintptr_t sec_entrypoint, + const plat_psci_ops_t **psci_ops) +{ + g12a_sec_entrypoint = sec_entrypoint; + *psci_ops = &g12a_ops; + g12a_cpu0_go = 0; + return 0; +} diff --git a/plat/amlogic/g12a/include/platform_def.h b/plat/amlogic/g12a/include/platform_def.h new file mode 100644 index 000000000..23d816dd4 --- /dev/null +++ b/plat/amlogic/g12a/include/platform_def.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <arch.h> +#include <lib/utils_def.h> + +#include "../g12a_def.h" + +#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" +#define PLATFORM_LINKER_ARCH aarch64 + +#define PLATFORM_STACK_SIZE UL(0x1000) + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT + +#define AML_PRIMARY_CPU U(0) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* Local power state for power-down. Valid for CPU and cluster power domains. */ +#define PLAT_LOCAL_STATE_OFF U(2) + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH U(4) +#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* Memory-related defines */ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_MMAP_REGIONS 16 +#define MAX_XLAT_TABLES 8 + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/amlogic/g12a/platform.mk b/plat/amlogic/g12a/platform.mk new file mode 100644 index 000000000..b0c91b063 --- /dev/null +++ b/plat/amlogic/g12a/platform.mk @@ -0,0 +1,91 @@ +# +# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +DOIMAGEPATH ?= tools/amlogic +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + drivers/amlogic/crypto/sha_dma.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_855873 := 1 +ERRATA_A53_819472 := 1 +ERRATA_A53_824069 := 1 +ERRATA_A53_827319 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif + +all: ${BUILD_PLAT}/bl31.img +distclean realclean clean: cleanimage + +cleanimage: + ${Q}${MAKE} -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: + ${Q}${MAKE} -C ${DOIMAGEPATH} + +${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} + ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img + diff --git a/plat/meson/gxbb/gxbb_bl31_setup.c b/plat/amlogic/gxbb/gxbb_bl31_setup.c index b867a5846..cc7a1c49b 100644 --- a/plat/meson/gxbb/gxbb_bl31_setup.c +++ b/plat/amlogic/gxbb/gxbb_bl31_setup.c @@ -1,20 +1,18 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> - -#include <platform_def.h> - #include <common/bl_common.h> #include <common/interrupt_props.h> #include <drivers/arm/gicv2.h> #include <lib/xlat_tables/xlat_mmu_helpers.h> #include <plat/common/platform.h> +#include <platform_def.h> -#include "gxbb_private.h" +#include "aml_private.h" /* * Placeholder variables for copying the arguments that have been passed to @@ -67,13 +65,13 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, struct gxbb_bl31_param *from_bl2; /* Initialize the console to provide early debug support */ - gxbb_console_init(); + aml_console_init(); /* * In debug builds, we pass a special value in 'arg1' to verify platform * parameters from BL2 to BL31. In release builds it's not used. */ - assert(arg1 == GXBB_BL31_PLAT_PARAM_VAL); + assert(arg1 == AML_BL31_PLAT_PARAM_VAL); /* Check that params passed from BL2 are not NULL. */ from_bl2 = (struct gxbb_bl31_param *) arg0; @@ -97,7 +95,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void bl31_plat_arch_setup(void) { - gxbb_setup_page_tables(); + aml_setup_page_tables(); enable_mmu_el3(0); } @@ -127,20 +125,20 @@ static const interrupt_prop_t gxbb_interrupt_props[] = { }; static const gicv2_driver_data_t gxbb_gic_data = { - .gicd_base = GXBB_GICD_BASE, - .gicc_base = GXBB_GICC_BASE, + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, .interrupt_props = gxbb_interrupt_props, .interrupt_props_num = ARRAY_SIZE(gxbb_interrupt_props), }; void bl31_platform_setup(void) { - mhu_secure_init(); + aml_mhu_secure_init(); gicv2_driver_init(&gxbb_gic_data); gicv2_distif_init(); gicv2_pcpu_distif_init(); gicv2_cpuif_enable(); - gxbb_thermal_unknown(); + aml_thermal_unknown(); } diff --git a/plat/meson/gxl/gxl_common.c b/plat/amlogic/gxbb/gxbb_common.c index e3bd6048a..260a347ab 100644 --- a/plat/meson/gxl/gxl_common.c +++ b/plat/amlogic/gxbb/gxbb_common.c @@ -1,49 +1,47 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> +#include <bl31/interrupt_mgmt.h> #include <common/bl_common.h> -#include <common/debug.h> #include <common/ep_info.h> -#include <bl31/interrupt_mgmt.h> -#include <meson_console.h> #include <lib/mmio.h> +#include <lib/xlat_tables/xlat_tables_v2.h> #include <platform_def.h> #include <stdint.h> -#include <lib/xlat_tables/xlat_tables_v2.h> /******************************************************************************* * Platform memory map regions ******************************************************************************/ -#define MAP_NSDRAM0 MAP_REGION_FLAT(GXBB_NSDRAM0_BASE, \ - GXBB_NSDRAM0_SIZE, \ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ MT_MEMORY | MT_RW | MT_NS) -#define MAP_NSDRAM1 MAP_REGION_FLAT(GXBB_NSDRAM1_BASE, \ - GXBB_NSDRAM1_SIZE, \ +#define MAP_NSDRAM1 MAP_REGION_FLAT(AML_NSDRAM1_BASE, \ + AML_NSDRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_NS) -#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(GXBB_SEC_DEVICE0_BASE, \ - GXBB_SEC_DEVICE0_SIZE, \ +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(GXBB_SEC_DEVICE1_BASE, \ - GXBB_SEC_DEVICE1_SIZE, \ +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_TZRAM MAP_REGION_FLAT(GXBB_TZRAM_BASE, \ - GXBB_TZRAM_SIZE, \ +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(GXBB_SEC_DEVICE2_BASE, \ - GXBB_SEC_DEVICE2_SIZE, \ +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE3 MAP_REGION_FLAT(GXBB_SEC_DEVICE3_BASE, \ - GXBB_SEC_DEVICE3_SIZE, \ +#define MAP_SEC_DEVICE3 MAP_REGION_FLAT(AML_SEC_DEVICE3_BASE, \ + AML_SEC_DEVICE3_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) static const mmap_region_t gxbb_mmap[] = { @@ -79,7 +77,7 @@ static const mmap_region_t gxbb_mmap[] = { /******************************************************************************* * Function that sets up the translation tables. ******************************************************************************/ -void gxbb_setup_page_tables(void) +void aml_setup_page_tables(void) { #if IMAGE_BL31 const mmap_region_t gxbb_bl_mmap[] = { @@ -101,43 +99,19 @@ void gxbb_setup_page_tables(void) } /******************************************************************************* - * Function that sets up the console - ******************************************************************************/ -static console_meson_t gxbb_console; - -void gxbb_console_init(void) -{ - int rc = console_meson_register(GXBB_UART0_AO_BASE, - GXBB_UART0_AO_CLK_IN_HZ, - GXBB_UART_BAUDRATE, - &gxbb_console); - if (rc == 0) { - /* - * The crash console doesn't use the multi console API, it uses - * the core console functions directly. It is safe to call panic - * and let it print debug information. - */ - panic(); - } - - console_set_scope(&gxbb_console.console, - CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); -} - -/******************************************************************************* * Function that returns the system counter frequency ******************************************************************************/ unsigned int plat_get_syscnt_freq2(void) { uint32_t val; - val = mmio_read_32(GXBB_SYS_CPU_CFG7); + val = mmio_read_32(AML_SYS_CPU_CFG7); val &= 0xFDFFFFFF; - mmio_write_32(GXBB_SYS_CPU_CFG7, val); + mmio_write_32(AML_SYS_CPU_CFG7, val); - val = mmio_read_32(GXBB_AO_TIMESTAMP_CNTL); + val = mmio_read_32(AML_AO_TIMESTAMP_CNTL); val &= 0xFFFFFE00; - mmio_write_32(GXBB_AO_TIMESTAMP_CNTL, val); + mmio_write_32(AML_AO_TIMESTAMP_CNTL, val); - return GXBB_OSC24M_CLK_IN_HZ; + return AML_OSC24M_CLK_IN_HZ; } diff --git a/plat/amlogic/gxbb/gxbb_def.h b/plat/amlogic/gxbb/gxbb_def.h new file mode 100644 index 000000000..fa5e4fa96 --- /dev/null +++ b/plat/amlogic/gxbb/gxbb_def.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GXBB_DEF_H +#define GXBB_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define AML_NSDRAM1_BASE UL(0x10000000) +#define AML_NSDRAM1_SIZE UL(0x00100000) + +#define BL31_BASE UL(0x10100000) +#define BL31_SIZE UL(0x000C0000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x100FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x100FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xC0000000) +#define AML_SEC_DEVICE0_SIZE UL(0x09000000) + +#define AML_SEC_DEVICE1_BASE UL(0xD0040000) +#define AML_SEC_DEVICE1_SIZE UL(0x00008000) + +#define AML_TZRAM_BASE UL(0xD9000000) +#define AML_TZRAM_SIZE UL(0x00014000) +/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */ + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xD9013800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xD9013A00) +#define AML_PSCI_MAILBOX_BASE UL(0xD9013F00) + +#define AML_TZROM_BASE UL(0xD9040000) +#define AML_TZROM_SIZE UL(0x00010000) + +#define AML_SEC_DEVICE2_BASE UL(0xDA000000) +#define AML_SEC_DEVICE2_SIZE UL(0x00200000) + +#define AML_SEC_DEVICE3_BASE UL(0xDA800000) +#define AML_SEC_DEVICE3_SIZE UL(0x00200000) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xC4301000) +#define AML_GICC_BASE UL(0xC4302000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xC81004C0) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xC81000B4) + +#define AML_SYS_CPU_CFG7 UL(0xC8834664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xDA10001C) + +#define AML_HIU_MAILBOX_SET_0 UL(0xDA83C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xDA83C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xDA83C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xDA83C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xDA83C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xDA83C430) + +#define AML_SHA_DMA_BASE UL(0xC883E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x18) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* GXBB_DEF_H */ diff --git a/plat/meson/gxbb/gxbb_pm.c b/plat/amlogic/gxbb/gxbb_pm.c index 59b9436fe..48bff7ba5 100644 --- a/plat/meson/gxbb/gxbb_pm.c +++ b/plat/amlogic/gxbb/gxbb_pm.c @@ -1,23 +1,21 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <assert.h> -#include <errno.h> - -#include <platform_def.h> - #include <arch_helpers.h> +#include <assert.h> #include <common/debug.h> #include <drivers/arm/gicv2.h> #include <drivers/console.h> +#include <errno.h> #include <lib/mmio.h> #include <lib/psci/psci.h> #include <plat/common/platform.h> +#include <platform_def.h> -#include "gxbb_private.h" +#include "aml_private.h" #define SCPI_POWER_ON 0 #define SCPI_POWER_RETENTION 1 @@ -31,8 +29,8 @@ static volatile uint32_t gxbb_cpu0_go; static void gxbb_program_mailbox(u_register_t mpidr, uint64_t value) { - unsigned int core = plat_gxbb_calc_core_pos(mpidr); - uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4); + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); mmio_write_64(cpu_mailbox_addr, value); flush_dcache_range(cpu_mailbox_addr, sizeof(uint64_t)); @@ -42,7 +40,7 @@ static void __dead2 gxbb_system_reset(void) { INFO("BL31: PSCI_SYSTEM_RESET\n"); - uint32_t status = mmio_read_32(GXBB_AO_RTI_STATUS_REG3); + uint32_t status = mmio_read_32(AML_AO_RTI_STATUS_REG3); NOTICE("BL31: Reboot reason: 0x%x\n", status); @@ -50,9 +48,9 @@ static void __dead2 gxbb_system_reset(void) console_flush(); - mmio_write_32(GXBB_AO_RTI_STATUS_REG3, status); + mmio_write_32(AML_AO_RTI_STATUS_REG3, status); - int ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + int ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); if (ret != 0) { ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %u\n", ret); @@ -69,7 +67,7 @@ static void __dead2 gxbb_system_off(void) { INFO("BL31: PSCI_SYSTEM_OFF\n"); - unsigned int ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + unsigned int ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); if (ret != 0) { ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %u\n", ret); @@ -86,10 +84,10 @@ static void __dead2 gxbb_system_off(void) static int32_t gxbb_pwr_domain_on(u_register_t mpidr) { - unsigned int core = plat_gxbb_calc_core_pos(mpidr); + unsigned int core = plat_calc_core_pos(mpidr); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) { + if (core == AML_PRIMARY_CPU) { VERBOSE("BL31: Releasing CPU0 from wait loop...\n"); gxbb_cpu0_go = 1; @@ -103,8 +101,8 @@ static int32_t gxbb_pwr_domain_on(u_register_t mpidr) } gxbb_program_mailbox(mpidr, gxbb_sec_entrypoint); - scpi_set_css_power_state(mpidr, - SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); dmbsy(); sev(); @@ -113,12 +111,12 @@ static int32_t gxbb_pwr_domain_on(u_register_t mpidr) static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state) { - unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1()); + unsigned int core = plat_calc_core_pos(read_mpidr_el1()); assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == PLAT_LOCAL_STATE_OFF); - if (core == GXBB_PRIMARY_CPU) { + if (core == AML_PRIMARY_CPU) { gxbb_cpu0_go = 0; flush_dcache_range((uintptr_t)&gxbb_cpu0_go, sizeof(gxbb_cpu0_go)); dsb(); @@ -132,8 +130,8 @@ static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state) static void gxbb_pwr_domain_off(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr_el1(); - unsigned int core = plat_gxbb_calc_core_pos(mpidr); - uintptr_t addr = GXBB_PSCI_MAILBOX_BASE + 8 + (core << 4); + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t addr = AML_PSCI_MAILBOX_BASE + 8 + (core << 4); mmio_write_32(addr, 0xFFFFFFFF); flush_dcache_range(addr, sizeof(uint32_t)); @@ -141,20 +139,20 @@ static void gxbb_pwr_domain_off(const psci_power_state_t *target_state) gicv2_cpuif_disable(); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) + if (core == AML_PRIMARY_CPU) return; - scpi_set_css_power_state(mpidr, - SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON); } static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) { - unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1()); + unsigned int core = plat_calc_core_pos(read_mpidr_el1()); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) { + if (core == AML_PRIMARY_CPU) { VERBOSE("BL31: CPU0 entering wait loop...\n"); while (gxbb_cpu0_go == 0) diff --git a/plat/meson/gxbb/include/platform_def.h b/plat/amlogic/gxbb/include/platform_def.h index da4aedde8..a5cbe78e1 100644 --- a/plat/meson/gxbb/include/platform_def.h +++ b/plat/amlogic/gxbb/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,7 @@ #define PLATFORM_LINKER_ARCH aarch64 /* Special value used to verify platform parameters from BL2 to BL31 */ -#define GXBB_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978) +#define AML_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978) #define PLATFORM_STACK_SIZE UL(0x1000) @@ -25,7 +25,7 @@ #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT -#define GXBB_PRIMARY_CPU U(0) +#define AML_PRIMARY_CPU U(0) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ diff --git a/plat/amlogic/gxbb/platform.mk b/plat/amlogic/gxbb/platform.mk new file mode 100644 index 000000000..62384d2aa --- /dev/null +++ b/plat/amlogic/gxbb/platform.mk @@ -0,0 +1,75 @@ +# +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_826319 := 1 +ERRATA_A53_835769 := 1 +ERRATA_A53_836870 := 1 +ERRATA_A53_843419 := 1 +ERRATA_A53_855873 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif diff --git a/plat/meson/gxl/gxl_bl31_setup.c b/plat/amlogic/gxl/gxl_bl31_setup.c index b1da7942b..f581dd134 100644 --- a/plat/meson/gxl/gxl_bl31_setup.c +++ b/plat/amlogic/gxl/gxl_bl31_setup.c @@ -6,14 +6,14 @@ #include <assert.h> #include <common/bl_common.h> -#include <drivers/arm/gicv2.h> #include <common/interrupt_props.h> -#include <plat/common/platform.h> -#include <platform_def.h> +#include <drivers/arm/gicv2.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <plat/common/platform.h> +#include <platform_def.h> -#include "gxl_private.h" +#include "aml_private.h" /* * Placeholder variables for copying the arguments that have been passed to @@ -69,7 +69,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, struct gxl_bl31_param *from_bl2; /* Initialize the console to provide early debug support */ - gxbb_console_init(); + aml_console_init(); /* Check that params passed from BL2 are not NULL. */ from_bl2 = (struct gxl_bl31_param *) arg0; @@ -96,22 +96,22 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void bl31_plat_arch_setup(void) { - gxbb_setup_page_tables(); + aml_setup_page_tables(); enable_mmu_el3(0); } static inline bool gxl_scp_ready(void) { - return GXBB_AO_RTI_SCP_IS_READY(mmio_read_32(GXBB_AO_RTI_SCP_STAT)); + return AML_AO_RTI_SCP_IS_READY(mmio_read_32(AML_AO_RTI_SCP_STAT)); } static inline void gxl_scp_boot(void) { - scpi_upload_scp_fw(bl30_image_info.image_base, - bl30_image_info.image_size, 0); - scpi_upload_scp_fw(bl301_image_info.image_base, - bl301_image_info.image_size, 1); + aml_scpi_upload_scp_fw(bl30_image_info.image_base, + bl30_image_info.image_size, 0); + aml_scpi_upload_scp_fw(bl301_image_info.image_base, + bl301_image_info.image_size, 1); while (!gxl_scp_ready()) ; } @@ -119,7 +119,7 @@ static inline void gxl_scp_boot(void) /******************************************************************************* * GICv2 driver setup information ******************************************************************************/ -static const interrupt_prop_t gxbb_interrupt_props[] = { +static const interrupt_prop_t gxl_interrupt_props[] = { INTR_PROP_DESC(IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), INTR_PROP_DESC(IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, @@ -140,23 +140,23 @@ static const interrupt_prop_t gxbb_interrupt_props[] = { GICV2_INTR_GROUP0, GIC_INTR_CFG_LEVEL), }; -static const gicv2_driver_data_t gxbb_gic_data = { - .gicd_base = GXBB_GICD_BASE, - .gicc_base = GXBB_GICC_BASE, - .interrupt_props = gxbb_interrupt_props, - .interrupt_props_num = ARRAY_SIZE(gxbb_interrupt_props), +static const gicv2_driver_data_t gxl_gic_data = { + .gicd_base = AML_GICD_BASE, + .gicc_base = AML_GICC_BASE, + .interrupt_props = gxl_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(gxl_interrupt_props), }; void bl31_platform_setup(void) { - mhu_secure_init(); + aml_mhu_secure_init(); - gicv2_driver_init(&gxbb_gic_data); + gicv2_driver_init(&gxl_gic_data); gicv2_distif_init(); gicv2_pcpu_distif_init(); gicv2_cpuif_enable(); gxl_scp_boot(); - gxbb_thermal_unknown(); + aml_thermal_unknown(); } diff --git a/plat/meson/gxbb/gxbb_common.c b/plat/amlogic/gxl/gxl_common.c index 0ca15e860..e1d7bfb92 100644 --- a/plat/meson/gxbb/gxbb_common.c +++ b/plat/amlogic/gxl/gxl_common.c @@ -1,54 +1,50 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> -#include <stdint.h> - -#include <platform_def.h> - #include <bl31/interrupt_mgmt.h> #include <common/bl_common.h> -#include <common/debug.h> #include <common/ep_info.h> -#include <drivers/meson/meson_console.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables_v2.h> +#include <platform_def.h> +#include <stdint.h> /******************************************************************************* * Platform memory map regions ******************************************************************************/ -#define MAP_NSDRAM0 MAP_REGION_FLAT(GXBB_NSDRAM0_BASE, \ - GXBB_NSDRAM0_SIZE, \ +#define MAP_NSDRAM0 MAP_REGION_FLAT(AML_NSDRAM0_BASE, \ + AML_NSDRAM0_SIZE, \ MT_MEMORY | MT_RW | MT_NS) -#define MAP_NSDRAM1 MAP_REGION_FLAT(GXBB_NSDRAM1_BASE, \ - GXBB_NSDRAM1_SIZE, \ +#define MAP_NSDRAM1 MAP_REGION_FLAT(AML_NSDRAM1_BASE, \ + AML_NSDRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_NS) -#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(GXBB_SEC_DEVICE0_BASE, \ - GXBB_SEC_DEVICE0_SIZE, \ +#define MAP_SEC_DEVICE0 MAP_REGION_FLAT(AML_SEC_DEVICE0_BASE, \ + AML_SEC_DEVICE0_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(GXBB_SEC_DEVICE1_BASE, \ - GXBB_SEC_DEVICE1_SIZE, \ +#define MAP_SEC_DEVICE1 MAP_REGION_FLAT(AML_SEC_DEVICE1_BASE, \ + AML_SEC_DEVICE1_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_TZRAM MAP_REGION_FLAT(GXBB_TZRAM_BASE, \ - GXBB_TZRAM_SIZE, \ +#define MAP_TZRAM MAP_REGION_FLAT(AML_TZRAM_BASE, \ + AML_TZRAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(GXBB_SEC_DEVICE2_BASE, \ - GXBB_SEC_DEVICE2_SIZE, \ +#define MAP_SEC_DEVICE2 MAP_REGION_FLAT(AML_SEC_DEVICE2_BASE, \ + AML_SEC_DEVICE2_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -#define MAP_SEC_DEVICE3 MAP_REGION_FLAT(GXBB_SEC_DEVICE3_BASE, \ - GXBB_SEC_DEVICE3_SIZE, \ +#define MAP_SEC_DEVICE3 MAP_REGION_FLAT(AML_SEC_DEVICE3_BASE, \ + AML_SEC_DEVICE3_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -static const mmap_region_t gxbb_mmap[] = { +static const mmap_region_t gxl_mmap[] = { MAP_NSDRAM0, MAP_NSDRAM1, MAP_SEC_DEVICE0, @@ -81,10 +77,10 @@ static const mmap_region_t gxbb_mmap[] = { /******************************************************************************* * Function that sets up the translation tables. ******************************************************************************/ -void gxbb_setup_page_tables(void) +void aml_setup_page_tables(void) { #if IMAGE_BL31 - const mmap_region_t gxbb_bl_mmap[] = { + const mmap_region_t gxl_bl_mmap[] = { MAP_BL31, MAP_BL_CODE, MAP_BL_RO_DATA, @@ -95,51 +91,27 @@ void gxbb_setup_page_tables(void) }; #endif - mmap_add(gxbb_bl_mmap); + mmap_add(gxl_bl_mmap); - mmap_add(gxbb_mmap); + mmap_add(gxl_mmap); init_xlat_tables(); } /******************************************************************************* - * Function that sets up the console - ******************************************************************************/ -static console_meson_t gxbb_console; - -void gxbb_console_init(void) -{ - int rc = console_meson_register(GXBB_UART0_AO_BASE, - GXBB_UART0_AO_CLK_IN_HZ, - GXBB_UART_BAUDRATE, - &gxbb_console); - if (rc == 0) { - /* - * The crash console doesn't use the multi console API, it uses - * the core console functions directly. It is safe to call panic - * and let it print debug information. - */ - panic(); - } - - console_set_scope(&gxbb_console.console, - CONSOLE_FLAG_BOOT | CONSOLE_FLAG_RUNTIME); -} - -/******************************************************************************* * Function that returns the system counter frequency ******************************************************************************/ unsigned int plat_get_syscnt_freq2(void) { uint32_t val; - val = mmio_read_32(GXBB_SYS_CPU_CFG7); + val = mmio_read_32(AML_SYS_CPU_CFG7); val &= 0xFDFFFFFF; - mmio_write_32(GXBB_SYS_CPU_CFG7, val); + mmio_write_32(AML_SYS_CPU_CFG7, val); - val = mmio_read_32(GXBB_AO_TIMESTAMP_CNTL); + val = mmio_read_32(AML_AO_TIMESTAMP_CNTL); val &= 0xFFFFFE00; - mmio_write_32(GXBB_AO_TIMESTAMP_CNTL, val); + mmio_write_32(AML_AO_TIMESTAMP_CNTL, val); - return GXBB_OSC24M_CLK_IN_HZ; + return AML_OSC24M_CLK_IN_HZ; } diff --git a/plat/amlogic/gxl/gxl_def.h b/plat/amlogic/gxl/gxl_def.h new file mode 100644 index 000000000..f30eb287d --- /dev/null +++ b/plat/amlogic/gxl/gxl_def.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef GXL_DEF_H +#define GXL_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * System oscillator + ******************************************************************************/ +#define AML_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ + +/******************************************************************************* + * Memory regions + ******************************************************************************/ +#define AML_NSDRAM0_BASE UL(0x01000000) +#define AML_NSDRAM0_SIZE UL(0x0F000000) + +#define AML_NSDRAM1_BASE UL(0x10000000) +#define AML_NSDRAM1_SIZE UL(0x00100000) + +#define BL31_BASE UL(0x05100000) +#define BL31_SIZE UL(0x000C0000) +#define BL31_LIMIT (BL31_BASE + BL31_SIZE) + +/* Shared memory used for SMC services */ +#define AML_SHARE_MEM_INPUT_BASE UL(0x050FE000) +#define AML_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) + +#define AML_SEC_DEVICE0_BASE UL(0xC0000000) +#define AML_SEC_DEVICE0_SIZE UL(0x09000000) + +#define AML_SEC_DEVICE1_BASE UL(0xD0040000) +#define AML_SEC_DEVICE1_SIZE UL(0x00008000) + +#define AML_TZRAM_BASE UL(0xD9000000) +#define AML_TZRAM_SIZE UL(0x00014000) +/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */ + +/* Mailboxes */ +#define AML_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xD9013800) +#define AML_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xD9013A00) +#define AML_PSCI_MAILBOX_BASE UL(0xD9013F00) + +// * [ 1K] 0xD901_3800 - 0xD901_3BFF Secure Mailbox (3) +// * [ 1K] 0xD901_3400 - 0xD901_37FF High Mailbox (2) * +// * [ 1K] 0xD901_3000 - 0xD901_33FF High Mailbox (1) * + +#define AML_TZROM_BASE UL(0xD9040000) +#define AML_TZROM_SIZE UL(0x00010000) + +#define AML_SEC_DEVICE2_BASE UL(0xDA000000) +#define AML_SEC_DEVICE2_SIZE UL(0x00200000) + +#define AML_SEC_DEVICE3_BASE UL(0xDA800000) +#define AML_SEC_DEVICE3_SIZE UL(0x00200000) + +/******************************************************************************* + * GIC-400 and interrupt handling related constants + ******************************************************************************/ +#define AML_GICD_BASE UL(0xC4301000) +#define AML_GICC_BASE UL(0xC4302000) + +#define IRQ_SEC_PHY_TIMER 29 + +#define IRQ_SEC_SGI_0 8 +#define IRQ_SEC_SGI_1 9 +#define IRQ_SEC_SGI_2 10 +#define IRQ_SEC_SGI_3 11 +#define IRQ_SEC_SGI_4 12 +#define IRQ_SEC_SGI_5 13 +#define IRQ_SEC_SGI_6 14 +#define IRQ_SEC_SGI_7 15 + +/******************************************************************************* + * UART definitions + ******************************************************************************/ +#define AML_UART0_AO_BASE UL(0xC81004C0) +#define AML_UART0_AO_CLK_IN_HZ AML_OSC24M_CLK_IN_HZ +#define AML_UART_BAUDRATE U(115200) + +/******************************************************************************* + * Memory-mapped I/O Registers + ******************************************************************************/ +#define AML_AO_TIMESTAMP_CNTL UL(0xC81000B4) + +#define AML_SYS_CPU_CFG7 UL(0xC8834664) + +#define AML_AO_RTI_STATUS_REG3 UL(0xDA10001C) +#define AML_AO_RTI_SCP_STAT UL(0xDA10023C) +#define AML_AO_RTI_SCP_READY_OFF U(0x14) +#define AML_A0_RTI_SCP_READY_MASK U(3) +#define AML_AO_RTI_SCP_IS_READY(v) \ + ((((v) >> AML_AO_RTI_SCP_READY_OFF) & \ + AML_A0_RTI_SCP_READY_MASK) == AML_A0_RTI_SCP_READY_MASK) + +#define AML_HIU_MAILBOX_SET_0 UL(0xDA83C404) +#define AML_HIU_MAILBOX_STAT_0 UL(0xDA83C408) +#define AML_HIU_MAILBOX_CLR_0 UL(0xDA83C40C) +#define AML_HIU_MAILBOX_SET_3 UL(0xDA83C428) +#define AML_HIU_MAILBOX_STAT_3 UL(0xDA83C42C) +#define AML_HIU_MAILBOX_CLR_3 UL(0xDA83C430) + +#define AML_SHA_DMA_BASE UL(0xC883E000) +#define AML_SHA_DMA_DESC (AML_SHA_DMA_BASE + 0x08) +#define AML_SHA_DMA_STATUS (AML_SHA_DMA_BASE + 0x18) + +/******************************************************************************* + * System Monitor Call IDs and arguments + ******************************************************************************/ +#define AML_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) +#define AML_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) + +#define AML_SM_EFUSE_READ U(0x82000030) +#define AML_SM_EFUSE_USER_MAX U(0x82000033) + +#define AML_SM_JTAG_ON U(0x82000040) +#define AML_SM_JTAG_OFF U(0x82000041) +#define AML_SM_GET_CHIP_ID U(0x82000044) + +#define AML_JTAG_STATE_ON U(0) +#define AML_JTAG_STATE_OFF U(1) + +#define AML_JTAG_M3_AO U(0) +#define AML_JTAG_M3_EE U(1) +#define AML_JTAG_A53_AO U(2) +#define AML_JTAG_A53_EE U(3) + +#endif /* GXL_DEF_H */ diff --git a/plat/meson/gxl/gxl_pm.c b/plat/amlogic/gxl/gxl_pm.c index 4a5d26e90..433140b77 100644 --- a/plat/meson/gxl/gxl_pm.c +++ b/plat/amlogic/gxl/gxl_pm.c @@ -6,16 +6,16 @@ #include <arch_helpers.h> #include <assert.h> -#include <drivers/console.h> #include <common/debug.h> -#include <errno.h> #include <drivers/arm/gicv2.h> +#include <drivers/console.h> +#include <errno.h> #include <lib/mmio.h> +#include <lib/psci/psci.h> #include <plat/common/platform.h> #include <platform_def.h> -#include <lib/psci/psci.h> -#include "gxl_private.h" +#include "aml_private.h" #define SCPI_POWER_ON 0 #define SCPI_POWER_RETENTION 1 @@ -24,31 +24,31 @@ #define SCPI_SYSTEM_SHUTDOWN 0 #define SCPI_SYSTEM_REBOOT 1 -static uintptr_t gxbb_sec_entrypoint; -static volatile uint32_t gxbb_cpu0_go; +static uintptr_t gxl_sec_entrypoint; +static volatile uint32_t gxl_cpu0_go; static void gxl_pm_set_reset_addr(u_register_t mpidr, uint64_t value) { - unsigned int core = plat_gxbb_calc_core_pos(mpidr); - uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4); + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4); mmio_write_64(cpu_mailbox_addr, value); } static void gxl_pm_reset(u_register_t mpidr) { - unsigned int core = plat_gxbb_calc_core_pos(mpidr); - uintptr_t cpu_mailbox_addr = GXBB_PSCI_MAILBOX_BASE + (core << 4) + 8; + unsigned int core = plat_calc_core_pos(mpidr); + uintptr_t cpu_mailbox_addr = AML_PSCI_MAILBOX_BASE + (core << 4) + 8; mmio_write_32(cpu_mailbox_addr, 0); } -static void __dead2 gxbb_system_reset(void) +static void __dead2 gxl_system_reset(void) { INFO("BL31: PSCI_SYSTEM_RESET\n"); u_register_t mpidr = read_mpidr_el1(); - uint32_t status = mmio_read_32(GXBB_AO_RTI_STATUS_REG3); + uint32_t status = mmio_read_32(AML_AO_RTI_STATUS_REG3); int ret; NOTICE("BL31: Reboot reason: 0x%x\n", status); @@ -57,9 +57,9 @@ static void __dead2 gxbb_system_reset(void) console_flush(); - mmio_write_32(GXBB_AO_RTI_STATUS_REG3, status); + mmio_write_32(AML_AO_RTI_STATUS_REG3, status); - ret = scpi_sys_power_state(SCPI_SYSTEM_REBOOT); + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_REBOOT); if (ret != 0) { ERROR("BL31: PSCI_SYSTEM_RESET: SCP error: %i\n", ret); @@ -74,14 +74,14 @@ static void __dead2 gxbb_system_reset(void) panic(); } -static void __dead2 gxbb_system_off(void) +static void __dead2 gxl_system_off(void) { INFO("BL31: PSCI_SYSTEM_OFF\n"); u_register_t mpidr = read_mpidr_el1(); int ret; - ret = scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); + ret = aml_scpi_sys_power_state(SCPI_SYSTEM_SHUTDOWN); if (ret != 0) { ERROR("BL31: PSCI_SYSTEM_OFF: SCP error %i\n", ret); @@ -97,17 +97,17 @@ static void __dead2 gxbb_system_off(void) panic(); } -static int32_t gxbb_pwr_domain_on(u_register_t mpidr) +static int32_t gxl_pwr_domain_on(u_register_t mpidr) { - unsigned int core = plat_gxbb_calc_core_pos(mpidr); + unsigned int core = plat_calc_core_pos(mpidr); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) { + if (core == AML_PRIMARY_CPU) { VERBOSE("BL31: Releasing CPU0 from wait loop...\n"); - gxbb_cpu0_go = 1; - flush_dcache_range((uintptr_t)&gxbb_cpu0_go, - sizeof(gxbb_cpu0_go)); + gxl_cpu0_go = 1; + flush_dcache_range((uintptr_t)&gxl_cpu0_go, + sizeof(gxl_cpu0_go)); dsb(); isb(); @@ -116,26 +116,26 @@ static int32_t gxbb_pwr_domain_on(u_register_t mpidr) return PSCI_E_SUCCESS; } - gxl_pm_set_reset_addr(mpidr, gxbb_sec_entrypoint); - scpi_set_css_power_state(mpidr, - SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); + gxl_pm_set_reset_addr(mpidr, gxl_sec_entrypoint); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_ON, SCPI_POWER_ON, SCPI_POWER_ON); dmbsy(); sev(); return PSCI_E_SUCCESS; } -static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state) +static void gxl_pwr_domain_on_finish(const psci_power_state_t *target_state) { - unsigned int core = plat_gxbb_calc_core_pos(read_mpidr_el1()); + unsigned int core = plat_calc_core_pos(read_mpidr_el1()); assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == PLAT_LOCAL_STATE_OFF); - if (core == GXBB_PRIMARY_CPU) { - gxbb_cpu0_go = 0; - flush_dcache_range((uintptr_t)&gxbb_cpu0_go, - sizeof(gxbb_cpu0_go)); + if (core == AML_PRIMARY_CPU) { + gxl_cpu0_go = 0; + flush_dcache_range((uintptr_t)&gxl_cpu0_go, + sizeof(gxl_cpu0_go)); dsb(); isb(); } @@ -144,32 +144,32 @@ static void gxbb_pwr_domain_on_finish(const psci_power_state_t *target_state) gicv2_cpuif_enable(); } -static void gxbb_pwr_domain_off(const psci_power_state_t *target_state) +static void gxl_pwr_domain_off(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr_el1(); - unsigned int core = plat_gxbb_calc_core_pos(mpidr); + unsigned int core = plat_calc_core_pos(mpidr); gicv2_cpuif_disable(); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) + if (core == AML_PRIMARY_CPU) return; - scpi_set_css_power_state(mpidr, - SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON); + aml_scpi_set_css_power_state(mpidr, + SCPI_POWER_OFF, SCPI_POWER_ON, SCPI_POWER_ON); } -static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t +static void __dead2 gxl_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) { u_register_t mpidr = read_mpidr_el1(); - unsigned int core = plat_gxbb_calc_core_pos(mpidr); + unsigned int core = plat_calc_core_pos(mpidr); /* CPU0 can't be turned OFF, emulate it with a WFE loop */ - if (core == GXBB_PRIMARY_CPU) { + if (core == AML_PRIMARY_CPU) { VERBOSE("BL31: CPU0 entering wait loop...\n"); - while (gxbb_cpu0_go == 0) + while (gxl_cpu0_go == 0) wfe(); VERBOSE("BL31: CPU0 resumed.\n"); @@ -181,7 +181,7 @@ static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t * In order to avoid an assert, mmu has to be disabled. */ disable_mmu_el3(); - ((void(*)(void))gxbb_sec_entrypoint)(); + ((void(*)(void))gxl_sec_entrypoint)(); } dsbsy(); @@ -195,20 +195,20 @@ static void __dead2 gxbb_pwr_domain_pwr_down_wfi(const psci_power_state_t /******************************************************************************* * Platform handlers and setup function. ******************************************************************************/ -static const plat_psci_ops_t gxbb_ops = { - .pwr_domain_on = gxbb_pwr_domain_on, - .pwr_domain_on_finish = gxbb_pwr_domain_on_finish, - .pwr_domain_off = gxbb_pwr_domain_off, - .pwr_domain_pwr_down_wfi = gxbb_pwr_domain_pwr_down_wfi, - .system_off = gxbb_system_off, - .system_reset = gxbb_system_reset, +static const plat_psci_ops_t gxl_ops = { + .pwr_domain_on = gxl_pwr_domain_on, + .pwr_domain_on_finish = gxl_pwr_domain_on_finish, + .pwr_domain_off = gxl_pwr_domain_off, + .pwr_domain_pwr_down_wfi = gxl_pwr_domain_pwr_down_wfi, + .system_off = gxl_system_off, + .system_reset = gxl_system_reset, }; int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { - gxbb_sec_entrypoint = sec_entrypoint; - *psci_ops = &gxbb_ops; - gxbb_cpu0_go = 0; + gxl_sec_entrypoint = sec_entrypoint; + *psci_ops = &gxl_ops; + gxl_cpu0_go = 0; return 0; } diff --git a/plat/meson/gxl/include/platform_def.h b/plat/amlogic/gxl/include/platform_def.h index b32ec56da..ec64d6853 100644 --- a/plat/meson/gxl/include/platform_def.h +++ b/plat/amlogic/gxl/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,9 +15,6 @@ #define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" #define PLATFORM_LINKER_ARCH aarch64 -/* Special value used to verify platform parameters from BL2 to BL31 */ -#define GXBB_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978) - #define PLATFORM_STACK_SIZE UL(0x1000) #define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) @@ -25,7 +22,7 @@ #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT -#define GXBB_PRIMARY_CPU U(0) +#define AML_PRIMARY_CPU U(0) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ diff --git a/plat/amlogic/gxl/platform.mk b/plat/amlogic/gxl/platform.mk new file mode 100644 index 000000000..641d177bc --- /dev/null +++ b/plat/amlogic/gxl/platform.mk @@ -0,0 +1,91 @@ +# +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/xlat_tables_v2/xlat_tables.mk + +AML_PLAT := plat/amlogic +AML_PLAT_SOC := ${AML_PLAT}/${PLAT} +AML_PLAT_COMMON := ${AML_PLAT}/common + +DOIMAGEPATH ?= tools/amlogic +DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage + +PLAT_INCLUDES := -Iinclude/drivers/amlogic/ \ + -I${AML_PLAT_SOC}/include \ + -I${AML_PLAT_COMMON}/include + +GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c + +BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ + plat/common/plat_psci_common.c \ + drivers/amlogic/console/aarch64/meson_console.S \ + ${AML_PLAT_SOC}/${PLAT}_bl31_setup.c \ + ${AML_PLAT_SOC}/${PLAT}_pm.c \ + ${AML_PLAT_SOC}/${PLAT}_common.c \ + ${AML_PLAT_COMMON}/aarch64/aml_helpers.S \ + ${AML_PLAT_COMMON}/aml_efuse.c \ + ${AML_PLAT_COMMON}/aml_mhu.c \ + ${AML_PLAT_COMMON}/aml_scpi.c \ + ${AML_PLAT_COMMON}/aml_sip_svc.c \ + ${AML_PLAT_COMMON}/aml_thermal.c \ + ${AML_PLAT_COMMON}/aml_topology.c \ + ${AML_PLAT_COMMON}/aml_console.c \ + drivers/amlogic/crypto/sha_dma.c \ + ${XLAT_TABLES_LIB_SRCS} \ + ${GIC_SOURCES} + +# Tune compiler for Cortex-A53 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a53 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a53 +endif + +# Build config flags +# ------------------ + +# Enable all errata workarounds for Cortex-A53 +ERRATA_A53_855873 := 1 +ERRATA_A53_819472 := 1 +ERRATA_A53_824069 := 1 +ERRATA_A53_827319 := 1 + +WORKAROUND_CVE_2017_5715 := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +# Verify build config +# ------------------- + +ifneq (${RESET_TO_BL31}, 0) + $(error Error: ${PLAT} needs RESET_TO_BL31=0) +endif + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on ${PLAT}) +endif + +all: ${BUILD_PLAT}/bl31.img +distclean realclean clean: cleanimage + +cleanimage: + ${Q}${MAKE} -C ${DOIMAGEPATH} clean + +${DOIMAGETOOL}: + ${Q}${MAKE} -C ${DOIMAGEPATH} + +${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} + ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img + diff --git a/plat/arm/board/a5ds/a5ds_common.c b/plat/arm/board/a5ds/a5ds_common.c index e462fa16e..a4a0cff92 100644 --- a/plat/arm/board/a5ds/a5ds_common.c +++ b/plat/arm/board/a5ds/a5ds_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -23,18 +23,18 @@ #ifdef IMAGE_BL1 const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, - MAP_FLASH1_RW, MAP_PERIPHBASE, MAP_A5_PERIPHERALS, + MAP_BOOT_RW, {0} }; #endif #ifdef IMAGE_BL2 const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, - MAP_FLASH1_RW, MAP_PERIPHBASE, MAP_A5_PERIPHERALS, + MAP_BOOT_RW, ARM_MAP_NS_DRAM1, {0} }; diff --git a/plat/arm/board/a5ds/a5ds_pm.c b/plat/arm/board/a5ds/a5ds_pm.c index 5fd443b12..7774002e6 100644 --- a/plat/arm/board/a5ds/a5ds_pm.c +++ b/plat/arm/board/a5ds/a5ds_pm.c @@ -3,9 +3,53 @@ * * SPDX-License-Identifier: BSD-3-Clause */ - +#include <assert.h> +#include <drivers/arm/gicv2.h> #include <lib/psci/psci.h> #include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned on. The + * mpidr determines the CPU to be turned on. + ******************************************************************************/ +static int a5ds_pwr_domain_on(u_register_t mpidr) +{ + unsigned int pos = plat_core_pos_by_mpidr(mpidr); + uint64_t *hold_base = (uint64_t *)A5DS_HOLD_BASE; + + hold_base[pos] = A5DS_HOLD_STATE_GO; + dsbish(); + sev(); + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Platform handler called when a power domain has just been powered on after + * being turned off earlier. The target_state encodes the low power state that + * each level has woken up from. + ******************************************************************************/ +void a5ds_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + /* TODO: This setup is needed only after a cold boot*/ + gicv2_pcpu_distif_init(); + + /* Enable the gic cpu interface */ + gicv2_cpuif_enable(); +} + +/******************************************************************************* + * Platform handler called when a power domain is about to be turned off. The + * target_state encodes the power state that each level should transition to. + * a5ds only has always-on power domain and there is no power control present. + ******************************************************************************/ +void a5ds_pwr_domain_off(const psci_power_state_t *target_state) +{ + ERROR("CPU_OFF not supported on this platform\n"); + assert(false); + panic(); +} /******************************************************************************* * Export the platform handlers via a5ds_psci_pm_ops. The ARM Standard @@ -14,11 +58,17 @@ plat_psci_ops_t a5ds_psci_pm_ops = { /* dummy struct */ .validate_ns_entrypoint = NULL, + .pwr_domain_on = a5ds_pwr_domain_on, + .pwr_domain_on_finish = a5ds_pwr_domain_on_finish, + .pwr_domain_off = a5ds_pwr_domain_off }; int __init plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { + uintptr_t *mailbox = (void *)A5DS_TRUSTED_MAILBOX_BASE; + *mailbox = sec_entrypoint; + *psci_ops = &a5ds_psci_pm_ops; return 0; diff --git a/plat/arm/board/a5ds/aarch32/a5ds_helpers.S b/plat/arm/board/a5ds/aarch32/a5ds_helpers.S index 23a22d9c5..ed7ad9c86 100644 --- a/plat/arm/board/a5ds/aarch32/a5ds_helpers.S +++ b/plat/arm/board/a5ds/aarch32/a5ds_helpers.S @@ -12,17 +12,36 @@ .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary - /* -------------------------------------------------------------------- + /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); * - * For AArch32, cold-booting secondary CPUs is not yet - * implemented and they panic. - * -------------------------------------------------------------------- + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- */ func plat_secondary_cold_boot_setup -cb_panic: - wfi - b cb_panic + /* Calculate address of our hold entry */ + bl plat_my_core_pos + lsl r0, r0, #A5DS_HOLD_ENTRY_SHIFT + mov_imm r2, A5DS_HOLD_BASE + /* Clear the value stored in the hold address for the specific core */ + mov_imm r3, A5DS_HOLD_STATE_WAIT + str r3, [r2, r0] + dmb ish + + /* Wait until we have a go */ +poll_mailbox: + ldr r1, [r2, r0] + cmp r1, #A5DS_HOLD_STATE_WAIT + beq 1f + mov_imm r0, A5DS_TRUSTED_MAILBOX_BASE + ldr r1, [r0] + bx r1 +1: + wfe + b poll_mailbox endfunc plat_secondary_cold_boot_setup /* --------------------------------------------------------------------- @@ -56,3 +75,52 @@ func plat_is_my_cpu_primary movne r0, #0 bx lr endfunc plat_is_my_cpu_primary + + /* --------------------------------------------------------------------- + * Loads MPIDR in r0 and calls plat_arm_calc_core_pos + * --------------------------------------------------------------------- + */ +func plat_my_core_pos + ldcopr r0, MPIDR + b plat_arm_calc_core_pos + +endfunc plat_my_core_pos + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on A5DS. + * + * (ClusterId * A5DS_MAX_CPUS_PER_CLUSTER * A5DS_MAX_PE_PER_CPU) + + * (CPUId * A5DS_MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * A5DS_MAX_CPUS_PER_CLUSTER + CPUId) * A5DS_MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- + */ +func plat_arm_calc_core_pos + mov r3, r0 + + /* + * Check for MT bit in MPIDR. If not set, shift MPIDR to left to make it + * look as if in a multi-threaded implementation + */ + tst r0, #MPIDR_MT_MASK + lsleq r3, r0, #MPIDR_AFFINITY_BITS + + /* Extract individual affinity fields from MPIDR */ + ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov r3, #A5DS_MAX_CPUS_PER_CLUSTER + mla r1, r2, r3, r1 + mov r3, #A5DS_MAX_PE_PER_CPU + mla r0, r1, r3, r0 + + bx lr +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts index 9ab2d9656..7b3aa1144 100644 --- a/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts +++ b/plat/arm/board/a5ds/fdts/a5ds_tb_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,7 @@ /* Platform Config */ plat_arm_bl2 { compatible = "arm,tb_fw"; - hw_config_addr = <0x0 0x82000000>; + hw_config_addr = <0x0 0x83000000>; hw_config_max_size = <0x01000000>; /* Disable authentication for development */ disable_auth = <0x0>; diff --git a/plat/arm/board/a5ds/include/platform_def.h b/plat/arm/board/a5ds/include/platform_def.h index db65c3778..31dfb1cf1 100644 --- a/plat/arm/board/a5ds/include/platform_def.h +++ b/plat/arm/board/a5ds/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,14 +21,6 @@ #define ARM_DRAM1_END (ARM_DRAM1_BASE + \ ARM_DRAM1_SIZE - 1) -#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE -/* - * The last 2MB is meant to be NOLOAD and will not be zero - * initialized. - */ -#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ - 0x00200000) - #define SRAM_BASE 0x2000000 #define SRAM_SIZE 0x200000 @@ -47,7 +39,7 @@ #define A5_PERIPHERALS_BASE 0x1c000000 #define A5_PERIPHERALS_SIZE 0x10000 -#define ARM_CACHE_WRITEBACK_SHIFT 6 +#define ARM_CACHE_WRITEBACK_SHIFT 5 #define ARM_IRQ_SEC_PHY_TIMER 29 @@ -89,28 +81,34 @@ #define A5DS_IRQ_SEC_SYS_TIMER 57 /* Default cluster count for A5DS */ -#define A5DS_CLUSTER_COUNT 1 +#define A5DS_CLUSTER_COUNT U(1) /* Default number of CPUs per cluster on A5DS */ -#define A5DS_MAX_CPUS_PER_CLUSTER 4 +#define A5DS_MAX_CPUS_PER_CLUSTER U(4) /* Default number of threads per CPU on A5DS */ -#define A5DS_MAX_PE_PER_CPU 1 +#define A5DS_MAX_PE_PER_CPU U(1) -#define A5DS_CORE_COUNT 1 +#define A5DS_CORE_COUNT U(4) -#define A5DS_PRIMARY_CPU 0x0 +#define A5DS_PRIMARY_CPU 0x0 -#define FLASH1_BASE UL(0x8000000) -#define FLASH1_SIZE UL(0x2800000) +#define BOOT_BASE ARM_DRAM1_BASE +#define BOOT_SIZE UL(0x2800000) -#define MAP_FLASH1_RW MAP_REGION_FLAT(FLASH1_BASE,\ - FLASH1_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) +#define ARM_NS_DRAM1_BASE (ARM_DRAM1_BASE + BOOT_SIZE) +/* + * The last 2MB is meant to be NOLOAD and will not be zero + * initialized. + */ +#define ARM_NS_DRAM1_SIZE (ARM_DRAM1_SIZE - \ + BOOT_SIZE - \ + 0x00200000) -#define MAP_FLASH1_RO MAP_REGION_FLAT(FLASH1_BASE,\ - FLASH1_SIZE, \ - MT_RO_DATA | MT_SECURE) +#define MAP_BOOT_RW MAP_REGION_FLAT( \ + BOOT_BASE, \ + BOOT_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) #define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ A5DS_SHARED_RAM_BASE, \ @@ -122,9 +120,9 @@ ARM_NS_DRAM1_SIZE, \ MT_MEMORY | MT_RW | MT_NS) -#define ARM_MAP_SRAM MAP_REGION_FLAT( \ - SRAM_BASE, \ - SRAM_SIZE, \ +#define ARM_MAP_SRAM MAP_REGION_FLAT( \ + SRAM_BASE, \ + SRAM_SIZE, \ MT_MEMORY | MT_RW | MT_NS) /* @@ -162,7 +160,7 @@ ARM_BL_REGIONS) /* Memory mapped Generic timer interfaces */ -#define A5DS_TIMER_BASE_FREQUENCY UL(24000000) +#define A5DS_TIMER_BASE_FREQUENCY UL(7500000) #define ARM_CONSOLE_BAUDRATE 115200 @@ -229,11 +227,11 @@ #define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) /* Required platform porting definitions */ -#define PLATFORM_CORE_COUNT 1 -#define PLAT_NUM_PWR_DOMAINS (A5DS_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) + 1 +#define PLATFORM_CORE_COUNT A5DS_CORE_COUNT +#define PLAT_NUM_PWR_DOMAINS (A5DS_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + U(1) -#define PLAT_MAX_PWR_LVL 2 +#define PLAT_MAX_PWR_LVL 2 /* * Other platform porting definitions are provided by included headers @@ -300,31 +298,42 @@ #define MAX_IO_HANDLES 4 /* Reserve the last block of flash for PSCI MEM PROTECT flag */ -#define PLAT_ARM_FIP_BASE FLASH1_BASE -#define PLAT_ARM_FIP_MAX_SIZE (FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE) +#define PLAT_ARM_FIP_BASE BOOT_BASE +#define PLAT_ARM_FIP_MAX_SIZE (BOOT_SIZE - V2M_FLASH_BLOCK_SIZE) -#define PLAT_ARM_NVM_BASE FLASH1_BASE -#define PLAT_ARM_NVM_SIZE (FLASH1_SIZE - V2M_FLASH_BLOCK_SIZE) +#define PLAT_ARM_NVM_BASE BOOT_BASE +#define PLAT_ARM_NVM_SIZE (BOOT_SIZE - V2M_FLASH_BLOCK_SIZE) /* * PL011 related constants */ #define PLAT_ARM_BOOT_UART_BASE 0x1A200000 -#define PLAT_ARM_BOOT_UART_CLK_IN_HZ 24000000 +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ UL(7500000) #define PLAT_ARM_RUN_UART_BASE 0x1A210000 -#define PLAT_ARM_RUN_UART_CLK_IN_HZ 24000000 +#define PLAT_ARM_RUN_UART_CLK_IN_HZ UL(7500000) #define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE #define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ -#define A5DS_TIMER_BASE_FREQUENCY UL(24000000) +#define A5DS_TIMER_BASE_FREQUENCY UL(7500000) /* System timer related constants */ #define PLAT_ARM_NSTIMER_FRAME_ID 1 /* Mailbox base address */ #define A5DS_TRUSTED_MAILBOX_BASE A5DS_SHARED_RAM_BASE +#define A5DS_TRUSTED_MAILBOX_SIZE (8 + A5DS_HOLD_SIZE) +#define A5DS_HOLD_BASE (A5DS_TRUSTED_MAILBOX_BASE + 8) +#define A5DS_HOLD_SIZE (PLATFORM_CORE_COUNT * \ + A5DS_HOLD_ENTRY_SIZE) +#define A5DS_HOLD_ENTRY_SHIFT 3 +#define A5DS_HOLD_ENTRY_SIZE (1 << A5DS_HOLD_ENTRY_SHIFT) +#define A5DS_HOLD_STATE_WAIT 0 +#define A5DS_HOLD_STATE_GO 1 + +/* Snoop Control Unit base address */ +#define A5DS_SCU_BASE 0x1C000000 /* * GIC related constants to cater for GICv2 diff --git a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c index 8b45af85b..a951dc7b4 100644 --- a/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c +++ b/plat/arm/board/a5ds/sp_min/a5ds_sp_min_setup.c @@ -4,12 +4,17 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <drivers/arm/scu.h> #include <plat/arm/common/plat_arm.h> + void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); + + /* enable snoop control unit */ + enable_snoop_ctrl_unit(A5DS_SCU_BASE); } /* diff --git a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk index da1d785c2..4b0c97dfd 100644 --- a/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk +++ b/plat/arm/board/a5ds/sp_min/sp_min-a5ds.mk @@ -5,7 +5,8 @@ # # SP_MIN source files specific to A5DS platform -BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ +BL32_SOURCES += drivers/arm/scu/scu.c \ + drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ lib/aarch32/arm32_aeabi_divmod.c \ lib/aarch32/arm32_aeabi_divmod_a32.S \ diff --git a/plat/arm/board/corstone700/corstone700_helpers.S b/plat/arm/board/corstone700/corstone700_helpers.S new file mode 100644 index 000000000..c713f4f1a --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_helpers.S @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <platform_def.h> + + .globl plat_secondary_cold_boot_setup + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl plat_arm_calc_core_pos + + /* -------------------------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * For AArch32, cold-booting secondary CPUs is not yet + * implemented and they panic. + * -------------------------------------------------------------------- + */ +func plat_secondary_cold_boot_setup +cb_panic: + b cb_panic +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * unsigned long plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and warm + * boot. On Corstone700, this information can be queried from the power + * controller. The Power Control SYS Status Register (PSYSR) indicates + * the wake-up reason for the CPU. + * + * For a cold boot, return 0. + * For a warm boot, Not yet supported. + * + * TODO: PSYSR is a common register and should be + * accessed using locks. Since it is not possible + * to use locks immediately after a cold reset + * we are relying on the fact that after a cold + * reset all cpus will read the same WK field + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* TODO support warm boot */ + /* Cold reset */ + mov r0, #0 + bx lr +endfunc plat_get_my_entrypoint + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current CPU is the primary + * CPU. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + ldcopr r0, MPIDR + ldr r1, =MPIDR_AFFINITY_MASK + and r0, r1 + cmp r0, #0 + moveq r0, #1 + movne r0, #0 + bx lr +endfunc plat_is_my_cpu_primary + + /* --------------------------------------------------------------------- + * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) + * + * Function to calculate the core position on Corstone700. + * + * (ClusterId * MAX_CPUS_PER_CLUSTER * MAX_PE_PER_CPU) + + * (CPUId * MAX_PE_PER_CPU) + + * ThreadId + * + * which can be simplified as: + * + * ((ClusterId * MAX_CPUS_PER_CLUSTER + CPUId) * MAX_PE_PER_CPU) + * + ThreadId + * --------------------------------------------------------------------- + */ +func plat_arm_calc_core_pos + mov r3, r0 + + /* Extract individual affinity fields from MPIDR */ + ubfx r0, r3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r1, r3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx r2, r3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + + /* Compute linear position */ + mov r3, #CORSTONE700_MAX_CPUS_PER_CLUSTER + mla r1, r2, r3, r1 + mov r3, #CORSTONE700_MAX_PE_PER_CPU + mla r0, r1, r3, r0 + + bx lr +endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/corstone700/corstone700_plat.c b/plat/arm/board/corstone700/corstone700_plat.c new file mode 100644 index 000000000..cee6fd618 --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_plat.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/bl_common.h> +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> +#include <platform_def.h> + +/* + * Table of regions to map using the MMU. + * Replace or extend the below regions as required + */ + +const mmap_region_t plat_arm_mmap[] = { + ARM_MAP_SHARED_RAM, + ARM_MAP_NS_DRAM1, + CORSTONE700_MAP_DEVICE, + {0} +}; + +/* Corstone700 only has one always-on power domain and there + * is no power control present + */ +void __init plat_arm_pwrc_setup(void) +{ +} + +unsigned int plat_get_syscnt_freq2(void) +{ + return CORSTONE700_TIMER_BASE_FREQUENCY; +} diff --git a/plat/arm/board/corstone700/corstone700_pm.c b/plat/arm/board/corstone700/corstone700_pm.c new file mode 100644 index 000000000..4884ea519 --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_pm.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/psci/psci.h> +#include <plat/arm/common/plat_arm.h> + +/******************************************************************************* + * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard + * platform layer will take care of registering the handlers with PSCI. + ******************************************************************************/ +plat_psci_ops_t plat_arm_psci_pm_ops = { + /* dummy struct */ + .validate_ns_entrypoint = NULL +}; + +const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) +{ + return ops; +} diff --git a/plat/arm/board/corstone700/corstone700_security.c b/plat/arm/board/corstone700/corstone700_security.c new file mode 100644 index 000000000..39b2fc902 --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_security.c @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * We assume that all security programming is done by the primary core. + */ +void plat_arm_security_setup(void) +{ + /* + * If the platform had additional peripheral specific security + * configurations, those would be configured here. + */ +} diff --git a/plat/arm/board/corstone700/corstone700_topology.c b/plat/arm/board/corstone700/corstone700_topology.c new file mode 100644 index 000000000..d9445e0c5 --- /dev/null +++ b/plat/arm/board/corstone700/corstone700_topology.c @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> +#include <plat/common/platform.h> + +/* The Corstone700 power domain tree descriptor */ +static unsigned char corstone700_power_domain_tree_desc + [PLAT_ARM_CLUSTER_COUNT + 2]; +/******************************************************************************* + * This function dynamically constructs the topology according to + * CLUSTER_COUNT and returns it. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + int i; + + /* + * The highest level is the system level. The next level is constituted + * by clusters and then cores in clusters. + */ + corstone700_power_domain_tree_desc[0] = 1; + corstone700_power_domain_tree_desc[1] = PLAT_ARM_CLUSTER_COUNT; + + for (i = 0; i < PLAT_ARM_CLUSTER_COUNT; i++) + corstone700_power_domain_tree_desc[i + 2] = PLATFORM_CORE_COUNT; + + return corstone700_power_domain_tree_desc; +} + +/****************************************************************************** + * This function implements a part of the critical interface between the PSCI + * generic layer and the platform that allows the former to query the platform + * to convert an MPIDR to a unique linear index. An error code (-1) is + * returned in case the MPIDR is invalid. + *****************************************************************************/ +int plat_core_pos_by_mpidr(u_register_t mpidr) +{ + return plat_arm_calc_core_pos(mpidr); +} diff --git a/plat/arm/board/corstone700/include/platform_def.h b/plat/arm/board/corstone700/include/platform_def.h new file mode 100644 index 000000000..8dff3ec3f --- /dev/null +++ b/plat/arm/board/corstone700/include/platform_def.h @@ -0,0 +1,228 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <lib/utils_def.h> +#include <lib/xlat_tables/xlat_tables_defs.h> +#include <plat/arm/board/common/v2m_def.h> +#include <plat/arm/common/arm_spm_def.h> +#include <plat/common/common_def.h> + +/* Core/Cluster/Thread counts for Corstone700 */ +#define CORSTONE700_CLUSTER_COUNT U(1) +#define CORSTONE700_MAX_CPUS_PER_CLUSTER U(4) +#define CORSTONE700_MAX_PE_PER_CPU U(1) +#define CORSTONE700_CORE_COUNT (CORSTONE700_CLUSTER_COUNT * \ + CORSTONE700_MAX_CPUS_PER_CLUSTER * \ + CORSTONE700_MAX_PE_PER_CPU) +#define PLATFORM_CORE_COUNT CORSTONE700_CORE_COUNT +#define PLAT_ARM_CLUSTER_COUNT CORSTONE700_CLUSTER_COUNT + +/* UART related constants */ +#define PLAT_ARM_BOOT_UART_BASE 0x1a510000 +#define PLAT_ARM_BOOT_UART_CLK_IN_HZ V2M_IOFPGA_UART0_CLK_IN_HZ +#define PLAT_ARM_RUN_UART_BASE 0x1a520000 +#define PLAT_ARM_RUN_UART_CLK_IN_HZ V2M_IOFPGA_UART1_CLK_IN_HZ +#define ARM_CONSOLE_BAUDRATE 115200 +#define PLAT_ARM_CRASH_UART_BASE PLAT_ARM_RUN_UART_BASE +#define PLAT_ARM_CRASH_UART_CLK_IN_HZ PLAT_ARM_RUN_UART_CLK_IN_HZ + +/* Memory related constants */ +#define ARM_DRAM1_BASE UL(0x80000000) +#define ARM_DRAM1_SIZE UL(0x80000000) +#define ARM_DRAM1_END (ARM_DRAM1_BASE + \ + ARM_DRAM1_SIZE - 1) +#define ARM_NS_DRAM1_BASE ARM_DRAM1_BASE +#define ARM_NS_DRAM1_SIZE ARM_DRAM1_SIZE +#define ARM_NS_DRAM1_END (ARM_NS_DRAM1_BASE + \ + ARM_NS_DRAM1_SIZE - 1) +#define ARM_TRUSTED_SRAM_BASE UL(0x02000000) +#define ARM_SHARED_RAM_BASE ARM_TRUSTED_SRAM_BASE +#define ARM_SHARED_RAM_SIZE UL(0x00001000) /* 4 KB */ +#define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00040000 /* 256 KB */ + +/* The remaining Trusted SRAM is used to load the BL images */ +#define ARM_BL_RAM_BASE (ARM_SHARED_RAM_BASE + \ + ARM_SHARED_RAM_SIZE) +#define ARM_BL_RAM_SIZE (PLAT_ARM_TRUSTED_SRAM_SIZE - \ + ARM_SHARED_RAM_SIZE) + +/* + * SP_MIN is the only BL image in SRAM. Allocate the whole of SRAM (excluding + * the page reserved for fw_configs) to BL32 + */ +#define BL32_BASE (ARM_BL_RAM_BASE + PAGE_SIZE) +#define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_GRANULE (U(1) << ARM_CACHE_WRITEBACK_SHIFT) +#define ARM_CACHE_WRITEBACK_SHIFT 6 + +/* + * To enable TB_FW_CONFIG to be loaded by BL1, define the corresponding base + * and limit. Leave enough space for BL2 meminfo. + */ +#define ARM_TB_FW_CONFIG_BASE (ARM_BL_RAM_BASE + sizeof(meminfo_t)) +#define ARM_TB_FW_CONFIG_LIMIT (ARM_BL_RAM_BASE + (PAGE_SIZE / 2U)) + +/* + * The max number of regions like RO(code), coherent and data required by + * different BL stages which need to be mapped in the MMU. + */ +#define ARM_BL_REGIONS 2 +#define PLAT_ARM_MMAP_ENTRIES 8 +#define MAX_XLAT_TABLES 5 +#define MAX_MMAP_REGIONS (PLAT_ARM_MMAP_ENTRIES + \ + ARM_BL_REGIONS) + +/* GIC related constants */ +#define PLAT_ARM_GICD_BASE 0x1C010000 +#define PLAT_ARM_GICC_BASE 0x1C02F000 + +/* Timer/watchdog related constants */ +#define ARM_SYS_CNTCTL_BASE UL(0x1a200000) +#define ARM_SYS_CNTREAD_BASE UL(0x1a210000) +#define ARM_SYS_TIMCTL_BASE UL(0x1a220000) +#define CORSTONE700_TIMER_BASE_FREQUENCY UL(24000000) +#define CORSTONE700_IRQ_TZ_WDOG 32 +#define CORSTONE700_IRQ_SEC_SYS_TIMER 34 + +#define PLAT_MAX_PWR_LVL 2 +/* + * Macros mapping the MPIDR Affinity levels to ARM Platform Power levels. The + * power levels have a 1:1 mapping with the MPIDR affinity levels. + */ +#define ARM_PWR_LVL0 MPIDR_AFFLVL0 +#define ARM_PWR_LVL1 MPIDR_AFFLVL1 +#define ARM_PWR_LVL2 MPIDR_AFFLVL2 + +/* + * Macros for local power states in ARM platforms encoded by State-ID field + * within the power-state parameter. + */ +/* Local power state for power domains in Run state. */ +#define ARM_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define ARM_LOCAL_STATE_RET U(1) +/* Local power state for OFF/power-down. Valid for CPU and cluster + * power domains + */ +#define ARM_LOCAL_STATE_OFF U(2) + +#define PLAT_ARM_TRUSTED_MAILBOX_BASE ARM_TRUSTED_SRAM_BASE +#define PLAT_ARM_NSTIMER_FRAME_ID U(1) + +#define PLAT_ARM_NS_IMAGE_OFFSET (ARM_DRAM1_BASE + UL(0x8000000)) + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) + +/* + * This macro defines the deepest retention state possible. A higher state + * ID will represent an invalid or a power down state. + */ +#define PLAT_MAX_RET_STATE 1 + +/* + * This macro defines the deepest power down states possible. Any state ID + * higher than this is invalid. + */ +#define PLAT_MAX_OFF_STATE 2 + +#define PLATFORM_STACK_SIZE UL(0x440) + +#define ARM_MAP_SHARED_RAM MAP_REGION_FLAT( \ + ARM_SHARED_RAM_BASE, \ + ARM_SHARED_RAM_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_MAP_NS_DRAM1 MAP_REGION_FLAT( \ + ARM_NS_DRAM1_BASE, \ + ARM_NS_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define ARM_MAP_BL_RO MAP_REGION_FLAT( \ + BL_CODE_BASE, \ + BL_CODE_END \ + - BL_CODE_BASE, \ + MT_CODE | MT_SECURE), \ + MAP_REGION_FLAT( \ + BL_RO_DATA_BASE, \ + BL_RO_DATA_END \ + - BL_RO_DATA_BASE, \ + MT_RO_DATA | MT_SECURE) +#if USE_COHERENT_MEM +#define ARM_MAP_BL_COHERENT_RAM MAP_REGION_FLAT( \ + BL_COHERENT_RAM_BASE, \ + BL_COHERENT_RAM_END \ + - BL_COHERENT_RAM_BASE, \ + MT_DEVICE | MT_RW | MT_SECURE) +#endif + +#define CORSTONE700_DEVICE_BASE (0x1A000000) +#define CORSTONE700_DEVICE_SIZE (0x26000000) +#define CORSTONE700_MAP_DEVICE MAP_REGION_FLAT( \ + CORSTONE700_DEVICE_BASE, \ + CORSTONE700_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_IRQ_SEC_PHY_TIMER 29 + +#define ARM_IRQ_SEC_SGI_0 8 +#define ARM_IRQ_SEC_SGI_1 9 +#define ARM_IRQ_SEC_SGI_2 10 +#define ARM_IRQ_SEC_SGI_3 11 +#define ARM_IRQ_SEC_SGI_4 12 +#define ARM_IRQ_SEC_SGI_5 13 +#define ARM_IRQ_SEC_SGI_6 14 +#define ARM_IRQ_SEC_SGI_7 15 + +/* + * Define a list of Group 1 Secure and Group 0 interrupt properties as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define ARM_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ + (grp), GIC_INTR_CFG_EDGE) + +#define ARM_G0_IRQ_PROPS(grp) \ + INTR_PROP_DESC(ARM_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, (grp), \ + GIC_INTR_CFG_EDGE) + +/* + * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 + * terminology. On a GICv2 system or mode, the lists will be merged and treated + * as Group 0 interrupts. + */ +#define PLAT_ARM_G1S_IRQ_PROPS(grp) \ + ARM_G1S_IRQ_PROPS(grp), \ + INTR_PROP_DESC(CORSTONE700_IRQ_TZ_WDOG, \ + GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(CORSTONE700_IRQ_SEC_SYS_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, (grp), GIC_INTR_CFG_LEVEL) \ + +#define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/arm/board/corstone700/platform.mk b/plat/arm/board/corstone700/platform.mk new file mode 100644 index 000000000..bff3589eb --- /dev/null +++ b/plat/arm/board/corstone700/platform.mk @@ -0,0 +1,49 @@ +# +# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CORSTONE700_CPU_LIBS += lib/cpus/aarch32/cortex_a32.S + +BL32_SOURCES += plat/arm/common/aarch32/arm_helpers.S \ + plat/arm/common/arm_console.c \ + plat/arm/common/arm_common.c \ + lib/xlat_tables/aarch32/xlat_tables.c \ + lib/xlat_tables/xlat_tables_common.c \ + ${CORSTONE700_CPU_LIBS} + +PLAT_INCLUDES := -Iplat/arm/board/corstone700/include + +NEED_BL32 := yes + +CORSTONE700_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_main.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + plat/common/plat_gicv2.c \ + plat/arm/common/arm_gicv2.c + +# BL1/BL2 Image not a part of the capsule Image for Corstone700 +override NEED_BL1 := no +override NEED_BL2 := no +override NEED_BL2U := no + +#TFA for Corstone700 starts from BL32 +override RESET_TO_SP_MIN := 1 + +#Device tree +CORSTONE700_HW_CONFIG_DTS := fdts/corstone700.dts +CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}.dtb +FDT_SOURCES += ${CORSTONE700_HW_CONFIG_DTS} +$(eval CORSTONE700_HW_CONFIG := ${BUILD_PLAT}/$(patsubst %.dts,%.dtb,$(CORSTONE700_HW_CONFIG_DTS))) + +# Add the HW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${CORSTONE700_HW_CONFIG},--hw-config)) + +# Check for Linux kernel as a BL33 image by default +$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) + ifndef ARM_PRELOADED_DTB_BASE + $(error "ARM_PRELOADED_DTB_BASE must be set if ARM_LINUX_KERNEL_AS_BL33 is used.") + endif + $(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) +include plat/arm/board/common/board_common.mk diff --git a/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c b/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c new file mode 100644 index 000000000..2fc0e0dec --- /dev/null +++ b/plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +void plat_arm_sp_min_early_platform_setup(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + arm_sp_min_early_platform_setup((void *)arg0, arg1, arg2, (void *)arg3); +} diff --git a/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk new file mode 100644 index 000000000..57e1ec3e4 --- /dev/null +++ b/plat/arm/board/corstone700/sp_min/sp_min-corstone700.mk @@ -0,0 +1,18 @@ +# +# Copyright (c) 2019, Arm Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# SP_MIN source files specific to FVP platform +BL32_SOURCES += drivers/cfi/v2m/v2m_flash.c \ + lib/utils/mem_region.c \ + plat/arm/board/corstone700/corstone700_helpers.S \ + plat/arm/board/corstone700/corstone700_topology.c \ + plat/arm/board/corstone700/corstone700_security.c \ + plat/arm/board/corstone700/corstone700_plat.c \ + plat/arm/board/corstone700/corstone700_pm.c \ + plat/arm/board/corstone700/sp_min/corstone700_sp_min_setup.c \ + ${CORSTONE700_GIC_SOURCES} + +include plat/arm/common/sp_min/arm_sp_min.mk diff --git a/plat/arm/board/fvp/fvp_bl1_setup.c b/plat/arm/board/fvp/fvp_bl1_setup.c index b90ddcd33..8f6170daa 100644 --- a/plat/arm/board/fvp/fvp_bl1_setup.c +++ b/plat/arm/board/fvp/fvp_bl1_setup.c @@ -48,6 +48,9 @@ void bl1_platform_setup(void) { arm_bl1_platform_setup(); + /* Initialize System level generic or SP804 timer */ + fvp_timer_init(); + /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_security_init(PLAT_FVP_SMMUV3_BASE); diff --git a/plat/arm/board/fvp/fvp_bl2_setup.c b/plat/arm/board/fvp/fvp_bl2_setup.c index d28094993..89636d18a 100644 --- a/plat/arm/board/fvp/fvp_bl2_setup.c +++ b/plat/arm/board/fvp/fvp_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,15 +25,6 @@ void bl2_platform_setup(void) { arm_bl2_platform_setup(); -#if FVP_USE_SP804_TIMER - /* Enable the clock override for SP804 timer 0, which means that no - * clock dividers are applied and the raw (35 MHz) clock will be used */ - mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV); - - /* Initialize delay timer driver using SP804 dual timer 0 */ - sp804_timer_init(V2M_SP804_TIMER0_BASE, - SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); -#else - generic_delay_timer_init(); -#endif /* FVP_USE_SP804_TIMER */ + /* Initialize System level generic or SP804 timer */ + fvp_timer_init(); } diff --git a/plat/arm/board/fvp/fvp_bl2u_setup.c b/plat/arm/board/fvp/fvp_bl2u_setup.c index a8db05567..fd73767c6 100644 --- a/plat/arm/board/fvp/fvp_bl2u_setup.c +++ b/plat/arm/board/fvp/fvp_bl2u_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -14,6 +14,9 @@ void bl2u_early_platform_setup(struct meminfo *mem_layout, void *plat_info) { arm_bl2u_early_platform_setup(mem_layout, plat_info); + /* Initialize System level generic or SP804 timer */ + fvp_timer_init(); + /* Initialize the platform config for future decision making */ fvp_config_setup(); } diff --git a/plat/arm/board/fvp/fvp_bl31_setup.c b/plat/arm/board/fvp/fvp_bl31_setup.c index 3f92d3772..8627c5ef0 100644 --- a/plat/arm/board/fvp/fvp_bl31_setup.c +++ b/plat/arm/board/fvp/fvp_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -34,6 +34,9 @@ void __init bl31_early_platform_setup2(u_register_t arg0, */ fvp_interconnect_enable(); + /* Initialize System level generic or SP804 timer */ + fvp_timer_init(); + /* On FVP RevC, initialize SMMUv3 */ if ((arm_config.flags & ARM_CONFIG_FVP_HAS_SMMUV3) != 0U) smmuv3_init(PLAT_FVP_SMMUV3_BASE); diff --git a/plat/arm/board/fvp/fvp_common.c b/plat/arm/board/fvp/fvp_common.c index 36cd5009a..ffaa93de4 100644 --- a/plat/arm/board/fvp/fvp_common.c +++ b/plat/arm/board/fvp/fvp_common.c @@ -10,13 +10,15 @@ #include <drivers/arm/cci.h> #include <drivers/arm/ccn.h> #include <drivers/arm/gicv2.h> +#include <drivers/arm/sp804_delay_timer.h> +#include <drivers/generic_delay_timer.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/arm_config.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> #include <platform_def.h> -#include <services/secure_partition.h> +#include <services/spm_mm_partition.h> #include "fvp_private.h" @@ -94,12 +96,9 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_BL1_RW, #endif #endif /* TRUSTED_BOARD_BOOT */ -#if ENABLE_SPM && SPM_MM +#if SPM_MM ARM_SP_IMAGE_MMAP, #endif -#if ENABLE_SPM && !SPM_MM - PLAT_MAP_SP_PACKAGE_MEM_RW, -#endif #if ARM_BL31_IN_DRAM ARM_MAP_BL31_SEC_DRAM, #endif @@ -120,21 +119,22 @@ const mmap_region_t plat_arm_mmap[] = { #ifdef IMAGE_BL31 const mmap_region_t plat_arm_mmap[] = { ARM_MAP_SHARED_RAM, +#if USE_DEBUGFS + /* Required by devfip, can be removed if devfip is not used */ + V2M_MAP_FLASH0_RW, +#endif /* USE_DEBUGFS */ ARM_MAP_EL3_TZC_DRAM, V2M_MAP_IOFPGA, MAP_DEVICE0, MAP_DEVICE1, ARM_V2M_MAP_MEM_PROTECT, -#if ENABLE_SPM && SPM_MM +#if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif -#if ENABLE_SPM && !SPM_MM - PLAT_MAP_SP_PACKAGE_MEM_RO, -#endif {0} }; -#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM +#if defined(IMAGE_BL31) && SPM_MM const mmap_region_t plat_arm_secure_partition_mmap[] = { V2M_MAP_IOFPGA_EL0, /* for the UART */ MAP_REGION_FLAT(DEVICE0_BASE, \ @@ -188,12 +188,12 @@ static unsigned int get_interconnect_master(void) } #endif -#if ENABLE_SPM && defined(IMAGE_BL31) && SPM_MM +#if defined(IMAGE_BL31) && SPM_MM /* * Boot information passed to a secure partition during initialisation. Linear * indices in MP information will be filled at runtime. */ -static secure_partition_mp_info_t sp_mp_info[] = { +static spm_mm_mp_info_t sp_mp_info[] = { [0] = {0x80000000, 0}, [1] = {0x80000001, 0}, [2] = {0x80000002, 0}, @@ -204,10 +204,10 @@ static secure_partition_mp_info_t sp_mp_info[] = { [7] = {0x80000103, 0}, }; -const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { +const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { .h.type = PARAM_SP_IMAGE_BOOT_INFO, .h.version = VERSION_1, - .h.size = sizeof(secure_partition_boot_info_t), + .h.size = sizeof(spm_mm_boot_info_t), .h.attr = 0, .sp_mem_base = ARM_SP_IMAGE_BASE, .sp_mem_limit = ARM_SP_IMAGE_LIMIT, @@ -231,7 +231,7 @@ const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) return plat_arm_secure_partition_mmap; } -const struct secure_partition_boot_info *plat_get_secure_partition_boot_info( +const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( void *cookie) { return &plat_arm_secure_partition_boot_info; @@ -407,3 +407,23 @@ int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) return arm_get_mbedtls_heap(heap_addr, heap_size); } #endif + +void fvp_timer_init(void) +{ +#if FVP_USE_SP804_TIMER + /* Enable the clock override for SP804 timer 0, which means that no + * clock dividers are applied and the raw (35MHz) clock will be used. + */ + mmio_write_32(V2M_SP810_BASE, FVP_SP810_CTRL_TIM0_OV); + + /* Initialize delay timer driver using SP804 dual timer 0 */ + sp804_timer_init(V2M_SP804_TIMER0_BASE, + SP804_TIMER_CLKMULT, SP804_TIMER_CLKDIV); +#else + generic_delay_timer_init(); + + /* Enable System level generic timer */ + mmio_write_32(ARM_SYS_CNTCTL_BASE + CNTCR_OFF, + CNTCR_FCREQ(0U) | CNTCR_EN); +#endif /* FVP_USE_SP804_TIMER */ +} diff --git a/plat/arm/board/fvp/fvp_def.h b/plat/arm/board/fvp/fvp_def.h index 1b9f84b00..347ba2e1e 100644 --- a/plat/arm/board/fvp/fvp_def.h +++ b/plat/arm/board/fvp/fvp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,15 +10,15 @@ #include <lib/utils_def.h> #ifndef FVP_CLUSTER_COUNT -#define FVP_CLUSTER_COUNT 2 +#error "FVP_CLUSTER_COUNT is not set in makefile" #endif #ifndef FVP_MAX_CPUS_PER_CLUSTER -#define FVP_MAX_CPUS_PER_CLUSTER 4 +#error "FVP_MAX_CPUS_PER_CLUSTER is not set in makefile" #endif #ifndef FVP_MAX_PE_PER_CPU -# define FVP_MAX_PE_PER_CPU 1 +#error "FVP_MAX_PE_PER_CPU is not set in makefile" #endif #define FVP_PRIMARY_CPU 0x0 diff --git a/plat/arm/board/fvp/fvp_pm.c b/plat/arm/board/fvp/fvp_pm.c index 42dec8dfc..0a62543fa 100644 --- a/plat/arm/board/fvp/fvp_pm.c +++ b/plat/arm/board/fvp/fvp_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -247,10 +247,19 @@ static void fvp_pwr_domain_on_finish(const psci_power_state_t *target_state) { fvp_power_domain_on_finish_common(target_state); - /* Enable the gic cpu interface */ +} + +/******************************************************************************* + * FVP handler called when a power domain has just been powered on and the cpu + * and its cluster are fully participating in coherent transaction on the + * interconnect. Data cache must be enabled for CPU at this point. + ******************************************************************************/ +static void fvp_pwr_domain_on_finish_late(const psci_power_state_t *target_state) +{ + /* Program GIC per-cpu distributor or re-distributor interface */ plat_arm_gic_pcpu_init(); - /* Program the gic per-cpu distributor or re-distributor interface */ + /* Enable GIC CPU interface */ plat_arm_gic_cpuif_enable(); } @@ -272,7 +281,7 @@ static void fvp_pwr_domain_suspend_finish(const psci_power_state_t *target_state fvp_power_domain_on_finish_common(target_state); - /* Enable the gic cpu interface */ + /* Enable GIC CPU interface */ plat_arm_gic_cpuif_enable(); } @@ -397,6 +406,7 @@ plat_psci_ops_t plat_arm_psci_pm_ops = { .pwr_domain_off = fvp_pwr_domain_off, .pwr_domain_suspend = fvp_pwr_domain_suspend, .pwr_domain_on_finish = fvp_pwr_domain_on_finish, + .pwr_domain_on_finish_late = fvp_pwr_domain_on_finish_late, .pwr_domain_suspend_finish = fvp_pwr_domain_suspend_finish, .system_off = fvp_system_off, .system_reset = fvp_system_reset, diff --git a/plat/arm/board/fvp/fvp_private.h b/plat/arm/board/fvp/fvp_private.h index 5067d3a2f..3590370df 100644 --- a/plat/arm/board/fvp/fvp_private.h +++ b/plat/arm/board/fvp/fvp_private.h @@ -18,6 +18,7 @@ void fvp_config_setup(void); void fvp_interconnect_init(void); void fvp_interconnect_enable(void); void fvp_interconnect_disable(void); +void fvp_timer_init(void); void tsp_early_platform_setup(void); #endif /* FVP_PRIVATE_H */ diff --git a/plat/arm/board/fvp/fvp_topology.c b/plat/arm/board/fvp/fvp_topology.c index 9823fb3b3..24e79b4d4 100644 --- a/plat/arm/board/fvp/fvp_topology.c +++ b/plat/arm/board/fvp/fvp_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -36,7 +36,8 @@ const unsigned char *plat_get_power_domain_tree_desc(void) fvp_power_domain_tree_desc[1] = FVP_CLUSTER_COUNT; for (i = 0; i < FVP_CLUSTER_COUNT; i++) - fvp_power_domain_tree_desc[i + 2] = FVP_MAX_CPUS_PER_CLUSTER; + fvp_power_domain_tree_desc[i + 2] = + FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU; return fvp_power_domain_tree_desc; diff --git a/plat/arm/board/fvp/fvp_trusted_boot.c b/plat/arm/board/fvp/fvp_trusted_boot.c index 0d160cb1d..dc5076435 100644 --- a/plat/arm/board/fvp/fvp_trusted_boot.c +++ b/plat/arm/board/fvp/fvp_trusted_boot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,39 +8,41 @@ #include <stdint.h> #include <string.h> +#include <lib/mmio.h> + #include <plat/common/platform.h> #include <platform_def.h> #include <tools_share/tbbr_oid.h> /* - * Store a new non-volatile counter value. On some FVP versions, the - * non-volatile counters are RO. On these versions we expect the values in the - * certificates to always match the RO values so that this function is never - * called. + * Store a new non-volatile counter value. + * + * On some FVP versions, the non-volatile counters are read-only so this + * function will always fail. * * Return: 0 = success, Otherwise = error */ int plat_set_nv_ctr(void *cookie, unsigned int nv_ctr) { const char *oid; - uint32_t *nv_ctr_addr; + uintptr_t nv_ctr_addr; assert(cookie != NULL); oid = (const char *)cookie; if (strcmp(oid, TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)TFW_NVCTR_BASE; + nv_ctr_addr = TFW_NVCTR_BASE; } else if (strcmp(oid, NON_TRUSTED_FW_NVCOUNTER_OID) == 0) { - nv_ctr_addr = (uint32_t *)NTFW_CTR_BASE; + nv_ctr_addr = NTFW_CTR_BASE; } else { return 1; } - *(unsigned int *)nv_ctr_addr = nv_ctr; - - /* Verify that the current value is the one we just wrote. */ - if (nv_ctr != (unsigned int)(*nv_ctr_addr)) - return 1; + mmio_write_32(nv_ctr_addr, nv_ctr); - return 0; + /* + * If the FVP models a locked counter then its value cannot be updated + * and the above write operation has been silently ignored. + */ + return (mmio_read_32(nv_ctr_addr) == nv_ctr) ? 0 : 1; } diff --git a/plat/arm/board/fvp/include/plat.ld.S b/plat/arm/board/fvp/include/plat.ld.S index f024f551a..7c8bf0655 100644 --- a/plat/arm/board/fvp/include/plat.ld.S +++ b/plat/arm/board/fvp/include/plat.ld.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,9 @@ #define PLAT_LD_S #include <plat/arm/common/arm_tzc_dram.ld.S> + +#if RECLAIM_INIT_CODE #include <plat/arm/common/arm_reclaim_init.ld.S> +#endif /* RECLAIM_INIT_CODE */ #endif /* PLAT_LD_S */ diff --git a/plat/arm/board/fvp/include/platform_def.h b/plat/arm/board/fvp/include/platform_def.h index 4f2627704..c2b7b98d4 100644 --- a/plat/arm/board/fvp/include/platform_def.h +++ b/plat/arm/board/fvp/include/platform_def.h @@ -17,11 +17,12 @@ #include "../fvp_def.h" /* Required platform porting definitions */ -#define PLATFORM_CORE_COUNT \ - (FVP_CLUSTER_COUNT * FVP_MAX_CPUS_PER_CLUSTER * FVP_MAX_PE_PER_CPU) +#define PLATFORM_CORE_COUNT (U(FVP_CLUSTER_COUNT) * \ + U(FVP_MAX_CPUS_PER_CLUSTER) * \ + U(FVP_MAX_PE_PER_CPU)) -#define PLAT_NUM_PWR_DOMAINS (FVP_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) + 1 +#define PLAT_NUM_PWR_DOMAINS (U(FVP_CLUSTER_COUNT) + \ + PLATFORM_CORE_COUNT + U(1)) #define PLAT_MAX_PWR_LVL ARM_PWR_LVL2 @@ -32,7 +33,7 @@ /* * Required ARM standard platform porting definitions */ -#define PLAT_ARM_CLUSTER_COUNT FVP_CLUSTER_COUNT +#define PLAT_ARM_CLUSTER_COUNT U(FVP_CLUSTER_COUNT) #define PLAT_ARM_TRUSTED_SRAM_SIZE UL(0x00040000) /* 256 KB */ @@ -61,14 +62,18 @@ * plat_arm_mmap array defined for each BL stage. */ #if defined(IMAGE_BL31) -# if ENABLE_SPM +# if SPM_MM # define PLAT_ARM_MMAP_ENTRIES 9 # define MAX_XLAT_TABLES 9 # define PLAT_SP_IMAGE_MMAP_REGIONS 30 # define PLAT_SP_IMAGE_MAX_XLAT_TABLES 10 # else # define PLAT_ARM_MMAP_ENTRIES 8 -# define MAX_XLAT_TABLES 5 +# if USE_DEBUGFS +# define MAX_XLAT_TABLES 6 +# else +# define MAX_XLAT_TABLES 5 +# endif # endif #elif defined(IMAGE_BL32) # define PLAT_ARM_MMAP_ENTRIES 8 @@ -94,9 +99,11 @@ #if USE_ROMLIB #define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000) #define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000) +#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0x6000) #else #define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0) #define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0) +#define FVP_BL2_ROMLIB_OPTIMIZATION UL(0) #endif /* @@ -104,9 +111,9 @@ * little space for growth. */ #if TRUSTED_BOARD_BOOT -# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - FVP_BL2_ROMLIB_OPTIMIZATION) #else -# define PLAT_ARM_MAX_BL2_SIZE UL(0x11000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x11000) - FVP_BL2_ROMLIB_OPTIMIZATION) #endif /* @@ -114,11 +121,7 @@ * calculated using the current BL31 PROGBITS debug size plus the sizes of * BL2 and BL1-RW */ -#if ENABLE_SPM && !SPM_MM -#define PLAT_ARM_MAX_BL31_SIZE UL(0x60000) -#else #define PLAT_ARM_MAX_BL31_SIZE UL(0x3B000) -#endif #ifndef __aarch64__ /* diff --git a/plat/arm/board/fvp/jmptbl.i b/plat/arm/board/fvp/jmptbl.i index bfa9b561f..6ccdd283f 100644 --- a/plat/arm/board/fvp/jmptbl.i +++ b/plat/arm/board/fvp/jmptbl.i @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -19,6 +19,7 @@ fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible +fdt fdt_setprop_inplace_namelen_partial mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/fvp/platform.mk b/plat/arm/board/fvp/platform.mk index 0eb62c44a..97a326c09 100644 --- a/plat/arm/board/fvp/platform.mk +++ b/plat/arm/board/fvp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -99,26 +99,30 @@ ifeq (${ARCH}, aarch64) # select a different set of CPU files, depending on whether we compile for # hardware assisted coherency cores or not ifeq (${HW_ASSISTED_COHERENCY}, 0) +# Cores used without DSU FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a35.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ lib/cpus/aarch64/cortex_a73.S else - # AArch64-only cores +# Cores used with DSU only ifeq (${CTX_INCLUDE_AARCH32_REGS}, 0) + # AArch64-only cores FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a76.S \ lib/cpus/aarch64/cortex_a76ae.S \ lib/cpus/aarch64/cortex_a77.S \ lib/cpus/aarch64/neoverse_n1.S \ lib/cpus/aarch64/neoverse_e1.S \ lib/cpus/aarch64/neoverse_zeus.S \ - lib/cpus/aarch64/cortex_hercules.S - # AArch64/AArch32 - else - FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ - lib/cpus/aarch64/cortex_a75.S + lib/cpus/aarch64/cortex_hercules.S \ + lib/cpus/aarch64/cortex_hercules_ae.S \ + lib/cpus/aarch64/cortex_a65.S \ + lib/cpus/aarch64/cortex_a65ae.S endif + # AArch64/AArch32 cores + FVP_CPU_LIBS += lib/cpus/aarch64/cortex_a55.S \ + lib/cpus/aarch64/cortex_a75.S endif else @@ -127,6 +131,7 @@ endif BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ drivers/arm/sp805/sp805.c \ + drivers/delay_timer/delay_timer.c \ drivers/io/io_semihosting.c \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ @@ -138,6 +143,12 @@ BL1_SOURCES += drivers/arm/smmu/smmu_v3.c \ ${FVP_CPU_LIBS} \ ${FVP_INTERCONNECT_SOURCES} +ifeq (${FVP_USE_SP804_TIMER},1) +BL1_SOURCES += drivers/arm/sp804/sp804_delay_timer.c +else +BL1_SOURCES += drivers/delay_timer/generic_delay_timer.c +endif + BL2_SOURCES += drivers/arm/sp805/sp805.c \ drivers/io/io_semihosting.c \ @@ -167,8 +178,13 @@ endif BL2U_SOURCES += plat/arm/board/fvp/fvp_bl2u_setup.c \ ${FVP_SECURITY_SOURCES} +ifeq (${FVP_USE_SP804_TIMER},1) +BL2U_SOURCES += drivers/arm/sp804/sp804_delay_timer.c +endif + BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ drivers/arm/smmu/smmu_v3.c \ + drivers/delay_timer/delay_timer.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/board/fvp/fvp_bl31_setup.c \ @@ -181,6 +197,12 @@ BL31_SOURCES += drivers/arm/fvp/fvp_pwrc.c \ ${FVP_INTERCONNECT_SOURCES} \ ${FVP_SECURITY_SOURCES} +ifeq (${FVP_USE_SP804_TIMER},1) +BL31_SOURCES += drivers/arm/sp804/sp804_delay_timer.c +else +BL31_SOURCES += drivers/delay_timer/generic_delay_timer.c +endif + # Add the FDT_SOURCES and options for Dynamic Config (only for Unix env) ifdef UNIX_MK FVP_HW_CONFIG_DTS := fdts/${FVP_DT_PREFIX}.dts @@ -222,15 +244,12 @@ ENABLE_AMU := 1 # Enable dynamic mitigation support by default DYNAMIC_WORKAROUND_CVE_2018_3639 := 1 +# Enable reclaiming of BL31 initialisation code for secondary cores +# stacks for FVP. However, don't enable reclaiming for clang. ifneq (${RESET_TO_BL31},1) -# Enable reclaiming of BL31 initialisation code for secondary cores stacks for -# FVP. We cannot enable PIE for this case because the overlayed init section -# creates some dynamic relocations which cannot be handled by the fixup -# logic currently. +ifeq ($(findstring clang,$(notdir $(CC))),) RECLAIM_INIT_CODE := 1 -else -# Enable PIE support when RESET_TO_BL31=1 -ENABLE_PIE := 1 +endif endif ifeq (${ENABLE_AMU},1) @@ -264,16 +283,15 @@ else # if AArch64 ifeq (${RESET_TO_BL31},1) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif - ifeq (${ENABLE_SPM},1) - ifeq (${SPM_MM},0) - BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 - endif - endif ifeq (${SPD},trusty) BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 endif endif +ifeq (${USE_DEBUGFS},1) + BL31_CFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC=1 +endif + # Add support for platform supplied linker script for BL31 build $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) diff --git a/plat/arm/board/fvp_ve/fvp_ve_def.h b/plat/arm/board/fvp_ve/fvp_ve_def.h index 565753ae7..98de5f66e 100644 --- a/plat/arm/board/fvp_ve/fvp_ve_def.h +++ b/plat/arm/board/fvp_ve/fvp_ve_def.h @@ -10,17 +10,17 @@ #include <lib/utils_def.h> /* Default cluster count for FVP VE */ -#define FVP_VE_CLUSTER_COUNT 1 +#define FVP_VE_CLUSTER_COUNT U(1) /* Default number of CPUs per cluster on FVP VE */ -#define FVP_VE_MAX_CPUS_PER_CLUSTER 1 +#define FVP_VE_MAX_CPUS_PER_CLUSTER U(1) /* Default number of threads per CPU on FVP VE */ -#define FVP_VE_MAX_PE_PER_CPU 1 +#define FVP_VE_MAX_PE_PER_CPU U(1) -#define FVP_VE_CORE_COUNT 1 +#define FVP_VE_CORE_COUNT U(1) -#define FVP_VE_PRIMARY_CPU 0x0 +#define FVP_VE_PRIMARY_CPU 0x0 /******************************************************************************* * FVP memory map related constants diff --git a/plat/arm/board/fvp_ve/include/platform_def.h b/plat/arm/board/fvp_ve/include/platform_def.h index 4e575e1ab..1b07a9b42 100644 --- a/plat/arm/board/fvp_ve/include/platform_def.h +++ b/plat/arm/board/fvp_ve/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Arm Limited. All rights reserved. + * Copyright (c) 2019-2020, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -211,9 +211,9 @@ #define BL32_LIMIT (ARM_BL_RAM_BASE + ARM_BL_RAM_SIZE) /* Required platform porting definitions */ -#define PLATFORM_CORE_COUNT 1 +#define PLATFORM_CORE_COUNT FVP_VE_CLUSTER_COUNT #define PLAT_NUM_PWR_DOMAINS ((FVP_VE_CLUSTER_COUNT + \ - PLATFORM_CORE_COUNT) + 1) + PLATFORM_CORE_COUNT) + U(1)) #define PLAT_MAX_PWR_LVL 2 diff --git a/plat/arm/board/juno/fdts/juno_tb_fw_config.dts b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts new file mode 100644 index 000000000..a8ab6c5f9 --- /dev/null +++ b/plat/arm/board/juno/fdts/juno_tb_fw_config.dts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +/ { + /* Platform Config */ + compatible = "arm,tb_fw"; + /* Disable authentication for development */ + disable_auth = <0x0>; + /* + * The following two entries are placeholders for Mbed TLS + * heap information. The default values don't matter since + * they will be overwritten by BL1. + * In case of having shared Mbed TLS heap between BL1 and BL2, + * BL1 will populate these two properties with the respective + * info about the shared heap. This info will be available for + * BL2 in order to locate and re-use the heap. + */ + mbedtls_heap_addr = <0x0 0x0>; + mbedtls_heap_size = <0x0>; +}; diff --git a/plat/arm/board/juno/include/platform_def.h b/plat/arm/board/juno/include/platform_def.h index 83aeeb4bd..16bb33d7e 100644 --- a/plat/arm/board/juno/include/platform_def.h +++ b/plat/arm/board/juno/include/platform_def.h @@ -60,9 +60,11 @@ #if USE_ROMLIB #define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0x1000) #define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0xe000) +#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0x8000) #else #define PLAT_ARM_MAX_ROMLIB_RW_SIZE UL(0) #define PLAT_ARM_MAX_ROMLIB_RO_SIZE UL(0) +#define JUNO_BL2_ROMLIB_OPTIMIZATION UL(0) #endif /* @@ -127,14 +129,14 @@ */ #if TRUSTED_BOARD_BOOT #if TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_RSA_AND_ECDSA -# define PLAT_ARM_MAX_BL2_SIZE UL(0x1F000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1F000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #elif TF_MBEDTLS_KEY_ALG_ID == TF_MBEDTLS_ECDSA -# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #else -# define PLAT_ARM_MAX_BL2_SIZE UL(0x1D000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0x1D000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif #else -# define PLAT_ARM_MAX_BL2_SIZE UL(0xF000) +# define PLAT_ARM_MAX_BL2_SIZE (UL(0xF000) - JUNO_BL2_ROMLIB_OPTIMIZATION) #endif /* diff --git a/plat/arm/board/juno/jmptbl.i b/plat/arm/board/juno/jmptbl.i index bfa9b561f..6ccdd283f 100644 --- a/plat/arm/board/juno/jmptbl.i +++ b/plat/arm/board/juno/jmptbl.i @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -19,6 +19,7 @@ fdt fdt_getprop_namelen fdt fdt_setprop_inplace fdt fdt_check_header fdt fdt_node_offset_by_compatible +fdt fdt_setprop_inplace_namelen_partial mbedtls mbedtls_asn1_get_alg mbedtls mbedtls_asn1_get_alg_null mbedtls mbedtls_asn1_get_bitstring_null diff --git a/plat/arm/board/juno/juno_common.c b/plat/arm/board/juno/juno_common.c index 98c5d3c94..9570d2d4c 100644 --- a/plat/arm/board/juno/juno_common.c +++ b/plat/arm/board/juno/juno_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -47,6 +47,9 @@ const mmap_region_t plat_arm_mmap[] = { ARM_MAP_OPTEE_CORE_MEM, ARM_OPTEE_PAGEABLE_LOAD_MEM, #endif +#if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 + ARM_MAP_BL1_RW, +#endif {0} }; #endif diff --git a/plat/arm/board/juno/juno_def.h b/plat/arm/board/juno/juno_def.h index 7a8bedf5a..3b34a9f6a 100644 --- a/plat/arm/board/juno/juno_def.h +++ b/plat/arm/board/juno/juno_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -32,9 +32,9 @@ /******************************************************************************* * Juno topology related constants ******************************************************************************/ -#define JUNO_CLUSTER_COUNT 2 -#define JUNO_CLUSTER0_CORE_COUNT 2 -#define JUNO_CLUSTER1_CORE_COUNT 4 +#define JUNO_CLUSTER_COUNT U(2) +#define JUNO_CLUSTER0_CORE_COUNT U(2) +#define JUNO_CLUSTER1_CORE_COUNT U(4) /******************************************************************************* * TZC-400 related constants diff --git a/plat/arm/board/juno/juno_security.c b/plat/arm/board/juno/juno_security.c index 6566b15c8..32823e01c 100644 --- a/plat/arm/board/juno/juno_security.c +++ b/plat/arm/board/juno/juno_security.c @@ -3,6 +3,7 @@ * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> #include <common/debug.h> #include <drivers/arm/nic_400.h> @@ -149,6 +150,9 @@ void plat_arm_security_setup(void) #if TRUSTED_BOARD_BOOT int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) { - return get_mbedtls_heap_helper(heap_addr, heap_size); + assert(heap_addr != NULL); + assert(heap_size != NULL); + + return arm_get_mbedtls_heap(heap_addr, heap_size); } #endif diff --git a/plat/arm/board/juno/platform.mk b/plat/arm/board/juno/platform.mk index ea7f85172..bd6bae536 100644 --- a/plat/arm/board/juno/platform.mk +++ b/plat/arm/board/juno/platform.mk @@ -150,8 +150,14 @@ else endif endif +# Add the FDT_SOURCES and options for Dynamic Config +FDT_SOURCES += plat/arm/board/juno/fdts/${PLAT}_tb_fw_config.dts +TB_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_tb_fw_config.dtb + +# Add the TB_FW_CONFIG to FIP and specify the same to certtool +$(eval $(call TOOL_ADD_PAYLOAD,${TB_FW_CONFIG},--tb-fw-config)) + include plat/arm/board/common/board_common.mk include plat/arm/common/arm_common.mk include plat/arm/soc/common/soc_css.mk include plat/arm/css/common/css_common.mk - diff --git a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S index c03185aea..3da55b66f 100644 --- a/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S +++ b/plat/arm/board/n1sdp/aarch64/n1sdp_helper.S @@ -17,19 +17,20 @@ * unsigned int plat_arm_calc_core_pos(u_register_t mpidr) * * Helper function to calculate the core position. - * (ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) + - * (CPUId * N1SDP_MAX_PE_PER_CPU) + - * ThreadId + * ((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * N1SDP_MAX_CPUS_PER_CLUSTER * N1SDP_MAX_PE_PER_CPU) + + * (CPUId * N1SDP_MAX_PE_PER_CPU) + ThreadId * * which can be simplified as: * - * ((ClusterId * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * - * N1SDP_MAX_PE_PER_CPU) + ThreadId + * (((ChipId * N1SDP_MAX_CLUSTERS_PER_CHIP + ClusterId) * + * N1SDP_MAX_CPUS_PER_CLUSTER + CPUId) * N1SDP_MAX_PE_PER_CPU) + + * ThreadId * ------------------------------------------------------ */ func plat_arm_calc_core_pos - mov x3, x0 + mov x4, x0 /* * The MT bit in MPIDR is always set for n1sdp and the @@ -37,15 +38,18 @@ func plat_arm_calc_core_pos */ /* Extract individual affinity fields from MPIDR */ - ubfx x0, x3, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x1, x3, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS - ubfx x2, x3, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x0, x4, #MPIDR_AFF0_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x1, x4, #MPIDR_AFF1_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x2, x4, #MPIDR_AFF2_SHIFT, #MPIDR_AFFINITY_BITS + ubfx x3, x4, #MPIDR_AFF3_SHIFT, #MPIDR_AFFINITY_BITS /* Compute linear position */ + mov x4, #N1SDP_MAX_CLUSTERS_PER_CHIP + madd x2, x3, x4, x2 mov x4, #N1SDP_MAX_CPUS_PER_CLUSTER madd x1, x2, x4, x1 - mov x5, #N1SDP_MAX_PE_PER_CPU - madd x0, x1, x5, x0 + mov x4, #N1SDP_MAX_PE_PER_CPU + madd x0, x1, x4, x0 ret endfunc plat_arm_calc_core_pos diff --git a/plat/arm/board/n1sdp/include/platform_def.h b/plat/arm/board/n1sdp/include/platform_def.h index 7348bf5e4..6a309e8e1 100644 --- a/plat/arm/board/n1sdp/include/platform_def.h +++ b/plat/arm/board/n1sdp/include/platform_def.h @@ -27,16 +27,27 @@ #define PLAT_ARM_DRAM2_BASE ULL(0x8080000000) #define PLAT_ARM_DRAM2_SIZE ULL(0xF80000000) +/* N1SDP remote chip at 4 TB offset */ +#define PLAT_ARM_REMOTE_CHIP_OFFSET (ULL(1) << 42) + +#define N1SDP_REMOTE_DRAM1_BASE ARM_DRAM1_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DRAM1_SIZE ARM_DRAM1_SIZE + +#define N1SDP_REMOTE_DRAM2_BASE PLAT_ARM_DRAM2_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DRAM2_SIZE PLAT_ARM_DRAM2_SIZE + /* * N1SDP platform supports RDIMMs with ECC capability. To use the ECC * capability, the entire DDR memory space has to be zeroed out before - * enabling the ECC bits in DMC620. The access the complete DDR memory - * space the physical & virtual address space limits are extended to - * 40-bits. + * enabling the ECC bits in DMC620. To access the complete DDR memory + * along with remote chip's DDR memory, which is at 4 TB offset, physical + * and virtual address space limits are extended to 43-bits. */ #ifdef __aarch64__ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 40) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 40) +#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 43) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 43) #else #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) @@ -51,34 +62,36 @@ #define PLAT_ARM_TRUSTED_SRAM_SIZE 0x00080000 /* 512 KB */ #define PLAT_ARM_MAX_BL31_SIZE 0X20000 - /******************************************************************************* * N1SDP topology related constants ******************************************************************************/ -#define N1SDP_MAX_CPUS_PER_CLUSTER 2 -#define PLAT_ARM_CLUSTER_COUNT 2 -#define N1SDP_MAX_PE_PER_CPU 1 - -#define PLATFORM_CORE_COUNT (PLAT_ARM_CLUSTER_COUNT * \ +#define N1SDP_MAX_CPUS_PER_CLUSTER U(2) +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define PLAT_N1SDP_CHIP_COUNT U(2) +#define N1SDP_MAX_CLUSTERS_PER_CHIP U(2) +#define N1SDP_MAX_PE_PER_CPU U(1) + +#define PLATFORM_CORE_COUNT (PLAT_N1SDP_CHIP_COUNT * \ + PLAT_ARM_CLUSTER_COUNT * \ N1SDP_MAX_CPUS_PER_CLUSTER * \ N1SDP_MAX_PE_PER_CPU) /* System power domain level */ -#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 +#define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL3 /* * PLAT_ARM_MMAP_ENTRIES depends on the number of entries in the * plat_arm_mmap array defined for each BL stage. */ -#define PLAT_ARM_MMAP_ENTRIES 6 -#define MAX_XLAT_TABLES 7 +#define PLAT_ARM_MMAP_ENTRIES 9 +#define MAX_XLAT_TABLES 10 #define PLATFORM_STACK_SIZE 0x400 #define PLAT_ARM_NSTIMER_FRAME_ID 0 #define PLAT_CSS_MHU_BASE 0x45000000 #define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE -#define PLAT_MAX_PWR_LVL 1 +#define PLAT_MAX_PWR_LVL 2 #define PLAT_ARM_G1S_IRQS ARM_G1S_IRQS, \ CSS_IRQ_MHU @@ -88,17 +101,36 @@ #define PLAT_ARM_G0_IRQ_PROPS(grp) ARM_G0_IRQ_PROPS(grp) -#define N1SDP_DEVICE_BASE (0x08000000) -#define N1SDP_DEVICE_SIZE (0x48000000) -#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \ - N1SDP_DEVICE_BASE, \ - N1SDP_DEVICE_SIZE, \ - MT_DEVICE | MT_RW | MT_SECURE) - -#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ - ARM_DRAM1_BASE, \ - ARM_DRAM1_SIZE, \ - MT_MEMORY | MT_RW | MT_NS) +#define N1SDP_DEVICE_BASE ULL(0x08000000) +#define N1SDP_DEVICE_SIZE ULL(0x48000000) +#define N1SDP_REMOTE_DEVICE_BASE N1SDP_DEVICE_BASE + \ + PLAT_ARM_REMOTE_CHIP_OFFSET +#define N1SDP_REMOTE_DEVICE_SIZE N1SDP_DEVICE_SIZE + +#define N1SDP_MAP_DEVICE MAP_REGION_FLAT( \ + N1SDP_DEVICE_BASE, \ + N1SDP_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define ARM_MAP_DRAM1 MAP_REGION_FLAT( \ + ARM_DRAM1_BASE, \ + ARM_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define N1SDP_MAP_REMOTE_DEVICE MAP_REGION_FLAT( \ + N1SDP_REMOTE_DEVICE_BASE, \ + N1SDP_REMOTE_DEVICE_SIZE, \ + MT_DEVICE | MT_RW | MT_SECURE) + +#define N1SDP_MAP_REMOTE_DRAM1 MAP_REGION_FLAT( \ + N1SDP_REMOTE_DRAM1_BASE, \ + N1SDP_REMOTE_DRAM1_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) + +#define N1SDP_MAP_REMOTE_DRAM2 MAP_REGION_FLAT( \ + N1SDP_REMOTE_DRAM2_BASE, \ + N1SDP_REMOTE_DRAM2_SIZE, \ + MT_MEMORY | MT_RW | MT_NS) /* GIC related constants */ #define PLAT_ARM_GICD_BASE 0x30000000 diff --git a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c index 632af7b40..b150b8959 100644 --- a/plat/arm/board/n1sdp/n1sdp_bl31_setup.c +++ b/plat/arm/board/n1sdp/n1sdp_bl31_setup.c @@ -1,15 +1,16 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <platform_def.h> +#include <common/debug.h> #include <drivers/arm/css/css_mhu_doorbell.h> #include <drivers/arm/css/scmi.h> #include <drivers/arm/css/sds.h> -#include <common/debug.h> +#include <drivers/arm/gic600_multichip.h> #include <lib/mmio.h> #include <lib/utils.h> #include <plat/arm/common/plat_arm.h> @@ -17,14 +18,22 @@ #include "n1sdp_def.h" /* - * Memory information structure stored in SDS. - * This structure holds the total DDR memory size which will be - * used when zeroing out the entire DDR memory before enabling - * the ECC capability in DMCs. + * Platform information structure stored in SDS. + * This structure holds information about platform's DDR + * size which will be used to zero out the memory before + * enabling the ECC capability as well as information + * about multichip setup + * - multichip mode + * - slave_count + * - Local DDR size in GB, DDR memory in master board + * - Remote DDR size in GB, DDR memory in slave board */ -struct n1sdp_mem_info { - uint32_t ddr_size_gb; -}; +struct n1sdp_plat_info { + bool multichip_mode; + uint8_t slave_count; + uint8_t local_ddr_size; + uint8_t remote_ddr_size; +} __packed; /* * BL33 image information structure stored in SDS. @@ -38,11 +47,31 @@ struct n1sdp_bl33_info { }; static scmi_channel_plat_info_t n1sdp_scmi_plat_info = { - .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, - .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, - .db_preserve_mask = 0xfffffffe, - .db_modify_mask = 0x1, - .ring_doorbell = &mhu_ring_doorbell, + .scmi_mbx_mem = N1SDP_SCMI_PAYLOAD_BASE, + .db_reg_addr = PLAT_CSS_MHU_BASE + CSS_SCMI_MHU_DB_REG_OFF, + .db_preserve_mask = 0xfffffffe, + .db_modify_mask = 0x1, + .ring_doorbell = &mhu_ring_doorbell +}; + +static struct gic600_multichip_data n1sdp_multichip_data __init = { + .rt_owner_base = PLAT_ARM_GICD_BASE, + .rt_owner = 0, + .chip_count = 1, + .chip_addrs = { + PLAT_ARM_GICD_BASE >> 16, + PLAT_ARM_GICD_BASE >> 16 + }, + .spi_ids = { + {32, 255}, + {0, 0} + } +}; + +static uintptr_t n1sdp_multichip_gicr_frames[3] = { + PLAT_ARM_GICR_BASE, + PLAT_ARM_GICR_BASE + PLAT_ARM_REMOTE_CHIP_OFFSET, + 0 }; scmi_channel_plat_info_t *plat_css_get_scmi_info() @@ -66,7 +95,7 @@ const plat_psci_ops_t *plat_arm_psci_override_pm_ops(plat_psci_ops_t *ops) * from IOFPGA-DDR3 memory to main DDR4 memory. */ -void dmc_ecc_setup(uint32_t ddr_size_gb) +void dmc_ecc_setup(uint8_t ddr_size_gb) { uint64_t dram2_size; @@ -93,6 +122,38 @@ void dmc_ecc_setup(uint32_t ddr_size_gb) mmio_write_32(N1SDP_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); } +void remote_dmc_ecc_setup(uint8_t remote_ddr_size) +{ + uint64_t remote_dram2_size; + + remote_dram2_size = (remote_ddr_size * 1024UL * 1024UL * 1024UL) - + N1SDP_REMOTE_DRAM1_SIZE; + /* multichip setup */ + INFO("Zeroing remote DDR memories\n"); + zero_normalmem((void *)N1SDP_REMOTE_DRAM1_BASE, + N1SDP_REMOTE_DRAM1_SIZE); + flush_dcache_range(N1SDP_REMOTE_DRAM1_BASE, N1SDP_REMOTE_DRAM1_SIZE); + zero_normalmem((void *)N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size); + flush_dcache_range(N1SDP_REMOTE_DRAM2_BASE, remote_dram2_size); + + INFO("Enabling ECC on remote DMCs\n"); + /* Set DMCs to CONFIG state before writing ERR0CTLR0 register */ + mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, + N1SDP_DMC_MEMC_CMD_CONFIG); + mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, + N1SDP_DMC_MEMC_CMD_CONFIG); + + /* Enable ECC in DMCs */ + mmio_setbits_32(N1SDP_REMOTE_DMC0_ERR0CTLR0_REG, + N1SDP_DMC_ERR0CTLR0_ECC_EN); + mmio_setbits_32(N1SDP_REMOTE_DMC1_ERR0CTLR0_REG, + N1SDP_DMC_ERR0CTLR0_ECC_EN); + + /* Set DMCs to READY state */ + mmio_write_32(N1SDP_REMOTE_DMC0_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); + mmio_write_32(N1SDP_REMOTE_DMC1_MEMC_CMD_REG, N1SDP_DMC_MEMC_CMD_READY); +} + void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) { uint32_t i; @@ -109,30 +170,53 @@ void copy_bl33(uint32_t src, uint32_t dst, uint32_t size) } } +void n1sdp_bl31_multichip_setup(void) +{ + plat_arm_override_gicr_frames(n1sdp_multichip_gicr_frames); + gic600_multichip_init(&n1sdp_multichip_data); +} + void bl31_platform_setup(void) { int ret; - struct n1sdp_mem_info mem_info; + struct n1sdp_plat_info plat_info; struct n1sdp_bl33_info bl33_info; - arm_bl31_platform_setup(); - ret = sds_init(); if (ret != SDS_OK) { ERROR("SDS initialization failed\n"); panic(); } - ret = sds_struct_read(N1SDP_SDS_MEM_INFO_STRUCT_ID, - N1SDP_SDS_MEM_INFO_OFFSET, - &mem_info, - N1SDP_SDS_MEM_INFO_SIZE, + ret = sds_struct_read(N1SDP_SDS_PLATFORM_INFO_STRUCT_ID, + N1SDP_SDS_PLATFORM_INFO_OFFSET, + &plat_info, + N1SDP_SDS_PLATFORM_INFO_SIZE, SDS_ACCESS_MODE_NON_CACHED); if (ret != SDS_OK) { - ERROR("Error getting memory info from SDS\n"); + ERROR("Error getting platform info from SDS\n"); panic(); } - dmc_ecc_setup(mem_info.ddr_size_gb); + /* Validate plat_info SDS */ + if ((plat_info.local_ddr_size == 0) + || (plat_info.local_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) + || (plat_info.remote_ddr_size > N1SDP_MAX_DDR_CAPACITY_GB) + || (plat_info.slave_count > N1SDP_MAX_SLAVE_COUNT)) { + ERROR("platform info SDS is corrupted\n"); + panic(); + } + + if (plat_info.multichip_mode) { + n1sdp_multichip_data.chip_count = plat_info.slave_count + 1; + n1sdp_bl31_multichip_setup(); + } + arm_bl31_platform_setup(); + + dmc_ecc_setup(plat_info.local_ddr_size); + + /* Check if remote memory is present */ + if ((plat_info.multichip_mode) && (plat_info.remote_ddr_size != 0)) + remote_dmc_ecc_setup(plat_info.remote_ddr_size); ret = sds_struct_read(N1SDP_SDS_BL33_INFO_STRUCT_ID, N1SDP_SDS_BL33_INFO_OFFSET, @@ -147,11 +231,11 @@ void bl31_platform_setup(void) bl33_info.bl33_dst_addr, bl33_info.bl33_size); /* - * Pass DDR memory size info to BL33. This method is followed as + * Pass platform information to BL33. This method is followed as * currently there is no BL1/BL2 involved in boot flow of N1SDP. * When TBBR is implemented for N1SDP, this method should be removed - * and DDR memory size shoule be passed to BL33 using NT_FW_CONFIG + * and platform information should be passed to BL33 using NT_FW_CONFIG * passing mechanism. */ - mmio_write_32(N1SDP_DDR_MEM_INFO_BASE, mem_info.ddr_size_gb); + mmio_write_32(N1SDP_PLATFORM_INFO_BASE, *(uint32_t *)&plat_info); } diff --git a/plat/arm/board/n1sdp/n1sdp_def.h b/plat/arm/board/n1sdp/n1sdp_def.h index d43c5a47b..30e29a758 100644 --- a/plat/arm/board/n1sdp/n1sdp_def.h +++ b/plat/arm/board/n1sdp/n1sdp_def.h @@ -15,10 +15,12 @@ N1SDP_NS_SRAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) -/* SDS memory information defines */ -#define N1SDP_SDS_MEM_INFO_STRUCT_ID 8 -#define N1SDP_SDS_MEM_INFO_OFFSET 0 -#define N1SDP_SDS_MEM_INFO_SIZE 4 +/* SDS Platform information defines */ +#define N1SDP_SDS_PLATFORM_INFO_STRUCT_ID 8 +#define N1SDP_SDS_PLATFORM_INFO_OFFSET 0 +#define N1SDP_SDS_PLATFORM_INFO_SIZE 4 +#define N1SDP_MAX_DDR_CAPACITY_GB 64 +#define N1SDP_MAX_SLAVE_COUNT 16 /* SDS BL33 image information defines */ #define N1SDP_SDS_BL33_INFO_STRUCT_ID 9 @@ -33,6 +35,18 @@ #define N1SDP_DMC0_ERR0CTLR0_REG 0x4E000708 #define N1SDP_DMC1_ERR0CTLR0_REG 0x4E100708 +/* Remote DMC memory command registers */ +#define N1SDP_REMOTE_DMC0_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC0_MEMC_CMD_REG +#define N1SDP_REMOTE_DMC1_MEMC_CMD_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC1_MEMC_CMD_REG + +/* Remote DMC ERR0CTLR0 registers */ +#define N1SDP_REMOTE_DMC0_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC0_ERR0CTLR0_REG +#define N1SDP_REMOTE_DMC1_ERR0CTLR0_REG PLAT_ARM_REMOTE_CHIP_OFFSET +\ + N1SDP_DMC1_ERR0CTLR0_REG + /* DMC memory commands */ #define N1SDP_DMC_MEMC_CMD_CONFIG 0 #define N1SDP_DMC_MEMC_CMD_READY 3 @@ -40,7 +54,7 @@ /* DMC ECC enable bit in ERR0CTLR0 register */ #define N1SDP_DMC_ERR0CTLR0_ECC_EN 0x1 -/* Base address of non-secure SRAM where DDR memory size will be filled */ -#define N1SDP_DDR_MEM_INFO_BASE 0x06008000 +/* Base address of non-secure SRAM where Platform information will be filled */ +#define N1SDP_PLATFORM_INFO_BASE 0x06008000 #endif /* N1SDP_DEF_H */ diff --git a/plat/arm/board/n1sdp/n1sdp_plat.c b/plat/arm/board/n1sdp/n1sdp_plat.c index a32ca7251..951a562f2 100644 --- a/plat/arm/board/n1sdp/n1sdp_plat.c +++ b/plat/arm/board/n1sdp/n1sdp_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,9 @@ const mmap_region_t plat_arm_mmap[] = { N1SDP_MAP_NS_SRAM, ARM_MAP_DRAM1, ARM_MAP_DRAM2, + N1SDP_MAP_REMOTE_DEVICE, + N1SDP_MAP_REMOTE_DRAM1, + N1SDP_MAP_REMOTE_DRAM2, {0} }; diff --git a/plat/arm/board/n1sdp/n1sdp_topology.c b/plat/arm/board/n1sdp/n1sdp_topology.c index edf117099..5c2db71b7 100644 --- a/plat/arm/board/n1sdp/n1sdp_topology.c +++ b/plat/arm/board/n1sdp/n1sdp_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,11 @@ typedef struct n1sdp_topology { * indices returned by plat_core_pos_by_mpidr(). */ const unsigned char n1sdp_pd_tree_desc[] = { + PLAT_N1SDP_CHIP_COUNT, PLAT_ARM_CLUSTER_COUNT, + PLAT_ARM_CLUSTER_COUNT, + N1SDP_MAX_CPUS_PER_CLUSTER, + N1SDP_MAX_CPUS_PER_CLUSTER, N1SDP_MAX_CPUS_PER_CLUSTER, N1SDP_MAX_CPUS_PER_CLUSTER }; @@ -52,4 +56,4 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) * to the SCMI power domain ID implemented by SCP. ******************************************************************************/ const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[PLATFORM_CORE_COUNT] = { - 0, 1, 2, 3}; + 0, 1, 2, 3, 4, 5, 6, 7}; diff --git a/plat/arm/board/n1sdp/platform.mk b/plat/arm/board/n1sdp/platform.mk index 986bd70a5..8816670dc 100644 --- a/plat/arm/board/n1sdp/platform.mk +++ b/plat/arm/board/n1sdp/platform.mk @@ -18,6 +18,7 @@ N1SDP_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S N1SDP_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gic600_multichip.c \ plat/common/plat_gicv3.c \ plat/arm/common/arm_gicv3.c \ drivers/arm/gic/v3/gic600.c diff --git a/plat/arm/board/rde1edge/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index 50b04f049..2be3f8852 100644 --- a/plat/arm/board/rde1edge/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -11,9 +11,9 @@ #include <sgi_base_platform_def.h> -#define PLAT_ARM_CLUSTER_COUNT 2 -#define CSS_SGI_MAX_CPUS_PER_CLUSTER 8 -#define CSS_SGI_MAX_PE_PER_CPU 2 +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(8) +#define CSS_SGI_MAX_PE_PER_CPU U(2) #define PLAT_CSS_MHU_BASE UL(0x45400000) #define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE diff --git a/plat/arm/board/rde1edge/platform.mk b/plat/arm/board/rde1edge/platform.mk index db41e0eda..43c37ffc1 100644 --- a/plat/arm/board/rde1edge/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, Arm Limited. All rights reserved. +# Copyright (c) 2018-2020, Arm Limited. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -24,6 +24,7 @@ BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_plat.c \ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDE1EDGE_BASE}/rde1edge_plat.c \ + ${RDE1EDGE_BASE}/rde1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c diff --git a/plat/arm/board/rde1edge/rde1edge_topology.c b/plat/arm/board/rde1edge/rde1edge_topology.c new file mode 100644 index 000000000..0b56f208a --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_topology.c @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +static const unsigned char rde1edge_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/****************************************************************************** + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rde1edge_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ + 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 +}; diff --git a/plat/arm/board/rdn1edge/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index 580ab8e6f..c635faa44 100644 --- a/plat/arm/board/rdn1edge/include/platform_def.h +++ b/plat/arm/board/rdn1edge/include/platform_def.h @@ -11,9 +11,9 @@ #include <sgi_base_platform_def.h> -#define PLAT_ARM_CLUSTER_COUNT 2 -#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4 -#define CSS_SGI_MAX_PE_PER_CPU 1 +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) +#define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45400000) #define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE diff --git a/plat/arm/board/rdn1edge/platform.mk b/plat/arm/board/rdn1edge/platform.mk index b44c70a3b..ca1e95eaf 100644 --- a/plat/arm/board/rdn1edge/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -24,6 +24,7 @@ BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_plat.c \ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${RDN1EDGE_BASE}/rdn1edge_plat.c \ + ${RDN1EDGE_BASE}/rdn1edge_topology.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c diff --git a/plat/arm/board/rdn1edge/rdn1edge_topology.c b/plat/arm/board/rdn1edge/rdn1edge_topology.c new file mode 100644 index 000000000..687ae3595 --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_topology.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +static const unsigned char rdn1edge_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return rdn1edge_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + 0, 1, 2, 3, 4, 5, 6, 7 +}; diff --git a/plat/arm/board/sgi575/include/platform_def.h b/plat/arm/board/sgi575/include/platform_def.h index f00146f99..fd59e5277 100644 --- a/plat/arm/board/sgi575/include/platform_def.h +++ b/plat/arm/board/sgi575/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,9 +11,9 @@ #include <sgi_base_platform_def.h> -#define PLAT_ARM_CLUSTER_COUNT 2 -#define CSS_SGI_MAX_CPUS_PER_CLUSTER 4 -#define CSS_SGI_MAX_PE_PER_CPU 1 +#define PLAT_ARM_CLUSTER_COUNT U(2) +#define CSS_SGI_MAX_CPUS_PER_CLUSTER U(4) +#define CSS_SGI_MAX_PE_PER_CPU U(1) #define PLAT_CSS_MHU_BASE UL(0x45000000) #define PLAT_MHUV2_BASE PLAT_CSS_MHU_BASE diff --git a/plat/arm/board/sgi575/platform.mk b/plat/arm/board/sgi575/platform.mk index b9fa0995d..ce2717fe0 100644 --- a/plat/arm/board/sgi575/platform.mk +++ b/plat/arm/board/sgi575/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -24,6 +24,7 @@ BL2_SOURCES += ${SGI575_BASE}/sgi575_plat.c \ BL31_SOURCES += ${SGI_CPU_SOURCES} \ ${SGI575_BASE}/sgi575_plat.c \ + ${SGI575_BASE}/sgi575_topology.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c diff --git a/plat/arm/board/sgi575/sgi575_topology.c b/plat/arm/board/sgi575/sgi575_topology.c new file mode 100644 index 000000000..f7c385673 --- /dev/null +++ b/plat/arm/board/sgi575/sgi575_topology.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019-2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <plat/arm/common/plat_arm.h> + +/****************************************************************************** + * The power domain tree descriptor. + ******************************************************************************/ +static const unsigned char sgi575_pd_tree_desc[] = { + PLAT_ARM_CLUSTER_COUNT, + CSS_SGI_MAX_CPUS_PER_CLUSTER, + CSS_SGI_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return sgi575_pd_tree_desc; +} + +/******************************************************************************* + * The array mapping platform core position (implemented by plat_my_core_pos()) + * to the SCMI power domain ID implemented by SCP. + ******************************************************************************/ +const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[] = { + 0, 1, 2, 3, 4, 5, 6, 7 +}; diff --git a/plat/arm/board/sgm775/include/platform_def.h b/plat/arm/board/sgm775/include/platform_def.h index 27d1b3304..d165ff9ed 100644 --- a/plat/arm/board/sgm775/include/platform_def.h +++ b/plat/arm/board/sgm775/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -9,8 +9,8 @@ #include <sgm_base_platform_def.h> -#define PLAT_MAX_CPUS_PER_CLUSTER 8 -#define PLAT_MAX_PE_PER_CPU 1 +#define PLAT_MAX_CPUS_PER_CLUSTER U(8) +#define PLAT_MAX_PE_PER_CPU U(1) /* * Physical and virtual address space limits for MMU in AARCH64 & AARCH32 modes diff --git a/plat/arm/common/aarch64/arm_ehf.c b/plat/arm/common/aarch64/arm_ehf.c index 4ae992c95..69ebd798f 100644 --- a/plat/arm/common/aarch64/arm_ehf.c +++ b/plat/arm/common/aarch64/arm_ehf.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,7 +24,7 @@ ehf_pri_desc_t arm_exceptions[] = { /* Normal priority SDEI */ EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SDEI_NORMAL_PRI), #endif -#if ENABLE_SPM +#if SPM_MM EHF_PRI_DESC(ARM_PRI_BITS, PLAT_SP_PRI), #endif }; diff --git a/plat/arm/common/aarch64/arm_pauth.c b/plat/arm/common/aarch64/arm_pauth.c index a685c319d..7cea8a0c9 100644 --- a/plat/arm/common/aarch64/arm_pauth.c +++ b/plat/arm/common/aarch64/arm_pauth.c @@ -4,27 +4,25 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <arch_helpers.h> #include <cdefs.h> #include <stdint.h> /* - * Instruction pointer authentication key A. The low 64-bit are at [0], and the - * high bits at [1]. + * This is only a toy implementation to generate a seemingly random + * 128-bit key from sp, x30 and cntpct_el0 values. + * A production system must re-implement this function to generate + * keys from a reliable randomness source. */ -uint64_t plat_apiakey[2]; - -/* - * This is only a toy implementation to generate a seemingly random 128-bit key - * from sp and x30 values. A production system must re-implement this function - * to generate keys from a reliable randomness source. - */ -uint64_t *plat_init_apiakey(void) +uint128_t plat_init_apkey(void) { - uintptr_t return_addr = (uintptr_t)__builtin_return_address(0U); - uintptr_t frame_addr = (uintptr_t)__builtin_frame_address(0U); + uint64_t return_addr = (uint64_t)__builtin_return_address(0U); + uint64_t frame_addr = (uint64_t)__builtin_frame_address(0U); + uint64_t cntpct = read_cntpct_el0(); - plat_apiakey[0] = (return_addr << 13) ^ frame_addr; - plat_apiakey[1] = (frame_addr << 15) ^ return_addr; + /* Generate 128-bit key */ + uint64_t key_lo = (return_addr << 13) ^ frame_addr ^ cntpct; + uint64_t key_hi = (frame_addr << 15) ^ return_addr ^ cntpct; - return plat_apiakey; + return ((uint128_t)(key_hi) << 64) | key_lo; } diff --git a/plat/arm/common/execution_state_switch.c b/plat/arm/common/aarch64/execution_state_switch.c index 00ac16ef0..8835fa135 100644 --- a/plat/arm/common/execution_state_switch.c +++ b/plat/arm/common/aarch64/execution_state_switch.c @@ -39,8 +39,6 @@ int arm_execution_state_switch(unsigned int smc_fid, uint32_t cookie_lo, void *handle) { - /* Execution state can be switched only if EL3 is AArch64 */ -#ifdef __aarch64__ bool caller_64, thumb = false, from_el2; unsigned int el, endianness; u_register_t spsr, pc, scr, sctlr; @@ -48,6 +46,11 @@ int arm_execution_state_switch(unsigned int smc_fid, cpu_context_t *ctx = (cpu_context_t *) handle; el3_state_t *el3_ctx = get_el3state_ctx(ctx); + /* Validate supplied entry point */ + pc = (u_register_t) (((uint64_t) pc_hi << 32) | pc_lo); + if (arm_validate_ns_entrypoint(pc) != 0) + goto invalid_param; + /* That the SMC originated from NS is already validated by the caller */ /* @@ -173,7 +176,6 @@ invalid_param: SMC_RET1(handle, STATE_SW_E_PARAM); exec_denied: -#endif /* __aarch64__ */ /* State switch denied */ SMC_RET1(handle, STATE_SW_E_DENIED); } diff --git a/plat/arm/common/arm_bl31_setup.c b/plat/arm/common/arm_bl31_setup.c index ab90f46a8..939885f98 100644 --- a/plat/arm/common/arm_bl31_setup.c +++ b/plat/arm/common/arm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <common/bl_common.h> #include <common/debug.h> #include <drivers/console.h> +#include <lib/debugfs.h> #include <lib/extensions/ras.h> #include <lib/mmio.h> #include <lib/utils.h> @@ -231,6 +232,10 @@ void arm_bl31_platform_setup(void) #if RAS_EXTENSION ras_init(); #endif + +#if USE_DEBUGFS + debugfs_init(); +#endif /* USE_DEBUGFS */ } /******************************************************************************* diff --git a/plat/arm/common/arm_common.c b/plat/arm/common/arm_common.c index bc0cf9a85..255e6b421 100644 --- a/plat/arm/common/arm_common.c +++ b/plat/arm/common/arm_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,7 @@ #include <lib/xlat_tables/xlat_tables_compat.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> -#include <services/secure_partition.h> +#include <services/spm_mm_partition.h> /* Weak definitions may be overridden in specific ARM standard platform */ #pragma weak plat_get_ns_image_entrypoint @@ -173,7 +173,7 @@ unsigned int plat_get_syscnt_freq2(void) int plat_sdei_validate_entry_point(uintptr_t ep, unsigned int client_mode) { uint64_t par, pa; - uint32_t scr_el3; + u_register_t scr_el3; /* Doing Non-secure address translation requires SCR_EL3.NS set */ scr_el3 = read_scr_el3(); diff --git a/plat/arm/common/arm_common.mk b/plat/arm/common/arm_common.mk index 10b6e5122..c8b7ab448 100644 --- a/plat/arm/common/arm_common.mk +++ b/plat/arm/common/arm_common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -130,6 +130,11 @@ ARM_CRYPTOCELL_INTEG := 0 $(eval $(call assert_boolean,ARM_CRYPTOCELL_INTEG)) $(eval $(call add_define,ARM_CRYPTOCELL_INTEG)) +# Enable PIE support for RESET_TO_BL31 case +ifeq (${RESET_TO_BL31},1) + ENABLE_PIE := 1 +endif + # CryptoCell integration relies on coherent buffers for passing data from # the AP CPU to the CryptoCell ifeq (${ARM_CRYPTOCELL_INTEG},1) @@ -210,12 +215,17 @@ BL2U_SOURCES += drivers/delay_timer/delay_timer.c \ BL31_SOURCES += plat/arm/common/arm_bl31_setup.c \ plat/arm/common/arm_pm.c \ plat/arm/common/arm_topology.c \ - plat/arm/common/execution_state_switch.c \ plat/common/plat_psci_common.c ifeq (${ENABLE_PMF}, 1) -BL31_SOURCES += plat/arm/common/arm_sip_svc.c \ +ifeq (${ARCH}, aarch64) +BL31_SOURCES += plat/arm/common/aarch64/execution_state_switch.c\ + plat/arm/common/arm_sip_svc.c \ lib/pmf/pmf_smc.c +else +BL32_SOURCES += plat/arm/common/arm_sip_svc.c \ + lib/pmf/pmf_smc.c +endif endif ifeq (${EL3_EXCEPTION_HANDLING},1) @@ -234,17 +244,8 @@ endif # Pointer Authentication sources ifeq (${ENABLE_PAUTH}, 1) -PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c -endif - -# SPM uses libfdt in Arm platforms -ifeq (${SPM_MM},0) -ifeq (${ENABLE_SPM},1) -BL31_SOURCES += common/fdt_wrappers.c \ - plat/common/plat_spm_rd.c \ - plat/common/plat_spm_sp.c \ - ${LIBFDT_SRCS} -endif +PLAT_BL_COMMON_SOURCES += plat/arm/common/aarch64/arm_pauth.c \ + lib/extensions/pauth/pauth_helpers.S endif ifneq (${TRUSTED_BOARD_BOOT},0) @@ -253,7 +254,13 @@ ifneq (${TRUSTED_BOARD_BOOT},0) AUTH_SOURCES := drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c \ + + # Include the selected chain of trust sources. + ifeq (${COT},tbbr) + AUTH_SOURCES += drivers/auth/tbbr/tbbr_cot.c + else + $(error Unknown chain of trust ${COT}) + endif BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ diff --git a/plat/arm/common/arm_dyn_cfg.c b/plat/arm/common/arm_dyn_cfg.c index 9a5364952..e6c5a7361 100644 --- a/plat/arm/common/arm_dyn_cfg.c +++ b/plat/arm/common/arm_dyn_cfg.c @@ -1,11 +1,12 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> #include <string.h> +#include <libfdt.h> #include <platform_def.h> @@ -21,8 +22,6 @@ /* Variable to store the address to TB_FW_CONFIG passed from BL1 */ static void *tb_fw_cfg_dtb; -static size_t tb_fw_cfg_dtb_size; - #if TRUSTED_BOARD_BOOT @@ -110,7 +109,7 @@ void arm_bl1_set_mbedtls_heap(void) * without the heap info. */ flush_dcache_range((uintptr_t)tb_fw_cfg_dtb, - tb_fw_cfg_dtb_size); + fdt_totalsize(tb_fw_cfg_dtb)); } } @@ -146,7 +145,6 @@ void arm_load_tb_fw_config(void) /* At this point we know that a DTB is indeed available */ config_base = arm_tb_fw_info.image_info.image_base; tb_fw_cfg_dtb = (void *)config_base; - tb_fw_cfg_dtb_size = (size_t)arm_tb_fw_info.image_info.image_max_size; /* The BL2 ep_info arg0 is modified to point to TB_FW_CONFIG */ desc = bl1_plat_get_image_desc(BL2_IMAGE_ID); @@ -245,7 +243,8 @@ void arm_bl2_dyn_cfg_init(void) #ifdef BL31_BASE /* Ensure the configs don't overlap with BL31 */ - if ((image_base > BL31_BASE) || ((image_base + image_size) > BL31_BASE)) + if ((image_base >= BL31_BASE) && + (image_base <= BL31_LIMIT)) continue; #endif /* Ensure the configs are loaded in a valid address */ @@ -256,7 +255,8 @@ void arm_bl2_dyn_cfg_init(void) * If BL32 is present, ensure that the configs don't * overlap with it. */ - if (image_base >= BL32_BASE && image_base <= BL32_LIMIT) + if ((image_base >= BL32_BASE) && + (image_base <= BL32_LIMIT)) continue; #endif } @@ -265,7 +265,10 @@ void arm_bl2_dyn_cfg_init(void) cfg_mem_params->image_info.image_base = (uintptr_t)image_base; cfg_mem_params->image_info.image_max_size = image_size; - /* Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from HW_CONFIG node */ + /* + * Remove the IMAGE_ATTRIB_SKIP_LOADING attribute from + * HW_CONFIG or FW_CONFIG nodes + */ cfg_mem_params->image_info.h.attr &= ~IMAGE_ATTRIB_SKIP_LOADING; } diff --git a/plat/arm/common/arm_gicv3.c b/plat/arm/common/arm_gicv3.c index 7f4957fa9..4a3a22ec0 100644 --- a/plat/arm/common/arm_gicv3.c +++ b/plat/arm/common/arm_gicv3.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> #include <platform_def.h> #include <common/interrupt_props.h> @@ -27,6 +28,15 @@ /* The GICv3 driver only needs to be initialized in EL3 */ static uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +/* Default GICR base address to be used for GICR probe. */ +static const uintptr_t gicr_base_addrs[2] = { + PLAT_ARM_GICR_BASE, /* GICR Base address of the primary CPU */ + 0U /* Zero Termination */ +}; + +/* List of zero terminated GICR frame addresses which CPUs will probe */ +static const uintptr_t *gicr_frames = gicr_base_addrs; + static const interrupt_prop_t arm_interrupt_props[] = { PLAT_ARM_G1S_IRQ_PROPS(INTR_GROUP1S), PLAT_ARM_G0_IRQ_PROPS(INTR_GROUP0) @@ -34,12 +44,11 @@ static const interrupt_prop_t arm_interrupt_props[] = { /* * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory. The `volatile` - * is used to prevent the compiler from removing the gicv3 contexts even - * though the DEFINE_LOAD_SYM_ADDR creates a dummy reference to it. + * data in the designated EL3 Secure carve-out memory. The `used` attribute + * is used to prevent the compiler from removing the gicv3 contexts. */ -static volatile gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -static volatile gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); +static gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram") __used; +static gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram") __used; /* Define accessor function to get reference to the GICv3 context */ DEFINE_LOAD_SYM_ADDR(rdist_ctx) @@ -67,7 +76,7 @@ static unsigned int arm_gicv3_mpidr_hash(u_register_t mpidr) static const gicv3_driver_data_t arm_gic_data __unused = { .gicd_base = PLAT_ARM_GICD_BASE, - .gicr_base = PLAT_ARM_GICR_BASE, + .gicr_base = 0U, .interrupt_props = arm_interrupt_props, .interrupt_props_num = ARRAY_SIZE(arm_interrupt_props), .rdistif_num = PLATFORM_CORE_COUNT, @@ -75,6 +84,18 @@ static const gicv3_driver_data_t arm_gic_data __unused = { .mpidr_to_core_pos = arm_gicv3_mpidr_hash }; +/* + * By default, gicr_frames will be pointing to gicr_base_addrs. If + * the platform supports a non-contiguous GICR frames (GICR frames located + * at uneven offset), plat_arm_override_gicr_frames function can be used by + * such platform to override the gicr_frames. + */ +void plat_arm_override_gicr_frames(const uintptr_t *plat_gicr_frames) +{ + assert(plat_gicr_frames != NULL); + gicr_frames = plat_gicr_frames; +} + void __init plat_arm_gic_driver_init(void) { /* @@ -86,6 +107,11 @@ void __init plat_arm_gic_driver_init(void) #if (!defined(__aarch64__) && defined(IMAGE_BL32)) || \ (defined(__aarch64__) && defined(IMAGE_BL31)) gicv3_driver_init(&arm_gic_data); + + if (gicv3_rdistif_probe(gicr_base_addrs[0]) == -1) { + ERROR("No GICR base frame found for Primary CPU\n"); + panic(); + } #endif } @@ -116,10 +142,29 @@ void plat_arm_gic_cpuif_disable(void) } /****************************************************************************** - * ARM common helper to initialize the per-cpu redistributor interface in GICv3 + * ARM common helper function to iterate over all GICR frames and discover the + * corresponding per-cpu redistributor frame as well as initialize the + * corresponding interface in GICv3. *****************************************************************************/ void plat_arm_gic_pcpu_init(void) { + int result; + const uintptr_t *plat_gicr_frames = gicr_frames; + + do { + result = gicv3_rdistif_probe(*plat_gicr_frames); + + /* If the probe is successful, no need to proceed further */ + if (result == 0) + break; + + plat_gicr_frames++; + } while (*plat_gicr_frames != 0U); + + if (result == -1) { + ERROR("No GICR base frame found for CPU 0x%lx\n", read_mpidr()); + panic(); + } gicv3_rdistif_init(plat_my_core_pos()); } diff --git a/plat/arm/common/arm_sip_svc.c b/plat/arm/common/arm_sip_svc.c index 3d308a335..9f5d4557c 100644 --- a/plat/arm/common/arm_sip_svc.c +++ b/plat/arm/common/arm_sip_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,6 +8,7 @@ #include <common/debug.h> #include <common/runtime_svc.h> +#include <lib/debugfs.h> #include <lib/pmf/pmf.h> #include <plat/arm/common/arm_sip_svc.h> #include <plat/arm/common/plat_arm.h> @@ -20,8 +21,18 @@ DEFINE_SVC_UUID2(arm_sip_svc_uid, static int arm_sip_setup(void) { - if (pmf_setup() != 0) + if (pmf_setup() != 0) { return 1; + } + +#if USE_DEBUGFS + + if (debugfs_smc_setup() != 0) { + return 1; + } + +#endif /* USE_DEBUGFS */ + return 0; } @@ -48,25 +59,33 @@ static uintptr_t arm_sip_handler(unsigned int smc_fid, handle, flags); } +#if USE_DEBUGFS + + if (is_debugfs_fid(smc_fid)) { + return debugfs_smc_handler(smc_fid, x1, x2, x3, x4, cookie, + handle, flags); + } + +#endif /* USE_DEBUGFS */ + switch (smc_fid) { case ARM_SIP_SVC_EXE_STATE_SWITCH: { - u_register_t pc; - + /* Execution state can be switched only if EL3 is AArch64 */ +#ifdef __aarch64__ /* Allow calls from non-secure only */ if (!is_caller_non_secure(flags)) SMC_RET1(handle, STATE_SW_E_DENIED); - /* Validate supplied entry point */ - pc = (u_register_t) ((x1 << 32) | (uint32_t) x2); - if (arm_validate_ns_entrypoint(pc) != 0) - SMC_RET1(handle, STATE_SW_E_PARAM); - /* * Pointers used in execution state switch are all 32 bits wide */ return (uintptr_t) arm_execution_state_switch(smc_fid, (uint32_t) x1, (uint32_t) x2, (uint32_t) x3, (uint32_t) x4, handle); +#else + /* State switch denied */ + SMC_RET1(handle, STATE_SW_E_DENIED); +#endif /* __aarch64__ */ } case ARM_SIP_SVC_CALL_COUNT: diff --git a/plat/arm/common/arm_topology.c b/plat/arm/common/arm_topology.c index 37047bcf3..c9993a725 100644 --- a/plat/arm/common/arm_topology.c +++ b/plat/arm/common/arm_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -24,7 +24,8 @@ int arm_check_mpidr(u_register_t mpidr) valid_mask = ~(MPIDR_AFFLVL_MASK | (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) | - (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT)); + (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT) | + (MPIDR_AFFLVL_MASK << MPIDR_AFF3_SHIFT)); cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK; cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; pe_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; diff --git a/plat/arm/css/common/css_pm.c b/plat/arm/css/common/css_pm.c index f6fc6aa7a..01c674f82 100644 --- a/plat/arm/css/common/css_pm.c +++ b/plat/arm/css/common/css_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -76,9 +76,6 @@ static void css_pwr_domain_on_finisher_common( { assert(CSS_CORE_PWR_STATE(target_state) == ARM_LOCAL_STATE_OFF); - /* Enable the gic cpu interface */ - plat_arm_gic_cpuif_enable(); - /* * Perform the common cluster specific operations i.e enable coherency * if this cluster was off. @@ -100,10 +97,21 @@ void css_pwr_domain_on_finish(const psci_power_state_t *target_state) /* Assert that the system power domain need not be initialized */ assert(css_system_pwr_state(target_state) == ARM_LOCAL_STATE_RUN); + css_pwr_domain_on_finisher_common(target_state); +} + +/******************************************************************************* + * Handler called when a power domain has just been powered on and the cpu + * and its cluster are fully participating in coherent transaction on the + * interconnect. Data cache must be enabled for CPU at this point. + ******************************************************************************/ +void css_pwr_domain_on_finish_late(const psci_power_state_t *target_state) +{ /* Program the gic per-cpu distributor or re-distributor interface */ plat_arm_gic_pcpu_init(); - css_pwr_domain_on_finisher_common(target_state); + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); } /******************************************************************************* @@ -185,6 +193,9 @@ void css_pwr_domain_suspend_finish( arm_system_pwr_domain_resume(); css_pwr_domain_on_finisher_common(target_state); + + /* Enable the gic cpu interface */ + plat_arm_gic_cpuif_enable(); } /******************************************************************************* @@ -306,6 +317,7 @@ static int css_translate_power_state_by_mpidr(u_register_t mpidr, plat_psci_ops_t plat_arm_psci_pm_ops = { .pwr_domain_on = css_pwr_domain_on, .pwr_domain_on_finish = css_pwr_domain_on_finish, + .pwr_domain_on_finish_late = css_pwr_domain_on_finish_late, .pwr_domain_off = css_pwr_domain_off, .cpu_standby = css_cpu_standby, .pwr_domain_suspend = css_pwr_domain_suspend, diff --git a/plat/arm/css/sgi/include/sgi_base_platform_def.h b/plat/arm/css/sgi/include/sgi_base_platform_def.h index a9cc85278..e21457304 100644 --- a/plat/arm/css/sgi/include/sgi_base_platform_def.h +++ b/plat/arm/css/sgi/include/sgi_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,7 +28,7 @@ * plat_arm_mmap array defined for each BL stage. */ #if defined(IMAGE_BL31) -# if ENABLE_SPM +# if SPM_MM # define PLAT_ARM_MMAP_ENTRIES 9 # define MAX_XLAT_TABLES 7 # define PLAT_SP_IMAGE_MMAP_REGIONS 7 @@ -101,7 +101,7 @@ #elif defined(IMAGE_BL2U) # define PLATFORM_STACK_SIZE 0x400 #elif defined(IMAGE_BL31) -# if ENABLE_SPM +# if SPM_MM # define PLATFORM_STACK_SIZE 0x500 # else # define PLATFORM_STACK_SIZE 0x400 diff --git a/plat/arm/css/sgi/sgi-common.mk b/plat/arm/css/sgi/sgi-common.mk index b736b0bb6..71601118f 100644 --- a/plat/arm/css/sgi/sgi-common.mk +++ b/plat/arm/css/sgi/sgi-common.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,8 +10,6 @@ CSS_ENT_BASE := plat/arm/css/sgi RAS_EXTENSION := 0 -ENABLE_SPM := 0 - SDEI_SUPPORT := 0 EL3_EXCEPTION_HANDLING := 0 diff --git a/plat/arm/css/sgi/sgi_plat.c b/plat/arm/css/sgi/sgi_plat.c index 3e207ecc2..b611eaff5 100644 --- a/plat/arm/css/sgi/sgi_plat.c +++ b/plat/arm/css/sgi/sgi_plat.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,7 +15,7 @@ #include <plat/common/platform.h> #include <drivers/arm/sbsa.h> #include <sgi_base_platform_def.h> -#include <services/secure_partition.h> +#include <services/spm_mm_partition.h> #define SGI_MAP_FLASH0_RO MAP_REGION_FLAT(V2M_FLASH0_BASE,\ V2M_FLASH0_SIZE, \ @@ -46,7 +46,7 @@ const mmap_region_t plat_arm_mmap[] = { #if ARM_BL31_IN_DRAM ARM_MAP_BL31_SEC_DRAM, #endif -#if ENABLE_SPM +#if SPM_MM ARM_SP_IMAGE_MMAP, #endif #if TRUSTED_BOARD_BOOT && !BL2_AT_EL3 @@ -61,13 +61,13 @@ const mmap_region_t plat_arm_mmap[] = { V2M_MAP_IOFPGA, CSS_SGI_MAP_DEVICE, SOC_CSS_MAP_DEVICE, -#if ENABLE_SPM +#if SPM_MM ARM_SPM_BUF_EL3_MMAP, #endif {0} }; -#if ENABLE_SPM && defined(IMAGE_BL31) +#if SPM_MM && defined(IMAGE_BL31) const mmap_region_t plat_arm_secure_partition_mmap[] = { PLAT_ARM_SECURE_MAP_DEVICE, ARM_SP_IMAGE_MMAP, @@ -77,17 +77,17 @@ const mmap_region_t plat_arm_secure_partition_mmap[] = { ARM_SPM_BUF_EL0_MMAP, {0} }; -#endif /* ENABLE_SPM && defined(IMAGE_BL31) */ +#endif /* SPM_MM && defined(IMAGE_BL31) */ #endif ARM_CASSERT_MMAP -#if ENABLE_SPM && defined(IMAGE_BL31) +#if SPM_MM && defined(IMAGE_BL31) /* * Boot information passed to a secure partition during initialisation. Linear * indices in MP information will be filled at runtime. */ -static secure_partition_mp_info_t sp_mp_info[] = { +static spm_mm_mp_info_t sp_mp_info[] = { [0] = {0x81000000, 0}, [1] = {0x81000100, 0}, [2] = {0x81000200, 0}, @@ -98,10 +98,10 @@ static secure_partition_mp_info_t sp_mp_info[] = { [7] = {0x81010300, 0}, }; -const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { +const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { .h.type = PARAM_SP_IMAGE_BOOT_INFO, .h.version = VERSION_1, - .h.size = sizeof(secure_partition_boot_info_t), + .h.size = sizeof(spm_mm_boot_info_t), .h.attr = 0, .sp_mem_base = ARM_SP_IMAGE_BASE, .sp_mem_limit = ARM_SP_IMAGE_LIMIT, @@ -125,12 +125,12 @@ const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) return plat_arm_secure_partition_mmap; } -const struct secure_partition_boot_info *plat_get_secure_partition_boot_info( +const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( void *cookie) { return &plat_arm_secure_partition_boot_info; } -#endif /* ENABLE_SPM && defined(IMAGE_BL31) */ +#endif /* SPM_MM && defined(IMAGE_BL31) */ #if TRUSTED_BOARD_BOOT int plat_get_mbedtls_heap(void **heap_addr, size_t *heap_size) diff --git a/plat/arm/css/sgi/sgi_ras.c b/plat/arm/css/sgi/sgi_ras.c index 0001ffdde..f56544e72 100644 --- a/plat/arm/css/sgi/sgi_ras.c +++ b/plat/arm/css/sgi/sgi_ras.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,9 +12,8 @@ #include <lib/extensions/ras.h> #include <plat/arm/common/arm_spm_def.h> #include <plat/common/platform.h> -#include <services/mm_svc.h> #include <services/sdei.h> -#include <services/spm_svc.h> +#include <services/spm_mm_svc.h> #include <sgi_ras.h> @@ -142,11 +141,11 @@ static int sgi_ras_intr_handler(const struct err_record_info *err_rec, sizeof(ras_map->ras_ev_num)); header->message_len = 4; - spm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0, - plat_my_core_pos()); + spm_mm_sp_call(MM_COMMUNICATE_AARCH64, (uint64_t)header, 0, + plat_my_core_pos()); /* - * Do an EOI of the RAS interuupt. This allows the + * Do an EOI of the RAS interrupt. This allows the * sdei event to be dispatched at the SDEI event's * priority. */ diff --git a/plat/arm/css/sgi/sgi_topology.c b/plat/arm/css/sgi/sgi_topology.c index 7aa9e40d3..1c3b5bfc8 100644 --- a/plat/arm/css/sgi/sgi_topology.c +++ b/plat/arm/css/sgi/sgi_topology.c @@ -1,62 +1,14 @@ /* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <plat/arm/common/plat_arm.h> -#include <plat/common/platform.h> -#include <sgi_variant.h> - -/* Topology */ /* - * The power domain tree descriptor. The cluster power domains are - * arranged so that when the PSCI generic code creates the power domain tree, - * the indices of the CPU power domain nodes it allocates match the linear - * indices returned by plat_core_pos_by_mpidr(). + * Common topology related methods for SGI and RD based platforms */ -const unsigned char sgi_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER -}; - -/* RD-E1-Edge platform consists of 16 physical CPUS and 32 threads */ -const unsigned char rd_e1_edge_pd_tree_desc[] = { - PLAT_ARM_CLUSTER_COUNT, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_CPUS_PER_CLUSTER, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU, - CSS_SGI_MAX_PE_PER_CPU -}; - -/******************************************************************************* - * This function returns the topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - if (sgi_plat_info.platform_id == RD_N1E1_EDGE_SID_VER_PART_NUM && - sgi_plat_info.config_id == RD_E1_EDGE_CONFIG_ID) - return rd_e1_edge_pd_tree_desc; - else - return sgi_pd_tree_desc; -} - /******************************************************************************* * This function returns the core count within the cluster corresponding to * `mpidr`. @@ -66,15 +18,7 @@ unsigned int plat_arm_get_cluster_core_count(u_register_t mpidr) return CSS_SGI_MAX_CPUS_PER_CLUSTER; } -/******************************************************************************* - * The array mapping platform core position (implemented by plat_my_core_pos()) - * to the SCMI power domain ID implemented by SCP. - ******************************************************************************/ -const uint32_t plat_css_core_pos_to_scmi_dmn_id_map[32] = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31 -}; - +#if ARM_PLAT_MT /****************************************************************************** * Return the number of PE's supported by the CPU. *****************************************************************************/ @@ -82,3 +26,4 @@ unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr) { return CSS_SGI_MAX_PE_PER_CPU; } +#endif diff --git a/plat/arm/css/sgm/include/sgm_base_platform_def.h b/plat/arm/css/sgm/include/sgm_base_platform_def.h index f349c196d..24bbed513 100644 --- a/plat/arm/css/sgm/include/sgm_base_platform_def.h +++ b/plat/arm/css/sgm/include/sgm_base_platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,8 +17,8 @@ #include <plat/common/common_def.h> /* CPU topology */ -#define PLAT_ARM_CLUSTER_COUNT 1 -#define PLAT_ARM_CLUSTER_CORE_COUNT 8 +#define PLAT_ARM_CLUSTER_COUNT U(1) +#define PLAT_ARM_CLUSTER_CORE_COUNT U(8) #define PLATFORM_CORE_COUNT PLAT_ARM_CLUSTER_CORE_COUNT #define PLAT_MAX_PWR_LVL ARM_PWR_LVL2 diff --git a/plat/arm/css/sgm/sgm-common.mk b/plat/arm/css/sgm/sgm-common.mk index 34e78b2f4..ac34450a7 100644 --- a/plat/arm/css/sgm/sgm-common.mk +++ b/plat/arm/css/sgm/sgm-common.mk @@ -4,6 +4,8 @@ # SPDX-License-Identifier: BSD-3-Clause # +CSS_USE_SCMI_SDS_DRIVER := 1 + CSS_SGM_BASE := plat/arm/css/sgm PLAT_INCLUDES := -I${CSS_SGM_BASE}/include diff --git a/plat/common/aarch64/crash_console_helpers.S b/plat/common/aarch64/crash_console_helpers.S index 2a48baf0a..e2950f5f7 100644 --- a/plat/common/aarch64/crash_console_helpers.S +++ b/plat/common/aarch64/crash_console_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -125,9 +125,18 @@ putc_loop: b.eq putc_continue ldr x2, [x15, #CONSOLE_T_PUTC] cbz x2, putc_continue + cmp w14, #'\n' + b.ne putc + tst w1, #CONSOLE_FLAG_TRANSLATE_CRLF + b.eq putc mov x1, x15 + mov w0, #'\r' blr x2 + ldr x2, [x15, #CONSOLE_T_PUTC] +putc: + mov x1, x15 mov w0, w14 + blr x2 putc_continue: ldr x15, [x15] /* X15 = next struct */ b putc_loop diff --git a/plat/common/plat_psci_common.c b/plat/common/plat_psci_common.c index 16bec7972..80ed8198b 100644 --- a/plat/common/plat_psci_common.c +++ b/plat/common/plat_psci_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -31,6 +31,8 @@ #define PSCI_STAT_ID_EXIT_LOW_PWR 1 #define PSCI_STAT_TOTAL_IDS 2 +PMF_DECLARE_CAPTURE_TIMESTAMP(psci_svc) +PMF_DECLARE_GET_TIMESTAMP(psci_svc) PMF_REGISTER_SERVICE(psci_svc, PMF_PSCI_STAT_SVC_ID, PSCI_STAT_TOTAL_IDS, PMF_STORE_ENABLE) @@ -92,7 +94,7 @@ void plat_psci_stat_accounting_stop( */ u_register_t plat_psci_stat_get_residency(unsigned int lvl, const psci_power_state_t *state_info, - int last_cpu_idx) + unsigned int last_cpu_idx) { plat_local_state_t state; unsigned long long pwrup_ts = 0, pwrdn_ts = 0; @@ -103,7 +105,7 @@ u_register_t plat_psci_stat_get_residency(unsigned int lvl, assert(last_cpu_idx <= PLATFORM_CORE_COUNT); if (lvl == PSCI_CPU_PWR_LVL) - assert((unsigned int)last_cpu_idx == plat_my_core_pos()); + assert(last_cpu_idx == plat_my_core_pos()); /* * If power down is requested, then timestamp capture will diff --git a/plat/common/plat_spm_rd.c b/plat/common/plat_spm_rd.c deleted file mode 100644 index ebd3e6dc6..000000000 --- a/plat/common/plat_spm_rd.c +++ /dev/null @@ -1,316 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <string.h> - -#include <libfdt.h> - -#include <platform_def.h> - -#include <common/debug.h> -#include <common/fdt_wrappers.h> -#include <lib/object_pool.h> -#include <plat/common/platform.h> -#include <services/sp_res_desc.h> - -/******************************************************************************* - * Resource pool - ******************************************************************************/ -static struct sp_rd_sect_mem_region rd_mem_regions[PLAT_SPM_MEM_REGIONS_MAX]; -static OBJECT_POOL_ARRAY(rd_mem_regions_pool, rd_mem_regions); - -static struct sp_rd_sect_notification rd_notifs[PLAT_SPM_NOTIFICATIONS_MAX]; -static OBJECT_POOL_ARRAY(rd_notifs_pool, rd_notifs); - -static struct sp_rd_sect_service rd_services[PLAT_SPM_SERVICES_MAX]; -static OBJECT_POOL_ARRAY(rd_services_pool, rd_services); - -/******************************************************************************* - * Attribute section handler - ******************************************************************************/ -static void rd_parse_attribute(struct sp_rd_sect_attribute *attr, - const void *fdt, int node) -{ - int rc = 0; - - /* The minimum size that can be read from the DTB is 32-bit. */ - uint32_t version, sp_type, runtime_el, exec_type; - uint32_t panic_policy, xlat_granule; - - rc |= fdtw_read_cells(fdt, node, "version", 1, &version); - - if (version != 1) { - ERROR("Unsupported resource description version: 0x%x\n", - version); - panic(); - } - - rc |= fdtw_read_cells(fdt, node, "sp_type", 1, &sp_type); - rc |= fdtw_read_cells(fdt, node, "pe_mpidr", 1, &attr->pe_mpidr); - rc |= fdtw_read_cells(fdt, node, "runtime_el", 1, &runtime_el); - rc |= fdtw_read_cells(fdt, node, "exec_type", 1, &exec_type); - rc |= fdtw_read_cells(fdt, node, "panic_policy", 1, &panic_policy); - rc |= fdtw_read_cells(fdt, node, "xlat_granule", 1, &xlat_granule); - rc |= fdtw_read_cells(fdt, node, "binary_size", 1, &attr->binary_size); - rc |= fdtw_read_cells(fdt, node, "load_address", 2, &attr->load_address); - rc |= fdtw_read_cells(fdt, node, "entrypoint", 2, &attr->entrypoint); - - attr->version = version; - attr->sp_type = sp_type; - attr->runtime_el = runtime_el; - attr->exec_type = exec_type; - attr->panic_policy = panic_policy; - attr->xlat_granule = xlat_granule; - - VERBOSE(" Attribute Section:\n"); - VERBOSE(" version: 0x%x\n", version); - VERBOSE(" sp_type: 0x%x\n", sp_type); - VERBOSE(" pe_mpidr: 0x%x\n", attr->pe_mpidr); - VERBOSE(" runtime_el: 0x%x\n", runtime_el); - VERBOSE(" exec_type: 0x%x\n", exec_type); - VERBOSE(" panic_policy: 0x%x\n", panic_policy); - VERBOSE(" xlat_granule: 0x%x\n", xlat_granule); - VERBOSE(" binary_size: 0x%x\n", attr->binary_size); - VERBOSE(" load_address: 0x%llx\n", attr->load_address); - VERBOSE(" entrypoint: 0x%llx\n", attr->entrypoint); - - if (rc) { - ERROR("Failed to read attribute node elements.\n"); - panic(); - } -} - -/******************************************************************************* - * Memory regions section handlers - ******************************************************************************/ -static void rd_parse_memory_region(struct sp_rd_sect_mem_region *rdmem, - const void *fdt, int node) -{ - int rc = 0; - char name[RD_MEM_REGION_NAME_LEN]; - - rc |= fdtw_read_string(fdt, node, "str", (char *)&name, sizeof(name)); - rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdmem->attr); - rc |= fdtw_read_cells(fdt, node, "base", 2, &rdmem->base); - rc |= fdtw_read_cells(fdt, node, "size", 2, &rdmem->size); - - size_t len = strlcpy(rdmem->name, name, RD_MEM_REGION_NAME_LEN); - - if (len >= RD_MEM_REGION_NAME_LEN) { - WARN("Memory region name truncated: '%s'\n", name); - } - - VERBOSE(" Memory Region:\n"); - VERBOSE(" name: '%s'\n", rdmem->name); - VERBOSE(" attr: 0x%x\n", rdmem->attr); - VERBOSE(" base: 0x%llx\n", rdmem->base); - VERBOSE(" size: 0x%llx\n", rdmem->size); - - if (rc) { - ERROR("Failed to read mem_region node elements.\n"); - panic(); - } -} - -static void rd_parse_memory_regions(struct sp_res_desc *rd, const void *fdt, - int node) -{ - int child; - struct sp_rd_sect_mem_region *rdmem, *old_rdmem; - - fdt_for_each_subnode(child, fdt, node) { - rdmem = pool_alloc(&rd_mem_regions_pool); - - /* Add element to the start of the list */ - old_rdmem = rd->mem_region; - rd->mem_region = rdmem; - rdmem->next = old_rdmem; - - rd_parse_memory_region(rdmem, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); - panic(); - } -} - -/******************************************************************************* - * Notifications section handlers - ******************************************************************************/ -static void rd_parse_notification(struct sp_rd_sect_notification *rdnot, - const void *fdt, int node) -{ - int rc = 0; - - rc |= fdtw_read_cells(fdt, node, "attr", 1, &rdnot->attr); - rc |= fdtw_read_cells(fdt, node, "pe", 1, &rdnot->pe); - - VERBOSE(" Notification:\n"); - VERBOSE(" attr: 0x%x\n", rdnot->attr); - VERBOSE(" pe: 0x%x\n", rdnot->pe); - - if (rc) { - ERROR("Failed to read notification node elements.\n"); - panic(); - } -} - -static void rd_parse_notifications(struct sp_res_desc *rd, const void *fdt, int node) -{ - int child; - struct sp_rd_sect_notification *rdnot, *old_rdnot; - - fdt_for_each_subnode(child, fdt, node) { - rdnot = pool_alloc(&rd_notifs_pool); - - /* Add element to the start of the list */ - old_rdnot = rd->notification; - rd->notification = rdnot; - rdnot->next = old_rdnot; - - rd_parse_notification(rdnot, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, child); - panic(); - } -} - -/******************************************************************************* - * Services section handlers - ******************************************************************************/ -static void rd_parse_service(struct sp_rd_sect_service *rdsvc, const void *fdt, - int node) -{ - int rc = 0; - - /* The minimum size that can be read from the DTB is 32-bit. */ - uint32_t accessibility, request_type, connection_quota; - - rc |= fdtw_read_array(fdt, node, "uuid", 4, &rdsvc->uuid); - rc |= fdtw_read_cells(fdt, node, "accessibility", 1, &accessibility); - rc |= fdtw_read_cells(fdt, node, "request_type", 1, &request_type); - rc |= fdtw_read_cells(fdt, node, "connection_quota", 1, &connection_quota); - rc |= fdtw_read_cells(fdt, node, "sec_mem_size", 1, &rdsvc->secure_mem_size); - rc |= fdtw_read_cells(fdt, node, "interrupt_num", 1, &rdsvc->interrupt_num); - - rdsvc->accessibility = accessibility; - rdsvc->request_type = request_type; - rdsvc->connection_quota = connection_quota; - - VERBOSE(" Service:\n"); - VERBOSE(" uuid: 0x%08x 0x%08x 0x%08x 0x%08x\n", rdsvc->uuid[0], - rdsvc->uuid[1], rdsvc->uuid[2], rdsvc->uuid[3]); - VERBOSE(" accessibility: 0x%x\n", accessibility); - VERBOSE(" request_type: 0x%x\n", request_type); - VERBOSE(" connection_quota: 0x%x\n", connection_quota); - VERBOSE(" secure_memory_size: 0x%x\n", rdsvc->secure_mem_size); - VERBOSE(" interrupt_num: 0x%x\n", rdsvc->interrupt_num); - - if (rc) { - ERROR("Failed to read attribute node elements.\n"); - panic(); - } -} - -static void rd_parse_services(struct sp_res_desc *rd, const void *fdt, int node) -{ - int child; - struct sp_rd_sect_service *rdsvc, *old_rdsvc; - - fdt_for_each_subnode(child, fdt, node) { - rdsvc = pool_alloc(&rd_services_pool); - - /* Add element to the start of the list */ - old_rdsvc = rd->service; - rd->service = rdsvc; - rdsvc->next = old_rdsvc; - - rd_parse_service(rdsvc, fdt, child); - } - - if ((child < 0) && (child != -FDT_ERR_NOTFOUND)) { - ERROR("%d: fdt_for_each_subnode(): %d\n", __LINE__, node); - panic(); - } -} - -/******************************************************************************* - * Root node handler - ******************************************************************************/ -static void rd_parse_root(struct sp_res_desc *rd, const void *fdt, int root) -{ - int node; - char *str; - - str = "attribute"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - ERROR("Root node doesn't contain subnode '%s'\n", str); - panic(); - } else { - rd_parse_attribute(&rd->attribute, fdt, node); - } - - str = "memory_regions"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - ERROR("Root node doesn't contain subnode '%s'\n", str); - panic(); - } else { - rd_parse_memory_regions(rd, fdt, node); - } - - str = "notifications"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - WARN("Root node doesn't contain subnode '%s'\n", str); - } else { - rd_parse_notifications(rd, fdt, node); - } - - str = "services"; - node = fdt_subnode_offset_namelen(fdt, root, str, strlen(str)); - if (node < 0) { - WARN("Root node doesn't contain subnode '%s'\n", str); - } else { - rd_parse_services(rd, fdt, node); - } -} - -/******************************************************************************* - * Platform handler to load resource descriptor blobs into the active Secure - * Partition context. - ******************************************************************************/ -int plat_spm_sp_rd_load(struct sp_res_desc *rd, const void *ptr, size_t size) -{ - int rc; - int root_node; - - assert(rd != NULL); - assert(ptr != NULL); - - INFO("Reading RD blob at address %p\n", ptr); - - rc = fdt_check_header(ptr); - if (rc != 0) { - ERROR("Wrong format for resource descriptor blob (%d).\n", rc); - return -1; - } - - root_node = fdt_node_offset_by_compatible(ptr, -1, "arm,sp_rd"); - if (root_node < 0) { - ERROR("Unrecognized resource descriptor blob (%d)\n", rc); - return -1; - } - - rd_parse_root(rd, ptr, root_node); - - return 0; -} diff --git a/plat/common/plat_spm_sp.c b/plat/common/plat_spm_sp.c deleted file mode 100644 index bc3d6a015..000000000 --- a/plat/common/plat_spm_sp.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2018-2019, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> - -#include <platform_def.h> - -#include <common/debug.h> -#include <plat/common/platform.h> -#include <tools_share/sptool.h> - -static unsigned int sp_next; - -/******************************************************************************* - * Platform handler get the address of a Secure Partition and its resource - * description blob. It iterates through all SPs detected by the platform. If - * there is information for another SP, it returns 0. If there are no more SPs, - * it returns -1. - ******************************************************************************/ -int plat_spm_sp_get_next_address(void **sp_base, size_t *sp_size, - void **rd_base, size_t *rd_size) -{ - assert((sp_base != NULL) && (sp_size != NULL)); - assert((rd_base != NULL) && (rd_base != NULL)); - - const uint64_t *pkg_base = (uint64_t *)PLAT_SP_PACKAGE_BASE; - - struct sp_pkg_header *pkg_header = (struct sp_pkg_header *)pkg_base; - - if (sp_next == 0) { - if (pkg_header->version != 0x1) { - ERROR("SP package has an unsupported version 0x%llx\n", - pkg_header->version); - panic(); - } - } - - if (sp_next >= pkg_header->number_of_sp) { - /* No more partitions in the package */ - return -1; - } - - const struct sp_pkg_entry *entry_list = - (const struct sp_pkg_entry *)((uintptr_t)pkg_base - + sizeof(struct sp_pkg_header)); - - const struct sp_pkg_entry *entry = &(entry_list[sp_next]); - - uint64_t sp_offset = entry->sp_offset; - uint64_t rd_offset = entry->rd_offset; - - uintptr_t pkg_sp_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + sp_offset); - uintptr_t pkg_rd_base = ((uintptr_t)PLAT_SP_PACKAGE_BASE + rd_offset); - - uint64_t pkg_sp_size = entry->sp_size; - uint64_t pkg_rd_size = entry->rd_size; - - uintptr_t pkg_end = (uintptr_t)PLAT_SP_PACKAGE_BASE - + (uintptr_t)PLAT_SP_PACKAGE_SIZE - 1U; - - /* - * Check for overflows. The package header isn't trusted, so assert() - * can't be used here. - */ - - uintptr_t pkg_sp_end = pkg_sp_base + pkg_sp_size - 1U; - uintptr_t pkg_rd_end = pkg_rd_base + pkg_rd_size - 1U; - - if ((pkg_sp_end > pkg_end) || (pkg_sp_end < pkg_sp_base)) { - ERROR("Invalid Secure Partition size (0x%llx)\n", pkg_sp_size); - panic(); - } - - if ((pkg_rd_end > pkg_end) || (pkg_rd_end < pkg_rd_base)) { - ERROR("Invalid Resource Description blob size (0x%llx)\n", - pkg_rd_size); - panic(); - } - - /* Return location of the binaries. */ - - *sp_base = (void *)pkg_sp_base; - *sp_size = pkg_sp_size; - *rd_base = (void *)pkg_rd_base; - *rd_size = pkg_rd_size; - - sp_next++; - - return 0; -} diff --git a/plat/common/ubsan.c b/plat/common/ubsan.c new file mode 100644 index 000000000..45b0f7cce --- /dev/null +++ b/plat/common/ubsan.c @@ -0,0 +1,220 @@ +/* + * Copyright (c) 2016, Linaro Limited + * Copyright (c) 2019, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <arch_helpers.h> +#include <context.h> +#include <common/debug.h> +#include <plat/common/platform.h> + +struct source_location { + const char *file_name; + uint32_t line; + uint32_t column; +}; + +struct type_descriptor { + uint16_t type_kind; + uint16_t type_info; + char type_name[1]; +}; + +struct type_mismatch_data { + struct source_location loc; + struct type_descriptor *type; + unsigned long alignment; + unsigned char type_check_kind; +}; + +struct overflow_data { + struct source_location loc; + struct type_descriptor *type; +}; + +struct shift_out_of_bounds_data { + struct source_location loc; + struct type_descriptor *lhs_type; + struct type_descriptor *rhs_type; +}; + +struct out_of_bounds_data { + struct source_location loc; + struct type_descriptor *array_type; + struct type_descriptor *index_type; +}; + +struct unreachable_data { + struct source_location loc; +}; + +struct vla_bound_data { + struct source_location loc; + struct type_descriptor *type; +}; + +struct invalid_value_data { + struct source_location loc; + struct type_descriptor *type; +}; + +struct nonnull_arg_data { + struct source_location loc; +}; + +/* + * When compiling with -fsanitize=undefined the compiler expects functions + * with the following signatures. The functions are never called directly, + * only when undefined behavior is detected in instrumented code. + */ +void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data, + unsigned long ptr); +void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data, + unsigned long ptr); +void __ubsan_handle_add_overflow_abort(struct overflow_data *data, + unsigned long lhs, unsigned long rhs); +void __ubsan_handle_sub_overflow_abort(struct overflow_data *data, + unsigned long lhs, unsigned long rhs); +void __ubsan_handle_mul_overflow_abort(struct overflow_data *data, + unsigned long lhs, unsigned long rhs); +void __ubsan_handle_negate_overflow_abort(struct overflow_data *data, + unsigned long old_val); +void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data, + unsigned long old_val); +void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data, + unsigned long lhs, unsigned long rhs); +void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data, + unsigned long lhs, unsigned long rhs); +void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data, + unsigned long idx); +void __ubsan_handle_unreachable_abort(struct unreachable_data *data); +void __ubsan_handle_missing_return_abort(struct unreachable_data *data); +void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data, + unsigned long bound); +void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data, + unsigned long val); +void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data +#if __GCC_VERSION < 60000 + , size_t arg_no +#endif + ); + +static void print_loc(const char *func, struct source_location *loc) +{ + ERROR("Undefined behavior at %s:%d col %d (%s)", + loc->file_name, loc->line, loc->column, func); +} + + +void __ubsan_handle_type_mismatch_abort(struct type_mismatch_data *data, + unsigned long ptr __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_type_mismatch_v1_abort(struct type_mismatch_data *data, + unsigned long ptr __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_add_overflow_abort(struct overflow_data *data, + unsigned long lhs __unused, + unsigned long rhs __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_sub_overflow_abort(struct overflow_data *data, + unsigned long lhs __unused, + unsigned long rhs __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_mul_overflow_abort(struct overflow_data *data, + unsigned long lhs __unused, + unsigned long rhs __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_negate_overflow_abort(struct overflow_data *data, + unsigned long old_val __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_pointer_overflow_abort(struct overflow_data *data, + unsigned long old_val __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_divrem_overflow_abort(struct overflow_data *data, + unsigned long lhs __unused, + unsigned long rhs __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_shift_out_of_bounds_abort(struct shift_out_of_bounds_data *data, + unsigned long lhs __unused, + unsigned long rhs __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_out_of_bounds_abort(struct out_of_bounds_data *data, + unsigned long idx __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_unreachable_abort(struct unreachable_data *data) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_missing_return_abort(struct unreachable_data *data) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_vla_bound_not_positive_abort(struct vla_bound_data *data, + unsigned long bound __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_load_invalid_value_abort(struct invalid_value_data *data, + unsigned long val __unused) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} + +void __ubsan_handle_nonnull_arg_abort(struct nonnull_arg_data *data +#if __GCC_VERSION < 60000 + , size_t arg_no __unused +#endif + ) +{ + print_loc(__func__, &data->loc); + plat_panic_handler(); +} diff --git a/plat/hisilicon/hikey/hikey_bl2_setup.c b/plat/hisilicon/hikey/hikey_bl2_setup.c index 2f96efcdb..96136ec12 100644 --- a/plat/hisilicon/hikey/hikey_bl2_setup.c +++ b/plat/hisilicon/hikey/hikey_bl2_setup.c @@ -114,6 +114,11 @@ uint32_t hikey_get_spsr_for_bl33_entry(void) } #endif /* __aarch64__ */ +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + return hikey_set_fip_addr(image_id, "fastboot"); +} + int hikey_bl2_handle_post_image_load(unsigned int image_id) { int err = 0; diff --git a/plat/hisilicon/hikey/hikey_io_storage.c b/plat/hisilicon/hikey/hikey_io_storage.c index 11dd97334..fd610d8c0 100644 --- a/plat/hisilicon/hikey/hikey_io_storage.c +++ b/plat/hisilicon/hikey/hikey_io_storage.c @@ -18,6 +18,7 @@ #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> #include <drivers/mmc.h> +#include <drivers/partition/partition.h> #include <lib/mmio.h> #include <lib/semihosting.h> #include <tools_share/firmware_image_package.h> @@ -43,9 +44,12 @@ static uintptr_t fip_dev_handle; static int check_emmc(const uintptr_t spec); static int check_fip(const uintptr_t spec); -static const io_block_spec_t emmc_fip_spec = { - .offset = HIKEY_FIP_BASE, - .length = HIKEY_FIP_MAX_SIZE, +static io_block_spec_t emmc_fip_spec; + +static const io_block_spec_t emmc_gpt_spec = { + .offset = 0, + .length = PLAT_PARTITION_BLOCK_SIZE * + (PLAT_PARTITION_MAX_ENTRIES / 4 + 2), }; static const io_block_dev_spec_t emmc_dev_spec = { @@ -213,6 +217,11 @@ static const struct plat_io_policy policies[] = { check_fip }, #endif /* TRUSTED_BOARD_BOOT */ + [GPT_IMAGE_ID] = { + &emmc_dev_handle, + (uintptr_t)&emmc_gpt_spec, + check_emmc + }, }; static int check_emmc(const uintptr_t spec) @@ -267,6 +276,23 @@ void hikey_io_setup(void) (void)result; } +int hikey_set_fip_addr(unsigned int image_id, const char *name) +{ + const partition_entry_t *entry; + + if (emmc_fip_spec.length == 0) { + partition_init(GPT_IMAGE_ID); + entry = get_partition_entry(name); + if (entry == NULL) { + ERROR("Could NOT find the %s partition!\n", name); + return -ENOENT; + } + emmc_fip_spec.offset = entry->start; + emmc_fip_spec.length = entry->length; + } + return 0; +} + /* Return an IO device handle and specification which can be used to access * an image. Use this to enforce platform load policy */ diff --git a/plat/hisilicon/hikey/hikey_private.h b/plat/hisilicon/hikey/hikey_private.h index d82a0794a..b75bc723d 100644 --- a/plat/hisilicon/hikey/hikey_private.h +++ b/plat/hisilicon/hikey/hikey_private.h @@ -72,4 +72,6 @@ int hikey_write_serialno(struct random_serial_num *serialno); void init_acpu_dvfs(void); +int hikey_set_fip_addr(unsigned int image_id, const char *name); + #endif /* HIKEY_PRIVATE_H */ diff --git a/plat/hisilicon/hikey/include/hikey_def.h b/plat/hisilicon/hikey/include/hikey_def.h index 4fb3e56a1..590700daf 100644 --- a/plat/hisilicon/hikey/include/hikey_def.h +++ b/plat/hisilicon/hikey/include/hikey_def.h @@ -84,8 +84,6 @@ #define HIKEY_BL1_MMC_DATA_SIZE 0x0000B000 #define EMMC_BASE 0 -#define HIKEY_FIP_BASE (EMMC_BASE + (4 << 20)) -#define HIKEY_FIP_MAX_SIZE (8 << 20) #define HIKEY_EMMC_RPMB_BASE (EMMC_BASE + 0) #define HIKEY_EMMC_RPMB_MAX_SIZE (128 << 10) #define HIKEY_EMMC_USERDATA_BASE (EMMC_BASE + 0) diff --git a/plat/hisilicon/hikey/include/platform_def.h b/plat/hisilicon/hikey/include/platform_def.h index 2537ac66b..04ea71f67 100644 --- a/plat/hisilicon/hikey/include/platform_def.h +++ b/plat/hisilicon/hikey/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,13 +28,13 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_CACHE_LINE_SIZE 64 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CORE_COUNT_PER_CLUSTER 4 +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CORE_COUNT_PER_CLUSTER U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_CORE_COUNT_PER_CLUSTER) #define PLAT_MAX_PWR_LVL (MPIDR_AFFLVL2) #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ - PLATFORM_CLUSTER_COUNT + 1) + PLATFORM_CLUSTER_COUNT + U(1)) #define PLAT_MAX_RET_STATE U(1) #define PLAT_MAX_OFF_STATE U(2) diff --git a/plat/hisilicon/hikey/platform.mk b/plat/hisilicon/hikey/platform.mk index 7fd897cda..fbf743292 100644 --- a/plat/hisilicon/hikey/platform.mk +++ b/plat/hisilicon/hikey/platform.mk @@ -76,6 +76,8 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ drivers/mmc/mmc.c \ + drivers/partition/gpt.c \ + drivers/partition/partition.c \ drivers/synopsys/emmc/dw_mmc.c \ lib/cpus/aarch64/cortex_a53.S \ plat/hisilicon/hikey/aarch64/hikey_helpers.S \ diff --git a/plat/hisilicon/hikey960/hikey960_bl2_setup.c b/plat/hisilicon/hikey960/hikey960_bl2_setup.c index fc9ddab0d..35d76921d 100644 --- a/plat/hisilicon/hikey960/hikey960_bl2_setup.c +++ b/plat/hisilicon/hikey960/hikey960_bl2_setup.c @@ -18,6 +18,7 @@ #include <drivers/delay_timer.h> #include <drivers/dw_ufs.h> #include <drivers/generic_delay_timer.h> +#include <drivers/partition/partition.h> #include <drivers/ufs.h> #include <lib/mmio.h> #ifdef SPD_opteed @@ -263,6 +264,11 @@ int hikey960_bl2_handle_post_image_load(unsigned int image_id) * This function can be used by the platforms to update/use image * information for given `image_id`. ******************************************************************************/ +int bl2_plat_handle_pre_image_load(unsigned int image_id) +{ + return hikey960_set_fip_addr(image_id, "fip"); +} + int bl2_plat_handle_post_image_load(unsigned int image_id) { return hikey960_bl2_handle_post_image_load(image_id); diff --git a/plat/hisilicon/hikey960/hikey960_def.h b/plat/hisilicon/hikey960/hikey960_def.h index 4ea3acd51..9651d7891 100644 --- a/plat/hisilicon/hikey960/hikey960_def.h +++ b/plat/hisilicon/hikey960/hikey960_def.h @@ -44,9 +44,6 @@ #define PL011_UART_CLK_IN_HZ 19200000 #define UFS_BASE 0 -/* FIP partition */ -#define HIKEY960_FIP_BASE (UFS_BASE + 0x1400000) -#define HIKEY960_FIP_MAX_SIZE (12 << 20) #define HIKEY960_UFS_DESC_BASE 0x20000000 #define HIKEY960_UFS_DESC_SIZE 0x00200000 /* 2MB */ diff --git a/plat/hisilicon/hikey960/hikey960_io_storage.c b/plat/hisilicon/hikey960/hikey960_io_storage.c index a4e83897e..e1c5845fb 100644 --- a/plat/hisilicon/hikey960/hikey960_io_storage.c +++ b/plat/hisilicon/hikey960/hikey960_io_storage.c @@ -18,6 +18,7 @@ #include <drivers/io/io_fip.h> #include <drivers/io/io_memmap.h> #include <drivers/io/io_storage.h> +#include <drivers/partition/partition.h> #include <lib/mmio.h> #include <lib/semihosting.h> #include <tools_share/firmware_image_package.h> @@ -36,9 +37,12 @@ static int check_fip(const uintptr_t spec); size_t ufs_read_lun3_blks(int lba, uintptr_t buf, size_t size); size_t ufs_write_lun3_blks(int lba, const uintptr_t buf, size_t size); -static const io_block_spec_t ufs_fip_spec = { - .offset = HIKEY960_FIP_BASE, - .length = HIKEY960_FIP_MAX_SIZE, +static io_block_spec_t ufs_fip_spec; + +static const io_block_spec_t ufs_gpt_spec = { + .offset = 0, + .length = PLAT_PARTITION_BLOCK_SIZE * + (PLAT_PARTITION_MAX_ENTRIES / 4 + 2), }; static const io_block_dev_spec_t ufs_dev_spec = { @@ -199,6 +203,11 @@ static const struct plat_io_policy policies[] = { check_fip }, #endif /* TRUSTED_BOARD_BOOT */ + [GPT_IMAGE_ID] = { + &ufs_dev_handle, + (uintptr_t)&ufs_gpt_spec, + check_ufs + }, }; static int check_ufs(const uintptr_t spec) @@ -253,6 +262,23 @@ void hikey960_io_setup(void) (void)result; } +int hikey960_set_fip_addr(unsigned int image_id, const char *name) +{ + const partition_entry_t *entry; + + if (ufs_fip_spec.length == 0) { + partition_init(GPT_IMAGE_ID); + entry = get_partition_entry(name); + if (entry == NULL) { + ERROR("Could NOT find the %s partition!\n", name); + return -ENOENT; + } + ufs_fip_spec.offset = entry->start; + ufs_fip_spec.length = entry->length; + } + return 0; +} + /* Return an IO device handle and specification which can be used to access * an image. Use this to enforce platform load policy */ diff --git a/plat/hisilicon/hikey960/hikey960_private.h b/plat/hisilicon/hikey960/hikey960_private.h index 9a18dd620..54bf50134 100644 --- a/plat/hisilicon/hikey960/hikey960_private.h +++ b/plat/hisilicon/hikey960/hikey960_private.h @@ -26,6 +26,7 @@ void hikey960_init_mmu_el3(unsigned long total_base, unsigned long coh_limit); void hikey960_io_setup(void); int hikey960_read_boardid(unsigned int *id); +int hikey960_set_fip_addr(unsigned int image_id, const char *name); void hikey960_clk_init(void); void hikey960_pmu_init(void); void hikey960_regulator_enable(void); diff --git a/plat/hisilicon/hikey960/include/platform_def.h b/plat/hisilicon/hikey960/include/platform_def.h index f6edad668..215eebe1b 100644 --- a/plat/hisilicon/hikey960/include/platform_def.h +++ b/plat/hisilicon/hikey960/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,12 +25,12 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_CACHE_LINE_SIZE 64 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CORE_COUNT_PER_CLUSTER 4 +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CORE_COUNT_PER_CLUSTER U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER_COUNT * \ PLATFORM_CORE_COUNT_PER_CLUSTER) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL2 -#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CORE_COUNT + \ PLATFORM_CLUSTER_COUNT + 1) #define PLAT_MAX_RET_STATE U(1) diff --git a/plat/hisilicon/hikey960/platform.mk b/plat/hisilicon/hikey960/platform.mk index 4f2c3c699..6cb53c7b6 100644 --- a/plat/hisilicon/hikey960/platform.mk +++ b/plat/hisilicon/hikey960/platform.mk @@ -22,11 +22,13 @@ COLD_BOOT_SINGLE_CPU := 1 PLAT_PL061_MAX_GPIOS := 176 PROGRAMMABLE_RESET_ADDRESS := 1 ENABLE_SVE_FOR_NS := 0 +PLAT_PARTITION_BLOCK_SIZE := 4096 # Process flags $(eval $(call add_define,HIKEY960_TSP_RAM_LOCATION_ID)) $(eval $(call add_define,CRASH_CONSOLE_BASE)) $(eval $(call add_define,PLAT_PL061_MAX_GPIOS)) +$(eval $(call add_define,PLAT_PARTITION_BLOCK_SIZE)) # Add the build options to pack Trusted OS Extra1 and Trusted OS Extra2 images # in the FIP if the platform requires. @@ -75,6 +77,8 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ drivers/io/io_storage.c \ + drivers/partition/gpt.c \ + drivers/partition/partition.c \ drivers/synopsys/ufs/dw_ufs.c \ drivers/ufs/ufs.c \ lib/cpus/aarch64/cortex_a53.S \ diff --git a/plat/hisilicon/poplar/include/platform_def.h b/plat/hisilicon/poplar/include/platform_def.h index 9783f8d2d..ce0fbbca0 100644 --- a/plat/hisilicon/poplar/include/platform_def.h +++ b/plat/hisilicon/poplar/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -34,9 +34,9 @@ #define BOOT_EMMC_NAME "l-loader.bin" #define PLATFORM_CACHE_LINE_SIZE (64) -#define PLATFORM_CLUSTER_COUNT (1) -#define PLATFORM_CORE_COUNT (4) -#define PLATFORM_MAX_CPUS_PER_CLUSTER (4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CORE_COUNT U(4) +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) /* IO framework user */ #define MAX_IO_DEVICES (4) diff --git a/plat/imx/common/include/imx_caam.h b/plat/imx/common/include/imx_caam.h index 335bd0f8b..61005b51c 100644 --- a/plat/imx/common/include/imx_caam.h +++ b/plat/imx/common/include/imx_caam.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,6 +7,7 @@ #ifndef IMX_CAAM_H #define IMX_CAAM_H +#include <cdefs.h> #include <stdint.h> #include <arch.h> #include <imx_regs.h> diff --git a/plat/imx/common/include/imx_snvs.h b/plat/imx/common/include/imx_snvs.h index 0b3d1085f..565c451dd 100644 --- a/plat/imx/common/include/imx_snvs.h +++ b/plat/imx/common/include/imx_snvs.h @@ -1,11 +1,12 @@ /* - * Copyright (C) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (C) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #ifndef IMX_SNVS_H #define IMX_SNVS_H +#include <cdefs.h> #include <stdint.h> #include <arch.h> diff --git a/plat/imx/common/include/sci/sci_ipc.h b/plat/imx/common/include/sci/sci_ipc.h index 1167ea367..39e9012bc 100644 --- a/plat/imx/common/include/sci/sci_ipc.h +++ b/plat/imx/common/include/sci/sci_ipc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -62,6 +62,6 @@ void sc_ipc_read(sc_ipc_t ipc, void *data); */ void sc_ipc_write(sc_ipc_t ipc, void *data); -sc_ipc_t ipc_handle; +extern sc_ipc_t ipc_handle; #endif /* SCI_IPC_H */ diff --git a/plat/imx/common/plat_imx8_gic.c b/plat/imx/common/plat_imx8_gic.c index 3a7dcfec6..afb9d1f1a 100644 --- a/plat/imx/common/plat_imx8_gic.c +++ b/plat/imx/common/plat_imx8_gic.c @@ -20,9 +20,7 @@ uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; static const interrupt_prop_t g01s_interrupt_props[] = { - INTR_PROP_DESC(6, GIC_HIGHEST_SEC_PRIORITY, - INTR_GROUP1S, GIC_INTR_CFG_LEVEL), - INTR_PROP_DESC(7, GIC_HIGHEST_SEC_PRIORITY, + INTR_PROP_DESC(8, GIC_HIGHEST_SEC_PRIORITY, INTR_GROUP0, GIC_INTR_CFG_LEVEL), }; diff --git a/plat/imx/common/sci/ipc.c b/plat/imx/common/sci/ipc.c index 6491ca575..576911925 100644 --- a/plat/imx/common/sci/ipc.c +++ b/plat/imx/common/sci/ipc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,6 +13,8 @@ #include <sci/sci_rpc.h> #include "imx8_mu.h" +sc_ipc_t ipc_handle; + DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock); #define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock) #define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock) diff --git a/plat/imx/imx7/picopi/include/platform_def.h b/plat/imx/imx7/picopi/include/platform_def.h index 1af1d0cfc..141571c67 100644 --- a/plat/imx/imx7/picopi/include/platform_def.h +++ b/plat/imx/imx7/picopi/include/platform_def.h @@ -13,15 +13,15 @@ #define PLATFORM_STACK_SIZE 0x1000 -#define PLATFORM_MAX_CPUS_PER_CLUSTER 2 -#define PLATFORM_CLUSTER_COUNT 1 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2) +#define PLATFORM_CLUSTER_COUNT U(1) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT -#define PICOPI_PRIMARY_CPU 0 +#define PICOPI_PRIMARY_CPU U(0) -#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) #define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 diff --git a/plat/imx/imx7/warp7/include/platform_def.h b/plat/imx/imx7/warp7/include/platform_def.h index 4f719083e..4afcb5497 100644 --- a/plat/imx/imx7/warp7/include/platform_def.h +++ b/plat/imx/imx7/warp7/include/platform_def.h @@ -13,15 +13,15 @@ #define PLATFORM_STACK_SIZE 0x1000 -#define PLATFORM_MAX_CPUS_PER_CLUSTER 2 -#define PLATFORM_CLUSTER_COUNT 1 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(2) +#define PLATFORM_CLUSTER_COUNT U(1) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ PLATFORM_CLUSTER1_CORE_COUNT) -#define WARP7_PRIMARY_CPU 0 +#define WARP7_PRIMARY_CPU U(0) #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) diff --git a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c index c3cd0d0cb..4c5f4f0d1 100644 --- a/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c +++ b/plat/imx/imx8m/imx8mm/imx8mm_bl31_setup.c @@ -124,6 +124,18 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + bl31_tzc380_setup(); } diff --git a/plat/imx/imx8m/imx8mm/include/platform_def.h b/plat/imx/imx8m/imx8mm/include/platform_def.h index de9e3b5c8..56caab7ce 100644 --- a/plat/imx/imx8m/imx8mm/include/platform_def.h +++ b/plat/imx/imx8m/imx8mm/include/platform_def.h @@ -10,11 +10,11 @@ #define PLATFORM_STACK_SIZE 0xB00 #define CACHE_WRITEBACK_GRANULE 64 -#define PLAT_PRIMARY_CPU 0x0 -#define PLATFORM_MAX_CPU_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) #define IMX_PWR_LVL0 MPIDR_AFFLVL0 @@ -31,7 +31,6 @@ #define BL31_BASE U(0x920000) #define BL31_LIMIT U(0x940000) -#define BL32_BASE U(0xbe000000) /* non-secure uboot base */ #define PLAT_NS_IMAGE_OFFSET U(0x40200000) diff --git a/plat/imx/imx8m/imx8mm/platform.mk b/plat/imx/imx8m/imx8mm/platform.mk index 6d32dbba3..c0cb6c2a5 100644 --- a/plat/imx/imx8m/imx8mm/platform.mk +++ b/plat/imx/imx8m/imx8mm/platform.mk @@ -45,3 +45,9 @@ A53_DISABLE_NON_TEMPORAL_HINT := 0 ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0xbe000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) diff --git a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c index 26a3b364e..a347389a2 100644 --- a/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c +++ b/plat/imx/imx8m/imx8mq/imx8mq_bl31_setup.c @@ -146,6 +146,18 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl33_image_ep_info.spsr = get_spsr_for_bl33_entry(); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); +#ifdef SPD_opteed + /* Populate entry point information for BL32 */ + SET_PARAM_HEAD(&bl32_image_ep_info, PARAM_EP, VERSION_1, 0); + SET_SECURITY_STATE(bl32_image_ep_info.h.attr, SECURE); + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = 0; + + /* Pass TEE base and size to bl33 */ + bl33_image_ep_info.args.arg1 = BL32_BASE; + bl33_image_ep_info.args.arg2 = BL32_SIZE; +#endif + bl31_tz380_setup(); } diff --git a/plat/imx/imx8m/imx8mq/include/platform_def.h b/plat/imx/imx8m/imx8mq/include/platform_def.h index 3c212e378..9db3a137a 100644 --- a/plat/imx/imx8m/imx8mq/include/platform_def.h +++ b/plat/imx/imx8m/imx8mq/include/platform_def.h @@ -10,11 +10,11 @@ #define PLATFORM_STACK_SIZE 0x800 #define CACHE_WRITEBACK_GRANULE 64 -#define PLAT_PRIMARY_CPU 0x0 -#define PLATFORM_MAX_CPU_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) #define IMX_PWR_LVL0 MPIDR_AFFLVL0 @@ -32,7 +32,6 @@ #define BL31_BASE U(0x910000) #define BL31_LIMIT U(0x920000) -#define BL32_BASE U(0xfe000000) /* non-secure uboot base */ #define PLAT_NS_IMAGE_OFFSET U(0x40200000) diff --git a/plat/imx/imx8m/imx8mq/platform.mk b/plat/imx/imx8m/imx8mq/platform.mk index 44ce55587..80ebe4062 100644 --- a/plat/imx/imx8m/imx8mq/platform.mk +++ b/plat/imx/imx8m/imx8mq/platform.mk @@ -44,3 +44,9 @@ A53_DISABLE_NON_TEMPORAL_HINT := 0 ERRATA_A53_835769 := 1 ERRATA_A53_843419 := 1 ERRATA_A53_855873 := 1 + +BL32_BASE ?= 0xfe000000 +$(eval $(call add_define,BL32_BASE)) + +BL32_SIZE ?= 0x2000000 +$(eval $(call add_define,BL32_SIZE)) diff --git a/plat/imx/imx8m/include/imx8m_psci.h b/plat/imx/imx8m/include/imx8m_psci.h index 496640383..c33d25e82 100644 --- a/plat/imx/imx8m/include/imx8m_psci.h +++ b/plat/imx/imx8m/include/imx8m_psci.h @@ -15,13 +15,9 @@ int imx_pwr_domain_on(u_register_t mpidr); void imx_pwr_domain_on_finish(const psci_power_state_t *target_state); void imx_pwr_domain_off(const psci_power_state_t *target_state); int imx_validate_ns_entrypoint(uintptr_t ns_entrypoint); -int imx_validate_power_state(unsigned int power_state, psci_power_state_t *rq_state); void imx_cpu_standby(plat_local_state_t cpu_state); void imx_domain_suspend(const psci_power_state_t *target_state); void imx_domain_suspend_finish(const psci_power_state_t *target_state); -void imx_get_sys_suspend_power_state(psci_power_state_t *req_state); -void __dead2 imx_system_reset(void); -void __dead2 imx_system_off(void); void __dead2 imx_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state); #endif /* IMX8M_PSCI_H */ diff --git a/plat/imx/imx8qm/imx8qm_bl31_setup.c b/plat/imx/imx8qm/imx8qm_bl31_setup.c index c76de6461..9232cbc2d 100644 --- a/plat/imx/imx8qm/imx8qm_bl31_setup.c +++ b/plat/imx/imx8qm/imx8qm_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,12 +27,13 @@ #include <sci/sci.h> #include <sec_rsrc.h> -IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START); -IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END); -IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_START); -IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_END); +static const unsigned long BL31_COHERENT_RAM_START = BL_COHERENT_RAM_BASE; +static const unsigned long BL31_COHERENT_RAM_END = BL_COHERENT_RAM_END; +static const unsigned long BL31_RO_START = BL_CODE_BASE; +static const unsigned long BL31_RO_END = BL_CODE_END; +static const unsigned long BL31_RW_END = BL_END; + IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START); -IMPORT_SYM(unsigned long, __RW_END__, BL31_RW_END); static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; diff --git a/plat/imx/imx8qm/include/platform_def.h b/plat/imx/imx8qm/include/platform_def.h index 138a4e1d3..b54943da0 100644 --- a/plat/imx/imx8qm/include/platform_def.h +++ b/plat/imx/imx8qm/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,11 +15,11 @@ #define PLATFORM_STACK_SIZE 0X400 #define CACHE_WRITEBACK_GRANULE 64 -#define PLAT_PRIMARY_CPU 0x0 -#define PLATFORM_MAX_CPU_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 2 +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(2) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ PLATFORM_CLUSTER1_CORE_COUNT) diff --git a/plat/imx/imx8qx/imx8qx_bl31_setup.c b/plat/imx/imx8qx/imx8qx_bl31_setup.c index bfe405284..58c82ce60 100644 --- a/plat/imx/imx8qx/imx8qx_bl31_setup.c +++ b/plat/imx/imx8qx/imx8qx_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -27,12 +27,13 @@ #include <sci/sci.h> #include <sec_rsrc.h> -IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL31_COHERENT_RAM_START); -IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL31_COHERENT_RAM_END); -IMPORT_SYM(unsigned long, __RO_START__, BL31_RO_START); -IMPORT_SYM(unsigned long, __RO_END__, BL31_RO_END); +static const unsigned long BL31_COHERENT_RAM_START = BL_COHERENT_RAM_BASE; +static const unsigned long BL31_COHERENT_RAM_END = BL_COHERENT_RAM_END; +static const unsigned long BL31_RO_START = BL_CODE_BASE; +static const unsigned long BL31_RO_END = BL_CODE_END; +static const unsigned long BL31_RW_END = BL_END; + IMPORT_SYM(unsigned long, __RW_START__, BL31_RW_START); -IMPORT_SYM(unsigned long, __RW_END__, BL31_RW_END); static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; diff --git a/plat/imx/imx8qx/include/platform_def.h b/plat/imx/imx8qx/include/platform_def.h index 108627f66..41475ffeb 100644 --- a/plat/imx/imx8qx/include/platform_def.h +++ b/plat/imx/imx8qx/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,12 +15,12 @@ #define PLATFORM_STACK_SIZE 0x400 #define CACHE_WRITEBACK_GRANULE 64 -#define PLAT_PRIMARY_CPU 0x0 -#define PLATFORM_MAX_CPU_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CORE_COUNT 4 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLAT_PRIMARY_CPU U(0x0) +#define PLATFORM_MAX_CPU_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CORE_COUNT U(4) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PWR_DOMAIN_AT_MAX_LVL U(1) #define PLAT_MAX_PWR_LVL U(2) diff --git a/plat/intel/soc/agilex/bl2_plat_setup.c b/plat/intel/soc/agilex/bl2_plat_setup.c index e9ab92850..9587d4859 100644 --- a/plat/intel/soc/agilex/bl2_plat_setup.c +++ b/plat/intel/soc/agilex/bl2_plat_setup.c @@ -14,20 +14,17 @@ #include <drivers/synopsys/dw_mmc.h> #include <drivers/ti/uart/uart_16550.h> #include <lib/xlat_tables/xlat_tables.h> -#include <platform_def.h> -#include <socfpga_private.h> #include "agilex_clock_manager.h" -#include "agilex_handoff.h" -#include "agilex_mailbox.h" #include "agilex_memory_controller.h" #include "agilex_pinmux.h" -#include "agilex_private.h" -#include "agilex_reset_manager.h" -#include "agilex_system_manager.h" - #include "ccu/ncore_ccu.h" #include "qspi/cadence_qspi.h" +#include "socfpga_handoff.h" +#include "socfpga_mailbox.h" +#include "socfpga_private.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" #include "wdt/watchdog.h" @@ -59,7 +56,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, generic_delay_timer_init(); - if (agilex_get_handoff(&reverse_handoff_ptr)) + if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); boot_source = reverse_handoff_ptr.boot_source; @@ -77,7 +74,10 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, socfpga_delay_timer_init(); init_ncore_ccu(); init_hard_memory_controller(); - enable_ns_bridge_access(); + mailbox_init(); + + if (!intel_mailbox_is_fpga_not_ready()) + socfpga_bridges_enable(); } @@ -110,8 +110,6 @@ void bl2_el3_plat_arch_setup(void) info.mmc_dev_type = MMC_IS_SD; info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3; - mailbox_init(); - switch (boot_source) { case BOOT_SOURCE_SDMMC: dw_mmc_init(¶ms, &info); diff --git a/plat/intel/soc/agilex/bl31_plat_setup.c b/plat/intel/soc/agilex/bl31_plat_setup.c index c8765e857..375483dd4 100644 --- a/plat/intel/soc/agilex/bl31_plat_setup.c +++ b/plat/intel/soc/agilex/bl31_plat_setup.c @@ -12,7 +12,6 @@ #include <drivers/arm/gicv2.h> #include <drivers/ti/uart/uart_16550.h> #include <lib/xlat_tables/xlat_tables.h> -#include <platform_def.h> static entry_point_info_t bl32_image_ep_info; @@ -67,15 +66,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, } static const interrupt_prop_t s10_interrupt_props[] = { - PLAT_INTEL_AGX_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), - PLAT_INTEL_AGX_G0_IRQ_PROPS(GICV2_INTR_GROUP0) + PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0) }; static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; static const gicv2_driver_data_t plat_gicv2_gic_data = { - .gicd_base = PLAT_INTEL_AGX_GICD_BASE, - .gicc_base = PLAT_INTEL_AGX_GICC_BASE, + .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE, + .gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE, .interrupt_props = s10_interrupt_props, .interrupt_props_num = ARRAY_SIZE(s10_interrupt_props), .target_masks = target_mask_array, @@ -104,7 +103,7 @@ const mmap_region_t plat_agilex_mmap[] = { MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(MEM64_BASE, MEM64_SIZE, MT_DEVICE | MT_RW | MT_NS), MAP_REGION_FLAT(DEVICE4_BASE, DEVICE4_SIZE, MT_DEVICE | MT_RW | MT_NS), - {0}, + {0} }; /******************************************************************************* @@ -126,7 +125,7 @@ void bl31_plat_arch_setup(void) BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, MT_DEVICE | MT_RW | MT_SECURE), #endif - {0}, + {0} }; setup_page_tables(bl_regions, plat_agilex_mmap); diff --git a/plat/intel/soc/agilex/include/agilex_clock_manager.h b/plat/intel/soc/agilex/include/agilex_clock_manager.h index 73e6c4e19..8af6a60bc 100644 --- a/plat/intel/soc/agilex/include/agilex_clock_manager.h +++ b/plat/intel/soc/agilex/include/agilex_clock_manager.h @@ -7,7 +7,7 @@ #ifndef CLOCKMANAGER_H #define CLOCKMANAGER_H -#include "agilex_handoff.h" +#include "socfpga_handoff.h" /* Clock Manager Registers */ #define CLKMGR_OFFSET 0xffd10000 @@ -33,6 +33,7 @@ #define CLKMGR_MAINPLL_PLLC2 0x40 #define CLKMGR_MAINPLL_PLLC3 0x44 #define CLKMGR_MAINPLL_PLLM 0x48 +#define CLKMGR_MAINPLL_LOSTLOCK 0x54 /* Peripheral PLL Group */ #define CLKMGR_PERPLL 0xffd1007c @@ -50,6 +51,7 @@ #define CLKMGR_PERPLL_PLLC2 0x3c #define CLKMGR_PERPLL_PLLC3 0x40 #define CLKMGR_PERPLL_PLLM 0x44 +#define CLKMGR_PERPLL_LOSTLOCK 0x50 /* Altera Group */ #define CLKMGR_ALTERA 0xffd100d0 @@ -112,6 +114,7 @@ #define CLKMGR_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000003ff) #define CLKMGR_VCOCALIB_MSCNT_SET(x) (((x) << 16) & 0x00ff0000) +#define CLKMGR_CLR_LOSTLOCK_BYPASS 0x20000000 typedef struct { uint32_t clk_freq_of_eosc1; diff --git a/plat/intel/soc/agilex/include/agilex_memory_controller.h b/plat/intel/soc/agilex/include/agilex_memory_controller.h index 419bd2eff..3746d92fc 100644 --- a/plat/intel/soc/agilex/include/agilex_memory_controller.h +++ b/plat/intel/soc/agilex/include/agilex_memory_controller.h @@ -24,9 +24,6 @@ #define AGX_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value) \ (((value) & 0x00000060) >> 5) -#define AGX_RSTMGR_BRGMODRST 0xffd1102c -#define AGX_RSTMGR_BRGMODRST_DDRSCH 0x00000040 - #define AGX_MPFE_HMC_ADP_ECCCTRL1 0xf8011100 #define AGX_MPFE_HMC_ADP_ECCCTRL2 0xf8011104 #define AGX_MPFE_HMC_ADP_RSTHANDSHAKESTAT 0xf8011218 diff --git a/plat/intel/soc/agilex/include/agilex_pinmux.h b/plat/intel/soc/agilex/include/agilex_pinmux.h index e6a7b341d..fe01062c0 100644 --- a/plat/intel/soc/agilex/include/agilex_pinmux.h +++ b/plat/intel/soc/agilex/include/agilex_pinmux.h @@ -12,7 +12,7 @@ #define AGX_PINMUX_PINMUX_EMAC0_USEFPGA 0xffd13300 #define AGX_PINMUX_IO0_DELAY 0xffd13400 -#include "agilex_handoff.h" +#include "socfpga_handoff.h" void config_pinmux(handoff *handoff); diff --git a/plat/intel/soc/agilex/include/agilex_private.h b/plat/intel/soc/agilex/include/agilex_private.h deleted file mode 100644 index fc0e9fddf..000000000 --- a/plat/intel/soc/agilex/include/agilex_private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AGX_PRIVATE_H -#define AGX_PRIVATE_H - -#define AGX_MMC_REG_BASE 0xff808000 - -#define EMMC_DESC_SIZE (1<<20) -#define EMMC_INIT_PARAMS(base, clk) \ - { .bus_width = MMC_BUS_WIDTH_4, \ - .clk_rate = (clk), \ - .desc_base = (base), \ - .desc_size = EMMC_DESC_SIZE, \ - .flags = 0, \ - .reg_base = AGX_MMC_REG_BASE \ - } - -typedef enum { - BOOT_SOURCE_FPGA = 0, - BOOT_SOURCE_SDMMC, - BOOT_SOURCE_NAND, - BOOT_SOURCE_RSVD, - BOOT_SOURCE_QSPI -} boot_source_type; - -void enable_nonsecure_access(void); -void socfpga_io_setup(int boot_source); - -#endif diff --git a/plat/intel/soc/agilex/include/agilex_reset_manager.h b/plat/intel/soc/agilex/include/agilex_reset_manager.h deleted file mode 100644 index a1b6297c1..000000000 --- a/plat/intel/soc/agilex/include/agilex_reset_manager.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AGX_RESETMANAGER_H -#define AGX_RESETMANAGER_H - -#define AGX_RSTMGR_HDSKEN 0xffd11010 -#define AGX_RSTMGR_PER0MODRST 0xffd11024 -#define AGX_RSTMGR_PER1MODRST 0xffd11028 -#define AGX_RSTMGR_BRGMODRST 0xffd1102c - -#define AGX_RSTMGR_PER0MODRST_EMAC0 0x00000001 -#define AGX_RSTMGR_PER0MODRST_EMAC1 0x00000002 -#define AGX_RSTMGR_PER0MODRST_EMAC2 0x00000004 -#define AGX_RSTMGR_PER0MODRST_USB0 0x00000008 -#define AGX_RSTMGR_PER0MODRST_USB1 0x00000010 -#define AGX_RSTMGR_PER0MODRST_NAND 0x00000020 -#define AGX_RSTMGR_PER0MODRST_SDMMC 0x00000080 -#define AGX_RSTMGR_PER0MODRST_EMAC0OCP 0x00000100 -#define AGX_RSTMGR_PER0MODRST_EMAC1OCP 0x00000200 -#define AGX_RSTMGR_PER0MODRST_EMAC2OCP 0x00000400 -#define AGX_RSTMGR_PER0MODRST_USB0OCP 0x00000800 -#define AGX_RSTMGR_PER0MODRST_USB1OCP 0x00001000 -#define AGX_RSTMGR_PER0MODRST_NANDOCP 0x00002000 -#define AGX_RSTMGR_PER0MODRST_SDMMCOCP 0x00008000 -#define AGX_RSTMGR_PER0MODRST_DMA 0x00010000 -#define AGX_RSTMGR_PER0MODRST_SPIM0 0x00020000 -#define AGX_RSTMGR_PER0MODRST_SPIM1 0x00040000 -#define AGX_RSTMGR_PER0MODRST_SPIS0 0x00080000 -#define AGX_RSTMGR_PER0MODRST_SPIS1 0x00100000 -#define AGX_RSTMGR_PER0MODRST_DMAOCP 0x00200000 -#define AGX_RSTMGR_PER0MODRST_EMACPTP 0x00400000 -#define AGX_RSTMGR_PER0MODRST_DMAIF0 0x01000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF1 0x02000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF2 0x04000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF3 0x08000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF4 0x10000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF5 0x20000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF6 0x40000000 -#define AGX_RSTMGR_PER0MODRST_DMAIF7 0x80000000 - -#define AGX_RSTMGR_PER1MODRST_WATCHDOG0 0x1 -#define AGX_RSTMGR_PER1MODRST_WATCHDOG1 0x2 -#define AGX_RSTMGR_PER1MODRST_WATCHDOG2 0x4 -#define AGX_RSTMGR_PER1MODRST_WATCHDOG3 0x8 -#define AGX_RSTMGR_PER1MODRST_L4SYSTIMER0 0x00000010 -#define AGX_RSTMGR_PER1MODRST_L4SYSTIMER1 0x00000020 -#define AGX_RSTMGR_PER1MODRST_SPTIMER0 0x00000040 -#define AGX_RSTMGR_PER1MODRST_SPTIMER1 0x00000080 -#define AGX_RSTMGR_PER1MODRST_I2C0 0x00000100 -#define AGX_RSTMGR_PER1MODRST_I2C1 0x00000200 -#define AGX_RSTMGR_PER1MODRST_I2C2 0x00000400 -#define AGX_RSTMGR_PER1MODRST_I2C3 0x00000800 -#define AGX_RSTMGR_PER1MODRST_I2C4 0x00001000 -#define AGX_RSTMGR_PER1MODRST_UART0 0x00010000 -#define AGX_RSTMGR_PER1MODRST_UART1 0x00020000 -#define AGX_RSTMGR_PER1MODRST_GPIO0 0x01000000 -#define AGX_RSTMGR_PER1MODRST_GPIO1 0x02000000 - -#define AGX_RSTMGR_HDSKEN_FPGAHSEN 0x00000004 -#define AGX_RSTMGR_HDSKEN_ETRSTALLEN 0x00000008 -#define AGX_RSTMGR_HDSKEN_L2FLUSHEN 0x00000100 -#define AGX_RSTMGR_HDSKEN_L3NOC_DBG 0x00010000 -#define AGX_RSTMGR_HDSKEN_DEBUG_L3NOC 0x00020000 -#define AGX_RSTMGR_HDSKEN_SDRSELFREFEN 0x00000001 - -#define AGX_RSTMGR_BRGMODRST_SOC2FPGA 0x1 -#define AGX_RSTMGR_BRGMODRST_LWHPS2FPGA 0x2 -#define AGX_RSTMGR_BRGMODRST_FPGA2SOC 0x4 -#define AGX_RSTMGR_BRGMODRST_MPFE 0x40 - -void deassert_peripheral_reset(void); -void config_hps_hs_before_warm_reset(void); - -#endif - diff --git a/plat/intel/soc/agilex/include/agilex_system_manager.h b/plat/intel/soc/agilex/include/agilex_system_manager.h deleted file mode 100644 index 381c2d355..000000000 --- a/plat/intel/soc/agilex/include/agilex_system_manager.h +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef AGX_SYSTEMMANAGER_H -#define AGX_SYSTEMMANAGER_H - -#define AGX_FIREWALL_SOC2FPGA 0xffd21200 -#define AGX_FIREWALL_LWSOC2FPGA 0xffd21300 - -#define AGX_NOC_FW_L4_PER_SCR_NAND_REGISTER 0xffd21000 -#define AGX_NOC_FW_L4_PER_SCR_NAND_DATA 0xffd21004 -#define AGX_NOC_FW_L4_PER_SCR_USB0_REGISTER 0xffd2100c -#define AGX_NOC_FW_L4_PER_SCR_USB1_REGISTER 0xffd21010 -#define AGX_NOC_FW_L4_PER_SCR_SPI_MASTER0 0xffd2101c -#define AGX_NOC_FW_L4_PER_SCR_SPI_MASTER1 0xffd21020 -#define AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0xffd21024 -#define AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0xffd21028 -#define AGX_NOC_FW_L4_PER_SCR_EMAC0 0xffd2102c -#define AGX_NOC_FW_L4_PER_SCR_EMAC1 0xffd21030 -#define AGX_NOC_FW_L4_PER_SCR_EMAC2 0xffd21034 -#define AGX_NOC_FW_L4_PER_SCR_SDMMC 0xffd21040 -#define AGX_NOC_FW_L4_PER_SCR_GPIO0 0xffd21044 -#define AGX_NOC_FW_L4_PER_SCR_GPIO1 0xffd21048 -#define AGX_NOC_FW_L4_PER_SCR_I2C0 0xffd21050 -#define AGX_NOC_FW_L4_PER_SCR_I2C1 0xffd21054 -#define AGX_NOC_FW_L4_PER_SCR_I2C2 0xffd21058 -#define AGX_NOC_FW_L4_PER_SCR_I2C3 0xffd2105c -#define AGX_NOC_FW_L4_PER_SCR_I2C4 0xffd21060 -#define AGX_NOC_FW_L4_PER_SCR_SP_TIMER0 0xffd21064 -#define AGX_NOC_FW_L4_PER_SCR_SP_TIMER1 0xffd21068 -#define AGX_NOC_FW_L4_PER_SCR_UART0 0xffd2106c -#define AGX_NOC_FW_L4_PER_SCR_UART1 0xffd21070 - -#define AGX_NOC_FW_L4_SYS_SCR_DMA_ECC 0xffd21108 -#define AGX_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0xffd2110c -#define AGX_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0xffd21110 -#define AGX_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0xffd21114 -#define AGX_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0xffd21118 -#define AGX_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0xffd2111c -#define AGX_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0xffd21120 -#define AGX_NOC_FW_L4_SYS_SCR_NAND_ECC 0xffd2112c -#define AGX_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0xffd21130 -#define AGX_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0xffd21134 -#define AGX_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0xffd21138 -#define AGX_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0xffd21140 -#define AGX_NOC_FW_L4_SYS_SCR_USB0_ECC 0xffd21144 -#define AGX_NOC_FW_L4_SYS_SCR_USB1_ECC 0xffd21148 -#define AGX_NOC_FW_L4_SYS_SCR_CLK_MGR 0xffd2114c -#define AGX_NOC_FW_L4_SYS_SCR_IO_MGR 0xffd21154 -#define AGX_NOC_FW_L4_SYS_SCR_RST_MGR 0xffd21158 -#define AGX_NOC_FW_L4_SYS_SCR_SYS_MGR 0xffd2115c -#define AGX_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0xffd21160 -#define AGX_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0xffd21164 -#define AGX_NOC_FW_L4_SYS_SCR_WATCHDOG0 0xffd21168 -#define AGX_NOC_FW_L4_SYS_SCR_WATCHDOG1 0xffd2116c -#define AGX_NOC_FW_L4_SYS_SCR_WATCHDOG2 0xffd21170 -#define AGX_NOC_FW_L4_SYS_SCR_WATCHDOG3 0xffd21174 -#define AGX_NOC_FW_L4_SYS_SCR_DAP 0xffd21178 -#define AGX_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0xffd21190 -#define AGX_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0xffd21194 - -#define AGX_CCU_NOC_CPU0_RAMSPACE0_0 0xf7004688 -#define AGX_CCU_NOC_IOM_RAMSPACE0_0 0xf7018628 - -#define AGX_SYSMGR_CORE(x) (0xffd12000 + (x)) -#define SYSMGR_BOOT_SCRATCH_COLD_0 0x200 -#define SYSMGR_BOOT_SCRATCH_COLD_1 0x204 -#define SYSMGR_BOOT_SCRATCH_COLD_2 0x208 - -#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101 -#define DISABLE_L4_FIREWALL (BIT(0) | BIT(16) | BIT(24)) - -void enable_nonsecure_access(void); -void enable_ns_bridge_access(void); - -#endif diff --git a/plat/intel/soc/agilex/include/socfpga_plat_def.h b/plat/intel/soc/agilex/include/socfpga_plat_def.h new file mode 100644 index 000000000..b4e09210f --- /dev/null +++ b/plat/intel/soc/agilex/include/socfpga_plat_def.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_SOCFPGA_DEF_H +#define PLAT_SOCFPGA_DEF_H + +#include <platform_def.h> + +/* Platform Setting */ +#define PLATFORM_MODEL PLAT_SOCFPGA_AGILEX + +/* Register Mapping */ +#define SOCFPGA_MMC_REG_BASE 0xff808000 + +#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000 +#define SOCFPGA_SYSMGR_REG_BASE 0xffd12000 + +#define SOCFPGA_L4_PER_SCR_REG_BASE 0xffd21000 +#define SOCFPGA_L4_SYS_SCR_REG_BASE 0xffd21100 +#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0xffd21200 +#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0xffd21300 + +#endif /* PLAT_SOCFPGA_DEF_H */ + diff --git a/plat/intel/soc/agilex/platform.mk b/plat/intel/soc/agilex/platform.mk index 5d20462b7..f47c3f113 100644 --- a/plat/intel/soc/agilex/platform.mk +++ b/plat/intel/soc/agilex/platform.mk @@ -4,7 +4,7 @@ # # SPDX-License-Identifier: BSD-3-Clause # -# + PLAT_INCLUDES := \ -Iplat/intel/soc/agilex/include/ \ -Iplat/intel/soc/common/drivers/ \ @@ -25,50 +25,45 @@ PLAT_BL_COMMON_SOURCES := \ BL2_SOURCES += \ common/desc_image_load.c \ - drivers/partition/partition.c \ - drivers/partition/gpt.c \ - drivers/arm/pl061/pl061_gpio.c \ drivers/mmc/mmc.c \ - drivers/synopsys/emmc/dw_mmc.c \ + drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \ drivers/io/io_storage.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ - drivers/gpio/gpio.c \ - drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \ + drivers/partition/partition.c \ + drivers/partition/gpt.c \ + drivers/synopsys/emmc/dw_mmc.c \ lib/cpus/aarch64/cortex_a53.S \ plat/intel/soc/agilex/bl2_plat_setup.c \ - plat/intel/soc/agilex/socfpga_storage.c \ - plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/agilex/soc/agilex_reset_manager.c \ - plat/intel/soc/agilex/soc/agilex_handoff.c \ plat/intel/soc/agilex/soc/agilex_clock_manager.c \ - plat/intel/soc/agilex/soc/agilex_pinmux.c \ plat/intel/soc/agilex/soc/agilex_memory_controller.c \ + plat/intel/soc/agilex/soc/agilex_pinmux.c \ + plat/intel/soc/common/bl2_plat_mem_params_desc.c \ plat/intel/soc/common/socfpga_delay_timer.c \ plat/intel/soc/common/socfpga_image_load.c \ - plat/intel/soc/agilex/soc/agilex_system_manager.c \ - plat/intel/soc/agilex/soc/agilex_mailbox.c \ + plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_handoff.c \ + plat/intel/soc/common/soc/socfpga_mailbox.c \ + plat/intel/soc/common/soc/socfpga_reset_manager.c \ + plat/intel/soc/common/soc/socfpga_system_manager.c \ plat/intel/soc/common/drivers/qspi/cadence_qspi.c \ plat/intel/soc/common/drivers/wdt/watchdog.c \ plat/intel/soc/common/drivers/ccu/ncore_ccu.c BL31_SOURCES += \ drivers/arm/cci/cci.c \ - lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_psci_common.c \ - plat/intel/soc/agilex/socfpga_sip_svc.c \ plat/intel/soc/agilex/bl31_plat_setup.c \ - plat/intel/soc/agilex/socfpga_psci.c \ + plat/intel/soc/common/socfpga_psci.c \ + plat/intel/soc/common/socfpga_sip_svc.c \ plat/intel/soc/common/socfpga_topology.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ - plat/intel/soc/agilex/soc/agilex_reset_manager.c \ - plat/intel/soc/agilex/soc/agilex_pinmux.c \ - plat/intel/soc/agilex/soc/agilex_clock_manager.c \ - plat/intel/soc/agilex/soc/agilex_handoff.c \ - plat/intel/soc/agilex/soc/agilex_mailbox.c + plat/intel/soc/common/soc/socfpga_mailbox.c \ + plat/intel/soc/common/soc/socfpga_reset_manager.c PROGRAMMABLE_RESET_ADDRESS := 0 BL2_AT_EL3 := 1 +BL2_INV_DCACHE := 0 MULTI_CONSOLE_API := 1 USE_COHERENT_MEM := 1 diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c index 218676a98..c6c48baea 100644 --- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c +++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c @@ -11,8 +11,8 @@ #include <lib/mmio.h> #include "agilex_clock_manager.h" -#include "agilex_handoff.h" -#include "agilex_system_manager.h" +#include "socfpga_handoff.h" +#include "socfpga_system_manager.h" uint32_t wait_pll_lock(void) @@ -222,6 +222,16 @@ void config_clkmgr_handoff(handoff *hoff_ptr) mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_PSIREFCTR, hoff_ptr->alt_psirefctr); + /* Clear lost lock bypass mode */ + mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_LOSTLOCK, 0x1); + mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_LOSTLOCK, 0x1); + + mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB, + CLKMGR_CLR_LOSTLOCK_BYPASS); + + mmio_setbits_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB, + CLKMGR_CLR_LOSTLOCK_BYPASS); + /* Take all PLLs out of bypass */ mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0); wait_fsm(); @@ -251,9 +261,9 @@ void config_clkmgr_handoff(handoff *hoff_ptr) CLKMGR_PERPLL_EN_RESET); /* Pass clock source frequency into scratch register */ - mmio_write_32(AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1), + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), hoff_ptr->hps_osc_clk_h); - mmio_write_32(AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_2), + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), hoff_ptr->fpga_clk_hz); } @@ -265,14 +275,14 @@ uint32_t get_ref_clk(uint32_t pllglob) switch (CLKMGR_PSRC(pllglob)) { case CLKMGR_PLLGLOB_PSRC_EOSC1: - scr_reg = AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_1); + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1); ref_clk = mmio_read_32(scr_reg); break; case CLKMGR_PLLGLOB_PSRC_INTOSC: ref_clk = CLKMGR_INTOSC_HZ; break; case CLKMGR_PLLGLOB_PSRC_F2S: - scr_reg = AGX_SYSMGR_CORE(SYSMGR_BOOT_SCRATCH_COLD_2); + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2); ref_clk = mmio_read_32(scr_reg); break; default: diff --git a/plat/intel/soc/agilex/soc/agilex_memory_controller.c b/plat/intel/soc/agilex/soc/agilex_memory_controller.c index f09238c1c..2aabe87cc 100644 --- a/plat/intel/soc/agilex/soc/agilex_memory_controller.c +++ b/plat/intel/soc/agilex/soc/agilex_memory_controller.c @@ -20,9 +20,8 @@ #define PRE_CALIBRATION_DELAY 1 #define POST_CALIBRATION_DELAY 1 #define TIMEOUT_EMIF_CALIBRATION 1000 -#define CLEAR_EMIF_DELAY 50000 -#define CLEAR_EMIF_TIMEOUT 0x100000 -#define TIMEOUT_INT_RESP 10000 +#define CLEAR_EMIF_DELAY 1000 +#define CLEAR_EMIF_TIMEOUT 1000 #define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R)) #define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t)) @@ -125,7 +124,7 @@ static int mem_calibration(void) data = mmio_read_32(AGX_MPFE_HMC_ADP_DDRCALSTAT); if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1) break; - mdelay(1); + udelay(500); } while (++timeout < TIMEOUT_EMIF_CALIBRATION); if (AGX_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) { @@ -160,8 +159,6 @@ int init_hard_memory_controller(void) return status; } -/* mmio_clrbits_32(AGX_RSTMGR_BRGMODRST, AGX_RSTMGR_BRGMODRST_DDRSCH);*/ - status = mem_calibration(); if (status) { ERROR("DDR: Memory Calibration Failed\n"); @@ -169,7 +166,6 @@ int init_hard_memory_controller(void) } configure_hmc_adaptor_regs(); -/* configure_ddr_sched_ctrl_regs();*/ return 0; } @@ -359,16 +355,17 @@ void configure_hmc_adaptor_regs(void) mmio_write_32(AGX_MPFE_HMC_ADP(ADP_DRAMADDRWIDTH), data); /* Enable nonsecure access to DDR */ - mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT, - AGX_DDR_SIZE - 1); - mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT, - 0x1f); + data = get_physical_dram_size(); - mmio_write_32(AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT, - AGX_DDR_SIZE - 1); + if (data < AGX_DDR_SIZE) + data = AGX_DDR_SIZE; - mmio_write_32(AGX_SOC_NOC_FW_DDR_SCR_ENABLESET, BIT(0) | BIT(8)); + mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMIT, data - 1); + mmio_write_32(AGX_NOC_FW_DDR_SCR_MPUREGION0ADDR_LIMITEXT, 0x1f); + mmio_write_32(AGX_NOC_FW_DDR_SCR_NONMPUREGION0ADDR_LIMIT, data - 1); + + mmio_write_32(AGX_SOC_NOC_FW_DDR_SCR_ENABLESET, BIT(0) | BIT(8)); /* ECC enablement */ data = mmio_read_32(AGX_MPFE_IOHMC_REG_CTRLCFG1); diff --git a/plat/intel/soc/agilex/soc/agilex_reset_manager.c b/plat/intel/soc/agilex/soc/agilex_reset_manager.c deleted file mode 100644 index 65d2029df..000000000 --- a/plat/intel/soc/agilex/soc/agilex_reset_manager.c +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/mmio.h> - -#include "agilex_reset_manager.h" - -void deassert_peripheral_reset(void) -{ - mmio_clrbits_32(AGX_RSTMGR_PER1MODRST, - AGX_RSTMGR_PER1MODRST_WATCHDOG0 | - AGX_RSTMGR_PER1MODRST_WATCHDOG1 | - AGX_RSTMGR_PER1MODRST_WATCHDOG2 | - AGX_RSTMGR_PER1MODRST_WATCHDOG3 | - AGX_RSTMGR_PER1MODRST_L4SYSTIMER0 | - AGX_RSTMGR_PER1MODRST_L4SYSTIMER1 | - AGX_RSTMGR_PER1MODRST_SPTIMER0 | - AGX_RSTMGR_PER1MODRST_SPTIMER1 | - AGX_RSTMGR_PER1MODRST_I2C0 | - AGX_RSTMGR_PER1MODRST_I2C1 | - AGX_RSTMGR_PER1MODRST_I2C2 | - AGX_RSTMGR_PER1MODRST_I2C3 | - AGX_RSTMGR_PER1MODRST_I2C4 | - AGX_RSTMGR_PER1MODRST_UART0 | - AGX_RSTMGR_PER1MODRST_UART1 | - AGX_RSTMGR_PER1MODRST_GPIO0 | - AGX_RSTMGR_PER1MODRST_GPIO1); - - mmio_clrbits_32(AGX_RSTMGR_PER0MODRST, - AGX_RSTMGR_PER0MODRST_EMAC0OCP | - AGX_RSTMGR_PER0MODRST_EMAC1OCP | - AGX_RSTMGR_PER0MODRST_EMAC2OCP | - AGX_RSTMGR_PER0MODRST_USB0OCP | - AGX_RSTMGR_PER0MODRST_USB1OCP | - AGX_RSTMGR_PER0MODRST_NANDOCP | - AGX_RSTMGR_PER0MODRST_SDMMCOCP | - AGX_RSTMGR_PER0MODRST_DMAOCP); - - mmio_clrbits_32(AGX_RSTMGR_PER0MODRST, - AGX_RSTMGR_PER0MODRST_EMAC0 | - AGX_RSTMGR_PER0MODRST_EMAC1 | - AGX_RSTMGR_PER0MODRST_EMAC2 | - AGX_RSTMGR_PER0MODRST_USB0 | - AGX_RSTMGR_PER0MODRST_USB1 | - AGX_RSTMGR_PER0MODRST_NAND | - AGX_RSTMGR_PER0MODRST_SDMMC | - AGX_RSTMGR_PER0MODRST_DMA | - AGX_RSTMGR_PER0MODRST_SPIM0 | - AGX_RSTMGR_PER0MODRST_SPIM1 | - AGX_RSTMGR_PER0MODRST_SPIS0 | - AGX_RSTMGR_PER0MODRST_SPIS1 | - AGX_RSTMGR_PER0MODRST_EMACPTP | - AGX_RSTMGR_PER0MODRST_DMAIF0 | - AGX_RSTMGR_PER0MODRST_DMAIF1 | - AGX_RSTMGR_PER0MODRST_DMAIF2 | - AGX_RSTMGR_PER0MODRST_DMAIF3 | - AGX_RSTMGR_PER0MODRST_DMAIF4 | - AGX_RSTMGR_PER0MODRST_DMAIF5 | - AGX_RSTMGR_PER0MODRST_DMAIF6 | - AGX_RSTMGR_PER0MODRST_DMAIF7); - - mmio_clrbits_32(AGX_RSTMGR_BRGMODRST, - AGX_RSTMGR_BRGMODRST_MPFE); -} - -void config_hps_hs_before_warm_reset(void) -{ - uint32_t or_mask = 0; - - or_mask |= AGX_RSTMGR_HDSKEN_SDRSELFREFEN; - or_mask |= AGX_RSTMGR_HDSKEN_FPGAHSEN; - or_mask |= AGX_RSTMGR_HDSKEN_ETRSTALLEN; - or_mask |= AGX_RSTMGR_HDSKEN_L2FLUSHEN; - or_mask |= AGX_RSTMGR_HDSKEN_L3NOC_DBG; - or_mask |= AGX_RSTMGR_HDSKEN_DEBUG_L3NOC; - - mmio_setbits_32(AGX_RSTMGR_HDSKEN, or_mask); -} - diff --git a/plat/intel/soc/agilex/soc/agilex_system_manager.c b/plat/intel/soc/agilex/soc/agilex_system_manager.c deleted file mode 100644 index 88e895d66..000000000 --- a/plat/intel/soc/agilex/soc/agilex_system_manager.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/mmio.h> -#include <lib/utils_def.h> - -#include "agilex_system_manager.h" - -void enable_nonsecure_access(void) -{ - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_NAND_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_NAND_DATA, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_NAND_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_NAND_READ_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC, - DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_USB0_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_USB1_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_USB0_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_USB1_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SPI_MASTER0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SPI_MASTER1, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SPI_SLAVE1, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_EMAC0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_EMAC1, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_EMAC2, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SDMMC, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_SDMMC_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_GPIO0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_GPIO1, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_I2C0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_I2C1, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_I2C2, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_I2C3, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_I2C4, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_SP_TIMER1, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_UART0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_PER_SCR_UART1, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_DMA_ECC, DISABLE_L4_FIREWALL); - - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_OCRAM_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_CLK_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_IO_MGR, DISABLE_L4_FIREWALL); - - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_RST_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_SYS_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_OSC0_TIMER, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_OSC1_TIMER, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_WATCHDOG0, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_WATCHDOG1, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_WATCHDOG2, DISABLE_L4_FIREWALL); - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_WATCHDOG3, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_DAP, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES, DISABLE_L4_FIREWALL); - - mmio_write_32(AGX_NOC_FW_L4_SYS_SCR_L4_NOC_QOS, DISABLE_L4_FIREWALL); -} - -void enable_ns_bridge_access(void) -{ - mmio_write_32(AGX_FIREWALL_SOC2FPGA, DISABLE_BRIDGE_FIREWALL); - mmio_write_32(AGX_FIREWALL_LWSOC2FPGA, DISABLE_BRIDGE_FIREWALL); -} diff --git a/plat/intel/soc/agilex/socfpga_sip_svc.c b/plat/intel/soc/agilex/socfpga_sip_svc.c deleted file mode 100644 index 6a1c957c3..000000000 --- a/plat/intel/soc/agilex/socfpga_sip_svc.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <common/debug.h> -#include <common/runtime_svc.h> -#include <tools_share/uuid.h> - -#include "agilex_mailbox.h" - -/* Number of SiP Calls implemented */ -#define SIP_NUM_CALLS 0x3 - -/* Total buffer the driver can hold */ -#define FPGA_CONFIG_BUFFER_SIZE 4 - -int current_block; -int current_buffer; -int current_id = 1; -int max_blocks; -uint32_t bytes_per_block; -uint32_t blocks_submitted; -uint32_t blocks_completed; - -struct fpga_config_info { - uint32_t addr; - int size; - int size_written; - uint32_t write_requested; - int subblocks_sent; - int block_number; -}; - -/* SiP Service UUID */ -DEFINE_SVC_UUID2(intl_svc_uid, - 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a, - 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81); - -uint64_t socfpga_sip_handler(uint32_t smc_fid, - uint64_t x1, - uint64_t x2, - uint64_t x3, - uint64_t x4, - void *cookie, - void *handle, - uint64_t flags) -{ - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); -} - -struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; - -static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) -{ - uint32_t args[3]; - - while (max_blocks > 0 && buffer->size > buffer->size_written) { - if (buffer->size - buffer->size_written <= - bytes_per_block) { - args[0] = (1<<8); - args[1] = buffer->addr + buffer->size_written; - args[2] = buffer->size - buffer->size_written; - buffer->size_written += - buffer->size - buffer->size_written; - buffer->subblocks_sent++; - mailbox_send_cmd_async(0x4, - MBOX_RECONFIG_DATA, - args, 3, 0); - current_buffer++; - current_buffer %= FPGA_CONFIG_BUFFER_SIZE; - } else { - args[0] = (1<<8); - args[1] = buffer->addr + buffer->size_written; - args[2] = bytes_per_block; - buffer->size_written += bytes_per_block; - mailbox_send_cmd_async(0x4, - MBOX_RECONFIG_DATA, - args, 3, 0); - buffer->subblocks_sent++; - } - max_blocks--; - } -} - -static int intel_fpga_sdm_write_all(void) -{ - int i; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) - intel_fpga_sdm_write_buffer( - &fpga_config_buffers[current_buffer]); - - return 0; -} - -uint32_t intel_mailbox_fpga_config_isdone(void) -{ - uint32_t args[2]; - uint32_t response[6]; - int status; - - status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0, - response); - - if (status < 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (response[RECONFIG_STATUS_STATE] && - response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS)) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_SEU_ERROR) - return INTEL_SIP_SMC_STATUS_ERROR; - - if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_CONF_DONE) && - (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_INIT_DONE)) - return INTEL_SIP_SMC_STATUS_OK; - - return INTEL_SIP_SMC_STATUS_ERROR; -} - -static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) -{ - int i; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (fpga_config_buffers[i].block_number == current_block) { - fpga_config_buffers[i].subblocks_sent--; - if (fpga_config_buffers[i].subblocks_sent == 0 - && fpga_config_buffers[i].size <= - fpga_config_buffers[i].size_written) { - fpga_config_buffers[i].write_requested = 0; - current_block++; - *buffer_addr_completed = - fpga_config_buffers[i].addr; - return 0; - } - } - } - - return -1; -} - -unsigned int address_in_ddr(uint32_t *addr) -{ - if (((unsigned long long)addr > DRAM_BASE) && - ((unsigned long long)addr < DRAM_BASE + DRAM_SIZE)) - return 0; - - return -1; -} - -int intel_fpga_config_completed_write(uint32_t *completed_addr, - uint32_t *count) -{ - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - *count = 0; - int resp_len = 0; - uint32_t resp[5]; - int all_completed = 1; - int count_check = 0; - - if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - for (count_check = 0; count_check < 3; count_check++) - if (address_in_ddr(&completed_addr[*count + count_check]) != 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - resp_len = mailbox_read_response(0x4, resp); - - while (resp_len >= 0 && *count < 3) { - max_blocks++; - if (mark_last_buffer_xfer_completed( - &completed_addr[*count]) == 0) - *count = *count + 1; - else - break; - resp_len = mailbox_read_response(0x4, resp); - } - - if (*count <= 0) { - if (resp_len != MBOX_NO_RESPONSE && - resp_len != MBOX_TIMEOUT && resp_len != 0) { - return INTEL_SIP_SMC_STATUS_ERROR; - } - - *count = 0; - } - - intel_fpga_sdm_write_all(); - - if (*count > 0) - status = INTEL_SIP_SMC_STATUS_OK; - else if (*count == 0) - status = INTEL_SIP_SMC_STATUS_BUSY; - - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (fpga_config_buffers[i].write_requested != 0) { - all_completed = 0; - break; - } - } - - if (all_completed == 1) - return INTEL_SIP_SMC_STATUS_OK; - - return status; -} - -int intel_fpga_config_start(uint32_t config_type) -{ - uint32_t response[3]; - int status = 0; - - status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0, - response); - - if (status < 0) - return status; - - max_blocks = response[0]; - bytes_per_block = response[1]; - - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - fpga_config_buffers[i].size = 0; - fpga_config_buffers[i].size_written = 0; - fpga_config_buffers[i].addr = 0; - fpga_config_buffers[i].write_requested = 0; - fpga_config_buffers[i].block_number = 0; - fpga_config_buffers[i].subblocks_sent = 0; - } - - blocks_submitted = 0; - current_block = 0; - current_buffer = 0; - - return 0; -} - - -uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) -{ - int i = 0; - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - - if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE) - status = INTEL_SIP_SMC_STATUS_REJECTED; - - if (mem + size > DRAM_BASE + DRAM_SIZE) - status = INTEL_SIP_SMC_STATUS_REJECTED; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (!fpga_config_buffers[i].write_requested) { - fpga_config_buffers[i].addr = mem; - fpga_config_buffers[i].size = size; - fpga_config_buffers[i].size_written = 0; - fpga_config_buffers[i].write_requested = 1; - fpga_config_buffers[i].block_number = - blocks_submitted++; - fpga_config_buffers[i].subblocks_sent = 0; - break; - } - } - - - if (i == FPGA_CONFIG_BUFFER_SIZE) { - status = INTEL_SIP_SMC_STATUS_REJECTED; - return status; - } else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) { - status = INTEL_SIP_SMC_STATUS_BUSY; - } - - intel_fpga_sdm_write_all(); - - return status; -} - -/* - * This function is responsible for handling all SiP calls from the NS world - */ - -uintptr_t sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - uint32_t completed_addr[3]; - uint32_t count = 0; - - switch (smc_fid) { - case SIP_SVC_UID: - /* Return UID to the caller */ - SMC_UUID_RET(handle, intl_svc_uid); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE: - status = intel_mailbox_fpga_config_isdone(); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM: - SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK, - INTEL_SIP_SMC_FPGA_CONFIG_ADDR, - INTEL_SIP_SMC_FPGA_CONFIG_SIZE - - INTEL_SIP_SMC_FPGA_CONFIG_ADDR); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_START: - status = intel_fpga_config_start(x1); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_WRITE: - status = intel_fpga_config_write(x1, x2); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: - status = intel_fpga_config_completed_write(completed_addr, - &count); - switch (count) { - case 1: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], 0, 0); - break; - case 2: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], - completed_addr[1], 0); - break; - case 3: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], - completed_addr[1], - completed_addr[2]); - break; - case 0: - SMC_RET4(handle, status, 0, 0, 0); - break; - default: - SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR); - } - break; - - default: - return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, - cookie, handle, flags); - } -} - -DECLARE_RT_SVC( - agilex_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - sip_smc_handler -); - -DECLARE_RT_SVC( - agilex_sip_svc_std, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_YIELD, - NULL, - sip_smc_handler -); diff --git a/plat/intel/soc/common/aarch64/plat_helpers.S b/plat/intel/soc/common/aarch64/plat_helpers.S index 00fe2d999..5cb9b699a 100644 --- a/plat/intel/soc/common/aarch64/plat_helpers.S +++ b/plat/intel/soc/common/aarch64/plat_helpers.S @@ -8,6 +8,7 @@ #include <asm_macros.S> #include <cpu_macros.S> #include <platform_def.h> +#include <el3_common_macros.S> .globl plat_secondary_cold_boot_setup .globl platform_is_primary_cpu @@ -17,6 +18,7 @@ .globl plat_crash_console_putc .globl plat_crash_console_flush .globl platform_mem_init + .globl plat_secondary_cpus_bl31_entry .globl plat_get_my_entrypoint @@ -33,7 +35,6 @@ func plat_secondary_cold_boot_setup /* Wait until the it gets reset signal from rstmgr gets populated */ poll_mailbox: wfi - mov_imm x0, PLAT_SEC_ENTRY ldr x1, [x0] mov_imm x2, PLAT_CPUID_RELEASE @@ -65,12 +66,34 @@ func plat_my_core_pos ret endfunc plat_my_core_pos +func warm_reset_req + str xzr, [x4] + bl plat_is_my_cpu_primary + cbz x0, cpu_in_wfi + mov_imm x1, PLAT_SEC_ENTRY + str xzr, [x1] + mrs x1, rmr_el3 + orr x1, x1, #0x02 + msr rmr_el3, x1 + isb + dsb sy +cpu_in_wfi: + wfi + b cpu_in_wfi +endfunc warm_reset_req + func plat_get_my_entrypoint + ldr x4, =L2_RESET_DONE_REG + ldr x5, [x4] + ldr x1, =L2_RESET_DONE_STATUS + cmp x1, x5 + b.eq warm_reset_req mov_imm x1, PLAT_SEC_ENTRY ldr x0, [x1] ret endfunc plat_get_my_entrypoint + /* --------------------------------------------- * int plat_crash_console_init(void) * Function to initialize the crash console @@ -114,3 +137,14 @@ func platform_mem_init mov x0, #0 ret endfunc platform_mem_init + +func plat_secondary_cpus_bl31_entry + el3_entrypoint_common \ + _init_sctlr=0 \ + _warm_boot_mailbox=!PROGRAMMABLE_RESET_ADDRESS \ + _secondary_cold_boot=!COLD_BOOT_SINGLE_CPU \ + _init_memory=1 \ + _init_c_runtime=1 \ + _exception_vectors=runtime_exceptions \ + _pie_fixup_size=BL31_LIMIT - BL31_BASE +endfunc plat_secondary_cpus_bl31_entry diff --git a/plat/intel/soc/common/aarch64/platform_common.c b/plat/intel/soc/common/aarch64/platform_common.c index 6d3d817d6..b79a63c86 100644 --- a/plat/intel/soc/common/aarch64/platform_common.c +++ b/plat/intel/soc/common/aarch64/platform_common.c @@ -8,7 +8,8 @@ #include <arch_helpers.h> #include <platform_def.h> #include <plat/common/platform.h> -#include <socfpga_private.h> + +#include "socfpga_private.h" unsigned int plat_get_syscnt_freq2(void) diff --git a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c index ac8218ecd..fce816b65 100644 --- a/plat/intel/soc/common/drivers/ccu/ncore_ccu.c +++ b/plat/intel/soc/common/drivers/ccu/ncore_ccu.c @@ -10,7 +10,6 @@ #include <lib/mmio.h> #include "ncore_ccu.h" -#include <platform_def.h> uint32_t poll_active_bit(uint32_t dir); diff --git a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c index 0fd11ec78..cecf56088 100644 --- a/plat/intel/soc/common/drivers/qspi/cadence_qspi.c +++ b/plat/intel/soc/common/drivers/qspi/cadence_qspi.c @@ -13,7 +13,6 @@ #include <drivers/console.h> #include "cadence_qspi.h" -#include <platform_def.h> #define LESS(a, b) (((a) < (b)) ? (a) : (b)) #define MORE(a, b) (((a) > (b)) ? (a) : (b)) @@ -689,10 +688,7 @@ int cad_qspi_read(void *buffer, uint32_t offset, uint32_t size) if ((offset >= qspi_device_size) || (offset + size - 1 >= qspi_device_size) || - (size == 0) || - ((long) ((int *)buffer) & 0x3) || - (offset & 0x3) || - (size & 0x3)) { + (size == 0)) { ERROR("Invalid read parameter\n"); return -1; } @@ -767,11 +763,9 @@ int cad_qspi_write(void *buffer, uint32_t offset, uint32_t size) if ((offset >= qspi_device_size) || (offset + size - 1 >= qspi_device_size) || - (size == 0) || - ((long)buffer & 0x3) || - (offset & 0x3) || - (size & 0x3)) + (size == 0)) { return -2; + } if (CAD_QSPI_INDWR_RDSTAT(mmio_read_32(CAD_QSPI_OFFSET + CAD_QSPI_INDWR))) { diff --git a/plat/intel/soc/common/drivers/wdt/watchdog.c b/plat/intel/soc/common/drivers/wdt/watchdog.c index 0f89b4fd3..651189b12 100644 --- a/plat/intel/soc/common/drivers/wdt/watchdog.c +++ b/plat/intel/soc/common/drivers/wdt/watchdog.c @@ -6,7 +6,6 @@ #include <common/debug.h> #include <lib/mmio.h> -#include <platform_def.h> #include "watchdog.h" diff --git a/plat/intel/soc/agilex/include/platform_def.h b/plat/intel/soc/common/include/platform_def.h index 277862a30..8a681e69d 100644 --- a/plat/intel/soc/agilex/include/platform_def.h +++ b/plat/intel/soc/common/include/platform_def.h @@ -13,12 +13,23 @@ #include <common/tbbr/tbbr_img_def.h> #include <plat/common/common_def.h> +#define PLAT_SOCFPGA_STRATIX10 1 +#define PLAT_SOCFPGA_AGILEX 2 -#define PLAT_CPUID_RELEASE 0xffe1b000 -#define PLAT_SEC_ENTRY 0xffe1b008 +/* sysmgr.boot_scratch_cold4 & 5 used for CPU release address for SPL */ +#define PLAT_CPU_RELEASE_ADDR 0xffd12210 + +/* + * sysmgr.boot_scratch_cold6 & 7 (64bit) are used to indicate L2 reset + * is done and HPS should trigger warm reset via RMR_EL3. + */ +#define L2_RESET_DONE_REG 0xFFD12218 + +/* Magic word to indicate L2 reset is completed */ +#define L2_RESET_DONE_STATUS 0x1228E5E7 /* Define next boot image name and offset */ -#define PLAT_NS_IMAGE_OFFSET 0x50000 +#define PLAT_NS_IMAGE_OFFSET 0x10000000 #define PLAT_HANDOFF_OFFSET 0xFFE3F000 /******************************************************************************* @@ -27,7 +38,7 @@ #define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" #define PLATFORM_LINKER_ARCH aarch64 -/* Agilex supports up to 124GB RAM */ +/* SoCFPGA supports up to 124GB RAM */ #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 39) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 39) @@ -46,28 +57,28 @@ #define PLAT_MAX_PWR_LVL 1 #define PLAT_MAX_RET_STATE 1 #define PLAT_MAX_OFF_STATE 2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) /* Interrupt related constant */ -#define INTEL_AGX_IRQ_SEC_PHY_TIMER 29 +#define INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER 29 -#define INTEL_AGX_IRQ_SEC_SGI_0 8 -#define INTEL_AGX_IRQ_SEC_SGI_1 9 -#define INTEL_AGX_IRQ_SEC_SGI_2 10 -#define INTEL_AGX_IRQ_SEC_SGI_3 11 -#define INTEL_AGX_IRQ_SEC_SGI_4 12 -#define INTEL_AGX_IRQ_SEC_SGI_5 13 -#define INTEL_AGX_IRQ_SEC_SGI_6 14 -#define INTEL_AGX_IRQ_SEC_SGI_7 15 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_0 8 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_1 9 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_2 10 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_3 11 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_4 12 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_5 13 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_6 14 +#define INTEL_SOCFPGA_IRQ_SEC_SGI_7 15 -#define TSP_IRQ_SEC_PHY_TIMER INTEL_AGX_IRQ_SEC_PHY_TIMER +#define TSP_IRQ_SEC_PHY_TIMER INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER #define TSP_SEC_MEM_BASE BL32_BASE #define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE + 1) /******************************************************************************* @@ -104,19 +115,24 @@ */ -#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" +#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" -#define BL1_RO_BASE (0xffe00000) -#define BL1_RO_LIMIT (0xffe0f000) -#define BL1_RW_BASE (0xffe10000) -#define BL1_RW_LIMIT (0xffe1ffff) -#define BL1_RW_SIZE (0x14000) +#define BL1_RO_BASE (0xffe00000) +#define BL1_RO_LIMIT (0xffe0f000) +#define BL1_RW_BASE (0xffe10000) +#define BL1_RW_LIMIT (0xffe1ffff) +#define BL1_RW_SIZE (0x14000) -#define BL2_BASE (0xffe00000) -#define BL2_LIMIT (0xffe1b000) +#define BL2_BASE (0xffe00000) +#define BL2_LIMIT (0xffe1b000) -#define BL31_BASE (0xffe1c000) -#define BL31_LIMIT (0xffe3bfff) +#define BL31_BASE (0x1000) +#define BL31_LIMIT (0x81000) + +#define BL_DATA_LIMIT PLAT_HANDOFF_OFFSET + +#define PLAT_CPUID_RELEASE (BL_DATA_LIMIT - 16) +#define PLAT_SEC_ENTRY (BL_DATA_LIMIT - 8) /******************************************************************************* * Platform specific page table and MMU setup constants @@ -158,39 +174,50 @@ #define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000) #define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400) -#define PLAT_INTEL_AGX_GICD_BASE PLAT_GICD_BASE -#define PLAT_INTEL_AGX_GICC_BASE PLAT_GICC_BASE +#define PLAT_INTEL_SOCFPGA_GICD_BASE PLAT_GICD_BASE +#define PLAT_INTEL_SOCFPGA_GICC_BASE PLAT_GICC_BASE /* * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 * terminology. On a GICv2 system or mode, the lists will be merged and treated * as Group 0 interrupts. */ -#define PLAT_INTEL_AGX_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_AGX_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE) - -#define PLAT_INTEL_AGX_G0_IRQ_PROPS(grp) +#define PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(grp) \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_PHY_TIMER, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_LEVEL), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_0, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_1, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_2, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_3, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_4, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_5, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_6, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(INTEL_SOCFPGA_IRQ_SEC_SGI_7, \ + GIC_HIGHEST_SEC_PRIORITY, grp, GIC_INTR_CFG_EDGE) + +#define PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(grp) #define MAX_IO_HANDLES 4 #define MAX_IO_DEVICES 4 #define MAX_IO_BLOCK_DEVICES 2 +#ifndef __ASSEMBLER__ +struct socfpga_bl31_params { + param_header_t h; + image_info_t *bl31_image_info; + entry_point_info_t *bl32_ep_info; + image_info_t *bl32_image_info; + entry_point_info_t *bl33_ep_info; + image_info_t *bl33_image_info; +}; +#endif + #endif /* PLATFORM_DEF_H */ diff --git a/plat/intel/soc/agilex/include/agilex_handoff.h b/plat/intel/soc/common/include/socfpga_handoff.h index 201640611..889d13767 100644 --- a/plat/intel/soc/agilex/include/agilex_handoff.h +++ b/plat/intel/soc/common/include/socfpga_handoff.h @@ -15,6 +15,8 @@ #define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */ #define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */ +#include <socfpga_plat_def.h> + typedef struct handoff_t { /* header */ uint32_t header_magic; @@ -47,6 +49,44 @@ typedef struct handoff_t { uint32_t pinmux_iodelay_array[96]; /* offset, value */ /* clock configuration */ + +#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10 + uint32_t clock_magic; + uint32_t clock_length; + uint32_t _pad_0x588_0x590[2]; + uint32_t main_pll_mpuclk; + uint32_t main_pll_nocclk; + uint32_t main_pll_cntr2clk; + uint32_t main_pll_cntr3clk; + uint32_t main_pll_cntr4clk; + uint32_t main_pll_cntr5clk; + uint32_t main_pll_cntr6clk; + uint32_t main_pll_cntr7clk; + uint32_t main_pll_cntr8clk; + uint32_t main_pll_cntr9clk; + uint32_t main_pll_nocdiv; + uint32_t main_pll_pllglob; + uint32_t main_pll_fdbck; + uint32_t main_pll_pllc0; + uint32_t main_pll_pllc1; + uint32_t _pad_0x5cc_0x5d0[1]; + uint32_t per_pll_cntr2clk; + uint32_t per_pll_cntr3clk; + uint32_t per_pll_cntr4clk; + uint32_t per_pll_cntr5clk; + uint32_t per_pll_cntr6clk; + uint32_t per_pll_cntr7clk; + uint32_t per_pll_cntr8clk; + uint32_t per_pll_cntr9clk; + uint32_t per_pll_emacctl; + uint32_t per_pll_gpiodiv; + uint32_t per_pll_pllglob; + uint32_t per_pll_fdbck; + uint32_t per_pll_pllc0; + uint32_t per_pll_pllc1; + uint32_t hps_osc_clk_h; + uint32_t fpga_clk_hz; +#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX uint32_t clock_magic; uint32_t clock_length; uint32_t _pad_0x588_0x590[2]; @@ -80,7 +120,7 @@ typedef struct handoff_t { uint32_t hps_osc_clk_h; uint32_t fpga_clk_hz; uint32_t _pad_0x604_0x610[3]; - +#endif /* misc configuration */ uint32_t misc_magic; uint32_t misc_length; @@ -89,7 +129,7 @@ typedef struct handoff_t { } handoff; int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr); -int agilex_get_handoff(handoff *hoff_ptr); +int socfpga_get_handoff(handoff *hoff_ptr); #endif diff --git a/plat/intel/soc/agilex/include/agilex_mailbox.h b/plat/intel/soc/common/include/socfpga_mailbox.h index cd8be2894..c4b9e5967 100644 --- a/plat/intel/soc/agilex/include/agilex_mailbox.h +++ b/plat/intel/soc/common/include/socfpga_mailbox.h @@ -4,13 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef AGX_MBOX_H -#define AGX_MBOX_H +#ifndef SOCFPGA_MBOX_H +#define SOCFPGA_MBOX_H #include <lib/utils_def.h> #define MBOX_OFFSET 0xffa30000 +#define MBOX_MAX_JOB_ID 0xf #define MBOX_ATF_CLIENT_ID 0x1 #define MBOX_JOB_ID 0x1 @@ -66,6 +67,9 @@ #define MBOX_CMD_GET_IDCODE 16 #define MBOX_CMD_QSPI_SET_CS 52 +/* Mailbox CANCEL command */ +#define MBOX_CMD_CANCEL 0x3 + /* Mailbox REBOOT commands */ #define MBOX_CMD_REBOOT_HPS 71 @@ -75,41 +79,31 @@ #define MBOX_WRONG_ID -3 /* Mailbox status */ -#define RECONFIG_STATUS_STATE 0 -#define RECONFIG_STATUS_PIN_STATUS 2 -#define RECONFIG_STATUS_SOFTFUNC_STATUS 3 -#define PIN_STATUS_NSTATUS (U(1) << 31) -#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3) -#define SOFTFUNC_STATUS_INIT_DONE (1 << 1) -#define SOFTFUNC_STATUS_CONF_DONE (1 << 0) -#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000 - -/* SMC function IDs for SiP Service queries */ -#define SIP_SVC_CALL_COUNT 0x8200ff00 -#define SIP_SVC_UID 0x8200ff01 -#define SIP_SVC_VERSION 0x8200ff03 - -/* SiP Service Calls version numbers */ -#define SIP_SVC_VERSION_MAJOR 0 -#define SIP_SVC_VERSION_MINOR 1 +#define RECONFIG_STATUS_STATE 0 +#define RECONFIG_STATUS_PIN_STATUS 2 +#define RECONFIG_STATUS_SOFTFUNC_STATUS 3 +#define PIN_STATUS_NSTATUS (U(1) << 31) +#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3) +#define SOFTFUNC_STATUS_INIT_DONE (1 << 1) +#define SOFTFUNC_STATUS_CONF_DONE (1 << 0) +#define MBOX_CFGSTAT_STATE_IDLE 0x00000000 +#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000 +#define MBOX_CFGSTAT_STATE_FAILACK 0x08000000 +#define MBOX_CFGSTAT_STATE_ERROR_INVALID 0xf0000001 +#define MBOX_CFGSTAT_STATE_ERROR_CORRUPT 0xf0000002 +#define MBOX_CFGSTAT_STATE_ERROR_AUTH 0xf0000003 +#define MBOX_CFGSTAT_STATE_ERROR_CORE_IO 0xf0000004 +#define MBOX_CFGSTAT_STATE_ERROR_HARDWARE 0xf0000005 +#define MBOX_CFGSTAT_STATE_ERROR_FAKE 0xf0000006 +#define MBOX_CFGSTAT_STATE_ERROR_BOOT_INFO 0xf0000007 +#define MBOX_CFGSTAT_STATE_ERROR_QSPI_ERROR 0xf0000008 /* Mailbox reconfiguration commands */ +#define MBOX_CONFIG_STATUS 4 #define MBOX_RECONFIG 6 #define MBOX_RECONFIG_DATA 8 #define MBOX_RECONFIG_STATUS 9 -/* Sip get memory */ -#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 -#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 -#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 -#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 -#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 -#define INTEL_SIP_SMC_STATUS_OK 0 -#define INTEL_SIP_SMC_STATUS_ERROR 0x4 -#define INTEL_SIP_SMC_STATUS_BUSY 0x1 -#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 -#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x1000 -#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 void mailbox_set_int(int interrupt_input); int mailbox_init(void); @@ -117,11 +111,15 @@ void mailbox_set_qspi_close(void); void mailbox_set_qspi_open(void); void mailbox_set_qspi_direct(void); int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response); -void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, + int len, int urgent, uint32_t *response, int resp_len); +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent); -int mailbox_read_response(int job_id, uint32_t *response); +int mailbox_read_response(int job_id, uint32_t *response, int resp_len); int mailbox_get_qspi_clock(void); void mailbox_reset_cold(void); +void mailbox_clear_response(void); + +uint32_t intel_mailbox_get_config_status(uint32_t cmd); +int intel_mailbox_is_fpga_not_ready(void); -#endif +#endif /* SOCFPGA_MBOX_H */ diff --git a/plat/intel/soc/common/include/socfpga_private.h b/plat/intel/soc/common/include/socfpga_private.h index 6ab14090f..ca38f62d8 100644 --- a/plat/intel/soc/common/include/socfpga_private.h +++ b/plat/intel/soc/common/include/socfpga_private.h @@ -4,12 +4,38 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef PLATFORM_PRIVATE_H -#define PLATFORM_PRIVATE_H +#ifndef SOCFPGA_PRIVATE_H +#define SOCFPGA_PRIVATE_H + +#include "socfpga_plat_def.h" + +#define EMMC_DESC_SIZE (1<<20) + +#define EMMC_INIT_PARAMS(base, clk) \ + { .bus_width = MMC_BUS_WIDTH_4, \ + .clk_rate = (clk), \ + .desc_base = (base), \ + .desc_size = EMMC_DESC_SIZE, \ + .flags = 0, \ + .reg_base = SOCFPGA_MMC_REG_BASE \ + } + +typedef enum { + BOOT_SOURCE_FPGA = 0, + BOOT_SOURCE_SDMMC, + BOOT_SOURCE_NAND, + BOOT_SOURCE_RSVD, + BOOT_SOURCE_QSPI +} boot_source_type; /******************************************************************************* * Function and variable prototypes ******************************************************************************/ + +void enable_nonsecure_access(void); + +void socfpga_io_setup(int boot_source); + void socfgpa_configure_mmu_el3(unsigned long total_base, unsigned long total_size, unsigned long ro_start, @@ -35,5 +61,6 @@ uint32_t socfpga_get_spsr_for_bl33_entry(void); unsigned long socfpga_get_ns_image_entrypoint(void); +void plat_secondary_cpus_bl31_entry(void); -#endif /* PLATFORM_PRIVATE_H */ +#endif /* SOCFPGA_PRIVATE_H */ diff --git a/plat/intel/soc/common/include/socfpga_reset_manager.h b/plat/intel/soc/common/include/socfpga_reset_manager.h new file mode 100644 index 000000000..637f8dfe5 --- /dev/null +++ b/plat/intel/soc/common/include/socfpga_reset_manager.h @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOCFPGA_RESETMANAGER_H +#define SOCFPGA_RESETMANAGER_H + +#include "socfpga_plat_def.h" + + +/* Register Mapping */ + +#define SOCFPGA_RSTMGR_STAT 0x000 +#define SOCFPGA_RSTMGR_HDSKEN 0x010 +#define SOCFPGA_RSTMGR_MPUMODRST 0x020 +#define SOCFPGA_RSTMGR_PER0MODRST 0x024 +#define SOCFPGA_RSTMGR_PER1MODRST 0x028 +#define SOCFPGA_RSTMGR_BRGMODRST 0x02c +#define SOCFPGA_RSTMGR_COLDMODRST 0x034 +#define SOCFPGA_RSTMGR_HDSKTIMEOUT 0x064 + +/* Field Mapping */ + +#define RSTMGR_PER0MODRST_EMAC0 0x00000001 +#define RSTMGR_PER0MODRST_EMAC1 0x00000002 +#define RSTMGR_PER0MODRST_EMAC2 0x00000004 +#define RSTMGR_PER0MODRST_USB0 0x00000008 +#define RSTMGR_PER0MODRST_USB1 0x00000010 +#define RSTMGR_PER0MODRST_NAND 0x00000020 +#define RSTMGR_PER0MODRST_SDMMC 0x00000080 +#define RSTMGR_PER0MODRST_EMAC0OCP 0x00000100 +#define RSTMGR_PER0MODRST_EMAC1OCP 0x00000200 +#define RSTMGR_PER0MODRST_EMAC2OCP 0x00000400 +#define RSTMGR_PER0MODRST_USB0OCP 0x00000800 +#define RSTMGR_PER0MODRST_USB1OCP 0x00001000 +#define RSTMGR_PER0MODRST_NANDOCP 0x00002000 +#define RSTMGR_PER0MODRST_SDMMCOCP 0x00008000 +#define RSTMGR_PER0MODRST_DMA 0x00010000 +#define RSTMGR_PER0MODRST_SPIM0 0x00020000 +#define RSTMGR_PER0MODRST_SPIM1 0x00040000 +#define RSTMGR_PER0MODRST_SPIS0 0x00080000 +#define RSTMGR_PER0MODRST_SPIS1 0x00100000 +#define RSTMGR_PER0MODRST_DMAOCP 0x00200000 +#define RSTMGR_PER0MODRST_EMACPTP 0x00400000 +#define RSTMGR_PER0MODRST_DMAIF0 0x01000000 +#define RSTMGR_PER0MODRST_DMAIF1 0x02000000 +#define RSTMGR_PER0MODRST_DMAIF2 0x04000000 +#define RSTMGR_PER0MODRST_DMAIF3 0x08000000 +#define RSTMGR_PER0MODRST_DMAIF4 0x10000000 +#define RSTMGR_PER0MODRST_DMAIF5 0x20000000 +#define RSTMGR_PER0MODRST_DMAIF6 0x40000000 +#define RSTMGR_PER0MODRST_DMAIF7 0x80000000 + +#define RSTMGR_PER1MODRST_WATCHDOG0 0x00000001 +#define RSTMGR_PER1MODRST_WATCHDOG1 0x00000002 +#define RSTMGR_PER1MODRST_WATCHDOG2 0x00000004 +#define RSTMGR_PER1MODRST_WATCHDOG3 0x00000008 +#define RSTMGR_PER1MODRST_L4SYSTIMER0 0x00000010 +#define RSTMGR_PER1MODRST_L4SYSTIMER1 0x00000020 +#define RSTMGR_PER1MODRST_SPTIMER0 0x00000040 +#define RSTMGR_PER1MODRST_SPTIMER1 0x00000080 +#define RSTMGR_PER1MODRST_I2C0 0x00000100 +#define RSTMGR_PER1MODRST_I2C1 0x00000200 +#define RSTMGR_PER1MODRST_I2C2 0x00000400 +#define RSTMGR_PER1MODRST_I2C3 0x00000800 +#define RSTMGR_PER1MODRST_I2C4 0x00001000 +#define RSTMGR_PER1MODRST_UART0 0x00010000 +#define RSTMGR_PER1MODRST_UART1 0x00020000 +#define RSTMGR_PER1MODRST_GPIO0 0x01000000 +#define RSTMGR_PER1MODRST_GPIO1 0x02000000 + +#define RSTMGR_HDSKEN_FPGAHSEN 0x00000004 +#define RSTMGR_HDSKEN_ETRSTALLEN 0x00000008 +#define RSTMGR_HDSKEN_L2FLUSHEN 0x00000100 +#define RSTMGR_HDSKEN_L3NOC_DBG 0x00010000 +#define RSTMGR_HDSKEN_DEBUG_L3NOC 0x00020000 +#define RSTMGR_HDSKEN_SDRSELFREFEN 0x00000001 + +#define RSTMGR_BRGMODRST_SOC2FPGA 0x1 +#define RSTMGR_BRGMODRST_LWHPS2FPGA 0x2 +#define RSTMGR_BRGMODRST_FPGA2SOC 0x4 +#define RSTMGR_BRGMODRST_F2SSDRAM1 0x10 +#define RSTMGR_BRGMODRST_F2SSDRAM2 0x20 +#define RSTMGR_BRGMODRST_MPFE 0x40 +#define RSTMGR_BRGMODRST_DDRSCH 0x40 + +/* Definitions */ + +#define RSTMGR_L2_MODRST 0x0100 +#define RSTMGR_HDSKEN_SET 0x010D + +/* Macros */ + +#define SOCFPGA_RSTMGR(_reg) (SOCFPGA_RSTMGR_REG_BASE \ + + (SOCFPGA_RSTMGR_##_reg)) +#define RSTMGR_FIELD(_reg, _field) (RSTMGR_##_reg##MODRST_##_field) + +/* Function Declarations */ + +void deassert_peripheral_reset(void); +void config_hps_hs_before_warm_reset(void); + +int socfpga_bridges_enable(void); +int socfpga_bridges_disable(void); + +#endif /* SOCFPGA_RESETMANAGER_H */ diff --git a/plat/intel/soc/common/include/socfpga_sip_svc.h b/plat/intel/soc/common/include/socfpga_sip_svc.h new file mode 100644 index 000000000..6bb41f31b --- /dev/null +++ b/plat/intel/soc/common/include/socfpga_sip_svc.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOCFPGA_SIP_SVC_H +#define SOCFPGA_SIP_SVC_H + + +/* SiP status response */ +#define INTEL_SIP_SMC_STATUS_OK 0 +#define INTEL_SIP_SMC_STATUS_ERROR 0x4 +#define INTEL_SIP_SMC_STATUS_BUSY 0x1 +#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 + +/* SMC SiP service function identifier */ +#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 +#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 +#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 +#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 +#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 +#define INTEL_SIP_SMC_REG_READ 0xC2000007 +#define INTEL_SIP_SMC_REG_WRITE 0xC2000008 +#define INTEL_SIP_SMC_REG_UPDATE 0xC2000009 +#define INTEL_SIP_SMC_RSU_STATUS 0xC200000B +#define INTEL_SIP_SMC_RSU_UPDATE 0xC200000C +#define INTEL_SIP_LEGACY_SMC_ECC_DBE 0xC200000D +#define INTEL_SIP_SMC_RSU_NOTIFY 0xC200000E +#define INTEL_SIP_SMC_RSU_RETRY_COUNTER 0xC200000F + +/* FPGA config helpers */ +#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x400000 +#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 + +/* SMC function IDs for SiP Service queries */ +#define SIP_SVC_CALL_COUNT 0x8200ff00 +#define SIP_SVC_UID 0x8200ff01 +#define SIP_SVC_VERSION 0x8200ff03 + +/* SiP Service Calls version numbers */ +#define SIP_SVC_VERSION_MAJOR 0 +#define SIP_SVC_VERSION_MINOR 1 + +#endif /* SOCFPGA_SIP_SVC_H */ diff --git a/plat/intel/soc/common/include/socfpga_system_manager.h b/plat/intel/soc/common/include/socfpga_system_manager.h new file mode 100644 index 000000000..68e30b894 --- /dev/null +++ b/plat/intel/soc/common/include/socfpga_system_manager.h @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019-2020, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SOCFPGA_SYSTEMMANAGER_H +#define SOCFPGA_SYSTEMMANAGER_H + +#include "socfpga_plat_def.h" + +/* System Manager Register Map */ + +#define SOCFPGA_SYSMGR_SDMMC 0x28 + +#define SOCFPGA_SYSMGR_NOC_TIMEOUT 0xc0 +#define SOCFPGA_SYSMGR_NOC_IDLEREQ_SET 0xc4 +#define SOCFPGA_SYSMGR_NOC_IDLEREQ_CLR 0xc8 +#define SOCFPGA_SYSMGR_NOC_IDLEREQ_VAL 0xcc +#define SOCFPGA_SYSMGR_NOC_IDLEACK 0xd0 +#define SOCFPGA_SYSMGR_NOC_IDLESTATUS 0xd4 + +#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_0 0x200 +#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_1 0x204 +#define SOCFPGA_SYSMGR_BOOT_SCRATCH_COLD_2 0x208 + +/* Field Masking */ + +#define SYSMGR_SDMMC_DRVSEL(x) (((x) & 0x7) << 0) + +#define IDLE_DATA_LWSOC2FPGA BIT(0) +#define IDLE_DATA_SOC2FPGA BIT(4) +#define IDLE_DATA_MASK (IDLE_DATA_LWSOC2FPGA | IDLE_DATA_SOC2FPGA) + +#define SCR_AXI_AP_MASK BIT(24) +#define SCR_FPGA2SOC_MASK BIT(16) +#define SCR_MPU_MASK BIT(0) +#define DISABLE_L4_FIREWALL (SCR_AXI_AP_MASK | SCR_FPGA2SOC_MASK \ + | SCR_MPU_MASK) +#define DISABLE_BRIDGE_FIREWALL 0x0ffe0101 + +/* Macros */ + +#define SOCFPGA_SYSMGR(_reg) (SOCFPGA_SYSMGR_REG_BASE \ + + (SOCFPGA_SYSMGR_##_reg)) + +#define SOCFPGA_L4_PER_SCR(_reg) (SOCFPGA_L4_PER_SCR_REG_BASE \ + + (SOCFPGA_NOC_FW_L4_PER_SCR_##_reg)) + +#define SOCFPGA_L4_SYS_SCR(_reg) (SOCFPGA_L4_SYS_SCR_REG_BASE \ + + (SOCFPGA_NOC_FW_L4_SYS_SCR_##_reg)) + +/* L3 Interconnect Register Map */ +#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_REGISTER 0x0000 +#define SOCFPGA_NOC_FW_L4_PER_SCR_NAND_DATA 0x0004 +#define SOCFPGA_NOC_FW_L4_PER_SCR_USB0_REGISTER 0x000c +#define SOCFPGA_NOC_FW_L4_PER_SCR_USB1_REGISTER 0x0010 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER0 0x001c +#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_MASTER1 0x0020 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0x0024 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0x0028 +#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC0 0x002c +#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC1 0x0030 +#define SOCFPGA_NOC_FW_L4_PER_SCR_EMAC2 0x0034 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SDMMC 0x0040 +#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO0 0x0044 +#define SOCFPGA_NOC_FW_L4_PER_SCR_GPIO1 0x0048 +#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C0 0x0050 +#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C1 0x0054 +#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C2 0x0058 +#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C3 0x005c +#define SOCFPGA_NOC_FW_L4_PER_SCR_I2C4 0x0060 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER0 0x0064 +#define SOCFPGA_NOC_FW_L4_PER_SCR_SP_TIMER1 0x0068 +#define SOCFPGA_NOC_FW_L4_PER_SCR_UART0 0x006c +#define SOCFPGA_NOC_FW_L4_PER_SCR_UART1 0x0070 + +#define SOCFPGA_NOC_FW_L4_SYS_SCR_DMA_ECC 0x0008 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0x000c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0x0010 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0x0014 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0x0018 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0x001c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0x0020 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_ECC 0x002c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0x0030 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0x0034 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0x0038 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0x0040 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB0_ECC 0x0044 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_USB1_ECC 0x0048 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_CLK_MGR 0x004c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_IO_MGR 0x0054 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_RST_MGR 0x0058 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_SYS_MGR 0x005c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0x0060 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0x0064 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG0 0x0068 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG1 0x006c +#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG2 0x0070 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_WATCHDOG3 0x0074 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_DAP 0x0078 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0x0090 +#define SOCFPGA_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0x0094 + +#define SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0 0xf7004688 +#define SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0 0xf7018628 + +void enable_ns_peripheral_access(void); +void enable_ns_bridge_access(void); + +#endif /* SOCFPGA_SYSTEMMANAGER_H */ diff --git a/plat/intel/soc/agilex/soc/agilex_handoff.c b/plat/intel/soc/common/soc/socfpga_handoff.c index a458686f1..4bb3a9619 100644 --- a/plat/intel/soc/agilex/soc/agilex_handoff.c +++ b/plat/intel/soc/common/soc/socfpga_handoff.c @@ -4,15 +4,14 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#include <platform_def.h> #include <string.h> -#include "agilex_handoff.h" +#include "socfpga_handoff.h" #define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | \ (((x) & 0x0000FF00) << 8) | ((x) << 24)) -int agilex_get_handoff(handoff *reverse_hoff_ptr) +int socfpga_get_handoff(handoff *reverse_hoff_ptr) { int i; uint32_t *buffer; diff --git a/plat/intel/soc/agilex/soc/agilex_mailbox.c b/plat/intel/soc/common/soc/socfpga_mailbox.c index ebfea6148..8d7c1d663 100644 --- a/plat/intel/soc/agilex/soc/agilex_mailbox.c +++ b/plat/intel/soc/common/soc/socfpga_mailbox.c @@ -6,8 +6,10 @@ #include <lib/mmio.h> #include <common/debug.h> +#include <drivers/delay_timer.h> -#include "agilex_mailbox.h" +#include "socfpga_mailbox.h" +#include "socfpga_sip_svc.h" static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, int len) @@ -17,12 +19,6 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN); - if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) { - INFO("Insufficient buffer in mailbox\n"); - return MBOX_INSUFFICIENT_BUFFER; - } - - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4), header_cmd); @@ -39,28 +35,21 @@ static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, return 0; } -int mailbox_read_response(int job_id, uint32_t *response) +int mailbox_read_response(int job_id, uint32_t *response, int resp_len) { int rin = 0; int rout = 0; int response_length = 0; int resp = 0; int total_resp_len = 0; - int timeout = 100000; - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); - - while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) { - if (timeout-- < 0) - return MBOX_NO_RESPONSE; - } - - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); + if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM)) + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); - while (rout != rin) { + if (rout != rin) { resp = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + ((rout++)*4)); @@ -84,8 +73,9 @@ int mailbox_read_response(int job_id, uint32_t *response) resp = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + (rout)*4); - if (response) { + if (response && resp_len) { *(response + total_resp_len) = resp; + resp_len--; total_resp_len++; } rout++; @@ -99,25 +89,25 @@ int mailbox_read_response(int job_id, uint32_t *response) } -int mailbox_poll_response(int job_id, int urgent, uint32_t *response) +int mailbox_poll_response(int job_id, int urgent, uint32_t *response, + int resp_len) { - int timeout = 80000; + int timeout = 0xFFFFFF; int rin = 0; int rout = 0; int response_length = 0; int resp = 0; int total_resp_len = 0; - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); - while (1) { + while (timeout > 0 && - mmio_read_32(MBOX_OFFSET + - MBOX_DOORBELL_FROM_SDM) != 1) { + !(mmio_read_32(MBOX_OFFSET + + MBOX_DOORBELL_FROM_SDM) & 1)) { timeout--; } - if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) { + if (!timeout) { INFO("Timed out waiting for SDM"); return MBOX_TIMEOUT; } @@ -125,6 +115,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response) mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); if (urgent & 1) { + mdelay(5); if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK) ^ (urgent & MBOX_STATUS_UA_MASK)) { @@ -158,13 +149,13 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response) response_length = MBOX_RESP_LEN(resp); while (response_length) { - response_length--; resp = mmio_read_32(MBOX_OFFSET + MBOX_RESP_BUFFER + (rout)*4); - if (response) { + if (response && resp_len) { *(response + total_resp_len) = resp; + resp_len--; total_resp_len++; } rout++; @@ -176,7 +167,7 @@ int mailbox_poll_response(int job_id, int urgent, uint32_t *response) } } -void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, +int mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, int len, int urgent) { if (urgent) @@ -187,29 +178,44 @@ void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, MBOX_CMD_LEN_CMD(len) | MBOX_INDIRECT | cmd, args, len); + + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + + return 0; } int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response) + int len, int urgent, uint32_t *response, int resp_len) { - int status; + int status = 0; if (urgent) { urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & MBOX_STATUS_UA_MASK; mmio_write_32(MBOX_OFFSET + MBOX_URG, cmd); - status = 0; - } else { + } + + else { status = fill_mailbox_circular_buffer( MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | MBOX_JOB_ID_CMD(job_id) | + MBOX_CMD_LEN_CMD(len) | cmd, args, len); } if (status) return status; - return mailbox_poll_response(job_id, urgent, response); + mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); + status = mailbox_poll_response(job_id, urgent, response, resp_len); + + return status; +} + +void mailbox_clear_response(void) +{ + mmio_write_32(MBOX_OFFSET + MBOX_ROUT, + mmio_read_32(MBOX_OFFSET + MBOX_RIN)); } void mailbox_set_int(int interrupt) @@ -223,24 +229,25 @@ void mailbox_set_int(int interrupt) void mailbox_set_qspi_open(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, NULL, 0); } void mailbox_set_qspi_direct(void) { - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, NULL, 0); } void mailbox_set_qspi_close(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, NULL, 0); } int mailbox_get_qspi_clock(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0); + return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, + NULL, 0); } void mailbox_qspi_set_cs(int device_select) @@ -251,13 +258,13 @@ void mailbox_qspi_set_cs(int device_select) cs_setting = (cs_setting << 28); mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, - 1, 0, 0); + 1, 0, NULL, 0); } void mailbox_reset_cold(void) { mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0); + mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, NULL, 0); } int mailbox_init(void) @@ -268,13 +275,54 @@ int mailbox_init(void) MBOX_INT_FLAG_UAE); mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); - status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0); + + status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, NULL, 0); if (status) return status; - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); + mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE | + MBOX_INT_FLAG_UAE); return 0; } +uint32_t intel_mailbox_get_config_status(uint32_t cmd) +{ + uint32_t status, res; + uint32_t response[6]; + + status = mailbox_send_cmd(1, cmd, NULL, 0, 0, response, + sizeof(response) / sizeof(response[0])); + + if (status < 0) + return status; + + res = response[RECONFIG_STATUS_STATE]; + if (res && res != MBOX_CFGSTAT_STATE_CONFIG) + return res; + + res = response[RECONFIG_STATUS_PIN_STATUS]; + if (!(res & PIN_STATUS_NSTATUS)) + return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + + res = response[RECONFIG_STATUS_SOFTFUNC_STATUS]; + if (res & SOFTFUNC_STATUS_SEU_ERROR) + return MBOX_CFGSTAT_STATE_ERROR_HARDWARE; + + if ((res & SOFTFUNC_STATUS_CONF_DONE) && + (res & SOFTFUNC_STATUS_INIT_DONE)) + return 0; + + return MBOX_CFGSTAT_STATE_CONFIG; +} + +int intel_mailbox_is_fpga_not_ready(void) +{ + int ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS); + + if (ret && ret != MBOX_CFGSTAT_STATE_CONFIG) + ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS); + + return ret; +} diff --git a/plat/intel/soc/common/soc/socfpga_reset_manager.c b/plat/intel/soc/common/soc/socfpga_reset_manager.c new file mode 100644 index 000000000..32604c914 --- /dev/null +++ b/plat/intel/soc/common/soc/socfpga_reset_manager.c @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <errno.h> +#include <lib/mmio.h> + +#include "socfpga_mailbox.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" + + +void deassert_peripheral_reset(void) +{ + mmio_clrbits_32(SOCFPGA_RSTMGR(PER1MODRST), + RSTMGR_FIELD(PER1, WATCHDOG0) | + RSTMGR_FIELD(PER1, WATCHDOG1) | + RSTMGR_FIELD(PER1, WATCHDOG2) | + RSTMGR_FIELD(PER1, WATCHDOG3) | + RSTMGR_FIELD(PER1, L4SYSTIMER0) | + RSTMGR_FIELD(PER1, L4SYSTIMER1) | + RSTMGR_FIELD(PER1, SPTIMER0) | + RSTMGR_FIELD(PER1, SPTIMER1) | + RSTMGR_FIELD(PER1, I2C0) | + RSTMGR_FIELD(PER1, I2C1) | + RSTMGR_FIELD(PER1, I2C2) | + RSTMGR_FIELD(PER1, I2C3) | + RSTMGR_FIELD(PER1, I2C4) | + RSTMGR_FIELD(PER1, UART0) | + RSTMGR_FIELD(PER1, UART1) | + RSTMGR_FIELD(PER1, GPIO0) | + RSTMGR_FIELD(PER1, GPIO1)); + + mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_FIELD(PER0, EMAC0OCP) | + RSTMGR_FIELD(PER0, EMAC1OCP) | + RSTMGR_FIELD(PER0, EMAC2OCP) | + RSTMGR_FIELD(PER0, USB0OCP) | + RSTMGR_FIELD(PER0, USB1OCP) | + RSTMGR_FIELD(PER0, NANDOCP) | + RSTMGR_FIELD(PER0, SDMMCOCP) | + RSTMGR_FIELD(PER0, DMAOCP)); + + mmio_clrbits_32(SOCFPGA_RSTMGR(PER0MODRST), + RSTMGR_FIELD(PER0, EMAC0) | + RSTMGR_FIELD(PER0, EMAC1) | + RSTMGR_FIELD(PER0, EMAC2) | + RSTMGR_FIELD(PER0, USB0) | + RSTMGR_FIELD(PER0, USB1) | + RSTMGR_FIELD(PER0, NAND) | + RSTMGR_FIELD(PER0, SDMMC) | + RSTMGR_FIELD(PER0, DMA) | + RSTMGR_FIELD(PER0, SPIM0) | + RSTMGR_FIELD(PER0, SPIM1) | + RSTMGR_FIELD(PER0, SPIS0) | + RSTMGR_FIELD(PER0, SPIS1) | + RSTMGR_FIELD(PER0, EMACPTP) | + RSTMGR_FIELD(PER0, DMAIF0) | + RSTMGR_FIELD(PER0, DMAIF1) | + RSTMGR_FIELD(PER0, DMAIF2) | + RSTMGR_FIELD(PER0, DMAIF3) | + RSTMGR_FIELD(PER0, DMAIF4) | + RSTMGR_FIELD(PER0, DMAIF5) | + RSTMGR_FIELD(PER0, DMAIF6) | + RSTMGR_FIELD(PER0, DMAIF7)); + +#if PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX + mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), + RSTMGR_FIELD(BRG, MPFE)); +#endif +} + +void config_hps_hs_before_warm_reset(void) +{ + uint32_t or_mask = 0; + + or_mask |= RSTMGR_HDSKEN_SDRSELFREFEN; + or_mask |= RSTMGR_HDSKEN_FPGAHSEN; + or_mask |= RSTMGR_HDSKEN_ETRSTALLEN; + or_mask |= RSTMGR_HDSKEN_L2FLUSHEN; + or_mask |= RSTMGR_HDSKEN_L3NOC_DBG; + or_mask |= RSTMGR_HDSKEN_DEBUG_L3NOC; + + mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), or_mask); +} + +static int poll_idle_status(uint32_t addr, uint32_t mask, uint32_t match) +{ + int time_out = 1000; + + while (time_out--) { + if ((mmio_read_32(addr) & mask) == match) { + return 0; + } + } + return -ETIMEDOUT; +} + +int socfpga_bridges_enable(void) +{ + /* Clear idle request */ + mmio_setbits_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_CLR), ~0); + + /* De-assert all bridges */ + mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), ~0); + + /* Wait until idle ack becomes 0 */ + return poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK), + IDLE_DATA_MASK, 0); +} + +int socfpga_bridges_disable(void) +{ + /* Set idle request */ + mmio_write_32(SOCFPGA_SYSMGR(NOC_IDLEREQ_SET), ~0); + + /* Enable NOC timeout */ + mmio_setbits_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1); + + /* Wait until each idle ack bit toggle to 1 */ + if (poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLEACK), + IDLE_DATA_MASK, IDLE_DATA_MASK)) + return -ETIMEDOUT; + + /* Wait until each idle status bit toggle to 1 */ + if (poll_idle_status(SOCFPGA_SYSMGR(NOC_IDLESTATUS), + IDLE_DATA_MASK, IDLE_DATA_MASK)) + return -ETIMEDOUT; + + /* Assert all bridges */ +#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10 + mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), + ~(RSTMGR_FIELD(BRG, DDRSCH) | RSTMGR_FIELD(BRG, FPGA2SOC))); +#elif PLATFORM_MODEL == PLAT_SOCFPGA_AGILEX + mmio_setbits_32(SOCFPGA_RSTMGR(BRGMODRST), + ~(RSTMGR_FIELD(BRG, MPFE) | RSTMGR_FIELD(BRG, FPGA2SOC))); +#endif + + /* Disable NOC timeout */ + mmio_clrbits_32(SOCFPGA_SYSMGR(NOC_TIMEOUT), 1); + + return 0; +} diff --git a/plat/intel/soc/common/soc/socfpga_system_manager.c b/plat/intel/soc/common/soc/socfpga_system_manager.c new file mode 100644 index 000000000..a64053ca6 --- /dev/null +++ b/plat/intel/soc/common/soc/socfpga_system_manager.c @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2019, Intel Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> +#include <lib/utils_def.h> + +#include "socfpga_system_manager.h" + +void enable_nonsecure_access(void) +{ + enable_ns_peripheral_access(); + enable_ns_bridge_access(); +} + +void enable_ns_peripheral_access(void) +{ + mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_REGISTER), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(NAND_DATA), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_READ_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(NAND_WRITE_ECC), + DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(USB0_REGISTER), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(USB1_REGISTER), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(USB0_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(USB1_ECC), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(SPI_MASTER0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(SPI_MASTER1), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(SPI_SLAVE0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(SPI_SLAVE1), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(EMAC0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(EMAC1), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(EMAC2), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC0RX_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC0TX_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC1RX_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC1TX_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC2RX_ECC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(EMAC2TX_ECC), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(SDMMC), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(SDMMC_ECC), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(GPIO0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(GPIO1), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(I2C0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(I2C1), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(I2C2), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(I2C3), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(I2C4), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(SP_TIMER1), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_PER_SCR(UART0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_PER_SCR(UART1), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(DMA_ECC), DISABLE_L4_FIREWALL); + + + mmio_write_32(SOCFPGA_L4_SYS_SCR(OCRAM_ECC), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(CLK_MGR), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(IO_MGR), DISABLE_L4_FIREWALL); + + + mmio_write_32(SOCFPGA_L4_SYS_SCR(RST_MGR), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(SYS_MGR), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(OSC0_TIMER), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(OSC1_TIMER), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG0), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG1), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG2), DISABLE_L4_FIREWALL); + mmio_write_32(SOCFPGA_L4_SYS_SCR(WATCHDOG3), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(DAP), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_PROBES), DISABLE_L4_FIREWALL); + + mmio_write_32(SOCFPGA_L4_SYS_SCR(L4_NOC_QOS), DISABLE_L4_FIREWALL); + +#if PLATFORM_MODEL == PLAT_SOCFPGA_STRATIX10 + mmio_clrbits_32(SOCFPGA_CCU_NOC_CPU0_RAMSPACE0_0, 0x03); + mmio_clrbits_32(SOCFPGA_CCU_NOC_IOM_RAMSPACE0_0, 0x03); + + mmio_write_32(SOCFPGA_SYSMGR(SDMMC), SYSMGR_SDMMC_DRVSEL(3)); +#endif + +} + +void enable_ns_bridge_access(void) +{ + mmio_write_32(SOCFPGA_SOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL); + mmio_write_32(SOCFPGA_LWSOC2FPGA_SCR_REG_BASE, DISABLE_BRIDGE_FIREWALL); +} diff --git a/plat/intel/soc/common/socfpga_image_load.c b/plat/intel/soc/common/socfpga_image_load.c index 67c02bc7d..a5c327990 100644 --- a/plat/intel/soc/common/socfpga_image_load.c +++ b/plat/intel/soc/common/socfpga_image_load.c @@ -28,5 +28,31 @@ bl_load_info_t *plat_get_bl_image_load_info(void) ******************************************************************************/ bl_params_t *plat_get_next_bl_params(void) { + unsigned int count; + unsigned int img_id = 0U; + unsigned int link_index = 0U; + bl_params_node_t *bl_exec_node = NULL; + bl_mem_params_node_t *desc_ptr; + + /* If there is no image to start with, return NULL */ + if (bl_mem_params_desc_num == 0U) + return NULL; + + /* Clean next_params_info in BL image node */ + for (count = 0U; count < bl_mem_params_desc_num; count++) { + + desc_ptr = &bl_mem_params_desc_ptr[link_index]; + bl_exec_node = &desc_ptr->params_node_mem; + bl_exec_node->next_params_info = NULL; + + /* If no next hand-off image then break out */ + img_id = desc_ptr->next_handoff_image_id; + if (img_id == INVALID_IMAGE_ID) + break; + + /* Get the index for the next hand-off image */ + link_index = get_bl_params_node_index(img_id); + } + return get_next_bl_params_from_mem_params_desc(); } diff --git a/plat/intel/soc/agilex/socfpga_psci.c b/plat/intel/soc/common/socfpga_psci.c index 04d8a0e91..d8a6c1980 100644 --- a/plat/intel/soc/agilex/socfpga_psci.c +++ b/plat/intel/soc/common/socfpga_psci.c @@ -11,14 +11,11 @@ #include <lib/psci/psci.h> #include <plat/common/platform.h> -#include "agilex_reset_manager.h" -#include "agilex_mailbox.h" +#include "socfpga_mailbox.h" +#include "socfpga_plat_def.h" +#include "socfpga_reset_manager.h" -#define AGX_RSTMGR_OFST 0xffd11000 -#define AGX_RSTMGR_MPUMODRST_OFST 0x20 -uintptr_t *agilex_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY; -uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE; /******************************************************************************* * plat handler called when a CPU is about to enter standby. @@ -47,11 +44,10 @@ int socfpga_pwr_domain_on(u_register_t mpidr) if (cpu_id == -1) return PSCI_E_INTERN_FAIL; - *cpuid_release = cpu_id; + mmio_write_64(PLAT_CPUID_RELEASE, cpu_id); /* release core reset */ - mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); + mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id); return PSCI_E_SUCCESS; } @@ -61,18 +57,12 @@ int socfpga_pwr_domain_on(u_register_t mpidr) ******************************************************************************/ void socfpga_pwr_domain_off(const psci_power_state_t *target_state) { - unsigned int cpu_id = plat_my_core_pos(); - for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", __func__, i, target_state->pwr_domain_state[i]); - /* TODO: Prevent interrupts from spuriously waking up this cpu */ - /* gicv2_cpuif_disable(); */ - - /* assert core reset */ - mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); + /* Prevent interrupts from spuriously waking up this cpu */ + gicv2_cpuif_disable(); } /******************************************************************************* @@ -86,9 +76,9 @@ void socfpga_pwr_domain_suspend(const psci_power_state_t *target_state) for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", __func__, i, target_state->pwr_domain_state[i]); + /* assert core reset */ - mmio_setbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); + mmio_setbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id); } @@ -127,8 +117,7 @@ void socfpga_pwr_domain_suspend_finish(const psci_power_state_t *target_state) __func__, i, target_state->pwr_domain_state[i]); /* release core reset */ - mmio_clrbits_32(AGX_RSTMGR_OFST + AGX_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); + mmio_clrbits_32(SOCFPGA_RSTMGR(MPUMODRST), 1 << cpu_id); } /******************************************************************************* @@ -143,15 +132,37 @@ static void __dead2 socfpga_system_off(void) static void __dead2 socfpga_system_reset(void) { - INFO("assert Peripheral from Reset\r\n"); - - deassert_peripheral_reset(); mailbox_reset_cold(); while (1) wfi(); } +static int socfpga_system_reset2(int is_vendor, int reset_type, + u_register_t cookie) +{ + /* disable cpuif */ + gicv2_cpuif_disable(); + + /* Store magic number */ + mmio_write_32(L2_RESET_DONE_REG, L2_RESET_DONE_STATUS); + + /* Increase timeout */ + mmio_write_32(SOCFPGA_RSTMGR(HDSKTIMEOUT), 0xffffff); + + /* Enable handshakes */ + mmio_setbits_32(SOCFPGA_RSTMGR(HDSKEN), RSTMGR_HDSKEN_SET); + + /* Reset L2 module */ + mmio_setbits_32(SOCFPGA_RSTMGR(COLDMODRST), 0x100); + + while (1) + wfi(); + + /* Should not reach here */ + return 0; +} + int socfpga_validate_power_state(unsigned int power_state, psci_power_state_t *req_state) { @@ -185,6 +196,7 @@ const plat_psci_ops_t socfpga_psci_pm_ops = { .pwr_domain_suspend_finish = socfpga_pwr_domain_suspend_finish, .system_off = socfpga_system_off, .system_reset = socfpga_system_reset, + .system_reset2 = socfpga_system_reset2, .validate_power_state = socfpga_validate_power_state, .validate_ns_entrypoint = socfpga_validate_ns_entrypoint, .get_sys_suspend_power_state = socfpga_get_sys_suspend_power_state @@ -197,8 +209,8 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, const struct plat_psci_ops **psci_ops) { /* Save warm boot entrypoint.*/ - *agilex_sec_entry = sec_entrypoint; - + mmio_write_64(PLAT_SEC_ENTRY, sec_entrypoint); *psci_ops = &socfpga_psci_pm_ops; + return 0; } diff --git a/plat/intel/soc/common/socfpga_sip_svc.c b/plat/intel/soc/common/socfpga_sip_svc.c new file mode 100644 index 000000000..41dae9e76 --- /dev/null +++ b/plat/intel/soc/common/socfpga_sip_svc.c @@ -0,0 +1,471 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <common/runtime_svc.h> +#include <lib/mmio.h> +#include <tools_share/uuid.h> + +#include "socfpga_mailbox.h" +#include "socfpga_reset_manager.h" +#include "socfpga_sip_svc.h" + +/* Number of SiP Calls implemented */ +#define SIP_NUM_CALLS 0x3 + +/* Total buffer the driver can hold */ +#define FPGA_CONFIG_BUFFER_SIZE 4 + +static int current_block; +static int read_block; +static int current_buffer; +static int send_id; +static int rcv_id; +static int max_blocks; +static uint32_t bytes_per_block; +static uint32_t blocks_submitted; +static int is_partial_reconfig; + +struct fpga_config_info { + uint32_t addr; + int size; + int size_written; + uint32_t write_requested; + int subblocks_sent; + int block_number; +}; + +/* SiP Service UUID */ +DEFINE_SVC_UUID2(intl_svc_uid, + 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a, + 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81); + +static uint64_t socfpga_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + void *cookie, + void *handle, + uint64_t flags) +{ + ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); + SMC_RET1(handle, SMC_UNK); +} + +struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; + +static int intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) +{ + uint32_t args[3]; + + while (max_blocks > 0 && buffer->size > buffer->size_written) { + args[0] = (1<<8); + args[1] = buffer->addr + buffer->size_written; + if (buffer->size - buffer->size_written <= bytes_per_block) { + args[2] = buffer->size - buffer->size_written; + current_buffer++; + current_buffer %= FPGA_CONFIG_BUFFER_SIZE; + } else + args[2] = bytes_per_block; + + buffer->size_written += args[2]; + mailbox_send_cmd_async( + send_id++ % MBOX_MAX_JOB_ID, + MBOX_RECONFIG_DATA, + args, 3, 0); + + buffer->subblocks_sent++; + max_blocks--; + } + + return !max_blocks; +} + +static int intel_fpga_sdm_write_all(void) +{ + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) + if (intel_fpga_sdm_write_buffer( + &fpga_config_buffers[current_buffer])) + break; + return 0; +} + +static uint32_t intel_mailbox_fpga_config_isdone(uint32_t query_type) +{ + uint32_t ret; + + if (query_type == 1) + ret = intel_mailbox_get_config_status(MBOX_CONFIG_STATUS); + else + ret = intel_mailbox_get_config_status(MBOX_RECONFIG_STATUS); + + if (ret) { + if (ret == MBOX_CFGSTAT_STATE_CONFIG) + return INTEL_SIP_SMC_STATUS_BUSY; + else + return INTEL_SIP_SMC_STATUS_ERROR; + } + + if (query_type != 1) { + /* full reconfiguration */ + if (!is_partial_reconfig) + socfpga_bridges_enable(); /* Enable bridge */ + } + + return INTEL_SIP_SMC_STATUS_OK; +} + +static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) +{ + int i; + + for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + if (fpga_config_buffers[i].block_number == current_block) { + fpga_config_buffers[i].subblocks_sent--; + if (fpga_config_buffers[i].subblocks_sent == 0 + && fpga_config_buffers[i].size <= + fpga_config_buffers[i].size_written) { + fpga_config_buffers[i].write_requested = 0; + current_block++; + *buffer_addr_completed = + fpga_config_buffers[i].addr; + return 0; + } + } + } + + return -1; +} + +static int intel_fpga_config_completed_write(uint32_t *completed_addr, + uint32_t *count) +{ + uint32_t status = INTEL_SIP_SMC_STATUS_OK; + *count = 0; + int resp_len = 0; + uint32_t resp[5]; + int all_completed = 1; + + while (*count < 3) { + + resp_len = mailbox_read_response(rcv_id % MBOX_MAX_JOB_ID, + resp, sizeof(resp) / sizeof(resp[0])); + + if (resp_len < 0) + break; + + max_blocks++; + rcv_id++; + + if (mark_last_buffer_xfer_completed( + &completed_addr[*count]) == 0) + *count = *count + 1; + else + break; + } + + if (*count <= 0) { + if (resp_len != MBOX_NO_RESPONSE && + resp_len != MBOX_TIMEOUT && resp_len != 0) { + mailbox_clear_response(); + return INTEL_SIP_SMC_STATUS_ERROR; + } + + *count = 0; + } + + intel_fpga_sdm_write_all(); + + if (*count > 0) + status = INTEL_SIP_SMC_STATUS_OK; + else if (*count == 0) + status = INTEL_SIP_SMC_STATUS_BUSY; + + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + if (fpga_config_buffers[i].write_requested != 0) { + all_completed = 0; + break; + } + } + + if (all_completed == 1) + return INTEL_SIP_SMC_STATUS_OK; + + return status; +} + +static int intel_fpga_config_start(uint32_t config_type) +{ + uint32_t response[3]; + int status = 0; + + is_partial_reconfig = config_type; + + mailbox_clear_response(); + + mailbox_send_cmd(1, MBOX_CMD_CANCEL, 0, 0, 0, NULL, 0); + + status = mailbox_send_cmd(1, MBOX_RECONFIG, 0, 0, 0, + response, sizeof(response) / sizeof(response[0])); + + if (status < 0) + return status; + + max_blocks = response[0]; + bytes_per_block = response[1]; + + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + fpga_config_buffers[i].size = 0; + fpga_config_buffers[i].size_written = 0; + fpga_config_buffers[i].addr = 0; + fpga_config_buffers[i].write_requested = 0; + fpga_config_buffers[i].block_number = 0; + fpga_config_buffers[i].subblocks_sent = 0; + } + + blocks_submitted = 0; + current_block = 0; + read_block = 0; + current_buffer = 0; + send_id = 0; + rcv_id = 0; + + /* full reconfiguration */ + if (!is_partial_reconfig) { + /* Disable bridge */ + socfpga_bridges_disable(); + } + + return 0; +} + +static bool is_fpga_config_buffer_full(void) +{ + for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) + if (!fpga_config_buffers[i].write_requested) + return false; + return true; +} + +static bool is_address_in_ddr_range(uint64_t addr) +{ + if (addr >= DRAM_BASE && addr <= DRAM_BASE + DRAM_SIZE) + return true; + + return false; +} + +static uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) +{ + int i; + + intel_fpga_sdm_write_all(); + + if (!is_address_in_ddr_range(mem) || + !is_address_in_ddr_range(mem + size) || + is_fpga_config_buffer_full()) + return INTEL_SIP_SMC_STATUS_REJECTED; + + for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { + int j = (i + current_buffer) % FPGA_CONFIG_BUFFER_SIZE; + + if (!fpga_config_buffers[j].write_requested) { + fpga_config_buffers[j].addr = mem; + fpga_config_buffers[j].size = size; + fpga_config_buffers[j].size_written = 0; + fpga_config_buffers[j].write_requested = 1; + fpga_config_buffers[j].block_number = + blocks_submitted++; + fpga_config_buffers[j].subblocks_sent = 0; + break; + } + } + + if (is_fpga_config_buffer_full()) + return INTEL_SIP_SMC_STATUS_BUSY; + + return INTEL_SIP_SMC_STATUS_OK; +} + +static int is_out_of_sec_range(uint64_t reg_addr) +{ + switch (reg_addr) { + case(0xF8011100): /* ECCCTRL1 */ + case(0xF8011104): /* ECCCTRL2 */ + case(0xF8011110): /* ERRINTEN */ + case(0xF8011114): /* ERRINTENS */ + case(0xF8011118): /* ERRINTENR */ + case(0xF801111C): /* INTMODE */ + case(0xF8011120): /* INTSTAT */ + case(0xF8011124): /* DIAGINTTEST */ + case(0xF801112C): /* DERRADDRA */ + case(0xFFD12028): /* SDMMCGRP_CTRL */ + case(0xFFD12044): /* EMAC0 */ + case(0xFFD12048): /* EMAC1 */ + case(0xFFD1204C): /* EMAC2 */ + case(0xFFD12090): /* ECC_INT_MASK_VALUE */ + case(0xFFD12094): /* ECC_INT_MASK_SET */ + case(0xFFD12098): /* ECC_INT_MASK_CLEAR */ + case(0xFFD1209C): /* ECC_INTSTATUS_SERR */ + case(0xFFD120A0): /* ECC_INTSTATUS_DERR */ + case(0xFFD120C0): /* NOC_TIMEOUT */ + case(0xFFD120C4): /* NOC_IDLEREQ_SET */ + case(0xFFD120C8): /* NOC_IDLEREQ_CLR */ + case(0xFFD120D0): /* NOC_IDLEACK */ + case(0xFFD120D4): /* NOC_IDLESTATUS */ + case(0xFFD12200): /* BOOT_SCRATCH_COLD0 */ + case(0xFFD12204): /* BOOT_SCRATCH_COLD1 */ + case(0xFFD12220): /* BOOT_SCRATCH_COLD8 */ + case(0xFFD12224): /* BOOT_SCRATCH_COLD9 */ + return 0; + + default: + break; + } + + return -1; +} + +/* Secure register access */ +uint32_t intel_secure_reg_read(uint64_t reg_addr, uint32_t *retval) +{ + if (is_out_of_sec_range(reg_addr)) + return INTEL_SIP_SMC_STATUS_ERROR; + + *retval = mmio_read_32(reg_addr); + + return INTEL_SIP_SMC_STATUS_OK; +} + +uint32_t intel_secure_reg_write(uint64_t reg_addr, uint32_t val, + uint32_t *retval) +{ + if (is_out_of_sec_range(reg_addr)) + return INTEL_SIP_SMC_STATUS_ERROR; + + mmio_write_32(reg_addr, val); + + return intel_secure_reg_read(reg_addr, retval); +} + +uint32_t intel_secure_reg_update(uint64_t reg_addr, uint32_t mask, + uint32_t val, uint32_t *retval) +{ + if (!intel_secure_reg_read(reg_addr, retval)) { + *retval &= ~mask; + *retval |= val; + return intel_secure_reg_write(reg_addr, *retval, retval); + } + + return INTEL_SIP_SMC_STATUS_ERROR; +} + +/* + * This function is responsible for handling all SiP calls from the NS world + */ + +uintptr_t sip_smc_handler(uint32_t smc_fid, + u_register_t x1, + u_register_t x2, + u_register_t x3, + u_register_t x4, + void *cookie, + void *handle, + u_register_t flags) +{ + uint32_t val = 0; + uint32_t status = INTEL_SIP_SMC_STATUS_OK; + uint32_t completed_addr[3]; + uint32_t count = 0; + + switch (smc_fid) { + case SIP_SVC_UID: + /* Return UID to the caller */ + SMC_UUID_RET(handle, intl_svc_uid); + + case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE: + status = intel_mailbox_fpga_config_isdone(x1); + SMC_RET4(handle, status, 0, 0, 0); + + case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM: + SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK, + INTEL_SIP_SMC_FPGA_CONFIG_ADDR, + INTEL_SIP_SMC_FPGA_CONFIG_SIZE - + INTEL_SIP_SMC_FPGA_CONFIG_ADDR); + + case INTEL_SIP_SMC_FPGA_CONFIG_START: + status = intel_fpga_config_start(x1); + SMC_RET4(handle, status, 0, 0, 0); + + case INTEL_SIP_SMC_FPGA_CONFIG_WRITE: + status = intel_fpga_config_write(x1, x2); + SMC_RET4(handle, status, 0, 0, 0); + + case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: + status = intel_fpga_config_completed_write(completed_addr, + &count); + switch (count) { + case 1: + SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, + completed_addr[0], 0, 0); + + case 2: + SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, + completed_addr[0], + completed_addr[1], 0); + + case 3: + SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, + completed_addr[0], + completed_addr[1], + completed_addr[2]); + + case 0: + SMC_RET4(handle, status, 0, 0, 0); + + default: + mailbox_clear_response(); + SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR); + } + + case INTEL_SIP_SMC_REG_READ: + status = intel_secure_reg_read(x1, &val); + SMC_RET3(handle, status, val, x1); + + case INTEL_SIP_SMC_REG_WRITE: + status = intel_secure_reg_write(x1, (uint32_t)x2, &val); + SMC_RET3(handle, status, val, x1); + + case INTEL_SIP_SMC_REG_UPDATE: + status = intel_secure_reg_update(x1, (uint32_t)x2, + (uint32_t)x3, &val); + SMC_RET3(handle, status, val, x1); + + default: + return socfpga_sip_handler(smc_fid, x1, x2, x3, x4, + cookie, handle, flags); + } +} + +DECLARE_RT_SVC( + socfpga_sip_svc, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_FAST, + NULL, + sip_smc_handler +); + +DECLARE_RT_SVC( + socfpga_sip_svc_std, + OEN_SIP_START, + OEN_SIP_END, + SMC_TYPE_YIELD, + NULL, + sip_smc_handler +); diff --git a/plat/intel/soc/agilex/socfpga_storage.c b/plat/intel/soc/common/socfpga_storage.c index 76dd81f75..a2f2c184c 100644 --- a/plat/intel/soc/agilex/socfpga_storage.c +++ b/plat/intel/soc/common/socfpga_storage.c @@ -19,7 +19,7 @@ #include <lib/mmio.h> #include <tools_share/firmware_image_package.h> -#include "agilex_private.h" +#include "socfpga_private.h" #define PLAT_FIP_BASE (0) #define PLAT_FIP_MAX_SIZE (0x1000000) diff --git a/plat/intel/soc/stratix10/bl2_plat_setup.c b/plat/intel/soc/stratix10/bl2_plat_setup.c index 8e8b582fc..7d183db0d 100644 --- a/plat/intel/soc/stratix10/bl2_plat_setup.c +++ b/plat/intel/soc/stratix10/bl2_plat_setup.c @@ -1,37 +1,29 @@ /* * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <arch.h> #include <arch_helpers.h> -#include <drivers/arm/gicv2.h> - -#include <drivers/generic_delay_timer.h> -#include <drivers/console.h> -#include <drivers/ti/uart/uart_16550.h> #include <common/bl_common.h> #include <common/debug.h> #include <common/desc_image_load.h> -#include <errno.h> -#include <drivers/io/io_storage.h> -#include <common/image_decompress.h> -#include <plat/common/platform.h> -#include <platform_def.h> -#include <socfpga_private.h> +#include <drivers/generic_delay_timer.h> #include <drivers/synopsys/dw_mmc.h> -#include <lib/mmio.h> +#include <drivers/ti/uart/uart_16550.h> #include <lib/xlat_tables/xlat_tables.h> -#include "s10_memory_controller.h" -#include "s10_reset_manager.h" +#include "qspi/cadence_qspi.h" +#include "socfpga_handoff.h" +#include "socfpga_mailbox.h" +#include "socfpga_private.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" #include "s10_clock_manager.h" -#include "s10_handoff.h" +#include "s10_memory_controller.h" #include "s10_pinmux.h" -#include "stratix10_private.h" -#include "include/s10_mailbox.h" -#include "qspi/cadence_qspi.h" #include "wdt/watchdog.h" @@ -63,7 +55,7 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, generic_delay_timer_init(); - if (s10_get_handoff(&reverse_handoff_ptr)) + if (socfpga_get_handoff(&reverse_handoff_ptr)) return; config_pinmux(&reverse_handoff_ptr); boot_source = reverse_handoff_ptr.boot_source; @@ -73,13 +65,17 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, deassert_peripheral_reset(); config_hps_hs_before_warm_reset(); - watchdog_init(get_wdt_clk(&reverse_handoff_ptr)); + watchdog_init(get_wdt_clk()); - console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, + console_16550_register(PLAT_UART0_BASE, get_uart_clk(), PLAT_BAUDRATE, &console); socfpga_delay_timer_init(); init_hard_memory_controller(); + mailbox_init(); + + if (!intel_mailbox_is_fpga_not_ready()) + socfpga_bridges_enable(); } @@ -107,7 +103,7 @@ void bl2_el3_plat_arch_setup(void) enable_mmu_el3(0); - dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000); + dw_mmc_params_t params = EMMC_INIT_PARAMS(0x100000, get_mmc_clk()); info.mmc_dev_type = MMC_IS_SD; info.ocr_voltage = OCR_3_3_3_4 | OCR_3_2_3_3; @@ -115,7 +111,7 @@ void bl2_el3_plat_arch_setup(void) switch (boot_source) { case BOOT_SOURCE_SDMMC: dw_mmc_init(¶ms, &info); - stratix10_io_setup(boot_source); + socfpga_io_setup(boot_source); break; case BOOT_SOURCE_QSPI: @@ -124,7 +120,7 @@ void bl2_el3_plat_arch_setup(void) cad_qspi_init(0, QSPI_CONFIG_CPHA, QSPI_CONFIG_CPOL, QSPI_CONFIG_CSDA, QSPI_CONFIG_CSDADS, QSPI_CONFIG_CSEOT, QSPI_CONFIG_CSSOT, 0); - stratix10_io_setup(boot_source); + socfpga_io_setup(boot_source); break; default: diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c index 7c9833b33..29f57c467 100644 --- a/plat/intel/soc/stratix10/bl31_plat_setup.c +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -1,34 +1,28 @@ /* * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, Intel Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#include <assert.h> #include <arch.h> #include <arch_helpers.h> +#include <assert.h> #include <common/bl_common.h> -#include <common/debug.h> -#include <drivers/console.h> -#include <drivers/delay_timer.h> -#include <drivers/arm/gic_common.h> #include <drivers/arm/gicv2.h> #include <drivers/ti/uart/uart_16550.h> -#include <drivers/generic_delay_timer.h> -#include <drivers/arm/gicv2.h> -#include <s10_mailbox.h> #include <lib/xlat_tables/xlat_tables.h> #include <lib/mmio.h> #include <plat/common/platform.h> #include <platform_def.h> -#include "stratix10_private.h" -#include "s10_handoff.h" -#include "s10_reset_manager.h" +#include "socfpga_private.h" +#include "socfpga_reset_manager.h" +#include "socfpga_system_manager.h" #include "s10_memory_controller.h" #include "s10_pinmux.h" #include "s10_clock_manager.h" -#include "s10_system_manager.h" + static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -60,37 +54,47 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, void *from_bl2 = (void *) arg0; bl_params_t *params_from_bl2 = (bl_params_t *)from_bl2; - assert(params_from_bl2 != NULL); - assert(params_from_bl2->h.type == PARAM_BL_PARAMS); - assert(params_from_bl2->h.version >= VERSION_2); /* * Copy BL32 (if populated by BL31) and BL33 entry point information. * They are stored in Secure RAM, in BL31's address space. */ - bl_params_node_t *bl_params = params_from_bl2->head; + if (params_from_bl2->h.type == PARAM_BL_PARAMS && + params_from_bl2->h.version >= VERSION_2) { - while (bl_params) { - if (bl_params->image_id == BL33_IMAGE_ID) - bl33_image_ep_info = *bl_params->ep_info; + bl_params_node_t *bl_params = params_from_bl2->head; - bl_params = bl_params->next_params_info; + while (bl_params) { + if (bl_params->image_id == BL33_IMAGE_ID) + bl33_image_ep_info = *bl_params->ep_info; + + bl_params = bl_params->next_params_info; + } + } else { + struct socfpga_bl31_params *arg_from_bl2 = + (struct socfpga_bl31_params *) from_bl2; + + assert(arg_from_bl2->h.type == PARAM_BL31); + assert(arg_from_bl2->h.version >= VERSION_1); + + bl32_image_ep_info = *arg_from_bl2->bl32_ep_info; + bl33_image_ep_info = *arg_from_bl2->bl33_ep_info; } SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); } static const interrupt_prop_t s10_interrupt_props[] = { - PLAT_INTEL_S10_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), - PLAT_INTEL_S10_G0_IRQ_PROPS(GICV2_INTR_GROUP0) + PLAT_INTEL_SOCFPGA_G1S_IRQ_PROPS(GICV2_INTR_GROUP0), + PLAT_INTEL_SOCFPGA_G0_IRQ_PROPS(GICV2_INTR_GROUP0) }; static unsigned int target_mask_array[PLATFORM_CORE_COUNT]; static const gicv2_driver_data_t plat_gicv2_gic_data = { - .gicd_base = PLAT_INTEL_S10_GICD_BASE, - .gicc_base = PLAT_INTEL_S10_GICC_BASE, + .gicd_base = PLAT_INTEL_SOCFPGA_GICD_BASE, + .gicc_base = PLAT_INTEL_SOCFPGA_GICC_BASE, .interrupt_props = s10_interrupt_props, .interrupt_props_num = ARRAY_SIZE(s10_interrupt_props), .target_masks = target_mask_array, @@ -107,6 +111,10 @@ void bl31_platform_setup(void) gicv2_distif_init(); gicv2_pcpu_distif_init(); gicv2_cpuif_enable(); + + /* Signal secondary CPUs to jump to BL31 (BL2 = U-boot SPL) */ + mmio_write_64(PLAT_CPU_RELEASE_ADDR, + (uint64_t)plat_secondary_cpus_bl31_entry); } const mmap_region_t plat_stratix10_mmap[] = { diff --git a/plat/intel/soc/stratix10/include/platform_def.h b/plat/intel/soc/stratix10/include/platform_def.h deleted file mode 100644 index a753acd20..000000000 --- a/plat/intel/soc/stratix10/include/platform_def.h +++ /dev/null @@ -1,198 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __PLATFORM_DEF_H__ -#define __PLATFORM_DEF_H__ - -#include <arch.h> -#include <common/bl_common.h> -#include <common/interrupt_props.h> -#include <common/tbbr/tbbr_img_def.h> -#include <drivers/arm/gic_common.h> -#include <plat/common/common_def.h> - - -#define PLAT_CPUID_RELEASE 0xffe1b000 -#define PLAT_SEC_ENTRY 0xffe1b008 - -/* Define next boot image name and offset */ -#define PLAT_NS_IMAGE_OFFSET 0x50000 -#define PLAT_HANDOFF_OFFSET 0xFFE3F000 - -/******************************************************************************* - * Platform binary types for linking - ******************************************************************************/ -#define PLATFORM_LINKER_FORMAT "elf64-littleaarch64" -#define PLATFORM_LINKER_ARCH aarch64 - -/* Stratix 10 supports up to 124GB RAM */ -#define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 39) -#define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 39) - - -/******************************************************************************* - * Generic platform constants - ******************************************************************************/ -#define PLAT_PRIMARY_CPU 0 -#define PLAT_SECONDARY_ENTRY_BASE 0x01f78bf0 - -/* Size of cacheable stacks */ -#define PLATFORM_STACK_SIZE 0x2000 - -/* PSCI related constant */ -#define PLAT_NUM_POWER_DOMAINS 5 -#define PLAT_MAX_PWR_LVL 1 -#define PLAT_MAX_RET_STATE 1 -#define PLAT_MAX_OFF_STATE 2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 -#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ - PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 - -/* Interrupt related constant */ - -#define INTEL_S10_IRQ_SEC_PHY_TIMER 29 - -#define INTEL_S10_IRQ_SEC_SGI_0 8 -#define INTEL_S10_IRQ_SEC_SGI_1 9 -#define INTEL_S10_IRQ_SEC_SGI_2 10 -#define INTEL_S10_IRQ_SEC_SGI_3 11 -#define INTEL_S10_IRQ_SEC_SGI_4 12 -#define INTEL_S10_IRQ_SEC_SGI_5 13 -#define INTEL_S10_IRQ_SEC_SGI_6 14 -#define INTEL_S10_IRQ_SEC_SGI_7 15 - -#define TSP_IRQ_SEC_PHY_TIMER INTEL_S10_IRQ_SEC_PHY_TIMER -#define TSP_SEC_MEM_BASE BL32_BASE -#define TSP_SEC_MEM_SIZE (BL32_LIMIT - BL32_BASE + 1) -/******************************************************************************* - * Platform memory map related constants - ******************************************************************************/ -#define DRAM_BASE (0x0) -#define DRAM_SIZE (0x80000000) - -#define OCRAM_BASE (0xFFE00000) -#define OCRAM_SIZE (0x00040000) - -#define MEM64_BASE (0x0100000000) -#define MEM64_SIZE (0x1F00000000) - -#define DEVICE1_BASE (0x80000000) -#define DEVICE1_SIZE (0x60000000) - -#define DEVICE2_BASE (0xF7000000) -#define DEVICE2_SIZE (0x08E00000) - -#define DEVICE3_BASE (0xFFFC0000) -#define DEVICE3_SIZE (0x00008000) - -#define DEVICE4_BASE (0x2000000000) -#define DEVICE4_SIZE (0x0100000000) - -/******************************************************************************* - * BL31 specific defines. - ******************************************************************************/ -/* - * Put BL3-1 at the top of the Trusted SRAM (just below the shared memory, if - * present). BL31_BASE is calculated using the current BL3-1 debug size plus a - * little space for growth. - */ - - -#define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" - -#define BL1_RO_BASE (0xffe00000) -#define BL1_RO_LIMIT (0xffe0f000) -#define BL1_RW_BASE (0xffe10000) -#define BL1_RW_LIMIT (0xffe1ffff) -#define BL1_RW_SIZE (0x14000) - -#define BL2_BASE (0xffe00000) -#define BL2_LIMIT (0xffe1b000) - -#define BL31_BASE (0xffe1c000) -#define BL31_LIMIT (0xffe3bfff) - -/******************************************************************************* - * Platform specific page table and MMU setup constants - ******************************************************************************/ -#define MAX_XLAT_TABLES 8 -#define MAX_MMAP_REGIONS 16 - -/******************************************************************************* - * Declarations and constants to access the mailboxes safely. Each mailbox is - * aligned on the biggest cache line size in the platform. This is known only - * to the platform as it might have a combination of integrated and external - * caches. Such alignment ensures that two maiboxes do not sit on the same cache - * line at any cache level. They could belong to different cpus/clusters & - * get written while being protected by different locks causing corruption of - * a valid mailbox address. - ******************************************************************************/ -#define CACHE_WRITEBACK_SHIFT 6 -#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) - -#define PLAT_GIC_BASE (0xFFFC0000) -#define PLAT_GICC_BASE (PLAT_GIC_BASE + 0x2000) -#define PLAT_GICD_BASE (PLAT_GIC_BASE + 0x1000) -#define PLAT_GICR_BASE 0 - -/******************************************************************************* - * UART related constants - ******************************************************************************/ -#define PLAT_UART0_BASE (0xFFC02000) -#define PLAT_UART1_BASE (0xFFC02100) - -#define CRASH_CONSOLE_BASE PLAT_UART0_BASE - -#define PLAT_BAUDRATE (115200) -#define PLAT_UART_CLOCK (100000000) - -/******************************************************************************* - * System counter frequency related constants - ******************************************************************************/ -#define PLAT_SYS_COUNTER_FREQ_IN_TICKS (400000000) -#define PLAT_SYS_COUNTER_FREQ_IN_MHZ (400) - -#define PLAT_INTEL_S10_GICD_BASE PLAT_GICD_BASE -#define PLAT_INTEL_S10_GICC_BASE PLAT_GICC_BASE - -/* - * Define a list of Group 1 Secure and Group 0 interrupts as per GICv3 - * terminology. On a GICv2 system or mode, the lists will be merged and treated - * as Group 0 interrupts. - */ -#define PLAT_INTEL_S10_G1S_IRQ_PROPS(grp) \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_PHY_TIMER, GIC_HIGHEST_SEC_PRIORITY, \ - grp, GIC_INTR_CFG_LEVEL), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE), \ - INTR_PROP_DESC(INTEL_S10_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ - GIC_INTR_CFG_EDGE) - -#define PLAT_INTEL_S10_G0_IRQ_PROPS(grp) - -#define MAX_IO_HANDLES 4 -#define MAX_IO_DEVICES 4 -#define MAX_IO_BLOCK_DEVICES 2 - - -#endif /* __PLATFORM_DEF_H__ */ - diff --git a/plat/intel/soc/stratix10/include/s10_clock_manager.h b/plat/intel/soc/stratix10/include/s10_clock_manager.h index 99eb7a6c3..acc700a07 100644 --- a/plat/intel/soc/stratix10/include/s10_clock_manager.h +++ b/plat/intel/soc/stratix10/include/s10_clock_manager.h @@ -7,7 +7,7 @@ #ifndef __CLOCKMANAGER_H__ #define __CLOCKMANAGER_H__ -#include "s10_handoff.h" +#include "socfpga_handoff.h" #define ALT_CLKMGR 0xffd10000 @@ -50,10 +50,13 @@ #define ALT_CLKMGR_MAINPLL_VCOCALIB_HSCNT_SET(x) (((x) << 0) & 0x000000ff) #define ALT_CLKMGR_MAINPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(x) (((x) & 0x00030000) >> 16) -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1 0x0 -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC 0x1 -#define ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S 0x2 +#define ALT_CLKMGR_PSRC(x) (((x) & 0x00030000) >> 16) +#define ALT_CLKMGR_SRC_MAIN 0 +#define ALT_CLKMGR_SRC_PER 1 + +#define ALT_CLKMGR_PLLGLOB_PSRC_EOSC1 0x0 +#define ALT_CLKMGR_PLLGLOB_PSRC_INTOSC 0x1 +#define ALT_CLKMGR_PLLGLOB_PSRC_F2S 0x2 #define ALT_CLKMGR_PERPLL 0xffd100a4 #define ALT_CLKMGR_PERPLL_EN 0x0 @@ -83,14 +86,11 @@ #define ALT_CLKMGR_PERPLL_VCOCALIB_MSCNT_SET(x) (((x) << 9) & 0x0001fe00) #define ALT_CLKMGR_PERPLL_VCOCALIB 0x58 - -typedef struct { - uint32_t clk_freq_of_eosc1; - uint32_t clk_freq_of_f2h_free; - uint32_t clk_freq_of_cb_intosc_ls; -} CLOCK_SOURCE_CONFIG; +#define ALT_CLKMGR_INTOSC_HZ 460000000 void config_clkmgr_handoff(handoff *hoff_ptr); -int get_wdt_clk(handoff *hoff_ptr); +uint32_t get_wdt_clk(void); +uint32_t get_uart_clk(void); +uint32_t get_mmc_clk(void); #endif diff --git a/plat/intel/soc/stratix10/include/s10_handoff.h b/plat/intel/soc/stratix10/include/s10_handoff.h deleted file mode 100644 index 1cc8d09d2..000000000 --- a/plat/intel/soc/stratix10/include/s10_handoff.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef _HANDOFF_H_ -#define _HANDOFF_H_ - -#define HANDOFF_MAGIC_HEADER 0x424f4f54 /* BOOT */ -#define HANDOFF_MAGIC_PINMUX_SEL 0x504d5558 /* PMUX */ -#define HANDOFF_MAGIC_IOCTLR 0x494f4354 /* IOCT */ -#define HANDOFF_MAGIC_FPGA 0x46504741 /* FPGA */ -#define HANDOFF_MAGIC_IODELAY 0x444c4159 /* DLAY */ -#define HANDOFF_MAGIC_CLOCK 0x434c4b53 /* CLKS */ -#define HANDOFF_MAGIC_MISC 0x4d495343 /* MISC */ - -typedef struct handoff_t { - /* header */ - uint32_t header_magic; - uint32_t header_device; - uint32_t _pad_0x08_0x10[2]; - - /* pinmux configuration - select */ - uint32_t pinmux_sel_magic; - uint32_t pinmux_sel_length; - uint32_t _pad_0x18_0x20[2]; - uint32_t pinmux_sel_array[96]; /* offset, value */ - - /* pinmux configuration - io control */ - uint32_t pinmux_io_magic; - uint32_t pinmux_io_length; - uint32_t _pad_0x1a8_0x1b0[2]; - uint32_t pinmux_io_array[96]; /* offset, value */ - - /* pinmux configuration - use fpga switch */ - uint32_t pinmux_fpga_magic; - uint32_t pinmux_fpga_length; - uint32_t _pad_0x338_0x340[2]; - uint32_t pinmux_fpga_array[42]; /* offset, value */ - uint32_t _pad_0x3e8_0x3f0[2]; - - /* pinmux configuration - io delay */ - uint32_t pinmux_delay_magic; - uint32_t pinmux_delay_length; - uint32_t _pad_0x3f8_0x400[2]; - uint32_t pinmux_iodelay_array[96]; /* offset, value */ - - /* clock configuration */ - uint32_t clock_magic; - uint32_t clock_length; - uint32_t _pad_0x588_0x590[2]; - uint32_t main_pll_mpuclk; - uint32_t main_pll_nocclk; - uint32_t main_pll_cntr2clk; - uint32_t main_pll_cntr3clk; - uint32_t main_pll_cntr4clk; - uint32_t main_pll_cntr5clk; - uint32_t main_pll_cntr6clk; - uint32_t main_pll_cntr7clk; - uint32_t main_pll_cntr8clk; - uint32_t main_pll_cntr9clk; - uint32_t main_pll_nocdiv; - uint32_t main_pll_pllglob; - uint32_t main_pll_fdbck; - uint32_t main_pll_pllc0; - uint32_t main_pll_pllc1; - uint32_t _pad_0x5cc_0x5d0[1]; - uint32_t per_pll_cntr2clk; - uint32_t per_pll_cntr3clk; - uint32_t per_pll_cntr4clk; - uint32_t per_pll_cntr5clk; - uint32_t per_pll_cntr6clk; - uint32_t per_pll_cntr7clk; - uint32_t per_pll_cntr8clk; - uint32_t per_pll_cntr9clk; - uint32_t per_pll_emacctl; - uint32_t per_pll_gpiodiv; - uint32_t per_pll_pllglob; - uint32_t per_pll_fdbck; - uint32_t per_pll_pllc0; - uint32_t per_pll_pllc1; - uint32_t hps_osc_clk_h; - uint32_t fpga_clk_hz; - - /* misc configuration */ - uint32_t misc_magic; - uint32_t misc_length; - uint32_t _pad_0x618_0x620[2]; - uint32_t boot_source; -} handoff; - -int verify_handoff_image(handoff *hoff_ptr, handoff *reverse_hoff_ptr); -int s10_get_handoff(handoff *hoff_ptr); - -#endif - - diff --git a/plat/intel/soc/stratix10/include/s10_mailbox.h b/plat/intel/soc/stratix10/include/s10_mailbox.h deleted file mode 100644 index 554c26566..000000000 --- a/plat/intel/soc/stratix10/include/s10_mailbox.h +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __S10_MBOX__ -#define __S10_MBOX__ - -#define MBOX_OFFSET 0xffa30000 - -#define MBOX_ATF_CLIENT_ID 0x1 -#define MBOX_JOB_ID 0x1 - -/* Mailbox interrupt flags and masks */ -#define MBOX_INT_FLAG_COE 0x1 -#define MBOX_INT_FLAG_RIE 0x2 -#define MBOX_INT_FLAG_UAE 0x100 -#define MBOX_COE_BIT(INTERRUPT) ((INTERRUPT) & 0x3) -#define MBOX_UAE_BIT(INTERRUPT) (((INTERRUPT) & (1<<4))) - -/* Mailbox response and status */ -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_ERR(BUFFER) ((BUFFER) & 0x00000fff) -#define MBOX_RESP_LEN(BUFFER) (((BUFFER) & 0x007ff000) >> 12) -#define MBOX_RESP_CLIENT_ID(BUFFER) (((BUFFER) & 0xf0000000) >> 28) -#define MBOX_RESP_JOB_ID(BUFFER) (((BUFFER) & 0x0f000000) >> 24) -#define MBOX_STATUS_UA_MASK (1<<8) - -/* Mailbox command and response */ -#define MBOX_CMD_FREE_OFFSET 0x14 -#define MBOX_CMD_BUFFER_SIZE 32 -#define MBOX_CLIENT_ID_CMD(CLIENT_ID) ((CLIENT_ID) << 28) -#define MBOX_JOB_ID_CMD(JOB_ID) (JOB_ID<<24) -#define MBOX_CMD_LEN_CMD(CMD_LEN) ((CMD_LEN) << 12) -#define MBOX_INDIRECT (1 << 11) -#define MBOX_INSUFFICIENT_BUFFER -2 -#define MBOX_CIN 0x00 -#define MBOX_ROUT 0x04 -#define MBOX_URG 0x08 -#define MBOX_INT 0x0C -#define MBOX_COUT 0x20 -#define MBOX_RIN 0x24 -#define MBOX_STATUS 0x2C -#define MBOX_CMD_BUFFER 0x40 -#define MBOX_RESP_BUFFER 0xC0 - -#define MBOX_RESP_BUFFER_SIZE 16 -#define MBOX_RESP_OK 0 -#define MBOX_RESP_INVALID_CMD 1 -#define MBOX_RESP_UNKNOWN_BR 2 -#define MBOX_RESP_UNKNOWN 3 -#define MBOX_RESP_NOT_CONFIGURED 256 - -/* Mailbox SDM doorbell */ -#define MBOX_DOORBELL_TO_SDM 0x400 -#define MBOX_DOORBELL_FROM_SDM 0x480 - -/* Mailbox QSPI commands */ -#define MBOX_CMD_RESTART 2 -#define MBOX_CMD_QSPI_OPEN 50 -#define MBOX_CMD_QSPI_CLOSE 51 -#define MBOX_CMD_QSPI_DIRECT 59 -#define MBOX_CMD_GET_IDCODE 16 -#define MBOX_CMD_QSPI_SET_CS 52 - -/* Mailbox REBOOT commands */ -#define MBOX_CMD_REBOOT_HPS 71 - -/* Generic error handling */ -#define MBOX_TIMEOUT -2047 -#define MBOX_NO_RESPONSE -2 -#define MBOX_WRONG_ID -3 - -/* Mailbox status */ -#define RECONFIG_STATUS_STATE 0 -#define RECONFIG_STATUS_PIN_STATUS 2 -#define RECONFIG_STATUS_SOFTFUNC_STATUS 3 -#define PIN_STATUS_NSTATUS (1U << 31) -#define SOFTFUNC_STATUS_SEU_ERROR (1 << 3) -#define SOFTFUNC_STATUS_INIT_DONE (1 << 1) -#define SOFTFUNC_STATUS_CONF_DONE (1 << 0) -#define MBOX_CFGSTAT_STATE_CONFIG 0x10000000 - -/* SMC function IDs for SiP Service queries */ -#define SIP_SVC_CALL_COUNT 0x8200ff00 -#define SIP_SVC_UID 0x8200ff01 -#define SIP_SVC_VERSION 0x8200ff03 - -/* SiP Service Calls version numbers */ -#define SIP_SVC_VERSION_MAJOR 0 -#define SIP_SVC_VERSION_MINOR 1 - -/* Mailbox reconfiguration commands */ -#define MBOX_RECONFIG 6 -#define MBOX_RECONFIG_DATA 8 -#define MBOX_RECONFIG_STATUS 9 - -/* Sip get memory */ -#define INTEL_SIP_SMC_FPGA_CONFIG_START 0xC2000001 -#define INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM 0xC2000005 -#define INTEL_SIP_SMC_FPGA_CONFIG_ISDONE 0xC2000004 -#define INTEL_SIP_SMC_FPGA_CONFIG_WRITE 0x42000002 -#define INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE 0xC2000003 -#define INTEL_SIP_SMC_STATUS_OK 0 -#define INTEL_SIP_SMC_STATUS_ERROR 0x4 -#define INTEL_SIP_SMC_STATUS_BUSY 0x1 -#define INTEL_SIP_SMC_STATUS_REJECTED 0x2 -#define INTEL_SIP_SMC_FPGA_CONFIG_ADDR 0x1000 -#define INTEL_SIP_SMC_FPGA_CONFIG_SIZE 16777216 - -void mailbox_set_int(int interrupt_input); -int mailbox_init(void); -void mailbox_set_qspi_close(void); -void mailbox_set_qspi_open(void); -void mailbox_set_qspi_direct(void); -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response); -void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent); -int mailbox_read_response(int job_id, uint32_t *response); -int mailbox_get_qspi_clock(void); -void mailbox_reset_cold(void); - -#endif diff --git a/plat/intel/soc/stratix10/include/s10_memory_controller.h b/plat/intel/soc/stratix10/include/s10_memory_controller.h index ad7cb9db1..155b2795e 100644 --- a/plat/intel/soc/stratix10/include/s10_memory_controller.h +++ b/plat/intel/soc/stratix10/include/s10_memory_controller.h @@ -22,8 +22,6 @@ #define S10_MPFE_IOHMC_CTRLCFG1_CFG_ADDR_ORDER(value) \ (((value) & 0x00000060) >> 5) -#define S10_RSTMGR_BRGMODRST 0xffd1102c -#define S10_RSTMGR_BRGMODRST_DDRSCH 0x00000040 #define S10_MPFE_HMC_ADP_ECCCTRL1 0xf8011100 #define S10_MPFE_HMC_ADP_ECCCTRL2 0xf8011104 diff --git a/plat/intel/soc/stratix10/include/s10_pinmux.h b/plat/intel/soc/stratix10/include/s10_pinmux.h index a1ba29ef9..82367d74f 100644 --- a/plat/intel/soc/stratix10/include/s10_pinmux.h +++ b/plat/intel/soc/stratix10/include/s10_pinmux.h @@ -12,7 +12,7 @@ #define S10_PINMUX_PINMUX_EMAC0_USEFPGA 0xffd13300 #define S10_PINMUX_IO0_DELAY 0xffd13400 -#include "s10_handoff.h" +#include "socfpga_handoff.h" void config_pinmux(handoff *handoff); diff --git a/plat/intel/soc/stratix10/include/s10_reset_manager.h b/plat/intel/soc/stratix10/include/s10_reset_manager.h deleted file mode 100644 index 731a8ddb6..000000000 --- a/plat/intel/soc/stratix10/include/s10_reset_manager.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __S10_RESETMANAGER_H__ -#define __S10_RESETMANAGER_H__ - -#define S10_RSTMGR_PER0MODRST 0xffd11024 -#define S10_RSTMGR_PER1MODRST 0xffd11028 -#define S10_RSTMGR_HDSKEN 0xffd11010 - -#define S10_RSTMGR_PER0MODRST_EMAC0 0x00000001 -#define S10_RSTMGR_PER0MODRST_EMAC1 0x00000002 -#define S10_RSTMGR_PER0MODRST_EMAC2 0x00000004 -#define S10_RSTMGR_PER0MODRST_EMAC0OCP 0x00000100 -#define S10_RSTMGR_PER0MODRST_EMAC1OCP 0x00000200 -#define S10_RSTMGR_PER0MODRST_DMAOCP 0x00200000 -#define S10_RSTMGR_PER0MODRST_DMA 0x00010000 -#define S10_RSTMGR_PER0MODRST_EMAC0 0x00000001 -#define S10_RSTMGR_PER0MODRST_EMAC1 0x00000002 -#define S10_RSTMGR_PER0MODRST_EMAC2OCP 0x00000400 -#define S10_RSTMGR_PER0MODRST_EMAC2 0x00000004 -#define S10_RSTMGR_PER0MODRST_EMACPTP 0x00400000 -#define S10_RSTMGR_PER0MODRST_NANDOCP 0x00002000 -#define S10_RSTMGR_PER0MODRST_NAND 0x00000020 -#define S10_RSTMGR_PER0MODRST_SDMMCOCP 0x00008000 -#define S10_RSTMGR_PER0MODRST_SDMMC 0x00000080 -#define S10_RSTMGR_PER0MODRST_SPIM0 0x00020000 -#define S10_RSTMGR_PER0MODRST_SPIM1 0x00040000 -#define S10_RSTMGR_PER0MODRST_SPIS0 0x00080000 -#define S10_RSTMGR_PER0MODRST_SPIS1 0x00100000 -#define S10_RSTMGR_PER0MODRST_USB0OCP 0x00000800 -#define S10_RSTMGR_PER0MODRST_USB0 0x00000008 -#define S10_RSTMGR_PER0MODRST_USB1OCP 0x00001000 -#define S10_RSTMGR_PER0MODRST_USB1 0x00000010 - -#define S10_RSTMGR_PER1MODRST_WATCHDOG0 0x1 -#define S10_RSTMGR_PER1MODRST_WATCHDOG1 0x2 -#define S10_RSTMGR_PER1MODRST_WATCHDOG2 0x4 -#define S10_RSTMGR_PER1MODRST_WATCHDOG3 0x8 -#define S10_RSTMGR_PER1MODRST_GPIO0 0x01000000 -#define S10_RSTMGR_PER1MODRST_GPIO0 0x01000000 -#define S10_RSTMGR_PER1MODRST_GPIO1 0x02000000 -#define S10_RSTMGR_PER1MODRST_GPIO1 0x02000000 -#define S10_RSTMGR_PER1MODRST_I2C0 0x00000100 -#define S10_RSTMGR_PER1MODRST_I2C0 0x00000100 -#define S10_RSTMGR_PER1MODRST_I2C1 0x00000200 -#define S10_RSTMGR_PER1MODRST_I2C1 0x00000200 -#define S10_RSTMGR_PER1MODRST_I2C2 0x00000400 -#define S10_RSTMGR_PER1MODRST_I2C2 0x00000400 -#define S10_RSTMGR_PER1MODRST_I2C3 0x00000800 -#define S10_RSTMGR_PER1MODRST_I2C3 0x00000800 -#define S10_RSTMGR_PER1MODRST_I2C4 0x00001000 -#define S10_RSTMGR_PER1MODRST_I2C4 0x00001000 -#define S10_RSTMGR_PER1MODRST_L4SYSTIMER0 0x00000010 -#define S10_RSTMGR_PER1MODRST_L4SYSTIMER1 0x00000020 -#define S10_RSTMGR_PER1MODRST_SPTIMER0 0x00000040 -#define S10_RSTMGR_PER1MODRST_SPTIMER0 0x00000040 -#define S10_RSTMGR_PER1MODRST_SPTIMER1 0x00000080 -#define S10_RSTMGR_PER1MODRST_SPTIMER1 0x00000080 -#define S10_RSTMGR_PER1MODRST_UART0 0x00010000 -#define S10_RSTMGR_PER1MODRST_UART0 0x00010000 -#define S10_RSTMGR_PER1MODRST_UART1 0x00020000 -#define S10_RSTMGR_PER1MODRST_UART1 0x00020000 -#define S10_RSTMGR_HDSKEN_DEBUG_L3NOC 0x00020000 -#define S10_RSTMGR_HDSKEN_ETRSTALLEN 0x00000008 -#define S10_RSTMGR_HDSKEN_FPGAHSEN 0x00000004 -#define S10_RSTMGR_HDSKEN_L2FLUSHEN 0x00000100 -#define S10_RSTMGR_HDSKEN_L3NOC_DBG 0x00010000 - -#define S10_RSTMGR_HDSKEN_SDRSELFREFEN 0x00000001 -#define S10_RSTMGR_PER0MODRST_DMAIF0 0x01000000 -#define S10_RSTMGR_PER0MODRST_DMAIF1 0x02000000 -#define S10_RSTMGR_PER0MODRST_DMAIF2 0x04000000 -#define S10_RSTMGR_PER0MODRST_DMAIF3 0x08000000 -#define S10_RSTMGR_PER0MODRST_DMAIF4 0x10000000 -#define S10_RSTMGR_PER0MODRST_DMAIF5 0x20000000 -#define S10_RSTMGR_PER0MODRST_DMAIF6 0x40000000 -#define S10_RSTMGR_PER0MODRST_DMAIF7 0x80000000 - -void deassert_peripheral_reset(void); -void config_hps_hs_before_warm_reset(void); - -#endif - diff --git a/plat/intel/soc/stratix10/include/s10_system_manager.h b/plat/intel/soc/stratix10/include/s10_system_manager.h deleted file mode 100644 index 4500c6fbd..000000000 --- a/plat/intel/soc/stratix10/include/s10_system_manager.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#define S10_NOC_FW_L4_PER_SCR_NAND_REGISTER 0xffd21000 -#define S10_NOC_FW_L4_PER_SCR_NAND_DATA 0xffd21004 -#define S10_NOC_FW_L4_PER_SCR_USB0_REGISTER 0xffd2100c -#define S10_NOC_FW_L4_PER_SCR_USB1_REGISTER 0xffd21010 -#define S10_NOC_FW_L4_PER_SCR_SPI_MASTER0 0xffd2101c -#define S10_NOC_FW_L4_PER_SCR_SPI_MASTER1 0xffd21020 -#define S10_NOC_FW_L4_PER_SCR_SPI_SLAVE0 0xffd21024 -#define S10_NOC_FW_L4_PER_SCR_SPI_SLAVE1 0xffd21028 -#define S10_NOC_FW_L4_PER_SCR_EMAC0 0xffd2102c -#define S10_NOC_FW_L4_PER_SCR_EMAC1 0xffd21030 -#define S10_NOC_FW_L4_PER_SCR_EMAC2 0xffd21034 -#define S10_NOC_FW_L4_PER_SCR_SDMMC 0xffd21040 -#define S10_NOC_FW_L4_PER_SCR_GPIO0 0xffd21044 -#define S10_NOC_FW_L4_PER_SCR_GPIO1 0xffd21048 -#define S10_NOC_FW_L4_PER_SCR_I2C0 0xffd21050 -#define S10_NOC_FW_L4_PER_SCR_I2C1 0xffd21054 -#define S10_NOC_FW_L4_PER_SCR_I2C2 0xffd21058 -#define S10_NOC_FW_L4_PER_SCR_I2C3 0xffd2105c -#define S10_NOC_FW_L4_PER_SCR_I2C4 0xffd21060 -#define S10_NOC_FW_L4_PER_SCR_SP_TIMER0 0xffd21064 -#define S10_NOC_FW_L4_PER_SCR_SP_TIMER1 0xffd21068 -#define S10_NOC_FW_L4_PER_SCR_UART0 0xffd2106c -#define S10_NOC_FW_L4_PER_SCR_UART1 0xffd21070 - -#define S10_NOC_FW_L4_SYS_SCR_DMA_ECC 0xffd21108 -#define S10_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC 0xffd2110c -#define S10_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC 0xffd21110 -#define S10_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC 0xffd21114 -#define S10_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC 0xffd21118 -#define S10_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC 0xffd2111c -#define S10_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC 0xffd21120 -#define S10_NOC_FW_L4_SYS_SCR_NAND_ECC 0xffd2112c -#define S10_NOC_FW_L4_SYS_SCR_NAND_READ_ECC 0xffd21130 -#define S10_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC 0xffd21134 -#define S10_NOC_FW_L4_SYS_SCR_OCRAM_ECC 0xffd21138 -#define S10_NOC_FW_L4_SYS_SCR_SDMMC_ECC 0xffd21140 -#define S10_NOC_FW_L4_SYS_SCR_USB0_ECC 0xffd21144 -#define S10_NOC_FW_L4_SYS_SCR_USB1_ECC 0xffd21148 -#define S10_NOC_FW_L4_SYS_SCR_CLK_MGR 0xffd2114c -#define S10_NOC_FW_L4_SYS_SCR_IO_MGR 0xffd21154 -#define S10_NOC_FW_L4_SYS_SCR_RST_MGR 0xffd21158 -#define S10_NOC_FW_L4_SYS_SCR_SYS_MGR 0xffd2115c -#define S10_NOC_FW_L4_SYS_SCR_OSC0_TIMER 0xffd21160 -#define S10_NOC_FW_L4_SYS_SCR_OSC1_TIMER 0xffd21164 -#define S10_NOC_FW_L4_SYS_SCR_WATCHDOG0 0xffd21168 -#define S10_NOC_FW_L4_SYS_SCR_WATCHDOG1 0xffd2116c -#define S10_NOC_FW_L4_SYS_SCR_WATCHDOG2 0xffd21170 -#define S10_NOC_FW_L4_SYS_SCR_WATCHDOG3 0xffd21174 -#define S10_NOC_FW_L4_SYS_SCR_DAP 0xffd21178 -#define S10_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES 0xffd21190 -#define S10_NOC_FW_L4_SYS_SCR_L4_NOC_QOS 0xffd21194 - -#define S10_CCU_NOC_CPU0_RAMSPACE0_0 0xf7004688 -#define S10_CCU_NOC_IOM_RAMSPACE0_0 0xf7018628 - -#define S10_SYSMGR_CORE(x) (0xffd12000 + (x)) -#define SYSMGR_MMC 0x28 -#define SYSMGR_MMC_DRVSEL(x) (((x) & 0x7) << 0) - - -#define DISABLE_L4_FIREWALL (BIT(0) | BIT(16) | BIT(24)) - -void enable_nonsecure_access(void); - diff --git a/plat/intel/soc/stratix10/include/socfpga_plat_def.h b/plat/intel/soc/stratix10/include/socfpga_plat_def.h new file mode 100644 index 000000000..9dc51514c --- /dev/null +++ b/plat/intel/soc/stratix10/include/socfpga_plat_def.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_SOCFPGA_DEF_H +#define PLAT_SOCFPGA_DEF_H + +#include <platform_def.h> + +/* Platform Setting */ +#define PLATFORM_MODEL PLAT_SOCFPGA_STRATIX10 + +/* Register Mapping */ +#define SOCFPGA_MMC_REG_BASE 0xff808000 + +#define SOCFPGA_RSTMGR_REG_BASE 0xffd11000 +#define SOCFPGA_SYSMGR_REG_BASE 0xffd12000 + +#define SOCFPGA_L4_PER_SCR_REG_BASE 0xffd21000 +#define SOCFPGA_L4_SYS_SCR_REG_BASE 0xffd21100 +#define SOCFPGA_SOC2FPGA_SCR_REG_BASE 0xffd21200 +#define SOCFPGA_LWSOC2FPGA_SCR_REG_BASE 0xffd21300 + + +#endif /* PLATSOCFPGA_DEF_H */ + diff --git a/plat/intel/soc/stratix10/include/stratix10_private.h b/plat/intel/soc/stratix10/include/stratix10_private.h deleted file mode 100644 index f437202fa..000000000 --- a/plat/intel/soc/stratix10/include/stratix10_private.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef __S10_PRIVATE_H__ -#define __S10_PRIVATE_H__ - -#define S10_MMC_REG_BASE 0xff808000 - -#define EMMC_DESC_SIZE (1<<20) -#define EMMC_INIT_PARAMS(base) \ - { .bus_width = MMC_BUS_WIDTH_4, \ - .clk_rate = 50000000, \ - .desc_base = (base), \ - .desc_size = EMMC_DESC_SIZE, \ - .flags = 0, \ - .reg_base = S10_MMC_REG_BASE, \ - \ - } - -typedef enum { - BOOT_SOURCE_FPGA = 0, - BOOT_SOURCE_SDMMC, - BOOT_SOURCE_NAND, - BOOT_SOURCE_RSVD, - BOOT_SOURCE_QSPI, -} boot_source_type; - -void enable_nonsecure_access(void); -void stratix10_io_setup(int boot_source); - -#endif diff --git a/plat/intel/soc/stratix10/plat_psci.c b/plat/intel/soc/stratix10/plat_psci.c deleted file mode 100644 index f4a970e75..000000000 --- a/plat/intel/soc/stratix10/plat_psci.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch_helpers.h> -#include <assert.h> -#include <common/debug.h> -#include <errno.h> -#include <lib/mmio.h> -#include <drivers/arm/gic_common.h> -#include <drivers/arm/gicv2.h> -#include <plat/common/platform.h> -#include <lib/psci/psci.h> - -#include "platform_def.h" -#include "s10_reset_manager.h" -#include "s10_mailbox.h" - -#define S10_RSTMGR_OFST 0xffd11000 -#define S10_RSTMGR_MPUMODRST_OFST 0x20 - -uintptr_t *stratix10_sec_entry = (uintptr_t *) PLAT_SEC_ENTRY; -uintptr_t *cpuid_release = (uintptr_t *) PLAT_CPUID_RELEASE; - -/******************************************************************************* - * plat handler called when a CPU is about to enter standby. - ******************************************************************************/ -void plat_cpu_standby(plat_local_state_t cpu_state) -{ - /* - * Enter standby state - * dsb is good practice before using wfi to enter low power states - */ - VERBOSE("%s: cpu_state: 0x%x\n", __func__, cpu_state); - dsb(); - wfi(); -} - -/******************************************************************************* - * plat handler called when a power domain is about to be turned on. The - * mpidr determines the CPU to be turned on. - ******************************************************************************/ -int plat_pwr_domain_on(u_register_t mpidr) -{ - unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr); - - VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr); - - if (cpu_id == -1) - return PSCI_E_INTERN_FAIL; - - *cpuid_release = cpu_id; - - /* release core reset */ - mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); - return PSCI_E_SUCCESS; -} - -/******************************************************************************* - * plat handler called when a power domain is about to be turned off. The - * target_state encodes the power state that each level should transition to. - ******************************************************************************/ -void plat_pwr_domain_off(const psci_power_state_t *target_state) -{ - unsigned int cpu_id = plat_my_core_pos(); - - for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) - VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", - __func__, i, target_state->pwr_domain_state[i]); - - /* TODO: Prevent interrupts from spuriously waking up this cpu */ - /* gicv2_cpuif_disable(); */ - - /* assert core reset */ - mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); -} - -/******************************************************************************* - * plat handler called when a power domain is about to be suspended. The - * target_state encodes the power state that each level should transition to. - ******************************************************************************/ -void plat_pwr_domain_suspend(const psci_power_state_t *target_state) -{ - unsigned int cpu_id = plat_my_core_pos(); - - for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) - VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", - __func__, i, target_state->pwr_domain_state[i]); - /* assert core reset */ - mmio_setbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); - -} - -/******************************************************************************* - * plat handler called when a power domain has just been powered on after - * being turned off earlier. The target_state encodes the low power state that - * each level has woken up from. - ******************************************************************************/ -void plat_pwr_domain_on_finish(const psci_power_state_t *target_state) -{ - for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) - VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", - __func__, i, target_state->pwr_domain_state[i]); - - /* Program the gic per-cpu distributor or re-distributor interface */ - gicv2_pcpu_distif_init(); - gicv2_set_pe_target_mask(plat_my_core_pos()); - - /* Enable the gic cpu interface */ - gicv2_cpuif_enable(); -} - -/******************************************************************************* - * plat handler called when a power domain has just been powered on after - * having been suspended earlier. The target_state encodes the low power state - * that each level has woken up from. - * TODO: At the moment we reuse the on finisher and reinitialize the secure - * context. Need to implement a separate suspend finisher. - ******************************************************************************/ -void plat_pwr_domain_suspend_finish(const psci_power_state_t *target_state) -{ - unsigned int cpu_id = plat_my_core_pos(); - - for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) - VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", - __func__, i, target_state->pwr_domain_state[i]); - - /* release core reset */ - mmio_clrbits_32(S10_RSTMGR_OFST + S10_RSTMGR_MPUMODRST_OFST, - 1 << cpu_id); -} - -/******************************************************************************* - * plat handlers to shutdown/reboot the system - ******************************************************************************/ -static void __dead2 plat_system_off(void) -{ - wfi(); - ERROR("System Off: operation not handled.\n"); - panic(); -} - -static void __dead2 plat_system_reset(void) -{ - INFO("assert Peripheral from Reset\r\n"); - - deassert_peripheral_reset(); - mailbox_reset_cold(); - - while (1) - wfi(); -} - -int plat_validate_power_state(unsigned int power_state, - psci_power_state_t *req_state) -{ - VERBOSE("%s: power_state: 0x%x\n", __func__, power_state); - - return PSCI_E_SUCCESS; -} - -int plat_validate_ns_entrypoint(unsigned long ns_entrypoint) -{ - VERBOSE("%s: ns_entrypoint: 0x%lx\n", __func__, ns_entrypoint); - return PSCI_E_SUCCESS; -} - -void plat_get_sys_suspend_power_state(psci_power_state_t *req_state) -{ - req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE; - req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE; -} - -/******************************************************************************* - * Export the platform handlers via plat_arm_psci_pm_ops. The ARM Standard - * platform layer will take care of registering the handlers with PSCI. - ******************************************************************************/ -const plat_psci_ops_t plat_psci_pm_ops = { - .cpu_standby = plat_cpu_standby, - .pwr_domain_on = plat_pwr_domain_on, - .pwr_domain_off = plat_pwr_domain_off, - .pwr_domain_suspend = plat_pwr_domain_suspend, - .pwr_domain_on_finish = plat_pwr_domain_on_finish, - .pwr_domain_suspend_finish = plat_pwr_domain_suspend_finish, - .system_off = plat_system_off, - .system_reset = plat_system_reset, - .validate_power_state = plat_validate_power_state, - .validate_ns_entrypoint = plat_validate_ns_entrypoint, - .get_sys_suspend_power_state = plat_get_sys_suspend_power_state -}; - -/******************************************************************************* - * Export the platform specific power ops. - ******************************************************************************/ -int plat_setup_psci_ops(uintptr_t sec_entrypoint, - const struct plat_psci_ops **psci_ops) -{ - /* Save warm boot entrypoint.*/ - *stratix10_sec_entry = sec_entrypoint; - - *psci_ops = &plat_psci_pm_ops; - return 0; -} diff --git a/plat/intel/soc/stratix10/plat_sip_svc.c b/plat/intel/soc/stratix10/plat_sip_svc.c deleted file mode 100644 index 2c2332ba9..000000000 --- a/plat/intel/soc/stratix10/plat_sip_svc.c +++ /dev/null @@ -1,378 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <common/debug.h> -#include <common/runtime_svc.h> -#include <lib/mmio.h> -#include <s10_mailbox.h> -#include <tools_share/uuid.h> - -/* Number of SiP Calls implemented */ -#define SIP_NUM_CALLS 0x3 - -/* Total buffer the driver can hold */ -#define FPGA_CONFIG_BUFFER_SIZE 4 - -int current_block; -int current_buffer; -int current_id = 1; -int max_blocks; -uint32_t bytes_per_block; -uint32_t blocks_submitted; -uint32_t blocks_completed; - -struct fpga_config_info { - uint32_t addr; - int size; - int size_written; - uint32_t write_requested; - int subblocks_sent; - int block_number; -}; - -/* SiP Service UUID */ -DEFINE_SVC_UUID2(intl_svc_uid, - 0xa85273b0, 0xe85a, 0x4862, 0xa6, 0x2a, - 0xfa, 0x88, 0x88, 0x17, 0x68, 0x81); - -uint64_t plat_sip_handler(uint32_t smc_fid, - uint64_t x1, - uint64_t x2, - uint64_t x3, - uint64_t x4, - void *cookie, - void *handle, - uint64_t flags) -{ - ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); - SMC_RET1(handle, SMC_UNK); -} - -struct fpga_config_info fpga_config_buffers[FPGA_CONFIG_BUFFER_SIZE]; - -static void intel_fpga_sdm_write_buffer(struct fpga_config_info *buffer) -{ - uint32_t args[3]; - - while (max_blocks > 0 && buffer->size > buffer->size_written) { - if (buffer->size - buffer->size_written <= - bytes_per_block) { - args[0] = (1<<8); - args[1] = buffer->addr + buffer->size_written; - args[2] = buffer->size - buffer->size_written; - buffer->size_written += - buffer->size - buffer->size_written; - buffer->subblocks_sent++; - mailbox_send_cmd_async(0x4, - MBOX_RECONFIG_DATA, - args, 3, 0); - current_buffer++; - current_buffer %= FPGA_CONFIG_BUFFER_SIZE; - } else { - args[0] = (1<<8); - args[1] = buffer->addr + buffer->size_written; - args[2] = bytes_per_block; - buffer->size_written += bytes_per_block; - mailbox_send_cmd_async(0x4, - MBOX_RECONFIG_DATA, - args, 3, 0); - buffer->subblocks_sent++; - } - max_blocks--; - } -} - -static int intel_fpga_sdm_write_all(void) -{ - int i; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) - intel_fpga_sdm_write_buffer( - &fpga_config_buffers[current_buffer]); - - return 0; -} - -uint32_t intel_mailbox_fpga_config_isdone(void) -{ - uint32_t args[2]; - uint32_t response[6]; - int status; - - status = mailbox_send_cmd(1, MBOX_RECONFIG_STATUS, args, 0, 0, - response); - - if (status < 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (response[RECONFIG_STATUS_STATE] && - response[RECONFIG_STATUS_STATE] != MBOX_CFGSTAT_STATE_CONFIG) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (!(response[RECONFIG_STATUS_PIN_STATUS] & PIN_STATUS_NSTATUS)) - return INTEL_SIP_SMC_STATUS_ERROR; - - if (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_SEU_ERROR) - return INTEL_SIP_SMC_STATUS_ERROR; - - if ((response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_CONF_DONE) && - (response[RECONFIG_STATUS_SOFTFUNC_STATUS] & - SOFTFUNC_STATUS_INIT_DONE)) - return INTEL_SIP_SMC_STATUS_OK; - - return INTEL_SIP_SMC_STATUS_ERROR; -} - -static int mark_last_buffer_xfer_completed(uint32_t *buffer_addr_completed) -{ - int i; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (fpga_config_buffers[i].block_number == current_block) { - fpga_config_buffers[i].subblocks_sent--; - if (fpga_config_buffers[i].subblocks_sent == 0 - && fpga_config_buffers[i].size <= - fpga_config_buffers[i].size_written) { - fpga_config_buffers[i].write_requested = 0; - current_block++; - *buffer_addr_completed = - fpga_config_buffers[i].addr; - return 0; - } - } - } - - return -1; -} - -unsigned int address_in_ddr(uint32_t *addr) -{ - if (((unsigned long long)addr > DRAM_BASE) && - ((unsigned long long)addr < DRAM_BASE + DRAM_SIZE)) - return 0; - - return -1; -} - -int intel_fpga_config_completed_write(uint32_t *completed_addr, - uint32_t *count) -{ - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - *count = 0; - int resp_len = 0; - uint32_t resp[5]; - int all_completed = 1; - int count_check = 0; - - if (address_in_ddr(completed_addr) != 0 || address_in_ddr(count) != 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - for (count_check = 0; count_check < 3; count_check++) - if (address_in_ddr(&completed_addr[*count + count_check]) != 0) - return INTEL_SIP_SMC_STATUS_ERROR; - - resp_len = mailbox_read_response(0x4, resp); - - while (resp_len >= 0 && *count < 3) { - max_blocks++; - if (mark_last_buffer_xfer_completed( - &completed_addr[*count]) == 0) - *count = *count + 1; - else - break; - resp_len = mailbox_read_response(0x4, resp); - } - - if (*count <= 0) { - if (resp_len != MBOX_NO_RESPONSE && - resp_len != MBOX_TIMEOUT && resp_len != 0) { - return INTEL_SIP_SMC_STATUS_ERROR; - } - - *count = 0; - } - - intel_fpga_sdm_write_all(); - - if (*count > 0) - status = INTEL_SIP_SMC_STATUS_OK; - else if (*count == 0) - status = INTEL_SIP_SMC_STATUS_BUSY; - - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (fpga_config_buffers[i].write_requested != 0) { - all_completed = 0; - break; - } - } - - if (all_completed == 1) - return INTEL_SIP_SMC_STATUS_OK; - - return status; -} - -int intel_fpga_config_start(uint32_t config_type) -{ - uint32_t response[3]; - int status = 0; - - status = mailbox_send_cmd(2, MBOX_RECONFIG, 0, 0, 0, - response); - - if (status < 0) - return status; - - max_blocks = response[0]; - bytes_per_block = response[1]; - - for (int i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - fpga_config_buffers[i].size = 0; - fpga_config_buffers[i].size_written = 0; - fpga_config_buffers[i].addr = 0; - fpga_config_buffers[i].write_requested = 0; - fpga_config_buffers[i].block_number = 0; - fpga_config_buffers[i].subblocks_sent = 0; - } - - blocks_submitted = 0; - current_block = 0; - current_buffer = 0; - - return 0; -} - - -uint32_t intel_fpga_config_write(uint64_t mem, uint64_t size) -{ - int i = 0; - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - - if (mem < DRAM_BASE || mem > DRAM_BASE + DRAM_SIZE) - status = INTEL_SIP_SMC_STATUS_REJECTED; - - if (mem + size > DRAM_BASE + DRAM_SIZE) - status = INTEL_SIP_SMC_STATUS_REJECTED; - - for (i = 0; i < FPGA_CONFIG_BUFFER_SIZE; i++) { - if (!fpga_config_buffers[i].write_requested) { - fpga_config_buffers[i].addr = mem; - fpga_config_buffers[i].size = size; - fpga_config_buffers[i].size_written = 0; - fpga_config_buffers[i].write_requested = 1; - fpga_config_buffers[i].block_number = - blocks_submitted++; - fpga_config_buffers[i].subblocks_sent = 0; - break; - } - } - - - if (i == FPGA_CONFIG_BUFFER_SIZE) { - status = INTEL_SIP_SMC_STATUS_REJECTED; - return status; - } else if (i == FPGA_CONFIG_BUFFER_SIZE - 1) { - status = INTEL_SIP_SMC_STATUS_BUSY; - } - - intel_fpga_sdm_write_all(); - - return status; -} - -/* - * This function is responsible for handling all SiP calls from the NS world - */ - -uintptr_t sip_smc_handler(uint32_t smc_fid, - u_register_t x1, - u_register_t x2, - u_register_t x3, - u_register_t x4, - void *cookie, - void *handle, - u_register_t flags) -{ - uint32_t status = INTEL_SIP_SMC_STATUS_OK; - uint32_t completed_addr[3]; - uint32_t count = 0; - - switch (smc_fid) { - case SIP_SVC_UID: - /* Return UID to the caller */ - SMC_UUID_RET(handle, intl_svc_uid); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_ISDONE: - status = intel_mailbox_fpga_config_isdone(); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_GET_MEM: - SMC_RET3(handle, INTEL_SIP_SMC_STATUS_OK, - INTEL_SIP_SMC_FPGA_CONFIG_ADDR, - INTEL_SIP_SMC_FPGA_CONFIG_SIZE - - INTEL_SIP_SMC_FPGA_CONFIG_ADDR); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_START: - status = intel_fpga_config_start(x1); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_WRITE: - status = intel_fpga_config_write(x1, x2); - SMC_RET4(handle, status, 0, 0, 0); - break; - case INTEL_SIP_SMC_FPGA_CONFIG_COMPLETED_WRITE: - status = intel_fpga_config_completed_write(completed_addr, - &count); - switch (count) { - case 1: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], 0, 0); - break; - case 2: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], - completed_addr[1], 0); - break; - case 3: - SMC_RET4(handle, INTEL_SIP_SMC_STATUS_OK, - completed_addr[0], - completed_addr[1], - completed_addr[2]); - break; - case 0: - SMC_RET4(handle, status, 0, 0, 0); - break; - default: - SMC_RET1(handle, INTEL_SIP_SMC_STATUS_ERROR); - } - break; - - default: - return plat_sip_handler(smc_fid, x1, x2, x3, x4, - cookie, handle, flags); - } -} - -DECLARE_RT_SVC( - s10_sip_svc, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - sip_smc_handler -); - -DECLARE_RT_SVC( - s10_sip_svc_std, - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_YIELD, - NULL, - sip_smc_handler -); diff --git a/plat/intel/soc/stratix10/plat_storage.c b/plat/intel/soc/stratix10/plat_storage.c deleted file mode 100644 index 0b8b9cd2a..000000000 --- a/plat/intel/soc/stratix10/plat_storage.c +++ /dev/null @@ -1,195 +0,0 @@ -/* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch_helpers.h> -#include <assert.h> -#include <common/debug.h> -#include <drivers/mmc.h> -#include <tools_share/firmware_image_package.h> -#include <drivers/io/io_block.h> -#include <drivers/io/io_driver.h> -#include <drivers/io/io_fip.h> -#include <drivers/io/io_memmap.h> -#include <drivers/io/io_storage.h> -#include <lib/mmio.h> -#include <drivers/partition/partition.h> -#include <lib/semihosting.h> -#include <string.h> -#include <lib/utils.h> -#include <common/tbbr/tbbr_img_def.h> -#include "platform_def.h" -#include "stratix10_private.h" - -#define STRATIX10_FIP_BASE (0) -#define STRATIX10_FIP_MAX_SIZE (0x1000000) -#define STRATIX10_MMC_DATA_BASE (0xffe3c000) -#define STRATIX10_MMC_DATA_SIZE (0x2000) -#define STRATIX10_QSPI_DATA_BASE (0x3C00000) -#define STRATIX10_QSPI_DATA_SIZE (0x1000000) - - -static const io_dev_connector_t *fip_dev_con; -static const io_dev_connector_t *boot_dev_con; - -static uintptr_t fip_dev_handle; -static uintptr_t boot_dev_handle; - -static const io_uuid_spec_t bl2_uuid_spec = { - .uuid = UUID_TRUSTED_BOOT_FIRMWARE_BL2, -}; - -static const io_uuid_spec_t bl31_uuid_spec = { - .uuid = UUID_EL3_RUNTIME_FIRMWARE_BL31, -}; - -static const io_uuid_spec_t bl33_uuid_spec = { - .uuid = UUID_NON_TRUSTED_FIRMWARE_BL33, -}; - -uintptr_t a2_lba_offset; -const char a2[] = {0xa2, 0x0}; - -static const io_block_spec_t gpt_block_spec = { - .offset = 0, - .length = MMC_BLOCK_SIZE -}; - -static int check_fip(const uintptr_t spec); -static int check_dev(const uintptr_t spec); - -static io_block_dev_spec_t boot_dev_spec; -static int (*register_io_dev)(const io_dev_connector_t **); - -static io_block_spec_t fip_spec = { - .offset = STRATIX10_FIP_BASE, - .length = STRATIX10_FIP_MAX_SIZE, -}; - -struct plat_io_policy { - uintptr_t *dev_handle; - uintptr_t image_spec; - int (*check)(const uintptr_t spec); -}; - -static const struct plat_io_policy policies[] = { - [FIP_IMAGE_ID] = { - &boot_dev_handle, - (uintptr_t)&fip_spec, - check_dev - }, - [BL2_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl2_uuid_spec, - check_fip - }, - [BL31_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t)&bl31_uuid_spec, - check_fip - }, - [BL33_IMAGE_ID] = { - &fip_dev_handle, - (uintptr_t) &bl33_uuid_spec, - check_fip - }, - [GPT_IMAGE_ID] = { - &boot_dev_handle, - (uintptr_t) &gpt_block_spec, - check_dev - }, -}; - -static int check_dev(const uintptr_t spec) -{ - int result; - uintptr_t local_handle; - - result = io_dev_init(boot_dev_handle, (uintptr_t)NULL); - if (result == 0) { - result = io_open(boot_dev_handle, spec, &local_handle); - if (result == 0) - io_close(local_handle); - } - return result; -} - -static int check_fip(const uintptr_t spec) -{ - int result; - uintptr_t local_image_handle; - - result = io_dev_init(fip_dev_handle, (uintptr_t)FIP_IMAGE_ID); - if (result == 0) { - result = io_open(fip_dev_handle, spec, &local_image_handle); - if (result == 0) - io_close(local_image_handle); - } - return result; -} - -void stratix10_io_setup(int boot_source) -{ - int result; - - switch (boot_source) { - case BOOT_SOURCE_SDMMC: - register_io_dev = ®ister_io_dev_block; - boot_dev_spec.buffer.offset = STRATIX10_MMC_DATA_BASE; - boot_dev_spec.buffer.length = MMC_BLOCK_SIZE; - boot_dev_spec.ops.read = mmc_read_blocks; - boot_dev_spec.ops.write = mmc_write_blocks; - boot_dev_spec.block_size = MMC_BLOCK_SIZE; - break; - - case BOOT_SOURCE_QSPI: - register_io_dev = ®ister_io_dev_memmap; - fip_spec.offset = fip_spec.offset + STRATIX10_QSPI_DATA_BASE; - break; - - default: - ERROR("Unsupported boot source\n"); - panic(); - break; - } - - result = (*register_io_dev)(&boot_dev_con); - assert(result == 0); - - result = register_io_dev_fip(&fip_dev_con); - assert(result == 0); - - result = io_dev_open(boot_dev_con, (uintptr_t)&boot_dev_spec, - &boot_dev_handle); - assert(result == 0); - - result = io_dev_open(fip_dev_con, (uintptr_t)NULL, &fip_dev_handle); - assert(result == 0); - - if (boot_source == BOOT_SOURCE_SDMMC) { - partition_init(GPT_IMAGE_ID); - fip_spec.offset = get_partition_entry(a2)->start; - } - - (void)result; -} - -int plat_get_image_source(unsigned int image_id, uintptr_t *dev_handle, - uintptr_t *image_spec) -{ - int result; - const struct plat_io_policy *policy; - - assert(image_id < ARRAY_SIZE(policies)); - - policy = &policies[image_id]; - result = policy->check(policy->image_spec); - assert(result == 0); - - *image_spec = policy->image_spec; - *dev_handle = *(policy->dev_handle); - - return result; -} diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 34674b0cd..efbab24b3 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -1,5 +1,6 @@ # # Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019, Intel Corporation. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,61 +11,55 @@ PLAT_INCLUDES := \ -Iplat/intel/soc/common/include/ PLAT_BL_COMMON_SOURCES := \ - lib/xlat_tables/xlat_tables_common.c \ - lib/xlat_tables/aarch64/xlat_tables.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/ti/uart/aarch64/16550_console.S \ + lib/xlat_tables/aarch64/xlat_tables.c \ + lib/xlat_tables/xlat_tables_common.c \ + plat/common/plat_gicv2.c \ plat/intel/soc/common/aarch64/platform_common.c \ plat/intel/soc/common/aarch64/plat_helpers.S BL2_SOURCES += \ - drivers/partition/partition.c \ - drivers/partition/gpt.c \ - drivers/arm/pl061/pl061_gpio.c \ + common/desc_image_load.c \ drivers/mmc/mmc.c \ - drivers/synopsys/emmc/dw_mmc.c \ + drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \ drivers/io/io_storage.c \ drivers/io/io_block.c \ drivers/io/io_fip.c \ - drivers/gpio/gpio.c \ - drivers/intel/soc/stratix10/io/s10_memmap_qspi.c \ + drivers/partition/partition.c \ + drivers/partition/gpt.c \ + drivers/synopsys/emmc/dw_mmc.c \ + lib/cpus/aarch64/cortex_a53.S \ plat/intel/soc/stratix10/bl2_plat_setup.c \ - plat/intel/soc/stratix10/plat_storage.c \ - plat/intel/soc/common/bl2_plat_mem_params_desc.c \ - plat/intel/soc/stratix10/soc/s10_reset_manager.c \ - plat/intel/soc/stratix10/soc/s10_handoff.c \ plat/intel/soc/stratix10/soc/s10_clock_manager.c \ - plat/intel/soc/stratix10/soc/s10_pinmux.c \ plat/intel/soc/stratix10/soc/s10_memory_controller.c \ + plat/intel/soc/stratix10/soc/s10_pinmux.c \ + plat/intel/soc/common/bl2_plat_mem_params_desc.c \ plat/intel/soc/common/socfpga_delay_timer.c \ - lib/cpus/aarch64/cortex_a53.S \ plat/intel/soc/common/socfpga_image_load.c \ - plat/intel/soc/stratix10/soc/s10_system_manager.c \ - common/desc_image_load.c \ - plat/intel/soc/stratix10/soc/s10_mailbox.c \ + plat/intel/soc/common/socfpga_storage.c \ + plat/intel/soc/common/soc/socfpga_handoff.c \ + plat/intel/soc/common/soc/socfpga_mailbox.c \ + plat/intel/soc/common/soc/socfpga_reset_manager.c \ + plat/intel/soc/common/soc/socfpga_system_manager.c \ plat/intel/soc/common/drivers/qspi/cadence_qspi.c \ plat/intel/soc/common/drivers/wdt/watchdog.c -BL31_SOURCES += drivers/arm/cci/cci.c \ +BL31_SOURCES += \ + drivers/arm/cci/cci.c \ + lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ - lib/cpus/aarch64/aem_generic.S \ - lib/cpus/aarch64/cortex_a53.S \ - plat/common/plat_psci_common.c \ - plat/intel/soc/stratix10/plat_sip_svc.c \ - plat/intel/soc/stratix10/bl31_plat_setup.c \ - plat/intel/soc/stratix10/plat_psci.c \ - plat/intel/soc/common/socfpga_topology.c \ - plat/intel/soc/common/socfpga_delay_timer.c \ - plat/intel/soc/stratix10/soc/s10_reset_manager.c\ - plat/intel/soc/stratix10/soc/s10_pinmux.c \ - plat/intel/soc/stratix10/soc/s10_clock_manager.c\ - plat/intel/soc/stratix10/soc/s10_handoff.c \ - plat/intel/soc/stratix10/soc/s10_mailbox.c + plat/common/plat_psci_common.c \ + plat/intel/soc/stratix10/bl31_plat_setup.c \ + plat/intel/soc/common/socfpga_psci.c \ + plat/intel/soc/common/socfpga_sip_svc.c \ + plat/intel/soc/common/socfpga_topology.c \ + plat/intel/soc/common/soc/socfpga_mailbox.c \ + plat/intel/soc/common/soc/socfpga_reset_manager.c PROGRAMMABLE_RESET_ADDRESS := 0 BL2_AT_EL3 := 1 diff --git a/plat/intel/soc/stratix10/soc/s10_clock_manager.c b/plat/intel/soc/stratix10/soc/s10_clock_manager.c index b4d057354..1e092dec4 100644 --- a/plat/intel/soc/stratix10/soc/s10_clock_manager.c +++ b/plat/intel/soc/stratix10/soc/s10_clock_manager.c @@ -12,16 +12,9 @@ #include <platform_def.h> #include "s10_clock_manager.h" -#include "s10_handoff.h" +#include "socfpga_handoff.h" +#include "socfpga_system_manager.h" -static const CLOCK_SOURCE_CONFIG clk_source = { - /* clk_freq_of_eosc1 */ - (uint32_t) 25000000, - /* clk_freq_of_f2h_free */ - (uint32_t) 460000000, - /* clk_freq_of_cb_intosc_ls */ - (uint32_t) 50000000, -}; void wait_pll_lock(void) { @@ -195,24 +188,32 @@ void config_clkmgr_handoff(handoff *hoff_ptr) mmio_write_32(ALT_CLKMGR + ALT_CLKMGR_INTRCLR, ALT_CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK | ALT_CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK); + + /* Pass clock source frequency into scratch register */ + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1), + hoff_ptr->hps_osc_clk_h); + mmio_write_32(SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2), + hoff_ptr->fpga_clk_hz); + } -int get_wdt_clk(handoff *hoff_ptr) +/* Extract reference clock from platform clock source */ +uint32_t get_ref_clk(uint32_t pllglob) { - int main_noc_base_clk, l3_main_free_clk, l4_sys_free_clk; - int data32, mdiv, refclkdiv, ref_clk; + uint32_t data32, mdiv, refclkdiv, ref_clk; + uint32_t scr_reg; - data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); - - switch (ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC(data32)) { - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_EOSC1: - ref_clk = clk_source.clk_freq_of_eosc1; + switch (ALT_CLKMGR_PSRC(pllglob)) { + case ALT_CLKMGR_PLLGLOB_PSRC_EOSC1: + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_1); + ref_clk = mmio_read_32(scr_reg); break; - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_INTOSC: - ref_clk = clk_source.clk_freq_of_cb_intosc_ls; + case ALT_CLKMGR_PLLGLOB_PSRC_INTOSC: + ref_clk = ALT_CLKMGR_INTOSC_HZ; break; - case ALT_CLKMGR_MAINPLL_PLLGLOB_PSRC_F2S: - ref_clk = clk_source.clk_freq_of_f2h_free; + case ALT_CLKMGR_PLLGLOB_PSRC_F2S: + scr_reg = SOCFPGA_SYSMGR(BOOT_SCRATCH_COLD_2); + ref_clk = mmio_read_32(scr_reg); break; default: ref_clk = 0; @@ -220,14 +221,89 @@ int get_wdt_clk(handoff *hoff_ptr) break; } - refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(data32); + refclkdiv = ALT_CLKMGR_MAINPLL_PLLGLOB_REFCLKDIV(pllglob); data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_FDBCK); mdiv = ALT_CLKMGR_MAINPLL_FDBCK_MDIV(data32); + ref_clk = (ref_clk / refclkdiv) * (6 + mdiv); - main_noc_base_clk = ref_clk / (hoff_ptr->main_pll_pllc1 & 0xff); - l3_main_free_clk = main_noc_base_clk / (hoff_ptr->main_pll_nocclk + 1); - l4_sys_free_clk = l3_main_free_clk / 4; + return ref_clk; +} + +/* Calculate L3 interconnect main clock */ +uint32_t get_l3_clk(uint32_t ref_clk) +{ + uint32_t noc_base_clk, l3_clk, noc_clk, data32; + uint32_t pllc1_reg; + + noc_clk = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCCLK); + + switch (ALT_CLKMGR_PSRC(noc_clk)) { + case ALT_CLKMGR_SRC_MAIN: + pllc1_reg = ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLC1; + break; + case ALT_CLKMGR_SRC_PER: + pllc1_reg = ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLC1; + break; + default: + pllc1_reg = 0; + assert(0); + break; + } + + data32 = mmio_read_32(pllc1_reg); + noc_base_clk = ref_clk / (data32 & 0xff); + l3_clk = noc_base_clk / (noc_clk + 1); + + return l3_clk; +} + +/* Calculate clock frequency to be used for watchdog timer */ +uint32_t get_wdt_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sys_clk; + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + l4_sys_clk = l3_clk / 4; + + return l4_sys_clk; +} + +/* Calculate clock frequency to be used for UART driver */ +uint32_t get_uart_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, l4_sp_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_NOCDIV); + data32 = (data32 >> 16) & 0x3; + data32 = 1 << data32; + + l4_sp_clk = (l3_clk / data32); + + return l4_sp_clk; +} + +/* Calculate clock frequency to be used for SDMMC driver */ +uint32_t get_mmc_clk(void) +{ + uint32_t data32, ref_clk, l3_clk, mmc_clk; + + data32 = mmio_read_32(ALT_CLKMGR_PERPLL + ALT_CLKMGR_PERPLL_PLLGLOB); + ref_clk = get_ref_clk(data32); + + l3_clk = get_l3_clk(ref_clk); + + data32 = mmio_read_32(ALT_CLKMGR_MAINPLL + ALT_CLKMGR_MAINPLL_CNTR6CLK); + mmc_clk = (l3_clk / (data32 + 1)) / 4; - return l4_sys_free_clk; + return mmc_clk; } diff --git a/plat/intel/soc/stratix10/soc/s10_handoff.c b/plat/intel/soc/stratix10/soc/s10_handoff.c deleted file mode 100644 index 1a4d5c326..000000000 --- a/plat/intel/soc/stratix10/soc/s10_handoff.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch.h> -#include <arch_helpers.h> -#include <drivers/arm/gicv2.h> -#include <assert.h> -#include <common/bl_common.h> -#include <lib/mmio.h> -#include <string.h> -#include <plat/common/platform.h> -#include <platform_def.h> - -#include "s10_handoff.h" - -#define SWAP_UINT32(x) (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | \ - (((x) & 0x0000FF00) << 8) | ((x) << 24)) - -int s10_get_handoff(handoff *reverse_hoff_ptr) -{ - int i; - uint32_t *buffer; - handoff *handoff_ptr = (handoff *) PLAT_HANDOFF_OFFSET; - - memcpy(reverse_hoff_ptr, handoff_ptr, sizeof(handoff)); - buffer = (uint32_t *)reverse_hoff_ptr; - - /* convert big indian to little indian */ - for (i = 0; i < sizeof(handoff) / 4; i++) - buffer[i] = SWAP_UINT32(buffer[i]); - - if (reverse_hoff_ptr->header_magic != HANDOFF_MAGIC_HEADER) - return -1; - if (reverse_hoff_ptr->pinmux_sel_magic != HANDOFF_MAGIC_PINMUX_SEL) - return -1; - if (reverse_hoff_ptr->pinmux_io_magic != HANDOFF_MAGIC_IOCTLR) - return -1; - if (reverse_hoff_ptr->pinmux_fpga_magic != HANDOFF_MAGIC_FPGA) - return -1; - if (reverse_hoff_ptr->pinmux_delay_magic != HANDOFF_MAGIC_IODELAY) - return -1; - - return 0; -} diff --git a/plat/intel/soc/stratix10/soc/s10_mailbox.c b/plat/intel/soc/stratix10/soc/s10_mailbox.c deleted file mode 100644 index 00a07f33a..000000000 --- a/plat/intel/soc/stratix10/soc/s10_mailbox.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/mmio.h> -#include <common/debug.h> -#include "s10_mailbox.h" - -static int fill_mailbox_circular_buffer(uint32_t header_cmd, uint32_t *args, - int len) -{ - uint32_t cmd_free_offset; - int i; - - cmd_free_offset = mmio_read_32(MBOX_OFFSET + MBOX_CIN); - - if (cmd_free_offset >= MBOX_CMD_BUFFER_SIZE) { - INFO("Insufficient buffer in mailbox\n"); - return MBOX_INSUFFICIENT_BUFFER; - } - - - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + (cmd_free_offset++ * 4), - header_cmd); - - - for (i = 0; i < len; i++) { - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CMD_BUFFER + - (cmd_free_offset++ * 4), args[i]); - } - - cmd_free_offset %= MBOX_CMD_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_CIN, cmd_free_offset); - - return 0; -} - -int mailbox_read_response(int job_id, uint32_t *response) -{ - int rin = 0; - int rout = 0; - int response_length = 0; - int resp = 0; - int total_resp_len = 0; - int timeout = 100000; - - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); - - while (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) { - if (timeout-- < 0) - return MBOX_NO_RESPONSE; - } - - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); - - rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); - rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); - - while (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); - - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) { - return MBOX_WRONG_ID; - } - - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -resp; - } - response_length = MBOX_RESP_LEN(resp); - - while (response_length) { - - response_length--; - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (response) { - *(response + total_resp_len) = resp; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - } - return total_resp_len; - } - - return MBOX_NO_RESPONSE; -} - - -int mailbox_poll_response(int job_id, int urgent, uint32_t *response) -{ - int timeout = 80000; - int rin = 0; - int rout = 0; - int response_length = 0; - int resp = 0; - int total_resp_len = 0; - - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_TO_SDM, 1); - - while (1) { - while (timeout > 0 && - mmio_read_32(MBOX_OFFSET + - MBOX_DOORBELL_FROM_SDM) != 1) { - timeout--; - } - - if (mmio_read_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM) != 1) { - INFO("Timed out waiting for SDM"); - return MBOX_TIMEOUT; - } - - mmio_write_32(MBOX_OFFSET + MBOX_DOORBELL_FROM_SDM, 0); - - if (urgent & 1) { - if ((mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & - MBOX_STATUS_UA_MASK) ^ - (urgent & MBOX_STATUS_UA_MASK)) { - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - return 0; - } - - mmio_write_32(MBOX_OFFSET + MBOX_URG, 0); - INFO("Error: Mailbox did not get UA"); - return -1; - } - - rin = mmio_read_32(MBOX_OFFSET + MBOX_RIN); - rout = mmio_read_32(MBOX_OFFSET + MBOX_ROUT); - - while (rout != rin) { - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + ((rout++)*4)); - - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - - if (MBOX_RESP_CLIENT_ID(resp) != MBOX_ATF_CLIENT_ID || - MBOX_RESP_JOB_ID(resp) != job_id) - continue; - - if (MBOX_RESP_ERR(resp) > 0) { - INFO("Error in response: %x\n", resp); - return -MBOX_RESP_ERR(resp); - } - response_length = MBOX_RESP_LEN(resp); - - while (response_length) { - - response_length--; - resp = mmio_read_32(MBOX_OFFSET + - MBOX_RESP_BUFFER + - (rout)*4); - if (response) { - *(response + total_resp_len) = resp; - total_resp_len++; - } - rout++; - rout %= MBOX_RESP_BUFFER_SIZE; - mmio_write_32(MBOX_OFFSET + MBOX_ROUT, rout); - } - return total_resp_len; - } - } -} - -void mailbox_send_cmd_async(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent) -{ - if (urgent) - mmio_write_32(MBOX_OFFSET + MBOX_URG, 1); - - fill_mailbox_circular_buffer(MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | - MBOX_JOB_ID_CMD(job_id) | - MBOX_CMD_LEN_CMD(len) | - MBOX_INDIRECT | - cmd, args, len); -} - -int mailbox_send_cmd(int job_id, unsigned int cmd, uint32_t *args, - int len, int urgent, uint32_t *response) -{ - int status; - - if (urgent) { - urgent |= mmio_read_32(MBOX_OFFSET + MBOX_STATUS) & - MBOX_STATUS_UA_MASK; - mmio_write_32(MBOX_OFFSET + MBOX_URG, 1); - } - - status = fill_mailbox_circular_buffer( - MBOX_CLIENT_ID_CMD(MBOX_ATF_CLIENT_ID) | - MBOX_JOB_ID_CMD(job_id) | - cmd, args, len); - - if (status) - return status; - - return mailbox_poll_response(job_id, urgent, response); -} - -void mailbox_set_int(int interrupt) -{ - - mmio_write_32(MBOX_OFFSET+MBOX_INT, MBOX_COE_BIT(interrupt) | - MBOX_UAE_BIT(interrupt)); -} - - -void mailbox_set_qspi_open(void) -{ - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_OPEN, 0, 0, 0, 0); -} - -void mailbox_set_qspi_direct(void) -{ - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0); -} - -void mailbox_set_qspi_close(void) -{ - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_CLOSE, 0, 0, 0, 0); -} - -int mailbox_get_qspi_clock(void) -{ - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - return mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_DIRECT, 0, 0, 0, 0); -} - -void mailbox_qspi_set_cs(int device_select) -{ - uint32_t cs_setting = device_select; - - /* QSPI device select settings at 31:28 */ - cs_setting = (cs_setting << 28); - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_QSPI_SET_CS, &cs_setting, - 1, 0, 0); -} - -void mailbox_reset_cold(void) -{ - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - mailbox_send_cmd(MBOX_JOB_ID, MBOX_CMD_REBOOT_HPS, 0, 0, 0, 0); -} - -int mailbox_init(void) -{ - int status = 0; - - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - status = mailbox_send_cmd(0, MBOX_CMD_RESTART, 0, 0, 1, 0); - - if (status) - return status; - - mailbox_set_int(MBOX_INT_FLAG_COE | MBOX_INT_FLAG_RIE); - - return 0; -} - diff --git a/plat/intel/soc/stratix10/soc/s10_memory_controller.c b/plat/intel/soc/stratix10/soc/s10_memory_controller.c index ed06f5498..ac756abac 100644 --- a/plat/intel/soc/stratix10/soc/s10_memory_controller.c +++ b/plat/intel/soc/stratix10/soc/s10_memory_controller.c @@ -15,6 +15,7 @@ #include <string.h> #include "s10_memory_controller.h" +#include "socfpga_reset_manager.h" #define ALT_CCU_NOC_DI_SET_MSK 0x10 @@ -22,10 +23,9 @@ #define MAX_MEM_CAL_RETRY 3 #define PRE_CALIBRATION_DELAY 1 #define POST_CALIBRATION_DELAY 1 -#define TIMEOUT_EMIF_CALIBRATION 100 -#define CLEAR_EMIF_DELAY 50000 -#define CLEAR_EMIF_TIMEOUT 0x100000 -#define TIMEOUT_INT_RESP 10000 +#define TIMEOUT_EMIF_CALIBRATION 1000 +#define CLEAR_EMIF_DELAY 1000 +#define CLEAR_EMIF_TIMEOUT 1000 #define DDR_CONFIG(A, B, C, R) (((A) << 24) | ((B) << 16) | ((C) << 8) | (R)) #define DDR_CONFIG_ELEMENTS (sizeof(ddr_config)/sizeof(uint32_t)) @@ -128,13 +128,13 @@ static int mem_calibration(void) data = mmio_read_32(S10_MPFE_HMC_ADP_DDRCALSTAT); if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 1) break; - udelay(1); + udelay(500); } while (++timeout < TIMEOUT_EMIF_CALIBRATION); if (S10_MPFE_HMC_ADP_DDRCALSTAT_CAL(data) == 0) { status = clear_emif(); - if (status) - ERROR("Failed to clear Emif\n"); + if (status) + ERROR("Failed to clear Emif\n"); } else { break; } @@ -185,7 +185,7 @@ int init_hard_memory_controller(void) return status; } - mmio_clrbits_32(S10_RSTMGR_BRGMODRST, S10_RSTMGR_BRGMODRST_DDRSCH); + mmio_clrbits_32(SOCFPGA_RSTMGR(BRGMODRST), RSTMGR_FIELD(BRG, DDRSCH)); status = mem_calibration(); if (status) { diff --git a/plat/intel/soc/stratix10/soc/s10_reset_manager.c b/plat/intel/soc/stratix10/soc/s10_reset_manager.c deleted file mode 100644 index 8b7420bf1..000000000 --- a/plat/intel/soc/stratix10/soc/s10_reset_manager.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch.h> -#include <arch_helpers.h> -#include <assert.h> -#include <common/bl_common.h> -#include <common/debug.h> -#include <drivers/arm/gicv2.h> -#include <drivers/console.h> -#include <lib/mmio.h> -#include <plat/common/platform.h> -#include <platform_def.h> -#include "s10_reset_manager.h" - -void deassert_peripheral_reset(void) -{ - mmio_clrbits_32(S10_RSTMGR_PER1MODRST, - S10_RSTMGR_PER1MODRST_WATCHDOG0 | - S10_RSTMGR_PER1MODRST_WATCHDOG1 | - S10_RSTMGR_PER1MODRST_WATCHDOG2 | - S10_RSTMGR_PER1MODRST_WATCHDOG3 | - S10_RSTMGR_PER1MODRST_L4SYSTIMER0 | - S10_RSTMGR_PER1MODRST_L4SYSTIMER1 | - S10_RSTMGR_PER1MODRST_SPTIMER0 | - S10_RSTMGR_PER1MODRST_SPTIMER1 | - S10_RSTMGR_PER1MODRST_I2C0 | - S10_RSTMGR_PER1MODRST_I2C1 | - S10_RSTMGR_PER1MODRST_I2C2 | - S10_RSTMGR_PER1MODRST_I2C3 | - S10_RSTMGR_PER1MODRST_I2C4 | - S10_RSTMGR_PER1MODRST_UART0 | - S10_RSTMGR_PER1MODRST_UART1 | - S10_RSTMGR_PER1MODRST_GPIO0 | - S10_RSTMGR_PER1MODRST_GPIO1); - - mmio_clrbits_32(S10_RSTMGR_PER0MODRST, - S10_RSTMGR_PER0MODRST_EMAC0OCP | - S10_RSTMGR_PER0MODRST_EMAC1OCP | - S10_RSTMGR_PER0MODRST_EMAC2OCP | - S10_RSTMGR_PER0MODRST_USB0OCP | - S10_RSTMGR_PER0MODRST_USB1OCP | - S10_RSTMGR_PER0MODRST_NANDOCP | - S10_RSTMGR_PER0MODRST_SDMMCOCP | - S10_RSTMGR_PER0MODRST_DMAOCP); - - mmio_clrbits_32(S10_RSTMGR_PER0MODRST, - S10_RSTMGR_PER0MODRST_EMAC0 | - S10_RSTMGR_PER0MODRST_EMAC1 | - S10_RSTMGR_PER0MODRST_EMAC2 | - S10_RSTMGR_PER0MODRST_USB0 | - S10_RSTMGR_PER0MODRST_USB1 | - S10_RSTMGR_PER0MODRST_NAND | - S10_RSTMGR_PER0MODRST_SDMMC | - S10_RSTMGR_PER0MODRST_DMA | - S10_RSTMGR_PER0MODRST_SPIM0 | - S10_RSTMGR_PER0MODRST_SPIM1 | - S10_RSTMGR_PER0MODRST_SPIS0 | - S10_RSTMGR_PER0MODRST_SPIS1 | - S10_RSTMGR_PER0MODRST_EMACPTP | - S10_RSTMGR_PER0MODRST_DMAIF0 | - S10_RSTMGR_PER0MODRST_DMAIF1 | - S10_RSTMGR_PER0MODRST_DMAIF2 | - S10_RSTMGR_PER0MODRST_DMAIF3 | - S10_RSTMGR_PER0MODRST_DMAIF4 | - S10_RSTMGR_PER0MODRST_DMAIF5 | - S10_RSTMGR_PER0MODRST_DMAIF6 | - S10_RSTMGR_PER0MODRST_DMAIF7); - -} - -void config_hps_hs_before_warm_reset(void) -{ - uint32_t or_mask = 0; - - or_mask |= S10_RSTMGR_HDSKEN_SDRSELFREFEN; - or_mask |= S10_RSTMGR_HDSKEN_FPGAHSEN; - or_mask |= S10_RSTMGR_HDSKEN_ETRSTALLEN; - or_mask |= S10_RSTMGR_HDSKEN_L2FLUSHEN; - or_mask |= S10_RSTMGR_HDSKEN_L3NOC_DBG; - or_mask |= S10_RSTMGR_HDSKEN_DEBUG_L3NOC; - - mmio_setbits_32(S10_RSTMGR_HDSKEN, or_mask); -} - diff --git a/plat/intel/soc/stratix10/soc/s10_system_manager.c b/plat/intel/soc/stratix10/soc/s10_system_manager.c deleted file mode 100644 index a2ed5a3ed..000000000 --- a/plat/intel/soc/stratix10/soc/s10_system_manager.c +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (c) 2019, Intel Corporation. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/mmio.h> -#include <lib/utils_def.h> -#include "s10_system_manager.h" - -void enable_nonsecure_access(void) -{ - mmio_write_32(S10_NOC_FW_L4_PER_SCR_NAND_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_NAND_DATA, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_NAND_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_NAND_READ_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_NAND_WRITE_ECC, - DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_USB0_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_USB1_REGISTER, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_USB0_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_USB1_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SPI_MASTER0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SPI_MASTER1, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SPI_SLAVE0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SPI_SLAVE1, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_EMAC0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_EMAC1, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_EMAC2, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC0RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC0TX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC1RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC1TX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC2RX_ECC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_EMAC2TX_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SDMMC, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_SDMMC_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_GPIO0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_GPIO1, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_I2C0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_I2C1, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_I2C2, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_I2C3, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_I2C4, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_SP_TIMER1, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_PER_SCR_UART0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_PER_SCR_UART1, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_DMA_ECC, DISABLE_L4_FIREWALL); - - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_OCRAM_ECC, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_CLK_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_IO_MGR, DISABLE_L4_FIREWALL); - - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_RST_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_SYS_MGR, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_OSC0_TIMER, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_OSC1_TIMER, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_WATCHDOG0, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_WATCHDOG1, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_WATCHDOG2, DISABLE_L4_FIREWALL); - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_WATCHDOG3, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_DAP, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_L4_NOC_PROBES, DISABLE_L4_FIREWALL); - - mmio_write_32(S10_NOC_FW_L4_SYS_SCR_L4_NOC_QOS, DISABLE_L4_FIREWALL); - - mmio_clrbits_32(S10_CCU_NOC_CPU0_RAMSPACE0_0, 0x03); - mmio_clrbits_32(S10_CCU_NOC_IOM_RAMSPACE0_0, 0x03); - - mmio_write_32(S10_SYSMGR_CORE(SYSMGR_MMC), SYSMGR_MMC_DRVSEL(3)); - -} - diff --git a/plat/layerscape/board/ls1043/include/platform_def.h b/plat/layerscape/board/ls1043/include/platform_def.h index b6130001c..8b0a94ae3 100644 --- a/plat/layerscape/board/ls1043/include/platform_def.h +++ b/plat/layerscape/board/ls1043/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,18 +19,18 @@ #define FIRMWARE_WELCOME_STR_LS1043_BL32 "Welcome to LS1043 BL32 Phase, TSP\n" /* Required platform porting definitions */ -#define PLAT_PRIMARY_CPU 0x0 +#define PLAT_PRIMARY_CPU U(0x0) #define PLAT_MAX_PWR_LVL LS_PWR_LVL1 -#define PLATFORM_CORE_COUNT 4 +#define PLATFORM_CORE_COUNT U(4) #define COUNTER_FREQUENCY 25000000 /* 25MHz */ /* * Required LS standard platform porting definitions */ -#define PLAT_LS_CLUSTER_COUNT 1 -#define PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX 4 -#define LS1043_CLUSTER_COUNT 1 -#define LS1043_MAX_CPUS_PER_CLUSTER 4 +#define PLAT_LS_CLUSTER_COUNT U(1) +#define PLAT_LS1043_CCI_CLUSTER0_SL_IFACE_IX U(4) +#define LS1043_CLUSTER_COUNT U(1) +#define LS1043_MAX_CPUS_PER_CLUSTER U(4) #define LS_DRAM1_BASE 0x80000000 #define LS_DRAM2_BASE 0x880000000 diff --git a/plat/layerscape/common/ns_access.c b/plat/layerscape/common/ns_access.c index b84fdbd7e..9717c7281 100644 --- a/plat/layerscape/common/ns_access.c +++ b/plat/layerscape/common/ns_access.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,7 +13,7 @@ #include "ns_access.h" -static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num) +static void enable_devices_ns_access(struct csu_ns_dev *_ns_dev, uint32_t num) { uint32_t *base = (uint32_t *)CONFIG_SYS_FSL_CSU_ADDR; uint32_t *reg; @@ -21,14 +21,14 @@ static void enable_devices_ns_access(struct csu_ns_dev *ns_dev, uint32_t num) int i; for (i = 0; i < num; i++) { - reg = base + ns_dev[i].ind / 2; + reg = base + _ns_dev[i].ind / 2; val = be32toh(mmio_read_32((uintptr_t)reg)); - if (ns_dev[i].ind % 2 == 0) { + if (_ns_dev[i].ind % 2 == 0) { val &= 0x0000ffff; - val |= ns_dev[i].val << 16; + val |= _ns_dev[i].val << 16; } else { val &= 0xffff0000; - val |= ns_dev[i].val; + val |= _ns_dev[i].val; } mmio_write_32((uintptr_t)reg, htobe32(val)); } diff --git a/plat/marvell/a3700/common/include/platform_def.h b/plat/marvell/a3700/common/include/platform_def.h index 591f04585..e6660d407 100644 --- a/plat/marvell/a3700/common/include/platform_def.h +++ b/plat/marvell/a3700/common/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Marvell International Ltd. + * Copyright (C) 2016-2019 Marvell International Ltd. * * SPDX-License-Identifier: BSD-3-Clause * https://spdx.org/licenses @@ -78,7 +78,7 @@ (PLAT_MARVELL_ATF_LOAD_ADDR + 0x20000) #define PLAT_MARVELL_FIP_MAX_SIZE 0x4000000 -#define PLAT_MARVELL_CLUSTER_CORE_COUNT 2 +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) /* DRAM[2MB..66MB] is used as Trusted ROM */ #define PLAT_MARVELL_TRUSTED_ROM_BASE PLAT_MARVELL_ATF_LOAD_ADDR /* 64 MB TODO: reduce this to minimum needed according to fip image size*/ diff --git a/plat/marvell/a8k/common/a8k_common.mk b/plat/marvell/a8k/common/a8k_common.mk index ccb662bb2..bf79ebeec 100644 --- a/plat/marvell/a8k/common/a8k_common.mk +++ b/plat/marvell/a8k/common/a8k_common.mk @@ -37,6 +37,13 @@ DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage ROM_BIN_EXT ?= $(BUILD_PLAT)/ble.bin DOIMAGE_FLAGS += -b $(ROM_BIN_EXT) $(NAND_DOIMAGE_FLAGS) $(DOIMAGE_SEC_FLAGS) +# Check whether to build system_power.c for the platform +ifneq ("$(wildcard $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c)","") +SYSTEM_POWER_SUPPORT = 1 +else +SYSTEM_POWER_SUPPORT = 0 +endif + # This define specifies DDR type for BLE $(eval $(call add_define,CONFIG_DDR4)) @@ -82,6 +89,10 @@ MARVELL_DRV := $(MARVELL_DRV_BASE)/io_win.c \ BL31_PORTING_SOURCES := $(PLAT_FAMILY_BASE)/$(PLAT)/board/marvell_plat_config.c +ifeq ($(SYSTEM_POWER_SUPPORT),1) +BL31_PORTING_SOURCES += $(PLAT_FAMILY_BASE)/$(PLAT)/board/system_power.c +endif + BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ $(PLAT_COMMON_BASE)/aarch64/plat_helpers.S \ $(PLAT_COMMON_BASE)/aarch64/plat_arch_config.c \ diff --git a/plat/marvell/a8k/common/ble/ble.mk b/plat/marvell/a8k/common/ble/ble.mk index b24083fc3..b6a9cd291 100644 --- a/plat/marvell/a8k/common/ble/ble.mk +++ b/plat/marvell/a8k/common/ble/ble.mk @@ -19,6 +19,7 @@ BLE_SOURCES += $(BLE_PATH)/ble_main.c \ PLAT_INCLUDES += -I$(MV_DDR_PATH) \ -I$(CURDIR)/include \ + -I$(CURDIR)/include/arch/aarch64 \ -I$(CURDIR)/include/lib/libc \ -I$(CURDIR)/include/lib/libc/aarch64 \ -I$(CURDIR)/drivers/marvell diff --git a/plat/marvell/a8k/common/include/platform_def.h b/plat/marvell/a8k/common/include/platform_def.h index b9c2e0ed7..ec1c9036c 100644 --- a/plat/marvell/a8k/common/include/platform_def.h +++ b/plat/marvell/a8k/common/include/platform_def.h @@ -86,8 +86,8 @@ #define PLAT_MARVELL_NORTHB_COUNT 1 -#define PLAT_MARVELL_CLUSTER_COUNT 2 -#define PLAT_MARVELL_CLUSTER_CORE_COUNT 2 +#define PLAT_MARVELL_CLUSTER_COUNT U(2) +#define PLAT_MARVELL_CLUSTER_CORE_COUNT U(2) #define PLAT_MARVELL_CORE_COUNT (PLAT_MARVELL_CLUSTER_COUNT * \ PLAT_MARVELL_CLUSTER_CORE_COUNT) diff --git a/plat/marvell/a8k/common/plat_pm.c b/plat/marvell/a8k/common/plat_pm.c index d07601a5f..96e95c271 100644 --- a/plat/marvell/a8k/common/plat_pm.c +++ b/plat/marvell/a8k/common/plat_pm.c @@ -792,8 +792,20 @@ __dead2 a8k_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) * A8K handlers to shutdown/reboot the system ***************************************************************************** */ + +/* Set a weak stub for platforms that don't configure system power off */ +#pragma weak system_power_off +int system_power_off(void) +{ + return 0; +} + static void __dead2 a8k_system_off(void) { + /* Call the platform specific system power off function */ + system_power_off(); + + /* board doesn't have a system off implementation */ ERROR("%s: needs to be implemented\n", __func__); panic(); } diff --git a/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.c b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init.c index 8120d9962..e3cfd46a0 100644 --- a/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.c +++ b/plat/mediatek/common/drivers/pmic_wrap/pmic_wrap_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,8 +7,7 @@ #include <common/debug.h> #include <drivers/delay_timer.h> #include <lib/mmio.h> - -#include <mt8173_def.h> +#include <platform_def.h> #include <pmic_wrap_init.h> /* pmic wrap module wait_idle and read polling interval (in microseconds) */ @@ -32,8 +31,9 @@ static inline uint32_t wait_for_state_idle(uint32_t timeout_us, udelay(WAIT_IDLE_POLLING_DELAY_US); reg_rdata = mmio_read_32((uintptr_t)wacs_register); /* if last read command timeout,clear vldclr bit - read command state machine:FSM_REQ-->wfdle-->WFVLDCLR; - write:FSM_REQ-->idle */ + * read command state machine:FSM_REQ-->wfdle-->WFVLDCLR; + * write:FSM_REQ-->idle + */ switch (((reg_rdata >> RDATA_WACS_FSM_SHIFT) & RDATA_WACS_FSM_MASK)) { case WACS_FSM_WFVLDCLR: @@ -107,7 +107,7 @@ static int32_t pwrap_wacs2(uint32_t write, uint32_t return_value = 0; if (init_check) { - reg_rdata = mmio_read_32((uintptr_t)&mt8173_pwrap->wacs2_rdata); + reg_rdata = mmio_read_32((uintptr_t)&mtk_pwrap->wacs2_rdata); /* Prevent someone to used pwrap before pwrap init */ if (((reg_rdata >> RDATA_INIT_DONE_SHIFT) & RDATA_INIT_DONE_MASK) != WACS_INIT_DONE) { @@ -118,8 +118,8 @@ static int32_t pwrap_wacs2(uint32_t write, reg_rdata = 0; /* Check IDLE in advance */ return_value = wait_for_state_idle(TIMEOUT_WAIT_IDLE, - &mt8173_pwrap->wacs2_rdata, - &mt8173_pwrap->wacs2_vldclr, + &mtk_pwrap->wacs2_rdata, + &mtk_pwrap->wacs2_vldclr, 0); if (return_value != 0) { ERROR("wait_for_fsm_idle fail,return_value=%d\n", return_value); @@ -129,15 +129,15 @@ static int32_t pwrap_wacs2(uint32_t write, wacs_adr = (adr >> 1) << 16; wacs_cmd = wacs_write | wacs_adr | wdata; - mmio_write_32((uintptr_t)&mt8173_pwrap->wacs2_cmd, wacs_cmd); + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_cmd, wacs_cmd); if (write == 0) { - if (NULL == rdata) { + if (rdata == NULL) { ERROR("rdata is a NULL pointer\n"); return_value = E_PWR_INVALID_ARG; goto FAIL; } return_value = wait_for_state_ready(TIMEOUT_READ, - &mt8173_pwrap->wacs2_rdata, + &mtk_pwrap->wacs2_rdata, ®_rdata); if (return_value != 0) { ERROR("wait_for_fsm_vldclr fail,return_value=%d\n", @@ -146,7 +146,7 @@ static int32_t pwrap_wacs2(uint32_t write, } *rdata = ((reg_rdata >> RDATA_WACS_RDATA_SHIFT) & RDATA_WACS_RDATA_MASK); - mmio_write_32((uintptr_t)&mt8173_pwrap->wacs2_vldclr, 1); + mmio_write_32((uintptr_t)&mtk_pwrap->wacs2_vldclr, 1); } FAIL: return return_value; diff --git a/plat/mediatek/common/drivers/rtc/rtc_common.c b/plat/mediatek/common/drivers/rtc/rtc_common.c new file mode 100644 index 000000000..cad12a03b --- /dev/null +++ b/plat/mediatek/common/drivers/rtc/rtc_common.c @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> + +#include <pmic_wrap_init.h> +#include <rtc.h> + +/* RTC busy status polling interval and retry count */ +enum { + RTC_WRTGR_POLLING_DELAY_MS = 10, + RTC_WRTGR_POLLING_CNT = 100 +}; + +uint16_t RTC_Read(uint32_t addr) +{ + uint32_t rdata = 0; + + pwrap_read((uint32_t)addr, &rdata); + return (uint16_t)rdata; +} + +void RTC_Write(uint32_t addr, uint16_t data) +{ + pwrap_write((uint32_t)addr, (uint32_t)data); +} + +int32_t rtc_busy_wait(void) +{ + uint64_t retry = RTC_WRTGR_POLLING_CNT; + + do { + mdelay(RTC_WRTGR_POLLING_DELAY_MS); + if (!(RTC_Read(RTC_BBPU) & RTC_BBPU_CBUSY)) + return 1; + retry--; + } while (retry); + + ERROR("[RTC] rtc cbusy time out!\n"); + return 0; +} + +int32_t RTC_Write_Trigger(void) +{ + RTC_Write(RTC_WRTGR, 1); + return rtc_busy_wait(); +} + +int32_t Writeif_unlock(void) +{ + RTC_Write(RTC_PROT, RTC_PROT_UNLOCK1); + if (!RTC_Write_Trigger()) + return 0; + RTC_Write(RTC_PROT, RTC_PROT_UNLOCK2); + if (!RTC_Write_Trigger()) + return 0; + + return 1; +} + diff --git a/plat/mediatek/common/params_setup.c b/plat/mediatek/common/params_setup.c new file mode 100644 index 000000000..a9df13e23 --- /dev/null +++ b/plat/mediatek/common/params_setup.c @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/bl_aux_params/bl_aux_params.h> +#include <common/debug.h> +#include <plat_params.h> +#include <string.h> + +static struct bl_aux_gpio_info rst_gpio; + +struct bl_aux_gpio_info *plat_get_mtk_gpio_reset(void) +{ + return &rst_gpio; +} + +static bool mtk_aux_param_handler(struct bl_aux_param_header *param) +{ + /* Store platform parameters for later processing if needed. */ + switch (param->type) { + case BL_AUX_PARAM_MTK_RESET_GPIO: + rst_gpio = ((struct bl_aux_param_gpio *)param)->gpio; + return true; + } + + return false; +} + +void params_early_setup(u_register_t plat_param_from_bl2) +{ + bl_aux_params_parse(plat_param_from_bl2, mtk_aux_param_handler); +} + diff --git a/plat/mediatek/common/plat_params.h b/plat/mediatek/common/plat_params.h new file mode 100644 index 000000000..828c3dccf --- /dev/null +++ b/plat/mediatek/common/plat_params.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_PARAMS_H +#define PLAT_PARAMS_H + +#include <stdint.h> + +#include <export/plat/mediatek/common/plat_params_exp.h> + +struct bl_aux_gpio_info *plat_get_mtk_gpio_reset(void); +void params_early_setup(u_register_t plat_param_from_bl2); + +#endif diff --git a/plat/mediatek/mt6795/include/platform_def.h b/plat/mediatek/mt6795/include/platform_def.h index 301610d4c..b353a3d3b 100644 --- a/plat/mediatek/mt6795/include/platform_def.h +++ b/plat/mediatek/mt6795/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -145,13 +145,13 @@ #define PLAT_MAX_OFF_STATE U(2) #define PLATFORM_CACHE_LINE_SIZE 64 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 4 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) diff --git a/plat/mediatek/mt8173/aarch64/plat_helpers.S b/plat/mediatek/mt8173/aarch64/plat_helpers.S index 983ebe3da..095dfc505 100644 --- a/plat/mediatek/mt8173/aarch64/plat_helpers.S +++ b/plat/mediatek/mt8173/aarch64/plat_helpers.S @@ -11,9 +11,6 @@ .globl plat_report_exception .globl platform_is_primary_cpu .globl plat_my_core_pos - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl plat_crash_console_flush /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); @@ -50,42 +47,3 @@ func plat_my_core_pos add x0, x1, x0, LSR #6 ret endfunc plat_my_core_pos - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0 - x4 - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, MT8173_UART0_BASE - mov_imm x1, MT8173_UART_CLOCK - mov_imm x2, MT8173_BAUDRATE - b console_core_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(void) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, MT8173_UART0_BASE - b console_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush(int c) - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, MT8173_UART0_BASE - b console_core_flush -endfunc plat_crash_console_flush diff --git a/plat/mediatek/mt8173/bl31_plat_setup.c b/plat/mediatek/mt8173/bl31_plat_setup.c index ad81b1695..73a479b50 100644 --- a/plat/mediatek/mt8173/bl31_plat_setup.c +++ b/plat/mediatek/mt8173/bl31_plat_setup.c @@ -9,8 +9,8 @@ #include <common/bl_common.h> #include <common/debug.h> #include <common/desc_image_load.h> -#include <drivers/console.h> #include <drivers/generic_delay_timer.h> +#include <drivers/ti/uart/uart_16550.h> #include <lib/mmio.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/common_def.h> @@ -100,7 +100,9 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { - console_init(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE); + static console_16550_t console; + + console_16550_register(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE, &console); VERBOSE("bl31_setup\n"); diff --git a/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.h index 0f0977137..0dffc23ee 100644 --- a/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.h +++ b/plat/mediatek/mt8173/drivers/pmic/pmic_wrap_init.h @@ -7,11 +7,13 @@ #ifndef PMIC_WRAP_INIT_H #define PMIC_WRAP_INIT_H +#include <platform_def.h> + /* external API */ int32_t pwrap_read(uint32_t adr, uint32_t *rdata); int32_t pwrap_write(uint32_t adr, uint32_t wdata); -static struct mt8173_pmic_wrap_regs *const mt8173_pwrap = +static struct mt8173_pmic_wrap_regs *const mtk_pwrap = (void *)PMIC_WRAP_BASE; /* timeout setting */ diff --git a/plat/mediatek/mt8173/drivers/rtc/rtc.c b/plat/mediatek/mt8173/drivers/rtc/rtc.c index 2b9033ed9..587886c68 100644 --- a/plat/mediatek/mt8173/drivers/rtc/rtc.c +++ b/plat/mediatek/mt8173/drivers/rtc/rtc.c @@ -5,66 +5,11 @@ */ #include <assert.h> - #include <common/debug.h> -#include <drivers/delay_timer.h> #include <mt8173_def.h> -#include <pmic_wrap_init.h> #include <rtc.h> -/* RTC busy status polling interval and retry count */ -enum { - RTC_WRTGR_POLLING_DELAY_MS = 10, - RTC_WRTGR_POLLING_CNT = 100 -}; - -static uint16_t RTC_Read(uint32_t addr) -{ - uint32_t rdata = 0; - - pwrap_read((uint32_t)addr, &rdata); - return (uint16_t)rdata; -} - -static void RTC_Write(uint32_t addr, uint16_t data) -{ - pwrap_write((uint32_t)addr, (uint32_t)data); -} - -static inline int32_t rtc_busy_wait(void) -{ - uint64_t retry = RTC_WRTGR_POLLING_CNT; - - do { - mdelay(RTC_WRTGR_POLLING_DELAY_MS); - if (!(RTC_Read(RTC_BBPU) & RTC_BBPU_CBUSY)) - return 1; - retry--; - } while (retry); - - ERROR("[RTC] rtc cbusy time out!\n"); - return 0; -} - -static int32_t Write_trigger(void) -{ - RTC_Write(RTC_WRTGR, 1); - return rtc_busy_wait(); -} - -static int32_t Writeif_unlock(void) -{ - RTC_Write(RTC_PROT, RTC_PROT_UNLOCK1); - if (!Write_trigger()) - return 0; - RTC_Write(RTC_PROT, RTC_PROT_UNLOCK2); - if (!Write_trigger()) - return 0; - - return 1; -} - void rtc_bbpu_power_down(void) { uint16_t bbpu; @@ -73,7 +18,7 @@ void rtc_bbpu_power_down(void) bbpu = RTC_BBPU_KEY | RTC_BBPU_AUTO | RTC_BBPU_PWREN; if (Writeif_unlock()) { RTC_Write(RTC_BBPU, bbpu); - if (!Write_trigger()) + if (!RTC_Write_Trigger()) assert(0); } else { assert(0); diff --git a/plat/mediatek/mt8173/drivers/rtc/rtc.h b/plat/mediatek/mt8173/drivers/rtc/rtc.h index 9c4ca49a9..f60a4c18f 100644 --- a/plat/mediatek/mt8173/drivers/rtc/rtc.h +++ b/plat/mediatek/mt8173/drivers/rtc/rtc.h @@ -49,6 +49,12 @@ enum { RTC_BBPU_KEY = 0x43 << 8 }; +/* external API */ +uint16_t RTC_Read(uint32_t addr); +void RTC_Write(uint32_t addr, uint16_t data); +int32_t rtc_busy_wait(void); +int32_t RTC_Write_Trigger(void); +int32_t Writeif_unlock(void); void rtc_bbpu_power_down(void); #endif /* RTC_H */ diff --git a/plat/mediatek/mt8173/drivers/spm/spm.h b/plat/mediatek/mt8173/drivers/spm/spm.h index 403303a0d..0c05410a6 100644 --- a/plat/mediatek/mt8173/drivers/spm/spm.h +++ b/plat/mediatek/mt8173/drivers/spm/spm.h @@ -320,7 +320,6 @@ void spm_register_init(void); void spm_go_to_hotplug(void); void spm_init_event_vector(const struct pcm_desc *pcmdesc); void spm_kick_im_to_fetch(const struct pcm_desc *pcmdesc); -void spm_set_sysclk_settle(void); int is_mcdi_ready(void); int is_hotplug_ready(void); int is_suspend_ready(void); diff --git a/plat/mediatek/mt8173/drivers/spm/spm_suspend.c b/plat/mediatek/mt8173/drivers/spm/spm_suspend.c index 5021695db..838455d8c 100644 --- a/plat/mediatek/mt8173/drivers/spm/spm_suspend.c +++ b/plat/mediatek/mt8173/drivers/spm/spm_suspend.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -239,13 +239,13 @@ static struct pwr_ctrl spm_ctrl = { /* * go_to_sleep_before_wfi() - trigger SPM to enter suspend scenario */ -static void go_to_sleep_before_wfi(const unsigned int spm_flags) +static void go_to_sleep_before_wfi(const unsigned int flags_spm) { struct pwr_ctrl *pwrctrl; pwrctrl = &spm_ctrl; - set_pwrctrl_pcm_flags(pwrctrl, spm_flags); + set_pwrctrl_pcm_flags(pwrctrl, flags_spm); spm_set_sysclk_settle(); diff --git a/plat/mediatek/mt8173/include/platform_def.h b/plat/mediatek/mt8173/include/platform_def.h index 205e26387..22129db13 100644 --- a/plat/mediatek/mt8173/include/platform_def.h +++ b/plat/mediatek/mt8173/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -40,13 +40,13 @@ #define PLAT_MAX_PWR_LVL U(2) #define PLAT_MAX_RET_STATE U(1) #define PLAT_MAX_OFF_STATE U(2) -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 2 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(2) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) diff --git a/plat/mediatek/mt8173/plat_pm.c b/plat/mediatek/mt8173/plat_pm.c index 1b52470d5..67f1c731b 100644 --- a/plat/mediatek/mt8173/plat_pm.c +++ b/plat/mediatek/mt8173/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,7 +11,7 @@ #include <common/debug.h> #include <drivers/arm/cci.h> #include <drivers/arm/gicv2.h> -#include <drivers/console.h> +#include <drivers/ti/uart/uart_16550.h> #include <lib/bakery_lock.h> #include <lib/mmio.h> #include <lib/psci/psci.h> @@ -236,7 +236,7 @@ static void mt_platform_restore_context(unsigned long mpidr) static void plat_cpu_standby(plat_local_state_t cpu_state) { - unsigned int scr; + u_register_t scr; scr = read_scr_el3(); write_scr_el3(scr | SCR_IRQ_BIT); @@ -543,12 +543,14 @@ int plat_validate_power_state(unsigned int power_state, void mtk_system_pwr_domain_resume(void) { - console_init(MT8173_UART0_BASE, MT8173_UART_CLOCK, MT8173_BAUDRATE); + console_switch_state(CONSOLE_FLAG_BOOT); /* Assert system power domain is available on the platform */ assert(PLAT_MAX_PWR_LVL >= MTK_PWR_LVL2); plat_arm_gic_init(); + + console_switch_state(CONSOLE_FLAG_RUNTIME); } static const plat_psci_ops_t plat_plat_pm_ops = { diff --git a/plat/mediatek/mt8173/platform.mk b/plat/mediatek/mt8173/platform.mk index 24e4ec650..a66c49bb4 100644 --- a/plat/mediatek/mt8173/platform.mk +++ b/plat/mediatek/mt8173/platform.mk @@ -8,7 +8,6 @@ MTK_PLAT := plat/mediatek MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ - -I${MTK_PLAT}/common/drivers/uart/ \ -Iinclude/plat/arm/common/aarch64 \ -I${MTK_PLAT_SOC}/drivers/crypt/ \ -I${MTK_PLAT_SOC}/drivers/mtcmos/ \ @@ -21,21 +20,23 @@ PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ plat/arm/common/arm_gicv2.c \ - plat/common/plat_gicv2.c + plat/common/plat_gicv2.c \ + plat/common/aarch64/crash_console_helpers.S BL31_SOURCES += common/desc_image_load.c \ drivers/arm/cci/cci.c \ drivers/arm/gic/common/gic_common.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/v2/gicv2_helpers.c \ - drivers/console/aarch64/console.S \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ + drivers/ti/uart/aarch64/16550_console.S \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ lib/cpus/aarch64/cortex_a72.S \ - ${MTK_PLAT}/common/drivers/uart/8250_console.S \ + ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \ + ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ ${MTK_PLAT}/common/mtk_sip_svc.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ @@ -43,7 +44,6 @@ BL31_SOURCES += common/desc_image_load.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/drivers/crypt/crypt.c \ ${MTK_PLAT_SOC}/drivers/mtcmos/mtcmos.c \ - ${MTK_PLAT_SOC}/drivers/pmic/pmic_wrap_init.c \ ${MTK_PLAT_SOC}/drivers/rtc/rtc.c \ ${MTK_PLAT_SOC}/drivers/spm/spm.c \ ${MTK_PLAT_SOC}/drivers/spm/spm_hotplug.c \ @@ -68,3 +68,5 @@ $(eval $(call add_define,MTK_SIP_SET_AUTHORIZED_SECURE_REG_ENABLE)) # Do not enable SVE ENABLE_SVE_FOR_NS := 0 + +MULTI_CONSOLE_API := 1 diff --git a/plat/mediatek/mt8183/bl31_plat_setup.c b/plat/mediatek/mt8183/bl31_plat_setup.c index e623e96ab..8204d7717 100644 --- a/plat/mediatek/mt8183/bl31_plat_setup.c +++ b/plat/mediatek/mt8183/bl31_plat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,18 +8,25 @@ #include <arch_helpers.h> #include <common/bl_common.h> #include <common/desc_image_load.h> +#include <devapc.h> +#include <emi_mpu.h> #include <plat/common/common_def.h> #include <drivers/console.h> #include <common/debug.h> #include <drivers/generic_delay_timer.h> #include <mcucfg.h> #include <mt_gic_v3.h> +#include <lib/coreboot.h> #include <lib/mmio.h> +#include <mtk_mcdi.h> #include <mtk_plat_common.h> +#include <mtspmc.h> #include <plat_debug.h> +#include <plat_params.h> #include <plat_private.h> #include <platform_def.h> #include <scu.h> +#include <spm.h> #include <drivers/ti/uart/uart_16550.h> static entry_point_info_t bl32_ep_info; @@ -29,15 +36,49 @@ static void platform_setup_cpu(void) { mmio_write_32((uintptr_t)&mt8183_mcucfg->mp0_rw_rsvd0, 0x00000001); - VERBOSE("addr of cci_adb400_dcm_config: 0x%x\n", - mmio_read_32((uintptr_t)&mt8183_mcucfg->cci_adb400_dcm_config)); - VERBOSE("addr of sync_dcm_config: 0x%x\n", - mmio_read_32((uintptr_t)&mt8183_mcucfg->sync_dcm_config)); - - VERBOSE("mp0_spmc: 0x%x\n", - mmio_read_32((uintptr_t)&mt8183_mcucfg->mp0_cputop_spmc_ctl)); - VERBOSE("mp1_spmc: 0x%x\n", - mmio_read_32((uintptr_t)&mt8183_mcucfg->mp1_cputop_spmc_ctl)); + /* Mcusys dcm control */ + /* Enable pll plldiv dcm */ + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->bus_pll_divider_cfg, + BUS_PLLDIV_DCM); + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->mp0_pll_divider_cfg, + MP0_PLLDIV_DCM); + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->mp2_pll_divider_cfg, + MP2_PLLDIV_DCM); + /* Enable mscib dcm */ + mmio_clrsetbits_32((uintptr_t)&mt8183_mcucfg->mscib_dcm_en, + MCSIB_CACTIVE_SEL_MASK, MCSIB_CACTIVE_SEL); + mmio_clrsetbits_32((uintptr_t)&mt8183_mcucfg->mscib_dcm_en, + MCSIB_DCM_MASK, MCSIB_DCM); + /* Enable adb400 dcm */ + mmio_clrsetbits_32((uintptr_t)&mt8183_mcucfg->cci_adb400_dcm_config, + CCI_ADB400_DCM_MASK, CCI_ADB400_DCM); + /* Enable bus clock dcm */ + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->cci_clk_ctrl, + MCU_BUS_DCM); + /* Enable bus fabric dcm */ + mmio_clrsetbits_32( + (uintptr_t)&mt8183_mcucfg->mcusys_bus_fabric_dcm_ctrl, + MCUSYS_BUS_FABRIC_DCM_MASK, + MCUSYS_BUS_FABRIC_DCM); + /* Enable l2c sram dcm */ + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->l2c_sram_ctrl, + L2C_SRAM_DCM); + /* Enable busmp0 sync dcm */ + mmio_clrsetbits_32((uintptr_t)&mt8183_mcucfg->sync_dcm_config, + SYNC_DCM_MASK, SYNC_DCM); + /* Enable cntvalue dcm */ + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->mcu_misc_dcm_ctrl, + CNTVALUEB_DCM); + /* Enable dcm cluster stall */ + mmio_clrsetbits_32( + (uintptr_t)&mt8183_mcucfg->sync_dcm_cluster_config, + MCUSYS_MAX_ACCESS_LATENCY_MASK, + MCUSYS_MAX_ACCESS_LATENCY); + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->sync_dcm_cluster_config, + MCU0_SYNC_DCM_STALL_WR_EN); + /* Enable rgu dcm */ + mmio_setbits_32((uintptr_t)&mt8183_mcucfg->mp0_rgu_dcm_config, + CPUSYS_RGU_DCM_CINFIG); } /******************************************************************************* @@ -73,7 +114,17 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { static console_16550_t console; + params_early_setup(arg1); + +#if COREBOOT + if (coreboot_serial.type) + console_16550_register(coreboot_serial.baseaddr, + coreboot_serial.input_hertz, + coreboot_serial.baud, + &console); +#else console_16550_register(UART0_BASE, UART_CLOCK, UART_BAUDRATE, &console); +#endif NOTICE("MT8183 bl31_setup\n"); @@ -86,6 +137,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, ******************************************************************************/ void bl31_platform_setup(void) { + devapc_init(); + + emi_mpu_init(); + platform_setup_cpu(); generic_delay_timer_init(); @@ -95,6 +150,12 @@ void bl31_platform_setup(void) /* Init mcsi SF */ plat_mtk_cci_init_sf(); + +#if SPMC_MODE == 1 + spmc_init(); +#endif + spm_boot_init(); + mcdi_init(); } /******************************************************************************* diff --git a/plat/mediatek/mt8183/drivers/devapc/devapc.c b/plat/mediatek/mt8183/drivers/devapc/devapc.c new file mode 100644 index 000000000..9d76aa547 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/devapc/devapc.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <devapc.h> +#include <drivers/console.h> +#include <lib/mmio.h> + +static void set_master_transaction(uint32_t master_index, + enum TRANSACTION transaction_type) +{ + uintptr_t base; + uint32_t master_register_index; + uint32_t master_set_index; + uint32_t set_bit; + + master_register_index = master_index / (MOD_NO_IN_1_DEVAPC * 2); + master_set_index = master_index % (MOD_NO_IN_1_DEVAPC * 2); + + base = DEVAPC_INFRA_MAS_SEC_0 + master_register_index * 4; + + set_bit = 0x1 << master_set_index; + if (transaction_type == SECURE_TRANSACTION) + mmio_setbits_32(base, set_bit); + else + mmio_clrbits_32(base, set_bit); +} + +static void set_master_domain(uint32_t master_index, enum MASK_DOM domain) +{ + uintptr_t base; + uint32_t domain_reg; + uint32_t domain_index; + uint32_t clr_bit; + uint32_t set_bit; + + domain_reg = master_index / MASTER_MOD_NO_IN_1_DEVAPC; + domain_index = master_index % MASTER_MOD_NO_IN_1_DEVAPC; + clr_bit = 0xF << (4 * domain_index); + set_bit = domain << (4 * domain_index); + + base = DEVAPC_INFRA_MAS_DOM_0 + domain_reg * 4; + mmio_clrsetbits_32(base, clr_bit, set_bit); +} + +static void set_master_domain_remap_infra(enum MASK_DOM domain_emi_view, + enum MASK_DOM domain_infra_view) +{ + uintptr_t base; + uint32_t clr_bit; + uint32_t set_bit; + + if (domain_emi_view < DOMAIN_10) { + base = DEVAPC_INFRA_DOM_RMP_0; + clr_bit = 0x7 << (domain_emi_view * 3); + set_bit = domain_infra_view << (domain_emi_view * 3); + mmio_clrsetbits_32(base, clr_bit, set_bit); + } else if (domain_emi_view > DOMAIN_10) { + base = DEVAPC_INFRA_DOM_RMP_1; + domain_emi_view = domain_emi_view - DOMAIN_11; + clr_bit = 0x7 << (domain_emi_view * 3 + 1); + set_bit = domain_infra_view << (domain_emi_view * 3 + 1); + mmio_clrsetbits_32(base, clr_bit, set_bit); + } else { + base = DEVAPC_INFRA_DOM_RMP_0; + clr_bit = 0x3 << (domain_emi_view * 3); + set_bit = domain_infra_view << (domain_emi_view * 3); + mmio_clrsetbits_32(base, clr_bit, set_bit); + + base = DEVAPC_INFRA_DOM_RMP_1; + set_bit = (domain_infra_view & 0x4) >> 2; + mmio_clrsetbits_32(base, 0x1, set_bit); + } +} + +static void set_master_domain_remap_mm(enum MASK_DOM domain_emi_view, + enum MASK_DOM domain_mm_view) +{ + uintptr_t base; + uint32_t clr_bit; + uint32_t set_bit; + + base = DEVAPC_MM_DOM_RMP_0; + clr_bit = 0x3 << (domain_emi_view * 2); + set_bit = domain_mm_view << (domain_emi_view * 2); + + mmio_clrsetbits_32(base, clr_bit, set_bit); +} + +static void set_module_apc(enum DAPC_SLAVE_TYPE slave_type, uint32_t module, + enum MASK_DOM domain_num, + enum APC_ATTR permission_control) +{ + uintptr_t base; + uint32_t apc_index; + uint32_t apc_set_index; + uint32_t clr_bit; + uint32_t set_bit; + + apc_index = module / MOD_NO_IN_1_DEVAPC; + apc_set_index = module % MOD_NO_IN_1_DEVAPC; + clr_bit = 0x3 << (apc_set_index * 2); + set_bit = permission_control << (apc_set_index * 2); + + if (slave_type == DAPC_INFRA_SLAVE && module <= SLAVE_INFRA_MAX_INDEX) + base = DEVAPC_INFRA_D0_APC_0 + domain_num * 0x100 + + apc_index * 4; + else if (slave_type == DAPC_MM_SLAVE && module <= SLAVE_MM_MAX_INDEX) + base = DEVAPC_MM_D0_APC_0 + domain_num * 0x100 + apc_index * 4; + else + return; + + mmio_clrsetbits_32(base, clr_bit, set_bit); +} + +static void set_default_master_transaction(void) +{ + set_master_transaction(MASTER_SSPM, SECURE_TRANSACTION); +} + +static void set_default_master_domain(void) +{ + set_master_domain(MASTER_SCP, DOMAIN_1); + set_master_domain_remap_infra(DOMAIN_1, DOMAIN_1); + set_master_domain_remap_mm(DOMAIN_1, DOMAIN_1); + + set_master_domain(MASTER_SPM, DOMAIN_2); + set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2); + set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2); + + set_master_domain(MASTER_SSPM, DOMAIN_2); + set_master_domain_remap_infra(DOMAIN_2, DOMAIN_2); + set_master_domain_remap_mm(DOMAIN_2, DOMAIN_2); +} + +static void set_default_slave_permission(void) +{ + uint32_t module_index; + uint32_t infra_size; + uint32_t mm_size; + + infra_size = sizeof(D_APC_INFRA_Devices) / sizeof(struct DEVICE_INFO); + mm_size = sizeof(D_APC_MM_Devices) / sizeof(struct DEVICE_INFO); + + for (module_index = 0; module_index < infra_size; module_index++) { + if (D_APC_INFRA_Devices[module_index].d0_permission > 0) { + set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_0, + D_APC_INFRA_Devices[module_index].d0_permission); + } + if (D_APC_INFRA_Devices[module_index].d1_permission > 0) { + set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_1, + D_APC_INFRA_Devices[module_index].d1_permission); + } + if (D_APC_INFRA_Devices[module_index].d2_permission > 0) { + set_module_apc(DAPC_INFRA_SLAVE, module_index, DOMAIN_2, + D_APC_INFRA_Devices[module_index].d2_permission); + } + } + + for (module_index = 0; module_index < mm_size; module_index++) { + if (D_APC_MM_Devices[module_index].d0_permission > 0) { + set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_0, + D_APC_MM_Devices[module_index].d0_permission); + } + if (D_APC_MM_Devices[module_index].d1_permission > 0) { + set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_1, + D_APC_MM_Devices[module_index].d1_permission); + } + if (D_APC_MM_Devices[module_index].d2_permission > 0) { + set_module_apc(DAPC_MM_SLAVE, module_index, DOMAIN_2, + D_APC_MM_Devices[module_index].d2_permission); + } + } +} + +static void dump_devapc(void) +{ + int i; + + INFO("[DEVAPC] dump DEVAPC registers:\n"); + + for (i = 0; i < 13; i++) { + INFO("[DEVAPC] (INFRA)D0_APC_%d = 0x%x, " + "(INFRA)D1_APC_%d = 0x%x, " + "(INFRA)D2_APC_%d = 0x%x\n", + i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + i * 4), + i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x100 + i * 4), + i, mmio_read_32(DEVAPC_INFRA_D0_APC_0 + 0x200 + i * 4)); + } + + for (i = 0; i < 9; i++) { + INFO("[DEVAPC] (MM)D0_APC_%d = 0x%x, " + "(MM)D1_APC_%d = 0x%x, " + "(MM)D2_APC_%d = 0x%x\n", + i, mmio_read_32(DEVAPC_MM_D0_APC_0 + i * 4), + i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x100 + i * 4), + i, mmio_read_32(DEVAPC_MM_D0_APC_0 + 0x200 + i * 4)); + } + + for (i = 0; i < 4; i++) { + INFO("[DEVAPC] MAS_DOM_%d = 0x%x\n", i, + mmio_read_32(DEVAPC_INFRA_MAS_DOM_0 + i * 4)); + } + + INFO("[DEVAPC] MAS_SEC_0 = 0x%x\n", + mmio_read_32(DEVAPC_INFRA_MAS_SEC_0)); + + INFO("[DEVAPC] (INFRA)MAS_DOMAIN_REMAP_0 = 0x%x, " + "(INFRA)MAS_DOMAIN_REMAP_1 = 0x%x\n", + mmio_read_32(DEVAPC_INFRA_DOM_RMP_0), + mmio_read_32(DEVAPC_INFRA_DOM_RMP_1)); + + INFO("[DEVAPC] (MM)MAS_DOMAIN_REMAP_0 = 0x%x\n", + mmio_read_32(DEVAPC_MM_DOM_RMP_0)); +} + +void devapc_init(void) +{ + mmio_write_32(DEVAPC_INFRA_APC_CON, 0x80000001); + mmio_write_32(DEVAPC_MM_APC_CON, 0x80000001); + mmio_write_32(DEVAPC_MD_APC_CON, 0x80000001); + + set_default_master_transaction(); + set_default_master_domain(); + set_default_slave_permission(); + dump_devapc(); +} + diff --git a/plat/mediatek/mt8183/drivers/devapc/devapc.h b/plat/mediatek/mt8183/drivers/devapc/devapc.h new file mode 100644 index 000000000..042a8ffea --- /dev/null +++ b/plat/mediatek/mt8183/drivers/devapc/devapc.h @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef DEVAPC_H +#define DEVAPC_H + +#include <stdint.h> + +#define DEVAPC_AO_INFRA_BASE 0x1000E000 +#define DEVAPC_AO_MM_BASE 0x1001C000 +#define DEVAPC_AO_MD_BASE 0x10019000 + +#define DEVAPC_INFRA_D0_APC_0 (DEVAPC_AO_INFRA_BASE + 0x0000) +#define DEVAPC_INFRA_MAS_DOM_0 (DEVAPC_AO_INFRA_BASE + 0x0A00) +#define DEVAPC_INFRA_MAS_SEC_0 (DEVAPC_AO_INFRA_BASE + 0x0B00) +#define DEVAPC_INFRA_DOM_RMP_0 (DEVAPC_AO_INFRA_BASE + 0x0D00) +#define DEVAPC_INFRA_DOM_RMP_1 (DEVAPC_AO_INFRA_BASE + 0x0D04) +#define DEVAPC_INFRA_APC_CON (DEVAPC_AO_INFRA_BASE + 0x0F00) + +#define DEVAPC_MD_APC_CON (DEVAPC_AO_MD_BASE + 0x0F00) + +#define DEVAPC_MM_D0_APC_0 (DEVAPC_AO_MM_BASE + 0x0000) +#define DEVAPC_MM_DOM_RMP_0 (DEVAPC_AO_MM_BASE + 0x0D00) +#define DEVAPC_MM_APC_CON (DEVAPC_AO_MM_BASE + 0x0F00) + +#define MOD_NO_IN_1_DEVAPC 16 +#define MASTER_MOD_NO_IN_1_DEVAPC 8 +#define SLAVE_INFRA_MAX_INDEX 195 +#define SLAVE_MM_MAX_INDEX 140 + +enum { + MASTER_SCP = 0, + MASTER_SPM = 10, + MASTER_SSPM = 27 +}; + +enum MASK_DOM { + DOMAIN_0 = 0, + DOMAIN_1, + DOMAIN_2, + DOMAIN_3, + DOMAIN_4, + DOMAIN_5, + DOMAIN_6, + DOMAIN_7, + DOMAIN_8, + DOMAIN_9, + DOMAIN_10, + DOMAIN_11 +}; + +enum TRANSACTION { + NON_SECURE_TRANSACTION = 0, + SECURE_TRANSACTION +}; + +enum DAPC_SLAVE_TYPE { + DAPC_INFRA_SLAVE = 0, + DAPC_MM_SLAVE +}; + +enum APC_ATTR { + NO_SEC = 0, + S_RW_ONLY, + S_RW_NS_R, + FORBID, +}; + +struct DEVICE_INFO { + uint8_t d0_permission; + uint8_t d1_permission; + uint8_t d2_permission; +}; + +#define PERMISSION(DEV_NAME, ATTR1, ATTR2, ATTR3) \ +{(uint8_t)ATTR1, (uint8_t)ATTR2, (uint8_t)ATTR3} + +static const struct DEVICE_INFO D_APC_INFRA_Devices[] = { +/* module, domain0, domain1, domain2 */ + +/* 0 */ +PERMISSION("INFRA_AO_TOPCKGEN", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("INFRA_AO_INFRASYS_CONFIG_REGS", NO_SEC, FORBID, NO_SEC), +PERMISSION("IO_CFG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PERICFG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_EFUSE_AO_DEBUG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_GPIO", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_SLEEP_CONTROLLER", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_TOPRGU", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_APXGPT", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_RESERVE", NO_SEC, FORBID, NO_SEC), + +/* 10 */ +PERMISSION("INFRA_AO_SEJ", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_AP_CIRQ_EINT", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_APMIXEDSYS", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("INFRA_AO_PMIC_WRAP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_DEVICE_APC_AO_INFRA_PERI", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_SLEEP_CONTROLLER_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_KEYPAD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_TOP_MISC", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_DVFS_CTRL_PROC", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_MBIST_AO_REG", NO_SEC, FORBID, NO_SEC), + +/* 20 */ +PERMISSION("INFRA_AO_CLDMA_AO_AP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_DEVICE_MPU", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_AES_TOP_0", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_SYS_TIMER", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_MDEM_TEMP_SHARE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_DEVICE_APC_AO_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_SECURITY_AO", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_TOPCKGEN_REG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_DEVICE_APC_AO_MM", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), + +/* 30 */ +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_SYS_CIRQ", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_MM_IOMMU", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_EFUSE_PDN_DEBUG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DEVICE_APC", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DBG_TRACKER", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF0_AP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF0_MD", NO_SEC, FORBID, NO_SEC), + +/* 40 */ +PERMISSION("INFRASYS_CCIF1_AP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF1_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_MBIST", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_INFRA_PDN_REGISTER", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_TRNG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DX_CC", NO_SEC, FORBID, NO_SEC), +PERMISSION("MD_CCIF_MD1", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CQ_DMA", NO_SEC, FORBID, NO_SEC), +PERMISSION("MD_CCIF_MD2", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_SRAMROM", NO_SEC, FORBID, NO_SEC), + +/* 50 */ +PERMISSION("ANA_MIPI_DSI0", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("ANA_MIPI_CSI0", NO_SEC, FORBID, NO_SEC), +PERMISSION("ANA_MIPI_CSI1", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_EMI", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CLDMA_PDN", NO_SEC, FORBID, NO_SEC), +PERMISSION("CLDMA_PDN_MD_MISC", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("BPI_BSI_SLV0", NO_SEC, FORBID, NO_SEC), + +/* 60 */ +PERMISSION("BPI_BSI_SLV1", NO_SEC, FORBID, NO_SEC), +PERMISSION("BPI_BSI_SLV2", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_EMI_MPU", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DVFS_PROC", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH0_TOP0", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH0_TOP1", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH0_TOP2", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH0_TOP3", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH0_TOP4", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH1_TOP0", NO_SEC, FORBID, NO_SEC), + +/* 70 */ +PERMISSION("INFRASYS_DRAMC_CH1_TOP1", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH1_TOP2", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH1_TOP3", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DRAMC_CH1_TOP4", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_GCE", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF2_AP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF2_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF3_AP", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_CCIF3_MD", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 1", S_RW_NS_R, FORBID, NO_SEC), + +/* 80 */ +PERMISSION("INFRA_AO_PWRMCU Partition 2", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 3", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 4", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 5", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 6", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 7", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_PWRMCU Partition 8", S_RW_NS_R, FORBID, NO_SEC), +PERMISSION("INFRA_AO_SCP", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("INFRA_AO_MCUCFG", NO_SEC, FORBID, NO_SEC), +PERMISSION("INFRASYS_DBUGSYS", NO_SEC, FORBID, NO_SEC), + +/* 90 */ +PERMISSION("PERISYS_APDMA", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_AUXADC", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_UART0", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("PERISYS_UART1", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_UART2", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C6", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_PWM", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C0", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C1", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C2", NO_SEC, FORBID, NO_SEC), + +/* 100 */ +PERMISSION("PERISYS_SPI0", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_PTP", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_BTIF", NO_SEC, FORBID, NO_SEC), +PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_DISP_PWM", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C3", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_SPI1", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C4", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_SPI2", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_SPI3", NO_SEC, FORBID, NO_SEC), + +/* 110 */ +PERMISSION("PERISYS_I2C1_IMM", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C2_IMM", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C5", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C5_IMM", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_SPI4", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_SPI5", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C7", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_I2C8", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_USB", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_USB_2_0_SUB", NO_SEC, FORBID, NO_SEC), + +/* 120 */ +PERMISSION("PERISYS_AUDIO", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_MSDC0", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_MSDC1", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_MSDC2", NO_SEC, FORBID, NO_SEC), +PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_UFS", NO_SEC, FORBID, NO_SEC), +PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_0", NO_SEC, FORBID, NO_SEC), + +/* 130 */ +PERMISSION("EAST_RESERVE_1", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_2", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_3", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_4", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_IO_CFG_RT", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_6", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_7", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_CSI0_TOP_AO", NO_SEC, FORBID, NO_SEC), +PERMISSION("RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_A", NO_SEC, FORBID, NO_SEC), + +/* 140 */ +PERMISSION("EAST_RESERVE_B", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_C", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_E", NO_SEC, FORBID, NO_SEC), +PERMISSION("EAST_RESERVE_F", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_0", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_1", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_IO_CFG_RM", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_IO_CFG_RB", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_EFUSE", NO_SEC, FORBID, NO_SEC), + +/* 150 */ +PERMISSION("SOUTH_RESERVE_5", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_6", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_7", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_8", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_9", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_B", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_C", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("SOUTH_RESERVE_E", NO_SEC, FORBID, NO_SEC), + +/* 160 */ +PERMISSION("SOUTH_RESERVE_F", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_0", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_MSDC1_PAD_MACRO", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_2", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_3", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_4", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_MIPI_TX_CONFIG", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_6", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_IO_CFG_LB", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_IO_CFG_LM", NO_SEC, FORBID, NO_SEC), + +/* 170 */ +PERMISSION("WEST_IO_CFG_BL", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_B", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_C", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_E", NO_SEC, FORBID, NO_SEC), +PERMISSION("WEST_RESERVE_F", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_0", NO_SEC, FORBID, NO_SEC), +PERMISSION("EFUSE_TOP", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_IO_CFG_LT", NO_SEC, FORBID, NO_SEC), + +/* 180 */ +PERMISSION("NORTH_IO_CFG_TL", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_USB20 PHY", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_MSDC0 PAD MACRO", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_6", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_7", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_8", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_9", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_UFS_MPHY", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_B", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_C", NO_SEC, FORBID, NO_SEC), + +/* 190 */ +PERMISSION("NORTH_RESERVE_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_E", NO_SEC, FORBID, NO_SEC), +PERMISSION("NORTH_RESERVE_F", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_CONN", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_MD_VIOLATION", NO_SEC, FORBID, NO_SEC), +PERMISSION("PERISYS_RESERVE", NO_SEC, FORBID, NO_SEC) +}; + +static const struct DEVICE_INFO D_APC_MM_Devices[] = { +/* module, domain0, domain1, domain2 */ + +/* 0 */ +PERMISSION("G3D_CONFIG", NO_SEC, FORBID, NO_SEC), +PERMISSION("MFG VAD", NO_SEC, FORBID, NO_SEC), +PERMISSION("SC0 VAD", NO_SEC, FORBID, NO_SEC), +PERMISSION("MFG_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("MMSYS_CONFIG", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_RDMA0", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_RDMA1", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_RSZ0", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_RSZ1", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_WROT0", NO_SEC, NO_SEC, NO_SEC), + +/* 10 */ +PERMISSION("MDP_WDMA", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_TDSHP", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_OVL0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_OVL0_2L", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_OVL1_2L", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_RDMA0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_RDMA1", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_WDMA0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_COLOR0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_CCORR0", NO_SEC, FORBID, NO_SEC), + +/* 20 */ +PERMISSION("DISP_AAL0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_GAMMA0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DISP_DITHER0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DSI_SPLIT", NO_SEC, FORBID, NO_SEC), +PERMISSION("DSI0", NO_SEC, FORBID, NO_SEC), +PERMISSION("DPI", NO_SEC, FORBID, NO_SEC), +PERMISSION("MM_MUTEX", NO_SEC, FORBID, NO_SEC), +PERMISSION("SMI_LARB0", NO_SEC, FORBID, NO_SEC), +PERMISSION("SMI_LARB1", NO_SEC, FORBID, NO_SEC), +PERMISSION("SMI_COMMON", NO_SEC, FORBID, NO_SEC), + +/* 30 */ +PERMISSION("DISP_RSZ", NO_SEC, FORBID, NO_SEC), +PERMISSION("MDP_AAL", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("MDP_CCORR", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("DBI", NO_SEC, FORBID, NO_SEC), +PERMISSION("MMSYS_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_CONFIG", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("IMGSYS_SMI_LARB1", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_DISP_A0", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("IMGSYS_DISP_A1", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_DISP_A2", NO_SEC, FORBID, NO_SEC), + +/* 40 */ +PERMISSION("IMGSYS_DISP_A3", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_DISP_A4", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_DISP_A5", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_DPE", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_RSC", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_WPEA", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_FDVT", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("IMGSYS_OWE", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_WPEB", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_MFB", NO_SEC, FORBID, NO_SEC), + +/* 50 */ +PERMISSION("IMGSYS_SMI_LARB2", NO_SEC, FORBID, NO_SEC), +PERMISSION("IMGSYS_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("VENCSYS_GLOBAL_CON", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("VENCSYSSYS_SMI_LARB4", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("VENCSYS_VENC", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("VENCSYS_JPGENC", NO_SEC, FORBID, NO_SEC), +PERMISSION("VENCSYS_MBIST_CTRL", NO_SEC, FORBID, NO_SEC), +PERMISSION("VENCSYS_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("VDECSYS_GLOBAL_CON", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("VDECSYS_SMI_LARB1", NO_SEC, FORBID, NO_SEC), + +/* 60 */ +PERMISSION("VDECSYS_FULL_TOP", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("VDECSYS_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAMSYS_TOP", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_LARB6", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_LARB3", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_TOP", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_A", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_A", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_B", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_B", NO_SEC, NO_SEC, NO_SEC), + +/* 70 */ +PERMISSION("CAMSYS_CAM_C", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_C", NO_SEC, NO_SEC, NO_SEC), +PERMISSION("CAMSYS_CAM_TOP_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_SET", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_TOP_INNER", NO_SEC, FORBID, NO_SEC), + +/* 80 */ +PERMISSION("CAMSYS_CAM_A_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_INNER", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_TOP_CLR", NO_SEC, FORBID, NO_SEC), + +/* 90 */ +PERMISSION("CAMSYS_CAM_A_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_CLR", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_A_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_B_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_C_EXT", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAM_RESERVE", NO_SEC, FORBID, NO_SEC), + +/* 100 */ +PERMISSION("CAMSYS_SENINF_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_B", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_C", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_E", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_F", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_G", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_SENINF_H", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAMSV_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAMSV_B", NO_SEC, FORBID, NO_SEC), + +/* 110 */ +PERMISSION("CAMSYS_CAMSV_C", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CAMSV_D", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_MD32 DMEM_12", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_RESEVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CCU_CTL", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CCU_H2T_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CCU_T2H_A", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_RESERVE", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_CCU_DMA", NO_SEC, FORBID, NO_SEC), + +/* 120 */ +PERMISSION("CAMSYS_TSF", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_MD32_PMEM_24", NO_SEC, FORBID, NO_SEC), +PERMISSION("CAMSYS_OTHERS", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_CFG", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_ADL_CTRL", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREA_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREA_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREA_IMEM_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREA_CONTROL", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREA_DEBUG", NO_SEC, FORBID, NO_SEC), + +/* 130 */ +PERMISSION("VPUSYS_COREB_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREB_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREB_IMEM_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREB_CONTROL", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREB_DEBUG", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREC_DMEM_0_128KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREC_DMEM_128_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREC_IMEM_256KB", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREC_CONTROL", NO_SEC, FORBID, NO_SEC), +PERMISSION("VPUSYS_COREC_DEBUG", NO_SEC, FORBID, NO_SEC), + +/* 140 */ +PERMISSION("VPUSYS_OTHERS", NO_SEC, FORBID, NO_SEC) +}; + +void devapc_init(void); + +#endif /* DEVAPC_H */ + diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c new file mode 100644 index 000000000..64d854885 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.c @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <lib/mmio.h> +#include <emi_mpu.h> + +int is_4GB(void) +{ + return 0; /* 8183 doesn't use 4GB */ +} + +/* + * emi_mpu_set_region_protection: protect a region. + * @start: start address of the region + * @end: end address of the region + * @region: EMI MPU region id + * @access_permission: EMI MPU access permission + * Return 0 for success, otherwise negative status code. + */ +int emi_mpu_set_region_protection( + unsigned long start, unsigned long end, + int region, + unsigned int access_permission) +{ + int ret = 0; + + if (end <= start) { + ERROR("[EMI][MTEE][MPU] Invalid address!.\n"); + return -1; + } + + if (is_4GB()) { + /* 4GB mode: emi_addr = phy_addr & 0xffff */ + start = EMI_PHY_OFFSET & 0xffff; + end = EMI_PHY_OFFSET & 0xffff; + } else { + /* non-4GB mode: emi_addr = phy_addr - MEM_OFFSET */ + start = start - EMI_PHY_OFFSET; + end = end - EMI_PHY_OFFSET; + } + + /*Address 64KB alignment*/ + start = start >> 16; + end = end >> 16; + + switch (region) { + case 0: + mmio_write_32(EMI_MPU_APC0, 0); + mmio_write_32(EMI_MPU_SA0, start); + mmio_write_32(EMI_MPU_EA0, end); + mmio_write_32(EMI_MPU_APC0, access_permission); + break; + + case 1: + mmio_write_32(EMI_MPU_APC1, 0); + mmio_write_32(EMI_MPU_SA1, start); + mmio_write_32(EMI_MPU_EA1, end); + mmio_write_32(EMI_MPU_APC1, access_permission); + break; + + case 2: + mmio_write_32(EMI_MPU_APC2, 0); + mmio_write_32(EMI_MPU_SA2, start); + mmio_write_32(EMI_MPU_EA2, end); + mmio_write_32(EMI_MPU_APC2, access_permission); + break; + + case 3: + mmio_write_32(EMI_MPU_APC3, 0); + mmio_write_32(EMI_MPU_SA3, start); + mmio_write_32(EMI_MPU_EA3, end); + mmio_write_32(EMI_MPU_APC3, access_permission); + break; + + case 4: + mmio_write_32(EMI_MPU_APC4, 0); + mmio_write_32(EMI_MPU_SA4, start); + mmio_write_32(EMI_MPU_EA4, end); + mmio_write_32(EMI_MPU_APC4, access_permission); + break; + + case 5: + mmio_write_32(EMI_MPU_APC5, 0); + mmio_write_32(EMI_MPU_SA5, start); + mmio_write_32(EMI_MPU_EA5, end); + mmio_write_32(EMI_MPU_APC5, access_permission); + break; + + case 6: + mmio_write_32(EMI_MPU_APC6, 0); + mmio_write_32(EMI_MPU_SA6, start); + mmio_write_32(EMI_MPU_EA6, end); + mmio_write_32(EMI_MPU_APC6, access_permission); + break; + + case 7: + mmio_write_32(EMI_MPU_APC7, 0); + mmio_write_32(EMI_MPU_SA7, start); + mmio_write_32(EMI_MPU_EA7, end); + mmio_write_32(EMI_MPU_APC7, access_permission); + break; + + default: + ret = -1; + break; + } + + return ret; +} + +void dump_emi_mpu_regions(void) +{ + unsigned int apc, sa, ea; + unsigned int apc_addr = EMI_MPU_APC0; + unsigned int sa_addr = EMI_MPU_SA0; + unsigned int ea_addr = EMI_MPU_EA0; + int i; + + for (i = 0; i < 8; ++i) { + apc = mmio_read_32(apc_addr + i * 4); + sa = mmio_read_32(sa_addr + i * 4); + ea = mmio_read_32(ea_addr + i * 4); + WARN("region %d:\n", i); + WARN("\tapc:0x%x, sa:0x%x, ea:0x%x\n", apc, sa, ea); + } +} + +void emi_mpu_init(void) +{ + /* Set permission */ + emi_mpu_set_region_protection(0x40000000UL, 0x4FFFFFFFUL, 0, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0x50000000UL, 0x528FFFFFUL, 1, + (FORBIDDEN << 6)); + emi_mpu_set_region_protection(0x52900000UL, 0x5FFFFFFFUL, 2, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0x60000000UL, 0x7FFFFFFFUL, 3, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0x80000000UL, 0x9FFFFFFFUL, 4, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0xA0000000UL, 0xBFFFFFFFUL, 5, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0xC0000000UL, 0xDFFFFFFFUL, 6, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + emi_mpu_set_region_protection(0xE0000000UL, 0xFFFFFFFFUL, 7, + (FORBIDDEN << 3 | FORBIDDEN << 6)); + dump_emi_mpu_regions(); +} + diff --git a/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h new file mode 100644 index 000000000..b67ea563f --- /dev/null +++ b/plat/mediatek/mt8183/drivers/emi_mpu/emi_mpu.h @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __EMI_MPU_H +#define __EMI_MPU_H + +#include <platform_def.h> + +#define EMI_MPUP (EMI_BASE + 0x01D8) +#define EMI_MPUQ (EMI_BASE + 0x01E0) +#define EMI_MPUR (EMI_BASE + 0x01E8) +#define EMI_MPUS (EMI_BASE + 0x01F0) +#define EMI_MPUT (EMI_BASE + 0x01F8) +#define EMI_MPUY (EMI_BASE + 0x0220) +#define EMI_MPU_CTRL (EMI_MPU_BASE + 0x0000) +#define EMI_MPUD0_ST (EMI_BASE + 0x0160) +#define EMI_MPUD1_ST (EMI_BASE + 0x0164) +#define EMI_MPUD2_ST (EMI_BASE + 0x0168) +#define EMI_MPUD3_ST (EMI_BASE + 0x016C) +#define EMI_MPUD0_ST2 (EMI_BASE + 0x0200) +#define EMI_MPUD1_ST2 (EMI_BASE + 0x0204) +#define EMI_MPUD2_ST2 (EMI_BASE + 0x0208) +#define EMI_MPUD3_ST2 (EMI_BASE + 0x020C) + +#define EMI_PHY_OFFSET (0x40000000UL) +#define EIGHT_DOMAIN + +#define NO_PROTECTION (0) +#define SEC_RW (1) +#define SEC_RW_NSEC_R (2) +#define SEC_RW_NSEC_W (3) +#define SEC_R_NSEC_R (4) +#define FORBIDDEN (5) +#define SEC_R_NSEC_RW (6) + +#define SECURE_OS_MPU_REGION_ID (0) +#define ATF_MPU_REGION_ID (1) + +#ifdef EIGHT_DOMAIN +#define SET_ACCESS_PERMISSON(d7, d6, d5, d4, d3, d2, d1, d0) \ + (((d7) << 21) | ((d6) << 18) | ((d5) << 15) | ((d4) << 12) \ + | ((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0)) +#else +#define SET_ACCESS_PERMISSON(d3, d2, d1, d0) \ + (((d3) << 9) | ((d2) << 6) | ((d1) << 3) | (d0)) +#endif + +//#define EMI_MPU_BASE (0x1020E000U) + +#define EMI_MPU_SA0 (EMI_MPU_BASE + 0x100) +#define EMI_MPU_SA1 (EMI_MPU_BASE + 0x104) +#define EMI_MPU_SA2 (EMI_MPU_BASE + 0x108) +#define EMI_MPU_SA3 (EMI_MPU_BASE + 0x10C) +#define EMI_MPU_SA4 (EMI_MPU_BASE + 0x110) +#define EMI_MPU_SA5 (EMI_MPU_BASE + 0x114) +#define EMI_MPU_SA6 (EMI_MPU_BASE + 0x118) +#define EMI_MPU_SA7 (EMI_MPU_BASE + 0x11C) + +#define EMI_MPU_EA0 (EMI_MPU_BASE + 0x200) +#define EMI_MPU_EA1 (EMI_MPU_BASE + 0x204) +#define EMI_MPU_EA2 (EMI_MPU_BASE + 0x208) +#define EMI_MPU_EA3 (EMI_MPU_BASE + 0x20C) +#define EMI_MPU_EA4 (EMI_MPU_BASE + 0x210) +#define EMI_MPU_EA5 (EMI_MPU_BASE + 0x214) +#define EMI_MPU_EA6 (EMI_MPU_BASE + 0x218) +#define EMI_MPU_EA7 (EMI_MPU_BASE + 0x21C) + +#define EMI_MPU_APC0 (EMI_MPU_BASE + 0x300) +#define EMI_MPU_APC1 (EMI_MPU_BASE + 0x304) +#define EMI_MPU_APC2 (EMI_MPU_BASE + 0x308) +#define EMI_MPU_APC3 (EMI_MPU_BASE + 0x30C) +#define EMI_MPU_APC4 (EMI_MPU_BASE + 0x310) +#define EMI_MPU_APC5 (EMI_MPU_BASE + 0x314) +#define EMI_MPU_APC6 (EMI_MPU_BASE + 0x318) +#define EMI_MPU_APC7 (EMI_MPU_BASE + 0x31C) + +#define EMI_MPU_CTRL_D0 (EMI_MPU_BASE + 0x800) +#define EMI_MPU_CTRL_D1 (EMI_MPU_BASE + 0x804) +#define EMI_MPU_CTRL_D2 (EMI_MPU_BASE + 0x808) +#define EMI_MPU_CTRL_D3 (EMI_MPU_BASE + 0x80C) +#define EMI_MPU_CTRL_D4 (EMI_MPU_BASE + 0x810) +#define EMI_MPU_CTRL_D5 (EMI_MPU_BASE + 0x814) +#define EMI_MPU_CTRL_D6 (EMI_MPU_BASE + 0x818) +#define EMI_MPU_CTRL_D7 (EMI_MPU_BASE + 0x81C) + +#define EMI_MPU_MASK_D0 (EMI_MPU_BASE + 0x900) +#define EMI_MPU_MASK_D1 (EMI_MPU_BASE + 0x904) +#define EMI_MPU_MASK_D2 (EMI_MPU_BASE + 0x908) +#define EMI_MPU_MASK_D3 (EMI_MPU_BASE + 0x90C) +#define EMI_MPU_MASK_D4 (EMI_MPU_BASE + 0x910) +#define EMI_MPU_MASK_D5 (EMI_MPU_BASE + 0x914) +#define EMI_MPU_MASK_D6 (EMI_MPU_BASE + 0x918) +#define EMI_MPU_MASK_D7 (EMI_MPU_BASE + 0x91C) + +int emi_mpu_set_region_protection( + unsigned long start, unsigned long end, + int region, + unsigned int access_permission); + +void dump_emi_mpu_regions(void); +void emi_mpu_init(void); + +#endif /* __EMI_MPU_H */ diff --git a/plat/mediatek/mt8183/drivers/gpio/mtgpio.c b/plat/mediatek/mt8183/drivers/gpio/mtgpio.c new file mode 100644 index 000000000..61aaeefbc --- /dev/null +++ b/plat/mediatek/mt8183/drivers/gpio/mtgpio.c @@ -0,0 +1,439 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <gpio/mtgpio.h> +#include <gpio/mtgpio_cfg.h> +#include <drivers/gpio.h> +#include <mcucfg.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <spm.h> +#include <stdbool.h> + +/****************************************************************************** + *Macro Definition + ******************************************************************************/ +#define GPIO_MODE_BITS 4 +#define MAX_GPIO_MODE_PER_REG 8 +#define MAX_GPIO_REG_BITS 32 +#define DIR_BASE (GPIO_BASE + 0x000) +#define DOUT_BASE (GPIO_BASE + 0x100) +#define DIN_BASE (GPIO_BASE + 0x200) +#define MODE_BASE (GPIO_BASE + 0x300) +#define SET 0x4 +#define CLR 0x8 +#define PULLEN_ADDR_OFFSET 0x060 +#define PULLSEL_ADDR_OFFSET 0x080 + +void mt_set_gpio_dir_chip(uint32_t pin, int dir) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(dir < GPIO_DIR_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (dir == GPIO_DIR_IN) + mmio_write_32(DIR_BASE + 0x10 * pos + CLR, 1U << bit); + else + mmio_write_32(DIR_BASE + 0x10 * pos + SET, 1U << bit); +} + +int mt_get_gpio_dir_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIR_BASE + 0x10 * pos); + return (((reg & (1U << bit)) != 0) ? GPIO_DIR_OUT : GPIO_DIR_IN); +} + +void mt_set_gpio_out_chip(uint32_t pin, int output) +{ + uint32_t pos, bit; + + assert(pin < MAX_GPIO_PIN); + assert(output < GPIO_OUT_MAX); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + if (output == GPIO_OUT_ZERO) + mmio_write_32(DOUT_BASE + 0x10 * pos + CLR, 1U << bit); + else + mmio_write_32(DOUT_BASE + 0x10 * pos + SET, 1U << bit); +} + +int mt_get_gpio_out_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DOUT_BASE + 0x10 * pos); + return (((reg & (1U << bit)) != 0) ? 1 : 0); +} + +int mt_get_gpio_in_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t reg; + + assert(pin < MAX_GPIO_PIN); + + pos = pin / MAX_GPIO_REG_BITS; + bit = pin % MAX_GPIO_REG_BITS; + + reg = mmio_read_32(DIN_BASE + 0x10 * pos); + return (((reg & (1U << bit)) != 0) ? 1 : 0); +} + +void mt_set_gpio_mode_chip(uint32_t pin, int mode) +{ + uint32_t pos, bit; + uint32_t data; + uint32_t mask; + + assert(pin < MAX_GPIO_PIN); + assert(mode < GPIO_MODE_MAX); + + mask = (1U << GPIO_MODE_BITS) - 1; + + mode = mode & mask; + pos = pin / MAX_GPIO_MODE_PER_REG; + bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS; + + data = mmio_read_32(MODE_BASE + 0x10 * pos); + data &= (~(mask << bit)); + data |= (mode << bit); + mmio_write_32(MODE_BASE + 0x10 * pos, data); +} + +int mt_get_gpio_mode_chip(uint32_t pin) +{ + uint32_t pos, bit; + uint32_t data; + uint32_t mask; + + assert(pin < MAX_GPIO_PIN); + + mask = (1U << GPIO_MODE_BITS) - 1; + + pos = pin / MAX_GPIO_MODE_PER_REG; + bit = (pin % MAX_GPIO_MODE_PER_REG) * GPIO_MODE_BITS; + + data = mmio_read_32(MODE_BASE + 0x10 * pos); + return (data >> bit) & mask; +} + +int32_t gpio_get_pull_iocfg(uint32_t pin) +{ + switch (pin) { + case 0 ... 10: + return IOCFG_5_BASE; + case 11 ... 12: + return IOCFG_0_BASE; + case 13 ... 28: + return IOCFG_1_BASE; + case 43 ... 49: + return IOCFG_2_BASE; + case 50 ... 60: + return IOCFG_3_BASE; + case 61 ... 88: + return IOCFG_4_BASE; + case 89 ... 90: + return IOCFG_5_BASE; + case 95 ... 106: + return IOCFG_5_BASE; + case 107 ... 121: + return IOCFG_6_BASE; + case 134 ... 160: + return IOCFG_0_BASE; + case 161 ... 166: + return IOCFG_1_BASE; + case 167 ... 176: + return IOCFG_3_BASE; + case 177 ... 179: + return IOCFG_5_BASE; + default: + return -1; + } +} + +int32_t gpio_get_pupd_iocfg(uint32_t pin) +{ + const int32_t offset = 0x0c0; + + switch (pin) { + case 29 ... 34: + return IOCFG_1_BASE + offset; + case 35 ... 42: + return IOCFG_2_BASE + offset; + case 91 ... 94: + return IOCFG_5_BASE + offset; + case 122 ... 133: + return IOCFG_7_BASE + offset; + default: + return -1; + } +} + +int gpio_get_pupd_offset(uint32_t pin) +{ + switch (pin) { + case 29 ... 34: + return (pin - 29) * 4 % 32; + case 35 ... 42: + return (pin - 35) * 4 % 32; + case 91 ... 94: + return (pin - 91) * 4 % 32; + case 122 ... 129: + return (pin - 122) * 4 % 32; + case 130 ... 133: + return (pin - 130) * 4 % 32; + default: + return -1; + } +} + +void mt_set_gpio_pull_enable_chip(uint32_t pin, int en) +{ + int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET; + int pupd_addr = gpio_get_pupd_iocfg(pin); + int pupd_offset = gpio_get_pupd_offset(pin); + + assert(pin < MAX_GPIO_PIN); + + assert(!((PULL_offset[pin].offset == (int8_t)-1) && + (pupd_offset == (int8_t)-1))); + + if (en == GPIO_PULL_DISABLE) { + if (PULL_offset[pin].offset == (int8_t)-1) + mmio_clrbits_32(pupd_addr, 3U << pupd_offset); + else + mmio_clrbits_32(pullen_addr, + 1U << PULL_offset[pin].offset); + } else if (en == GPIO_PULL_ENABLE) { + if (PULL_offset[pin].offset == (int8_t)-1) { + /* For PUPD+R0+R1 Type, mt_set_gpio_pull_enable + * does not know + * which one between PU and PD shall be enabled. + * Use R0 to guarantee at one resistor is set when lk + * apply default setting + */ + mmio_setbits_32(pupd_addr, 1U << pupd_offset); + mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1)); + } else { + /* For PULLEN + PULLSEL Type */ + mmio_setbits_32(pullen_addr, + 1U << PULL_offset[pin].offset); + } + } else if (en == GPIO_PULL_ENABLE_R0) { + assert(!(pupd_offset == (int8_t)-1)); + mmio_setbits_32(pupd_addr, 1U << pupd_offset); + mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 1)); + } else if (en == GPIO_PULL_ENABLE_R1) { + assert(!(pupd_offset == (int8_t)-1)); + + mmio_clrbits_32(pupd_addr, 1U << pupd_offset); + mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 1)); + } else if (en == GPIO_PULL_ENABLE_R0R1) { + assert(!(pupd_offset == (int8_t)-1)); + mmio_setbits_32(pupd_addr, 3U << pupd_offset); + } +} + +int mt_get_gpio_pull_enable_chip(uint32_t pin) +{ + uint32_t reg; + + int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET; + int pupd_addr = gpio_get_pupd_iocfg(pin); + int pupd_offset = gpio_get_pupd_offset(pin); + + assert(pin < MAX_GPIO_PIN); + + assert(!((PULL_offset[pin].offset == (int8_t)-1) && + (pupd_offset == (int8_t)-1))); + + if (PULL_offset[pin].offset == (int8_t)-1) { + reg = mmio_read_32(pupd_addr); + return ((reg & (3U << pupd_offset)) ? 1 : 0); + } else if (pupd_offset == (int8_t)-1) { + reg = mmio_read_32(pullen_addr); + return ((reg & (1U << PULL_offset[pin].offset)) ? 1 : 0); + } + + return -ERINVAL; +} + +void mt_set_gpio_pull_select_chip(uint32_t pin, int sel) +{ + int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET; + int pupd_addr = gpio_get_pupd_iocfg(pin); + int pupd_offset = gpio_get_pupd_offset(pin); + + assert(pin < MAX_GPIO_PIN); + + assert(!((PULL_offset[pin].offset == (int8_t) -1) && + (pupd_offset == (int8_t)-1))); + + if (sel == GPIO_PULL_NONE) { + /* Regard No PULL as PULL disable + pull down */ + mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_DISABLE); + if (PULL_offset[pin].offset == (int8_t)-1) + mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2)); + else + mmio_clrbits_32(pullsel_addr, + 1U << PULL_offset[pin].offset); + } else if (sel == GPIO_PULL_UP) { + mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE); + if (PULL_offset[pin].offset == (int8_t)-1) + mmio_clrbits_32(pupd_addr, 1U << (pupd_offset + 2)); + else + mmio_setbits_32(pullsel_addr, + 1U << PULL_offset[pin].offset); + } else if (sel == GPIO_PULL_DOWN) { + mt_set_gpio_pull_enable_chip(pin, GPIO_PULL_ENABLE); + if (PULL_offset[pin].offset == -1) + mmio_setbits_32(pupd_addr, 1U << (pupd_offset + 2)); + else + mmio_clrbits_32(pullsel_addr, + 1U << PULL_offset[pin].offset); + } +} + +/* get pull-up or pull-down, regardless of resistor value */ +int mt_get_gpio_pull_select_chip(uint32_t pin) +{ + uint32_t reg; + + int pullen_addr = gpio_get_pull_iocfg(pin) + PULLEN_ADDR_OFFSET; + int pullsel_addr = gpio_get_pull_iocfg(pin) + PULLSEL_ADDR_OFFSET; + int pupd_addr = gpio_get_pupd_iocfg(pin); + int pupd_offset = gpio_get_pupd_offset(pin); + + assert(pin < MAX_GPIO_PIN); + + assert(!((PULL_offset[pin].offset == (int8_t)-1) && + (pupd_offset == (int8_t)-1))); + + if (PULL_offset[pin].offset == (int8_t)-1) { + reg = mmio_read_32(pupd_addr); + if (reg & (3U << pupd_offset)) { + reg = mmio_read_32(pupd_addr); + /* Reg value: 0 for PU, 1 for PD --> + * reverse return value */ + return ((reg & (1U << (pupd_offset + 2))) ? + GPIO_PULL_DOWN : GPIO_PULL_UP); + } else { + return GPIO_PULL_NONE; + } + } else if (pupd_offset == (int8_t)-1) { + reg = mmio_read_32(pullen_addr); + if ((reg & (1U << PULL_offset[pin].offset))) { + reg = mmio_read_32(pullsel_addr); + return ((reg & (1U << PULL_offset[pin].offset)) ? + GPIO_PULL_UP : GPIO_PULL_DOWN); + } else { + return GPIO_PULL_NONE; + } + } + + return -ERINVAL; +} + +void mt_set_gpio_dir(int gpio, int direction) +{ + mt_set_gpio_dir_chip((uint32_t)gpio, direction); +} + +int mt_get_gpio_dir(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_dir_chip(pin); +} + +void mt_set_gpio_pull(int gpio, int pull) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_pull_select_chip(pin, pull); +} + +int mt_get_gpio_pull(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_pull_select_chip(pin); +} + +void mt_set_gpio_out(int gpio, int value) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_out_chip(pin, value); +} + +int mt_get_gpio_out(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_out_chip(pin); +} + +int mt_get_gpio_in(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_in_chip(pin); +} + +void mt_set_gpio_mode(int gpio, int mode) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + mt_set_gpio_mode_chip(pin, mode); +} + +int mt_get_gpio_mode(int gpio) +{ + uint32_t pin; + + pin = (uint32_t)gpio; + return mt_get_gpio_mode_chip(pin); +} + +const gpio_ops_t mtgpio_ops = { + .get_direction = mt_get_gpio_dir, + .set_direction = mt_set_gpio_dir, + .get_value = mt_get_gpio_in, + .set_value = mt_set_gpio_out, + .set_pull = mt_set_gpio_pull, + .get_pull = mt_get_gpio_pull, +}; diff --git a/plat/mediatek/mt8183/drivers/gpio/mtgpio.h b/plat/mediatek/mt8183/drivers/gpio/mtgpio.h new file mode 100644 index 000000000..9461c54bc --- /dev/null +++ b/plat/mediatek/mt8183/drivers/gpio/mtgpio.h @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GPIO_H +#define MT_GPIO_H + +#include <stdint.h> +#include <plat/common/common_def.h> + +/* Error Code No. */ +#define RSUCCESS 0 +#define ERACCESS 1 +#define ERINVAL 2 +#define ERWRAPPER 3 +#define MAX_GPIO_PIN MT_GPIO_BASE_MAX + +/* Enumeration for GPIO pin */ +typedef enum GPIO_PIN { + GPIO_UNSUPPORTED = -1, + + GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, GPIO5, GPIO6, GPIO7, + GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24, GPIO25, GPIO26, GPIO27, GPIO28, GPIO29, GPIO30, GPIO31, + GPIO32, GPIO33, GPIO34, GPIO35, GPIO36, GPIO37, GPIO38, GPIO39, + GPIO40, GPIO41, GPIO42, GPIO43, GPIO44, GPIO45, GPIO46, GPIO47, + GPIO48, GPIO49, GPIO50, GPIO51, GPIO52, GPIO53, GPIO54, GPIO55, + GPIO56, GPIO57, GPIO58, GPIO59, GPIO60, GPIO61, GPIO62, GPIO63, + GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70, GPIO71, + GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78, GPIO79, + GPIO80, GPIO81, GPIO82, GPIO83, GPIO84, GPIO85, GPIO86, GPIO87, + GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95, + GPIO96, GPIO97, GPIO98, GPIO99, GPIO100, GPIO101, GPIO102, GPIO103, + GPIO104, GPIO105, GPIO106, GPIO107, GPIO108, GPIO109, GPIO110, GPIO111, + GPIO112, GPIO113, GPIO114, GPIO115, GPIO116, GPIO117, GPIO118, GPIO119, + GPIO120, GPIO121, GPIO122, GPIO123, GPIO124, GPIO125, GPIO126, GPIO127, + GPIO128, GPIO129, GPIO130, GPIO131, GPIO132, GPIO133, GPIO134, GPIO135, + GPIO136, GPIO137, GPIO138, GPIO139, GPIO140, GPIO141, GPIO142, GPIO143, + GPIO144, GPIO145, GPIO146, GPIO147, GPIO148, GPIO149, GPIO150, GPIO151, + GPIO152, GPIO153, GPIO154, GPIO155, GPIO156, GPIO157, GPIO158, GPIO159, + GPIO160, GPIO161, GPIO162, GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, + GPIO168, GPIO169, GPIO170, GPIO171, GPIO172, GPIO173, GPIO174, GPIO175, + GPIO176, GPIO177, GPIO178, GPIO179, + MT_GPIO_BASE_MAX +} GPIO_PIN; + +/* GPIO MODE CONTROL VALUE*/ +typedef enum { + GPIO_MODE_UNSUPPORTED = -1, + GPIO_MODE_GPIO = 0, + GPIO_MODE_00 = 0, + GPIO_MODE_01, + GPIO_MODE_02, + GPIO_MODE_03, + GPIO_MODE_04, + GPIO_MODE_05, + GPIO_MODE_06, + GPIO_MODE_07, + + GPIO_MODE_MAX, + GPIO_MODE_DEFAULT = GPIO_MODE_00, +} GPIO_MODE; + +/* GPIO DIRECTION */ +typedef enum { + GPIO_DIR_UNSUPPORTED = -1, + GPIO_DIR_OUT = 0, + GPIO_DIR_IN = 1, + GPIO_DIR_MAX, + GPIO_DIR_DEFAULT = GPIO_DIR_IN, +} GPIO_DIR; + +/* GPIO PULL ENABLE*/ +typedef enum { + GPIO_PULL_EN_UNSUPPORTED = -1, + GPIO_PULL_DISABLE = 0, + GPIO_PULL_ENABLE = 1, + GPIO_PULL_ENABLE_R0 = 2, + GPIO_PULL_ENABLE_R1 = 3, + GPIO_PULL_ENABLE_R0R1 = 4, + + GPIO_PULL_EN_MAX, + GPIO_PULL_EN_DEFAULT = GPIO_PULL_ENABLE, +} GPIO_PULL_EN; + +/* GPIO PULL-UP/PULL-DOWN*/ +typedef enum { + GPIO_PULL_UNSUPPORTED = -1, + GPIO_PULL_NONE = 0, + GPIO_PULL_UP = 1, + GPIO_PULL_DOWN = 2, + GPIO_PULL_MAX, + GPIO_PULL_DEFAULT = GPIO_PULL_DOWN +} GPIO_PULL; + +/* GPIO OUTPUT */ +typedef enum { + GPIO_OUT_UNSUPPORTED = -1, + GPIO_OUT_ZERO = 0, + GPIO_OUT_ONE = 1, + + GPIO_OUT_MAX, + GPIO_OUT_DEFAULT = GPIO_OUT_ZERO, + GPIO_DATA_OUT_DEFAULT = GPIO_OUT_ZERO, /*compatible with DCT*/ +} GPIO_OUT; + +/* GPIO INPUT */ +typedef enum { + GPIO_IN_UNSUPPORTED = -1, + GPIO_IN_ZERO = 0, + GPIO_IN_ONE = 1, + + GPIO_IN_MAX, +} GPIO_IN; + +typedef struct { + uint32_t val; + uint32_t set; + uint32_t rst; + uint32_t _align1; +} VAL_REGS; + +typedef struct { + VAL_REGS dir[6]; /*0x0000 ~ 0x005F: 96 bytes */ + uint8_t rsv00[160]; /*0x0060 ~ 0x00FF: 160 bytes */ + VAL_REGS dout[6]; /*0x0100 ~ 0x015F: 96 bytes */ + uint8_t rsv01[160]; /*0x0160 ~ 0x01FF: 160 bytes */ + VAL_REGS din[6]; /*0x0200 ~ 0x025F: 96 bytes */ + uint8_t rsv02[160]; /*0x0260 ~ 0x02FF: 160 bytes */ + VAL_REGS mode[23]; /*0x0300 ~ 0x046F: 368 bytes */ +} GPIO_REGS; + +/* GPIO Driver interface */ +/*direction*/ +void mt_set_gpio_dir(int gpio, int direction); +int mt_get_gpio_dir(int gpio); + +/*pull select*/ +void mt_set_gpio_pull(int gpio, int pull); +int mt_get_gpio_pull(int gpio); + +/*input/output*/ +void mt_set_gpio_out(int gpio, int value); +int mt_get_gpio_out(int gpio); +int mt_get_gpio_in(int gpio); + +/*mode control*/ +void mt_set_gpio_mode(int gpio, int mode); +int mt_get_gpio_mode(int gpio); + +#endif /* MT_GPIO_H */ diff --git a/plat/mediatek/mt8183/drivers/gpio/mtgpio_cfg.h b/plat/mediatek/mt8183/drivers/gpio/mtgpio_cfg.h new file mode 100644 index 000000000..4e1fd2b2b --- /dev/null +++ b/plat/mediatek/mt8183/drivers/gpio/mtgpio_cfg.h @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MT_GPIO_CFG_H +#define MT_GPIO_CFG_H + +#include <stdint.h> +#include <plat/common/common_def.h> + +#define IOCFG_0_BASE 0x11F20000 +#define IOCFG_1_BASE 0x11E80000 +#define IOCFG_2_BASE 0x11E70000 +#define IOCFG_3_BASE 0x11E90000 +#define IOCFG_4_BASE 0x11D30000 +#define IOCFG_5_BASE 0x11D20000 +#define IOCFG_6_BASE 0x11C50000 +#define IOCFG_7_BASE 0x11F30000 + +typedef struct { + int8_t offset; +} PIN_offset; + +PIN_offset PULL_offset[] = { + /* 0 */ {6}, + /* 1 */ {7}, + /* 2 */ {8}, + /* 3 */ {9}, + /* 4 */ {11}, + /* 5 */ {12}, + /* 6 */ {13}, + /* 7 */ {14}, + /* 8 */ {0}, + /* 9 */ {26}, + /* 10 */ {27}, + /* 11 */ {10}, + /* 12 */ {17}, + /* 13 */ {6}, + /* 14 */ {7}, + /* 15 */ {8}, + /* 16 */ {9}, + /* 17 */ {10}, + /* 18 */ {11}, + /* 19 */ {12}, + /* 20 */ {13}, + /* 21 */ {14}, + /* 22 */ {15}, + /* 23 */ {16}, + /* 24 */ {17}, + /* 25 */ {18}, + /* 26 */ {19}, + /* 27 */ {20}, + /* 28 */ {21}, + /* 29 */ {-1}, + /* 30 */ {-1}, + /* 31 */ {-1}, + /* 32 */ {-1}, + /* 33 */ {-1}, + /* 34 */ {-1}, + /* 35 */ {-1}, + /* 36 */ {-1}, + /* 37 */ {-1}, + /* 38 */ {-1}, + /* 39 */ {-1}, + /* 40 */ {-1}, + /* 41 */ {-1}, + /* 42 */ {-1}, + /* 43 */ {8}, + /* 44 */ {9}, + /* 45 */ {10}, + /* 46 */ {11}, + /* 47 */ {12}, + /* 48 */ {13}, + /* 49 */ {14}, + /* 50 */ {0}, + /* 51 */ {1}, + /* 52 */ {2}, + /* 53 */ {3}, + /* 54 */ {4}, + /* 55 */ {5}, + /* 56 */ {6}, + /* 57 */ {7}, + /* 58 */ {8}, + /* 59 */ {9}, + /* 60 */ {10}, + /* 61 */ {0}, + /* 62 */ {1}, + /* 63 */ {2}, + /* 64 */ {3}, + /* 65 */ {4}, + /* 66 */ {5}, + /* 67 */ {6}, + /* 68 */ {7}, + /* 69 */ {8}, + /* 70 */ {9}, + /* 71 */ {10}, + /* 72 */ {11}, + /* 73 */ {12}, + /* 74 */ {13}, + /* 75 */ {14}, + /* 76 */ {15}, + /* 77 */ {16}, + /* 78 */ {17}, + /* 79 */ {18}, + /* 80 */ {19}, + /* 81 */ {20}, + /* 82 */ {21}, + /* 83 */ {22}, + /* 84 */ {23}, + /* 85 */ {24}, + /* 86 */ {25}, + /* 87 */ {26}, + /* 88 */ {27}, + /* 89 */ {24}, + /* 90 */ {1}, + /* 91 */ {-1}, + /* 92 */ {-1}, + /* 93 */ {-1}, + /* 94 */ {-1}, + /* 95 */ {15}, + /* 96 */ {17}, + /* 97 */ {18}, + /* 98 */ {19}, + /* 99 */ {20}, + /* 100 */ {21}, + /* 101 */ {22}, + /* 102 */ {23}, + /* 103 */ {28}, + /* 104 */ {29}, + /* 105 */ {30}, + /* 106 */ {31}, + /* 107 */ {0}, + /* 108 */ {1}, + /* 109 */ {2}, + /* 110 */ {3}, + /* 111 */ {4}, + /* 112 */ {5}, + /* 113 */ {6}, + /* 114 */ {7}, + /* 115 */ {8}, + /* 116 */ {9}, + /* 117 */ {10}, + /* 118 */ {11}, + /* 119 */ {12}, + /* 120 */ {13}, + /* 121 */ {14}, + /* 122 */ {-1}, + /* 123 */ {-1}, + /* 124 */ {-1}, + /* 125 */ {-1}, + /* 126 */ {-1}, + /* 127 */ {-1}, + /* 128 */ {-1}, + /* 129 */ {-1}, + /* 130 */ {-1}, + /* 131 */ {-1}, + /* 132 */ {-1}, + /* 133 */ {-1}, + /* 134 */ {0}, + /* 135 */ {1}, + /* 136 */ {2}, + /* 137 */ {3}, + /* 138 */ {4}, + /* 139 */ {5}, + /* 140 */ {6}, + /* 141 */ {7}, + /* 142 */ {8}, + /* 143 */ {9}, + /* 144 */ {11}, + /* 145 */ {12}, + /* 146 */ {13}, + /* 147 */ {14}, + /* 148 */ {15}, + /* 149 */ {16}, + /* 150 */ {18}, + /* 151 */ {19}, + /* 152 */ {20}, + /* 153 */ {21}, + /* 154 */ {22}, + /* 155 */ {23}, + /* 156 */ {24}, + /* 157 */ {25}, + /* 158 */ {26}, + /* 159 */ {27}, + /* 160 */ {28}, + /* 161 */ {0}, + /* 162 */ {1}, + /* 163 */ {2}, + /* 164 */ {3}, + /* 165 */ {4}, + /* 166 */ {5}, + /* 167 */ {11}, + /* 168 */ {12}, + /* 169 */ {13}, + /* 170 */ {14}, + /* 171 */ {15}, + /* 172 */ {16}, + /* 173 */ {17}, + /* 174 */ {18}, + /* 175 */ {19}, + /* 176 */ {20}, + /* 177 */ {10}, + /* 178 */ {16}, + /* 179 */ {25} +}; +#endif /* MT_GPIO_CFG_H */ diff --git a/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.c b/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.c new file mode 100644 index 000000000..29eebcb98 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.c @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <sspm_reg.h> +#include <mtk_mcdi.h> + +static inline uint32_t mcdi_mbox_read(uint32_t id) +{ + return mmio_read_32(SSPM_MBOX_3_BASE + (id << 2)); +} + +static inline void mcdi_mbox_write(uint32_t id, uint32_t val) +{ + mmio_write_32(SSPM_MBOX_3_BASE + (id << 2), val); +} + +void sspm_set_bootaddr(uint32_t bootaddr) +{ + mcdi_mbox_write(MCDI_MBOX_BOOTADDR, bootaddr); +} + +void sspm_cluster_pwr_off_notify(uint32_t cluster) +{ + mcdi_mbox_write(MCDI_MBOX_CLUSTER_0_ATF_ACTION_DONE + cluster, 1); +} + +void sspm_cluster_pwr_on_notify(uint32_t cluster) +{ + mcdi_mbox_write(MCDI_MBOX_CLUSTER_0_ATF_ACTION_DONE + cluster, 0); +} + +void sspm_standbywfi_irq_enable(uint32_t cpu_idx) +{ + mmio_write_32(SSPM_CFGREG_ACAO_INT_SET, STANDBYWFI_EN(cpu_idx)); +} + +uint32_t mcdi_avail_cpu_mask_read(void) +{ + return mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK); +} + +uint32_t mcdi_avail_cpu_mask_write(uint32_t mask) +{ + mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, mask); + + return mask; +} + +uint32_t mcdi_avail_cpu_mask_set(uint32_t mask) +{ + uint32_t m; + + m = mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK); + m |= mask; + mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, m); + + return m; +} + +uint32_t mcdi_avail_cpu_mask_clr(uint32_t mask) +{ + uint32_t m; + + m = mcdi_mbox_read(MCDI_MBOX_AVAIL_CPU_MASK); + m &= ~mask; + mcdi_mbox_write(MCDI_MBOX_AVAIL_CPU_MASK, m); + + return m; +} + +uint32_t mcdi_cpu_cluster_pwr_stat_read(void) +{ + return mcdi_mbox_read(MCDI_MBOX_CPU_CLUSTER_PWR_STAT); +} + +#define PAUSE_BIT 1 +#define CLUSTER_OFF_OFS 20 +#define CPU_OFF_OFS 24 +#define CLUSTER_ON_OFS 4 +#define CPU_ON_OFS 8 + +static uint32_t target_mask(int cluster, int cpu_idx, bool on) +{ + uint32_t t = 0; + + if (on) { + if (cluster >= 0) + t |= BIT(cluster + CLUSTER_ON_OFS); + + if (cpu_idx >= 0) + t |= BIT(cpu_idx + CPU_ON_OFS); + } else { + if (cluster >= 0) + t |= BIT(cluster + CLUSTER_OFF_OFS); + + if (cpu_idx >= 0) + t |= BIT(cpu_idx + CPU_OFF_OFS); + } + + return t; +} + +void mcdi_pause_clr(int cluster, int cpu_idx, bool on) +{ + uint32_t tgt = target_mask(cluster, cpu_idx, on); + uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION); + + m &= ~tgt; + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); +} + +void mcdi_pause_set(int cluster, int cpu_idx, bool on) +{ + uint32_t tgt = target_mask(cluster, cpu_idx, on); + uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION); + uint32_t tgtn = target_mask(-1, cpu_idx, !on); + + /* request on and off at the same time to ensure it can be paused */ + m |= tgt | tgtn; + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); + + /* wait pause_ack */ + while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK)) + ; + + /* clear non-requested operation */ + m &= ~tgtn; + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); +} + +void mcdi_pause(void) +{ + uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) | BIT(PAUSE_BIT); + + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); + + /* wait pause_ack */ + while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK)) + ; +} + +void mcdi_unpause(void) +{ + uint32_t m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) & ~BIT(PAUSE_BIT); + + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); +} + +void mcdi_hotplug_wait_ack(int cluster, int cpu_idx, bool on) +{ + uint32_t tgt = target_mask(cluster, cpu_idx, on); + uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); + + /* wait until ack */ + while (!(ack & tgt)) + ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); +} + +void mcdi_hotplug_clr(int cluster, int cpu_idx, bool on) +{ + uint32_t tgt = target_mask(cluster, cpu_idx, on); + uint32_t tgt_cpu = target_mask(-1, cpu_idx, on); + uint32_t cmd = mcdi_mbox_read(MCDI_MBOX_HP_CMD); + uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); + + if (!(cmd & tgt)) + return; + + /* wait until ack */ + while (!(ack & tgt_cpu)) + ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); + + cmd &= ~tgt; + mcdi_mbox_write(MCDI_MBOX_HP_CMD, cmd); +} + +void mcdi_hotplug_set(int cluster, int cpu_idx, bool on) +{ + uint32_t tgt = target_mask(cluster, cpu_idx, on); + uint32_t tgt_cpu = target_mask(-1, cpu_idx, on); + uint32_t cmd = mcdi_mbox_read(MCDI_MBOX_HP_CMD); + uint32_t ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); + + if ((cmd & tgt) == tgt) + return; + + /* wait until ack clear */ + while (ack & tgt_cpu) + ack = mcdi_mbox_read(MCDI_MBOX_HP_ACK); + + cmd |= tgt; + mcdi_mbox_write(MCDI_MBOX_HP_CMD, cmd); +} + +bool check_mcdi_ctl_stat(void) +{ + uint32_t clk_regs[] = {0x100010ac, 0x100010c8}; + uint32_t clk_mask[] = {0x00028000, 0x00000018}; + uint32_t tgt = target_mask(0, 0, true); + uint32_t m; + int i; + + /* check clk status */ + for (i = 0; i < ARRAY_SIZE(clk_regs); i++) { + if (mmio_read_32(clk_regs[i]) & clk_mask[i]) { + WARN("mcdi: clk check fail.\n"); + return false; + } + } + + /* check mcdi cmd handling */ + m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) | BIT(PAUSE_BIT); + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); + + i = 500; + while (!mcdi_mbox_read(MCDI_MBOX_PAUSE_ACK) && --i > 0) + udelay(10); + + m = mcdi_mbox_read(MCDI_MBOX_PAUSE_ACTION) & ~BIT(PAUSE_BIT); + mcdi_mbox_write(MCDI_MBOX_PAUSE_ACTION, m); + + if (i == 0) { + WARN("mcdi: pause_action fail.\n"); + return false; + } + + /* check mcdi cmd handling */ + if (mcdi_mbox_read(MCDI_MBOX_HP_CMD) || + mcdi_mbox_read(MCDI_MBOX_HP_ACK)) { + WARN("mcdi: hp_cmd fail.\n"); + return false; + } + + mcdi_mbox_write(MCDI_MBOX_HP_CMD, tgt); + + i = 500; + while ((mcdi_mbox_read(MCDI_MBOX_HP_ACK) & tgt) != tgt && --i > 0) + udelay(10); + + mcdi_mbox_write(MCDI_MBOX_HP_CMD, 0); + + if (i == 0) { + WARN("mcdi: hp_ack fail.\n"); + return false; + } + + return true; +} + +void mcdi_init(void) +{ + mcdi_avail_cpu_mask_write(0x01); /* cpu0 default on */ +} diff --git a/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.h b/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.h new file mode 100644 index 000000000..9a40df1ca --- /dev/null +++ b/plat/mediatek/mt8183/drivers/mcdi/mtk_mcdi.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __MTK_MCDI_H__ +#define __MTK_MCDI_H__ + +#include <stdbool.h> + +void sspm_set_bootaddr(uint32_t bootaddr); +void sspm_standbywfi_irq_enable(uint32_t cpu_idx); +void sspm_cluster_pwr_off_notify(uint32_t cluster); +void sspm_cluster_pwr_on_notify(uint32_t cluster); + +uint32_t mcdi_avail_cpu_mask_read(void); +uint32_t mcdi_avail_cpu_mask_write(uint32_t mask); +uint32_t mcdi_avail_cpu_mask_set(uint32_t mask); +uint32_t mcdi_avail_cpu_mask_clr(uint32_t mask); +uint32_t mcdi_cpu_cluster_pwr_stat_read(void); + +void mcdi_pause(void); +void mcdi_unpause(void); +void mcdi_pause_set(int cluster, int cpu_idx, bool on); +void mcdi_pause_clr(int cluster, int cpu_idx, bool on); +void mcdi_hotplug_set(int cluster, int cpu_idx, bool on); +void mcdi_hotplug_clr(int cluster, int cpu_idx, bool on); +void mcdi_hotplug_wait_ack(int cluster, int cpu_idx, bool on); + +bool check_mcdi_ctl_stat(void); +void mcdi_init(void); + +#endif /* __MTK_MCDI_H__ */ diff --git a/plat/mediatek/mt8183/drivers/pmic/pmic.c b/plat/mediatek/mt8183/drivers/pmic/pmic.c new file mode 100644 index 000000000..b0f898e21 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/pmic/pmic.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <pmic_wrap_init.h> +#include <pmic.h> + +void bcpu_enable(uint32_t en) +{ + pwrap_write(PMIC_VPROC11_OP_EN, 0x1); + if (en) + pwrap_write(PMIC_VPROC11_CON0, 1); + else + pwrap_write(PMIC_VPROC11_CON0, 0); +} + +void bcpu_sram_enable(uint32_t en) +{ + pwrap_write(PMIC_VSRAM_PROC11_OP_EN, 0x1); + if (en) + pwrap_write(PMIC_VSRAM_PROC11_CON0, 1); + else + pwrap_write(PMIC_VSRAM_PROC11_CON0, 0); +} + +void wk_pmic_enable_sdn_delay(void) +{ + uint32_t con; + + pwrap_write(PMIC_TMA_KEY, 0x9CA7); + pwrap_read(PMIC_PSEQ_ELR11, &con); + con &= ~PMIC_RG_SDN_DLY_ENB; + pwrap_write(PMIC_PSEQ_ELR11, con); + pwrap_write(PMIC_TMA_KEY, 0); +} + +void pmic_power_off(void) +{ + pwrap_write(PMIC_PWRHOLD, 0x0); +} diff --git a/plat/mediatek/mt8183/drivers/pmic/pmic.h b/plat/mediatek/mt8183/drivers/pmic/pmic.h new file mode 100644 index 000000000..f19f9f6e4 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/pmic/pmic.h @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_H +#define PMIC_H + +enum { + PMIC_TMA_KEY = 0x03a8, + PMIC_PWRHOLD = 0x0a08, + PMIC_PSEQ_ELR11 = 0x0a62, + PMIC_VPROC11_CON0 = 0x1388, + PMIC_VPROC11_OP_EN = 0x1390, + PMIC_VSRAM_PROC11_CON0 = 0x1b46, + PMIC_VSRAM_PROC11_OP_EN = 0x1b4e +}; + +enum { + PMIC_RG_SDN_DLY_ENB = 1U << 10 +}; + +/* external API */ +void bcpu_enable(uint32_t en); +void bcpu_sram_enable(uint32_t en); +void wk_pmic_enable_sdn_delay(void); +void pmic_power_off(void); + +#endif /* PMIC_H */ diff --git a/plat/mediatek/mt8183/drivers/pmic/pmic_wrap_init.h b/plat/mediatek/mt8183/drivers/pmic/pmic_wrap_init.h new file mode 100644 index 000000000..679c5e4c3 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/pmic/pmic_wrap_init.h @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PMIC_WRAP_INIT_H +#define PMIC_WRAP_INIT_H + +#include <platform_def.h> +#include <stdint.h> + +/* external API */ +int32_t pwrap_read(uint32_t adr, uint32_t *rdata); +int32_t pwrap_write(uint32_t adr, uint32_t wdata); + +static struct mt8183_pmic_wrap_regs *const mtk_pwrap = + (void *)PMIC_WRAP_BASE; + +/* timeout setting */ +enum { + TIMEOUT_READ = 255, /* us */ + TIMEOUT_WAIT_IDLE = 255 /* us */ +}; + +/* PMIC_WRAP registers */ +struct mt8183_pmic_wrap_regs { + uint32_t reserved[776]; + uint32_t wacs2_cmd; + uint32_t wacs2_rdata; + uint32_t wacs2_vldclr; + uint32_t reserved1[4]; +}; + +enum { + RDATA_WACS_RDATA_SHIFT = 0, + RDATA_WACS_FSM_SHIFT = 16, + RDATA_WACS_REQ_SHIFT = 19, + RDATA_SYNC_IDLE_SHIFT, + RDATA_INIT_DONE_SHIFT, + RDATA_SYS_IDLE_SHIFT, +}; + +enum { + RDATA_WACS_RDATA_MASK = 0xffff, + RDATA_WACS_FSM_MASK = 0x7, + RDATA_WACS_REQ_MASK = 0x1, + RDATA_SYNC_IDLE_MASK = 0x1, + RDATA_INIT_DONE_MASK = 0x1, + RDATA_SYS_IDLE_MASK = 0x1, +}; + +/* WACS_FSM */ +enum { + WACS_FSM_IDLE = 0x00, + WACS_FSM_REQ = 0x02, + WACS_FSM_WFDLE = 0x04, + WACS_FSM_WFVLDCLR = 0x06, + WACS_INIT_DONE = 0x01, + WACS_SYNC_IDLE = 0x01, + WACS_SYNC_BUSY = 0x00 +}; + +/* error information flag */ +enum { + E_PWR_INVALID_ARG = 1, + E_PWR_INVALID_RW = 2, + E_PWR_INVALID_ADDR = 3, + E_PWR_INVALID_WDAT = 4, + E_PWR_INVALID_OP_MANUAL = 5, + E_PWR_NOT_IDLE_STATE = 6, + E_PWR_NOT_INIT_DONE = 7, + E_PWR_NOT_INIT_DONE_READ = 8, + E_PWR_WAIT_IDLE_TIMEOUT = 9, + E_PWR_WAIT_IDLE_TIMEOUT_READ = 10, + E_PWR_INIT_SIDLY_FAIL = 11, + E_PWR_RESET_TIMEOUT = 12, + E_PWR_TIMEOUT = 13, + E_PWR_INIT_RESET_SPI = 20, + E_PWR_INIT_SIDLY = 21, + E_PWR_INIT_REG_CLOCK = 22, + E_PWR_INIT_ENABLE_PMIC = 23, + E_PWR_INIT_DIO = 24, + E_PWR_INIT_CIPHER = 25, + E_PWR_INIT_WRITE_TEST = 26, + E_PWR_INIT_ENABLE_CRC = 27, + E_PWR_INIT_ENABLE_DEWRAP = 28, + E_PWR_INIT_ENABLE_EVENT = 29, + E_PWR_READ_TEST_FAIL = 30, + E_PWR_WRITE_TEST_FAIL = 31, + E_PWR_SWITCH_DIO = 32 +}; + +#endif /* PMIC_WRAP_INIT_H */ diff --git a/plat/mediatek/mt8183/drivers/rtc/rtc.c b/plat/mediatek/mt8183/drivers/rtc/rtc.c new file mode 100644 index 000000000..a821c1bc8 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/rtc/rtc.c @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <rtc.h> + +static void RTC_Config_Interface(uint32_t addr, uint16_t data, + uint16_t MASK, uint16_t SHIFT) +{ + uint16_t pmic_reg = 0; + + pmic_reg = RTC_Read(addr); + + pmic_reg &= ~(MASK << SHIFT); + pmic_reg |= (data << SHIFT); + + RTC_Write(addr, pmic_reg); +} + +static void rtc_disable_2sec_reboot(void) +{ + uint16_t reboot; + + reboot = (RTC_Read(RTC_AL_SEC) & ~RTC_BBPU_2SEC_EN) & + ~RTC_BBPU_AUTO_PDN_SEL; + RTC_Write(RTC_AL_SEC, reboot); + RTC_Write_Trigger(); +} + +static void rtc_xosc_write(uint16_t val, bool reload) +{ + uint16_t bbpu; + + RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK1); + rtc_busy_wait(); + RTC_Write(RTC_OSC32CON, RTC_OSC32CON_UNLOCK2); + rtc_busy_wait(); + + RTC_Write(RTC_OSC32CON, val); + rtc_busy_wait(); + + if (reload) { + bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; + RTC_Write(RTC_BBPU, bbpu); + RTC_Write_Trigger(); + } +} + +static void rtc_enable_k_eosc(void) +{ + uint16_t osc32; + uint16_t rtc_eosc_cali_td = 8; /* eosc cali period time */ + + /* Truning on eosc cali mode clock */ + RTC_Config_Interface(PMIC_RG_TOP_CON, 1, + PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK, + PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT); + RTC_Config_Interface(PMIC_RG_TOP_CON, 1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK, + PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT); + RTC_Config_Interface(PMIC_RG_SCK_TOP_CKPDN_CON0, 0, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT); + + switch (rtc_eosc_cali_td) { + case 1: + RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x3, + PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); + break; + case 2: + RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x4, + PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); + break; + case 4: + RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x5, + PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); + break; + case 16: + RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x7, + PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); + break; + default: + RTC_Config_Interface(PMIC_RG_EOSC_CALI_CON0, 0x6, + PMIC_RG_EOSC_CALI_TD_MASK, PMIC_RG_EOSC_CALI_TD_SHIFT); + break; + } + /* Switch the DCXO from 32k-less mode to RTC mode, + * otherwise, EOSC cali will fail + */ + /* RTC mode will have only OFF mode and FPM */ + RTC_Config_Interface(PMIC_RG_DCXO_CW02, 0, PMIC_RG_XO_EN32K_MAN_MASK, + PMIC_RG_XO_EN32K_MAN_SHIFT); + RTC_Write(RTC_BBPU, + RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD); + RTC_Write_Trigger(); + /* Enable K EOSC mode for normal power off and then plug out battery */ + RTC_Write(RTC_AL_YEA, ((RTC_Read(RTC_AL_YEA) | RTC_K_EOSC_RSV_0) + & (~RTC_K_EOSC_RSV_1)) | RTC_K_EOSC_RSV_2); + RTC_Write_Trigger(); + + osc32 = RTC_Read(RTC_OSC32CON); + rtc_xosc_write(osc32 | RTC_EMBCK_SRC_SEL, true); + INFO("[RTC] RTC_enable_k_eosc\n"); +} + +void rtc_power_off_sequence(void) +{ + uint16_t bbpu; + + rtc_disable_2sec_reboot(); + rtc_enable_k_eosc(); + + /* clear alarm */ + bbpu = RTC_BBPU_KEY | RTC_BBPU_CLR | RTC_BBPU_PWREN; + if (Writeif_unlock()) { + RTC_Write(RTC_BBPU, bbpu); + + RTC_Write(RTC_AL_MASK, RTC_AL_MASK_DOW); + RTC_Write_Trigger(); + mdelay(1); + + bbpu = RTC_Read(RTC_BBPU) | RTC_BBPU_KEY | RTC_BBPU_RELOAD; + RTC_Write(RTC_BBPU, bbpu); + RTC_Write_Trigger(); + INFO("[RTC] BBPU=0x%x, IRQ_EN=0x%x, AL_MSK=0x%x, AL_SEC=0x%x\n", + RTC_Read(RTC_BBPU), RTC_Read(RTC_IRQ_EN), + RTC_Read(RTC_AL_MASK), RTC_Read(RTC_AL_SEC)); + } +} diff --git a/plat/mediatek/mt8183/drivers/rtc/rtc.h b/plat/mediatek/mt8183/drivers/rtc/rtc.h new file mode 100644 index 000000000..66686b400 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/rtc/rtc.h @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RTC_H +#define RTC_H + +/* RTC registers */ +enum { + RTC_BBPU = 0x0588, + RTC_IRQ_STA = 0x058A, + RTC_IRQ_EN = 0x058C, + RTC_CII_EN = 0x058E +}; + +enum { + RTC_AL_SEC = 0x05A0, + RTC_AL_MIN = 0x05A2, + RTC_AL_HOU = 0x05A4, + RTC_AL_DOM = 0x05A6, + RTC_AL_DOW = 0x05A8, + RTC_AL_MTH = 0x05AA, + RTC_AL_YEA = 0x05AC, + RTC_AL_MASK = 0x0590 +}; + +enum { + RTC_OSC32CON = 0x05AE, + RTC_CON = 0x05C4, + RTC_WRTGR = 0x05C2 +}; + +enum { + RTC_PDN1 = 0x05B4, + RTC_PDN2 = 0x05B6, + RTC_SPAR0 = 0x05B8, + RTC_SPAR1 = 0x05BA, + RTC_PROT = 0x05BC, + RTC_DIFF = 0x05BE, + RTC_CALI = 0x05C0 +}; + +enum { + RTC_OSC32CON_UNLOCK1 = 0x1A57, + RTC_OSC32CON_UNLOCK2 = 0x2B68 +}; + +enum { + RTC_PROT_UNLOCK1 = 0x586A, + RTC_PROT_UNLOCK2 = 0x9136 +}; + +enum { + RTC_BBPU_PWREN = 1U << 0, + RTC_BBPU_CLR = 1U << 1, + RTC_BBPU_INIT = 1U << 2, + RTC_BBPU_AUTO = 1U << 3, + RTC_BBPU_CLRPKY = 1U << 4, + RTC_BBPU_RELOAD = 1U << 5, + RTC_BBPU_CBUSY = 1U << 6 +}; + +enum { + RTC_AL_MASK_SEC = 1U << 0, + RTC_AL_MASK_MIN = 1U << 1, + RTC_AL_MASK_HOU = 1U << 2, + RTC_AL_MASK_DOM = 1U << 3, + RTC_AL_MASK_DOW = 1U << 4, + RTC_AL_MASK_MTH = 1U << 5, + RTC_AL_MASK_YEA = 1U << 6 +}; + +enum { + RTC_BBPU_AUTO_PDN_SEL = 1U << 6, + RTC_BBPU_2SEC_CK_SEL = 1U << 7, + RTC_BBPU_2SEC_EN = 1U << 8, + RTC_BBPU_2SEC_MODE = 0x3 << 9, + RTC_BBPU_2SEC_STAT_CLEAR = 1U << 11, + RTC_BBPU_2SEC_STAT_STA = 1U << 12 +}; + +enum { + RTC_BBPU_KEY = 0x43 << 8 +}; + +enum { + RTC_EMBCK_SRC_SEL = 1 << 8, + RTC_EMBCK_SEL_MODE = 3 << 6, + RTC_XOSC32_ENB = 1 << 5, + RTC_REG_XOSC32_ENB = 1 << 15 +}; + +enum { + RTC_K_EOSC_RSV_0 = 1 << 8, + RTC_K_EOSC_RSV_1 = 1 << 9, + RTC_K_EOSC_RSV_2 = 1 << 10 +}; + +/* PMIC TOP Register Definition */ +enum { + PMIC_RG_TOP_CON = 0x001E, + PMIC_RG_TOP_CKPDN_CON1 = 0x0112, + PMIC_RG_TOP_CKPDN_CON1_SET = 0x0114, + PMIC_RG_TOP_CKPDN_CON1_CLR = 0x0116, + PMIC_RG_TOP_CKSEL_CON0 = 0x0118, + PMIC_RG_TOP_CKSEL_CON0_SET = 0x011A, + PMIC_RG_TOP_CKSEL_CON0_CLR = 0x011C +}; + +/* PMIC SCK Register Definition */ +enum { + PMIC_RG_SCK_TOP_CKPDN_CON0 = 0x051A, + PMIC_RG_SCK_TOP_CKPDN_CON0_SET = 0x051C, + PMIC_RG_SCK_TOP_CKPDN_CON0_CLR = 0x051E, + PMIC_RG_EOSC_CALI_CON0 = 0x540 +}; + +/* PMIC DCXO Register Definition */ +enum { + PMIC_RG_DCXO_CW00 = 0x0788, + PMIC_RG_DCXO_CW02 = 0x0790 +}; + +enum { + PMIC_RG_SRCLKEN_IN0_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN0_HW_MODE_SHIFT = 1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_MASK = 0x1, + PMIC_RG_SRCLKEN_IN1_HW_MODE_SHIFT = 3, + PMIC_RG_RTC_EOSC32_CK_PDN_MASK = 0x1, + PMIC_RG_RTC_EOSC32_CK_PDN_SHIFT = 2, + PMIC_RG_EOSC_CALI_TD_MASK = 0x7, + PMIC_RG_EOSC_CALI_TD_SHIFT = 5, + PMIC_RG_XO_EN32K_MAN_MASK = 0x1, + PMIC_RG_XO_EN32K_MAN_SHIFT = 0 +}; + +/* external API */ +uint16_t RTC_Read(uint32_t addr); +void RTC_Write(uint32_t addr, uint16_t data); +int32_t rtc_busy_wait(void); +int32_t RTC_Write_Trigger(void); +int32_t Writeif_unlock(void); +void rtc_power_off_sequence(void); + +#endif /* RTC_H */ diff --git a/plat/mediatek/mt8183/drivers/spm/spm.c b/plat/mediatek/mt8183/drivers/spm/spm.c new file mode 100644 index 000000000..d6d2344c1 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm.c @@ -0,0 +1,363 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <lib/bakery_lock.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <spm.h> +#include <spm_pmic_wrap.h> + +DEFINE_BAKERY_LOCK(spm_lock); + +/* SPM_DVS_LEVEL */ +#define SPM_VMODEM_LEVEL_MASK (0xff << 16) +#define SPM_VMODEM_LEVEL (1U << 18) +#define SPM_VCORE_LEVEL_MASK (0xff) +#define SPM_VCORE_LEVEL (1U << 1) + +/* CLK_SCP_CFG_0 */ +#define SPM_CK_OFF_CONTROL (0x3FF) + +/* CLK_SCP_CFG_1 */ +#define SPM_AXI_26M_SEL (0x1) + +/* AP_PLL_CON3 */ +#define SPM_PLL_CONTROL (0x7FAAAAF) + +/* AP_PLL_CON4 */ +#define SPM_PLL_OUT_OFF_CONTROL (0xFA0A) + +/* AP_PLL_CON6 */ +#define PLL_DLY (0x20000) + +const char *wakeup_src_str[32] = { + [0] = "R12_PCM_TIMER", + [1] = "R12_SSPM_WDT_EVENT_B", + [2] = "R12_KP_IRQ_B", + [3] = "R12_APWDT_EVENT_B", + [4] = "R12_APXGPT1_EVENT_B", + [5] = "R12_CONN2AP_SPM_WAKEUP_B", + [6] = "R12_EINT_EVENT_B", + [7] = "R12_CONN_WDT_IRQ_B", + [8] = "R12_CCIF0_EVENT_B", + [9] = "R12_LOWBATTERY_IRQ_B", + [10] = "R12_SSPM_SPM_IRQ_B", + [11] = "R12_SCP_SPM_IRQ_B", + [12] = "R12_SCP_WDT_EVENT_B", + [13] = "R12_PCM_WDT_WAKEUP_B", + [14] = "R12_USB_CDSC_B ", + [15] = "R12_USB_POWERDWN_B", + [16] = "R12_SYS_TIMER_EVENT_B", + [17] = "R12_EINT_EVENT_SECURE_B", + [18] = "R12_CCIF1_EVENT_B", + [19] = "R12_UART0_IRQ_B", + [20] = "R12_AFE_IRQ_MCU_B", + [21] = "R12_THERM_CTRL_EVENT_B", + [22] = "R12_SYS_CIRQ_IRQ_B", + [23] = "R12_MD2AP_PEER_EVENT_B", + [24] = "R12_CSYSPWREQ_B", + [25] = "R12_MD1_WDT_B ", + [26] = "R12_CLDMA_EVENT_B", + [27] = "R12_SEJ_WDT_GPT_B", + [28] = "R12_ALL_SSPM_WAKEUP_B", + [29] = "R12_CPU_IRQ_B", + [30] = "R12_CPU_WFI_AND_B" +}; + +const char *spm_get_firmware_version(void) +{ + return "DYNAMIC_SPM_FW_VERSION"; +} + +void spm_lock_init(void) +{ + bakery_lock_init(&spm_lock); +} + +void spm_lock_get(void) +{ + bakery_lock_get(&spm_lock); +} + +void spm_lock_release(void) +{ + bakery_lock_release(&spm_lock); +} + +void spm_set_bootaddr(unsigned long bootaddr) +{ + /* initialize core4~7 boot entry address */ + mmio_write_32(SW2SPM_MAILBOX_3, bootaddr); +} + +void spm_set_cpu_status(int cpu) +{ + if (cpu >= 0 && cpu < 4) { + mmio_write_32(ROOT_CPUTOP_ADDR, 0x10006204); + mmio_write_32(ROOT_CORE_ADDR, 0x10006208 + (cpu * 0x4)); + } else if (cpu >= 4 && cpu < 8) { + mmio_write_32(ROOT_CPUTOP_ADDR, 0x10006218); + mmio_write_32(ROOT_CORE_ADDR, 0x1000621c + ((cpu - 4) * 0x4)); + } else { + ERROR("%s: error cpu number %d\n", __func__, cpu); + } +} + +void spm_set_power_control(const struct pwr_ctrl *pwrctrl) +{ + mmio_write_32(SPM_AP_STANDBY_CON, + ((pwrctrl->wfi_op & 0x1) << 0) | + ((pwrctrl->mp0_cputop_idle_mask & 0x1) << 1) | + ((pwrctrl->mp1_cputop_idle_mask & 0x1) << 2) | + ((pwrctrl->mcusys_idle_mask & 0x1) << 4) | + ((pwrctrl->mm_mask_b & 0x3) << 16) | + ((pwrctrl->md_ddr_en_0_dbc_en & 0x1) << 18) | + ((pwrctrl->md_ddr_en_1_dbc_en & 0x1) << 19) | + ((pwrctrl->md_mask_b & 0x3) << 20) | + ((pwrctrl->sspm_mask_b & 0x1) << 22) | + ((pwrctrl->scp_mask_b & 0x1) << 23) | + ((pwrctrl->srcclkeni_mask_b & 0x1) << 24) | + ((pwrctrl->md_apsrc_1_sel & 0x1) << 25) | + ((pwrctrl->md_apsrc_0_sel & 0x1) << 26) | + ((pwrctrl->conn_ddr_en_dbc_en & 0x1) << 27) | + ((pwrctrl->conn_mask_b & 0x1) << 28) | + ((pwrctrl->conn_apsrc_sel & 0x1) << 29)); + + mmio_write_32(SPM_SRC_REQ, + ((pwrctrl->spm_apsrc_req & 0x1) << 0) | + ((pwrctrl->spm_f26m_req & 0x1) << 1) | + ((pwrctrl->spm_infra_req & 0x1) << 3) | + ((pwrctrl->spm_vrf18_req & 0x1) << 4) | + ((pwrctrl->spm_ddren_req & 0x1) << 7) | + ((pwrctrl->spm_rsv_src_req & 0x7) << 8) | + ((pwrctrl->spm_ddren_2_req & 0x1) << 11) | + ((pwrctrl->cpu_md_dvfs_sop_force_on & 0x1) << 16)); + + mmio_write_32(SPM_SRC_MASK, + ((pwrctrl->csyspwreq_mask & 0x1) << 0) | + ((pwrctrl->ccif0_md_event_mask_b & 0x1) << 1) | + ((pwrctrl->ccif0_ap_event_mask_b & 0x1) << 2) | + ((pwrctrl->ccif1_md_event_mask_b & 0x1) << 3) | + ((pwrctrl->ccif1_ap_event_mask_b & 0x1) << 4) | + ((pwrctrl->ccif2_md_event_mask_b & 0x1) << 5) | + ((pwrctrl->ccif2_ap_event_mask_b & 0x1) << 6) | + ((pwrctrl->ccif3_md_event_mask_b & 0x1) << 7) | + ((pwrctrl->ccif3_ap_event_mask_b & 0x1) << 8) | + ((pwrctrl->md_srcclkena_0_infra_mask_b & 0x1) << 9) | + ((pwrctrl->md_srcclkena_1_infra_mask_b & 0x1) << 10) | + ((pwrctrl->conn_srcclkena_infra_mask_b & 0x1) << 11) | + ((pwrctrl->ufs_infra_req_mask_b & 0x1) << 12) | + ((pwrctrl->srcclkeni_infra_mask_b & 0x1) << 13) | + ((pwrctrl->md_apsrc_req_0_infra_mask_b & 0x1) << 14) | + ((pwrctrl->md_apsrc_req_1_infra_mask_b & 0x1) << 15) | + ((pwrctrl->conn_apsrcreq_infra_mask_b & 0x1) << 16) | + ((pwrctrl->ufs_srcclkena_mask_b & 0x1) << 17) | + ((pwrctrl->md_vrf18_req_0_mask_b & 0x1) << 18) | + ((pwrctrl->md_vrf18_req_1_mask_b & 0x1) << 19) | + ((pwrctrl->ufs_vrf18_req_mask_b & 0x1) << 20) | + ((pwrctrl->gce_vrf18_req_mask_b & 0x1) << 21) | + ((pwrctrl->conn_infra_req_mask_b & 0x1) << 22) | + ((pwrctrl->gce_apsrc_req_mask_b & 0x1) << 23) | + ((pwrctrl->disp0_apsrc_req_mask_b & 0x1) << 24) | + ((pwrctrl->disp1_apsrc_req_mask_b & 0x1) << 25) | + ((pwrctrl->mfg_req_mask_b & 0x1) << 26) | + ((pwrctrl->vdec_req_mask_b & 0x1) << 27)); + + mmio_write_32(SPM_SRC2_MASK, + ((pwrctrl->md_ddr_en_0_mask_b & 0x1) << 0) | + ((pwrctrl->md_ddr_en_1_mask_b & 0x1) << 1) | + ((pwrctrl->conn_ddr_en_mask_b & 0x1) << 2) | + ((pwrctrl->ddren_sspm_apsrc_req_mask_b & 0x1) << 3) | + ((pwrctrl->ddren_scp_apsrc_req_mask_b & 0x1) << 4) | + ((pwrctrl->disp0_ddren_mask_b & 0x1) << 5) | + ((pwrctrl->disp1_ddren_mask_b & 0x1) << 6) | + ((pwrctrl->gce_ddren_mask_b & 0x1) << 7) | + ((pwrctrl->ddren_emi_self_refresh_ch0_mask_b & 0x1) + << 8) | + ((pwrctrl->ddren_emi_self_refresh_ch1_mask_b & 0x1) + << 9)); + + mmio_write_32(SPM_WAKEUP_EVENT_MASK, + ((pwrctrl->spm_wakeup_event_mask & 0xffffffff) << 0)); + + mmio_write_32(SPM_WAKEUP_EVENT_EXT_MASK, + ((pwrctrl->spm_wakeup_event_ext_mask & 0xffffffff) + << 0)); + + mmio_write_32(SPM_SRC3_MASK, + ((pwrctrl->md_ddr_en_2_0_mask_b & 0x1) << 0) | + ((pwrctrl->md_ddr_en_2_1_mask_b & 0x1) << 1) | + ((pwrctrl->conn_ddr_en_2_mask_b & 0x1) << 2) | + ((pwrctrl->ddren2_sspm_apsrc_req_mask_b & 0x1) << 3) | + ((pwrctrl->ddren2_scp_apsrc_req_mask_b & 0x1) << 4) | + ((pwrctrl->disp0_ddren2_mask_b & 0x1) << 5) | + ((pwrctrl->disp1_ddren2_mask_b & 0x1) << 6) | + ((pwrctrl->gce_ddren2_mask_b & 0x1) << 7) | + ((pwrctrl->ddren2_emi_self_refresh_ch0_mask_b & 0x1) + << 8) | + ((pwrctrl->ddren2_emi_self_refresh_ch1_mask_b & 0x1) + << 9)); + + mmio_write_32(MP0_CPU0_WFI_EN, + ((pwrctrl->mp0_cpu0_wfi_en & 0x1) << 0)); + mmio_write_32(MP0_CPU1_WFI_EN, + ((pwrctrl->mp0_cpu1_wfi_en & 0x1) << 0)); + mmio_write_32(MP0_CPU2_WFI_EN, + ((pwrctrl->mp0_cpu2_wfi_en & 0x1) << 0)); + mmio_write_32(MP0_CPU3_WFI_EN, + ((pwrctrl->mp0_cpu3_wfi_en & 0x1) << 0)); + + mmio_write_32(MP1_CPU0_WFI_EN, + ((pwrctrl->mp1_cpu0_wfi_en & 0x1) << 0)); + mmio_write_32(MP1_CPU1_WFI_EN, + ((pwrctrl->mp1_cpu1_wfi_en & 0x1) << 0)); + mmio_write_32(MP1_CPU2_WFI_EN, + ((pwrctrl->mp1_cpu2_wfi_en & 0x1) << 0)); + mmio_write_32(MP1_CPU3_WFI_EN, + ((pwrctrl->mp1_cpu3_wfi_en & 0x1) << 0)); +} + +void spm_disable_pcm_timer(void) +{ + mmio_clrsetbits_32(PCM_CON1, PCM_TIMER_EN_LSB, SPM_REGWR_CFG_KEY); +} + +void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl) +{ + uint32_t val, mask, isr; + + val = pwrctrl->timer_val ? pwrctrl->timer_val : PCM_TIMER_MAX; + mmio_write_32(PCM_TIMER_VAL, val); + mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | PCM_TIMER_EN_LSB); + + mask = pwrctrl->wake_src; + + if (pwrctrl->csyspwreq_mask) + mask &= ~WAKE_SRC_R12_CSYSPWREQ_B; + + mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~mask); + + isr = mmio_read_32(SPM_IRQ_MASK) & SPM_TWAM_IRQ_MASK_LSB; + mmio_write_32(SPM_IRQ_MASK, isr | ISRM_RET_IRQ_AUX); +} + +void spm_set_pcm_flags(const struct pwr_ctrl *pwrctrl) +{ + mmio_write_32(SPM_SW_FLAG, pwrctrl->pcm_flags); + mmio_write_32(SPM_SW_RSV_2, pwrctrl->pcm_flags1); +} + +void spm_set_pcm_wdt(int en) +{ + if (en) { + mmio_clrsetbits_32(PCM_CON1, PCM_WDT_WAKE_MODE_LSB, + SPM_REGWR_CFG_KEY); + + if (mmio_read_32(PCM_TIMER_VAL) > PCM_TIMER_MAX) + mmio_write_32(PCM_TIMER_VAL, PCM_TIMER_MAX); + mmio_write_32(PCM_WDT_VAL, + mmio_read_32(PCM_TIMER_VAL) + PCM_WDT_TIMEOUT); + mmio_setbits_32(PCM_CON1, SPM_REGWR_CFG_KEY | PCM_WDT_EN_LSB); + } else { + mmio_clrsetbits_32(PCM_CON1, PCM_WDT_EN_LSB, + SPM_REGWR_CFG_KEY); + } +} + +void spm_send_cpu_wakeup_event(void) +{ + mmio_write_32(PCM_REG_DATA_INI, 0); + mmio_write_32(SPM_CPU_WAKEUP_EVENT, 1); +} + +void spm_get_wakeup_status(struct wake_status *wakesta) +{ + wakesta->assert_pc = mmio_read_32(PCM_REG_DATA_INI); + wakesta->r12 = mmio_read_32(SPM_SW_RSV_0); + wakesta->r12_ext = mmio_read_32(PCM_REG12_EXT_DATA); + wakesta->raw_sta = mmio_read_32(SPM_WAKEUP_STA); + wakesta->raw_ext_sta = mmio_read_32(SPM_WAKEUP_EXT_STA); + wakesta->wake_misc = mmio_read_32(SPM_BSI_D0_SR); + wakesta->timer_out = mmio_read_32(SPM_BSI_D1_SR); + wakesta->r13 = mmio_read_32(PCM_REG13_DATA); + wakesta->idle_sta = mmio_read_32(SUBSYS_IDLE_STA); + wakesta->req_sta = mmio_read_32(SRC_REQ_STA); + wakesta->sw_flag = mmio_read_32(SPM_SW_FLAG); + wakesta->sw_flag1 = mmio_read_32(SPM_SW_RSV_2); + wakesta->r15 = mmio_read_32(PCM_REG15_DATA); + wakesta->debug_flag = mmio_read_32(SPM_SW_DEBUG); + wakesta->debug_flag1 = mmio_read_32(WDT_LATCH_SPARE0_FIX); + wakesta->event_reg = mmio_read_32(SPM_BSI_D2_SR); + wakesta->isr = mmio_read_32(SPM_IRQ_STA); +} + +void spm_clean_after_wakeup(void) +{ + mmio_write_32(SPM_SW_RSV_0, + mmio_read_32(SPM_WAKEUP_STA) | + mmio_read_32(SPM_SW_RSV_0)); + mmio_write_32(SPM_CPU_WAKEUP_EVENT, 0); + mmio_write_32(SPM_WAKEUP_EVENT_MASK, ~0); + mmio_setbits_32(SPM_IRQ_MASK, ISRM_ALL_EXC_TWAM); + mmio_write_32(SPM_IRQ_STA, ISRC_ALL_EXC_TWAM); + mmio_write_32(SPM_SWINT_CLR, PCM_SW_INT_ALL); +} + +void spm_output_wake_reason(struct wake_status *wakesta, const char *scenario) +{ + uint32_t i; + + if (wakesta->assert_pc != 0) { + INFO("%s: PCM ASSERT AT %u, ULPOSC_CON = 0x%x\n", + scenario, wakesta->assert_pc, mmio_read_32(ULPOSC_CON)); + goto spm_debug_flags; + } + + for (i = 0; i <= 31; i++) { + if (wakesta->r12 & (1U << i)) { + INFO("%s: wake up by %s, timer_out = %u\n", + scenario, wakeup_src_str[i], wakesta->timer_out); + break; + } + } + +spm_debug_flags: + INFO("r15 = 0x%x, r13 = 0x%x, debug_flag = 0x%x 0x%x\n", + wakesta->r15, wakesta->r13, wakesta->debug_flag, + wakesta->debug_flag1); + INFO("sw_flag = 0x%x 0x%x, r12 = 0x%x, r12_ext = 0x%x\n", + wakesta->sw_flag, wakesta->sw_flag1, wakesta->r12, + wakesta->r12_ext); + INFO("idle_sta = 0x%x, req_sta = 0x%x, event_reg = 0x%x\n", + wakesta->idle_sta, wakesta->req_sta, wakesta->event_reg); + INFO("isr = 0x%x, raw_sta = 0x%x, raw_ext_sta = 0x%x\n", + wakesta->isr, wakesta->raw_sta, wakesta->raw_ext_sta); + INFO("wake_misc = 0x%x\n", wakesta->wake_misc); +} + +void spm_boot_init(void) +{ + NOTICE("%s() start\n", __func__); + + spm_lock_init(); + mt_spm_pmic_wrap_set_phase(PMIC_WRAP_PHASE_ALLINONE); + + /* Set Vmodem / Vcore DVS init level */ + mmio_clrsetbits_32(SPM_DVS_LEVEL, + SPM_VMODEM_LEVEL_MASK | SPM_VCORE_LEVEL_MASK, + SPM_VMODEM_LEVEL | SPM_VCORE_LEVEL); + + /* switch ck_off/axi_26m control to SPM */ + mmio_setbits_32(CLK_SCP_CFG_0, SPM_CK_OFF_CONTROL); + mmio_setbits_32(CLK_SCP_CFG_1, SPM_AXI_26M_SEL); + + /* switch PLL/CLKSQ control to SPM */ + mmio_clrbits_32(AP_PLL_CON3, SPM_PLL_CONTROL); + mmio_clrbits_32(AP_PLL_CON4, SPM_PLL_OUT_OFF_CONTROL); + mmio_clrbits_32(AP_PLL_CON6, PLL_DLY); + + NOTICE("%s() end\n", __func__); +} diff --git a/plat/mediatek/mt8183/drivers/spm/spm.h b/plat/mediatek/mt8183/drivers/spm/spm.h new file mode 100644 index 000000000..b2e83dc7a --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm.h @@ -0,0 +1,2552 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPM_H +#define SPM_H + +/************************************** + * Define and Declare + **************************************/ + +#define POWERON_CONFIG_EN (SPM_BASE + 0x000) +#define SPM_POWER_ON_VAL0 (SPM_BASE + 0x004) +#define SPM_POWER_ON_VAL1 (SPM_BASE + 0x008) +#define SPM_CLK_CON (SPM_BASE + 0x00C) +#define SPM_CLK_SETTLE (SPM_BASE + 0x010) +#define SPM_AP_STANDBY_CON (SPM_BASE + 0x014) +#define PCM_CON0 (SPM_BASE + 0x018) +#define PCM_CON1 (SPM_BASE + 0x01C) +#define PCM_IM_PTR (SPM_BASE + 0x020) +#define PCM_IM_LEN (SPM_BASE + 0x024) +#define PCM_REG_DATA_INI (SPM_BASE + 0x028) +#define PCM_PWR_IO_EN (SPM_BASE + 0x02C) +#define PCM_TIMER_VAL (SPM_BASE + 0x030) +#define PCM_WDT_VAL (SPM_BASE + 0x034) +#define PCM_IM_HOST_RW_PTR (SPM_BASE + 0x038) +#define PCM_IM_HOST_RW_DAT (SPM_BASE + 0x03C) +#define PCM_EVENT_VECTOR0 (SPM_BASE + 0x040) +#define PCM_EVENT_VECTOR1 (SPM_BASE + 0x044) +#define PCM_EVENT_VECTOR2 (SPM_BASE + 0x048) +#define PCM_EVENT_VECTOR3 (SPM_BASE + 0x04C) +#define PCM_EVENT_VECTOR4 (SPM_BASE + 0x050) +#define PCM_EVENT_VECTOR5 (SPM_BASE + 0x054) +#define PCM_EVENT_VECTOR6 (SPM_BASE + 0x058) +#define PCM_EVENT_VECTOR7 (SPM_BASE + 0x05C) +#define PCM_EVENT_VECTOR8 (SPM_BASE + 0x060) +#define PCM_EVENT_VECTOR9 (SPM_BASE + 0x064) +#define PCM_EVENT_VECTOR10 (SPM_BASE + 0x068) +#define PCM_EVENT_VECTOR11 (SPM_BASE + 0x06C) +#define PCM_EVENT_VECTOR12 (SPM_BASE + 0x070) +#define PCM_EVENT_VECTOR13 (SPM_BASE + 0x074) +#define PCM_EVENT_VECTOR14 (SPM_BASE + 0x078) +#define PCM_EVENT_VECTOR15 (SPM_BASE + 0x07C) +#define PCM_EVENT_VECTOR_EN (SPM_BASE + 0x080) +#define SPM_SRAM_RSV_CON (SPM_BASE + 0x088) +#define SPM_SWINT (SPM_BASE + 0x08C) +#define SPM_SWINT_SET (SPM_BASE + 0x090) +#define SPM_SWINT_CLR (SPM_BASE + 0x094) +#define SPM_SCP_MAILBOX (SPM_BASE + 0x098) +#define SCP_SPM_MAILBOX (SPM_BASE + 0x09C) +#define SPM_TWAM_CON (SPM_BASE + 0x0A0) +#define SPM_TWAM_WINDOW_LEN (SPM_BASE + 0x0A4) +#define SPM_TWAM_IDLE_SEL (SPM_BASE + 0x0A8) +#define SPM_SCP_IRQ (SPM_BASE + 0x0AC) +#define SPM_CPU_WAKEUP_EVENT (SPM_BASE + 0x0B0) +#define SPM_IRQ_MASK (SPM_BASE + 0x0B4) +#define SPM_SRC_REQ (SPM_BASE + 0x0B8) +#define SPM_SRC_MASK (SPM_BASE + 0x0BC) +#define SPM_SRC2_MASK (SPM_BASE + 0x0C0) +#define SPM_WAKEUP_EVENT_MASK (SPM_BASE + 0x0C4) +#define SPM_WAKEUP_EVENT_EXT_MASK (SPM_BASE + 0x0C8) +#define SPM_TWAM_EVENT_CLEAR (SPM_BASE + 0x0CC) +#define SCP_CLK_CON (SPM_BASE + 0x0D0) +#define PCM_DEBUG_CON (SPM_BASE + 0x0D4) +#define DDR_EN_DBC_LEN (SPM_BASE + 0x0D8) +#define AHB_BUS_CON (SPM_BASE + 0x0DC) +#define SPM_SRC3_MASK (SPM_BASE + 0x0E0) +#define DDR_EN_EMI_DBC_CON (SPM_BASE + 0x0E4) +#define SSPM_CLK_CON (SPM_BASE + 0x0E8) +#define PCM_REG0_DATA (SPM_BASE + 0x100) +#define PCM_REG1_DATA (SPM_BASE + 0x104) +#define PCM_REG2_DATA (SPM_BASE + 0x108) +#define PCM_REG3_DATA (SPM_BASE + 0x10C) +#define PCM_REG4_DATA (SPM_BASE + 0x110) +#define PCM_REG5_DATA (SPM_BASE + 0x114) +#define PCM_REG6_DATA (SPM_BASE + 0x118) +#define PCM_REG7_DATA (SPM_BASE + 0x11C) +#define PCM_REG8_DATA (SPM_BASE + 0x120) +#define PCM_REG9_DATA (SPM_BASE + 0x124) +#define PCM_REG10_DATA (SPM_BASE + 0x128) +#define PCM_REG11_DATA (SPM_BASE + 0x12C) +#define PCM_REG12_DATA (SPM_BASE + 0x130) +#define PCM_REG13_DATA (SPM_BASE + 0x134) +#define PCM_REG14_DATA (SPM_BASE + 0x138) +#define PCM_REG15_DATA (SPM_BASE + 0x13C) +#define PCM_REG12_MASK_B_STA (SPM_BASE + 0x140) +#define PCM_REG12_EXT_DATA (SPM_BASE + 0x144) +#define PCM_REG12_EXT_MASK_B_STA (SPM_BASE + 0x148) +#define PCM_EVENT_REG_STA (SPM_BASE + 0x14C) +#define PCM_TIMER_OUT (SPM_BASE + 0x150) +#define PCM_WDT_OUT (SPM_BASE + 0x154) +#define SPM_IRQ_STA (SPM_BASE + 0x158) +#define SPM_WAKEUP_STA (SPM_BASE + 0x15C) +#define SPM_WAKEUP_EXT_STA (SPM_BASE + 0x160) +#define SPM_WAKEUP_MISC (SPM_BASE + 0x164) +#define BUS_PROTECT_RDY (SPM_BASE + 0x168) +#define BUS_PROTECT2_RDY (SPM_BASE + 0x16C) +#define SUBSYS_IDLE_STA (SPM_BASE + 0x170) +#define CPU_IDLE_STA (SPM_BASE + 0x174) +#define PCM_FSM_STA (SPM_BASE + 0x178) +#define SRC_REQ_STA (SPM_BASE + 0x17C) +#define PWR_STATUS (SPM_BASE + 0x180) +#define PWR_STATUS_2ND (SPM_BASE + 0x184) +#define CPU_PWR_STATUS (SPM_BASE + 0x188) +#define CPU_PWR_STATUS_2ND (SPM_BASE + 0x18C) +#define MISC_STA (SPM_BASE + 0x190) +#define SPM_SRC_RDY_STA (SPM_BASE + 0x194) +#define DRAMC_DBG_LATCH (SPM_BASE + 0x19C) +#define SPM_TWAM_LAST_STA0 (SPM_BASE + 0x1A0) +#define SPM_TWAM_LAST_STA1 (SPM_BASE + 0x1A4) +#define SPM_TWAM_LAST_STA2 (SPM_BASE + 0x1A8) +#define SPM_TWAM_LAST_STA3 (SPM_BASE + 0x1AC) +#define SPM_TWAM_CURR_STA0 (SPM_BASE + 0x1B0) +#define SPM_TWAM_CURR_STA1 (SPM_BASE + 0x1B4) +#define SPM_TWAM_CURR_STA2 (SPM_BASE + 0x1B8) +#define SPM_TWAM_CURR_STA3 (SPM_BASE + 0x1BC) +#define SPM_TWAM_TIMER_OUT (SPM_BASE + 0x1C0) +#define SPM_DVFS_STA (SPM_BASE + 0x1C8) +#define BUS_PROTECT3_RDY (SPM_BASE + 0x1CC) +#define SRC_DDREN_STA (SPM_BASE + 0x1E0) +#define MCU_PWR_CON (SPM_BASE + 0x200) +#define MP0_CPUTOP_PWR_CON (SPM_BASE + 0x204) +#define MP0_CPU0_PWR_CON (SPM_BASE + 0x208) +#define MP0_CPU1_PWR_CON (SPM_BASE + 0x20C) +#define MP0_CPU2_PWR_CON (SPM_BASE + 0x210) +#define MP0_CPU3_PWR_CON (SPM_BASE + 0x214) +#define MP1_CPUTOP_PWR_CON (SPM_BASE + 0x218) +#define MP1_CPU0_PWR_CON (SPM_BASE + 0x21C) +#define MP1_CPU1_PWR_CON (SPM_BASE + 0x220) +#define MP1_CPU2_PWR_CON (SPM_BASE + 0x224) +#define MP1_CPU3_PWR_CON (SPM_BASE + 0x228) +#define MP0_CPUTOP_L2_PDN (SPM_BASE + 0x240) +#define MP0_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x244) +#define MP0_CPU0_L1_PDN (SPM_BASE + 0x248) +#define MP0_CPU1_L1_PDN (SPM_BASE + 0x24C) +#define MP0_CPU2_L1_PDN (SPM_BASE + 0x250) +#define MP0_CPU3_L1_PDN (SPM_BASE + 0x254) +#define MP1_CPUTOP_L2_PDN (SPM_BASE + 0x258) +#define MP1_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x25C) +#define MP1_CPU0_L1_PDN (SPM_BASE + 0x260) +#define MP1_CPU1_L1_PDN (SPM_BASE + 0x264) +#define MP1_CPU2_L1_PDN (SPM_BASE + 0x268) +#define MP1_CPU3_L1_PDN (SPM_BASE + 0x26C) +#define CPU_EXT_BUCK_ISO (SPM_BASE + 0x290) +#define DUMMY1_PWR_CON (SPM_BASE + 0x2B0) +#define BYPASS_SPMC (SPM_BASE + 0x2B4) +#define SPMC_DORMANT_ENABLE (SPM_BASE + 0x2B8) +#define ARMPLL_CLK_CON (SPM_BASE + 0x2BC) +#define SPMC_IN_RET (SPM_BASE + 0x2C0) +#define VDE_PWR_CON (SPM_BASE + 0x300) +#define VEN_PWR_CON (SPM_BASE + 0x304) +#define ISP_PWR_CON (SPM_BASE + 0x308) +#define DIS_PWR_CON (SPM_BASE + 0x30C) +#define MFG_CORE1_PWR_CON (SPM_BASE + 0x310) +#define AUDIO_PWR_CON (SPM_BASE + 0x314) +#define IFR_PWR_CON (SPM_BASE + 0x318) +#define DPY_PWR_CON (SPM_BASE + 0x31C) +#define MD1_PWR_CON (SPM_BASE + 0x320) +#define VPU_TOP_PWR_CON (SPM_BASE + 0x324) +#define CONN_PWR_CON (SPM_BASE + 0x32C) +#define VPU_CORE2_PWR_CON (SPM_BASE + 0x330) +#define MFG_ASYNC_PWR_CON (SPM_BASE + 0x334) +#define MFG_PWR_CON (SPM_BASE + 0x338) +#define VPU_CORE0_PWR_CON (SPM_BASE + 0x33C) +#define VPU_CORE1_PWR_CON (SPM_BASE + 0x340) +#define CAM_PWR_CON (SPM_BASE + 0x344) +#define MFG_2D_PWR_CON (SPM_BASE + 0x348) +#define MFG_CORE0_PWR_CON (SPM_BASE + 0x34C) +#define SYSRAM_CON (SPM_BASE + 0x350) +#define SYSROM_CON (SPM_BASE + 0x354) +#define SSPM_SRAM_CON (SPM_BASE + 0x358) +#define SCP_SRAM_CON (SPM_BASE + 0x35C) +#define UFS_SRAM_CON (SPM_BASE + 0x36C) +#define DUMMY_SRAM_CON (SPM_BASE + 0x380) +#define MD_EXT_BUCK_ISO_CON (SPM_BASE + 0x390) +#define MD_SRAM_ISO_CON (SPM_BASE + 0x394) +#define MD_EXTRA_PWR_CON (SPM_BASE + 0x398) +#define EXT_BUCK_CON (SPM_BASE + 0x3A0) +#define MBIST_EFUSE_REPAIR_ACK_STA (SPM_BASE + 0x3D0) +#define SPM_DVFS_CON (SPM_BASE + 0x400) +#define SPM_MDBSI_CON (SPM_BASE + 0x404) +#define SPM_MAS_PAUSE_MASK_B (SPM_BASE + 0x408) +#define SPM_MAS_PAUSE2_MASK_B (SPM_BASE + 0x40C) +#define SPM_BSI_GEN (SPM_BASE + 0x410) +#define SPM_BSI_EN_SR (SPM_BASE + 0x414) +#define SPM_BSI_CLK_SR (SPM_BASE + 0x418) +#define SPM_BSI_D0_SR (SPM_BASE + 0x41C) +#define SPM_BSI_D1_SR (SPM_BASE + 0x420) +#define SPM_BSI_D2_SR (SPM_BASE + 0x424) +#define SPM_AP_SEMA (SPM_BASE + 0x428) +#define SPM_SPM_SEMA (SPM_BASE + 0x42C) +#define AP_MDSRC_REQ (SPM_BASE + 0x430) +#define SPM2MD_DVFS_CON (SPM_BASE + 0x438) +#define MD2SPM_DVFS_CON (SPM_BASE + 0x43C) +#define DRAMC_DPY_CLK_SW_CON_RSV (SPM_BASE + 0x440) +#define DPY_LP_CON (SPM_BASE + 0x444) +#define CPU_DVFS_REQ (SPM_BASE + 0x448) +#define SPM_PLL_CON (SPM_BASE + 0x44C) +#define SPM_EMI_BW_MODE (SPM_BASE + 0x450) +#define AP2MD_PEER_WAKEUP (SPM_BASE + 0x454) +#define ULPOSC_CON (SPM_BASE + 0x458) +#define SPM2MM_CON (SPM_BASE + 0x45C) +#define DRAMC_DPY_CLK_SW_CON_SEL (SPM_BASE + 0x460) +#define DRAMC_DPY_CLK_SW_CON (SPM_BASE + 0x464) +#define SPM_S1_MODE_CH (SPM_BASE + 0x468) +#define EMI_SELF_REFRESH_CH_STA (SPM_BASE + 0x46C) +#define DRAMC_DPY_CLK_SW_CON_SEL2 (SPM_BASE + 0x470) +#define DRAMC_DPY_CLK_SW_CON2 (SPM_BASE + 0x474) +#define DRAMC_DMYRD_CON (SPM_BASE + 0x478) +#define SPM_DRS_CON (SPM_BASE + 0x47C) +#define SPM_SEMA_M0 (SPM_BASE + 0x480) +#define SPM_SEMA_M1 (SPM_BASE + 0x484) +#define SPM_SEMA_M2 (SPM_BASE + 0x488) +#define SPM_SEMA_M3 (SPM_BASE + 0x48C) +#define SPM_SEMA_M4 (SPM_BASE + 0x490) +#define SPM_SEMA_M5 (SPM_BASE + 0x494) +#define SPM_SEMA_M6 (SPM_BASE + 0x498) +#define SPM_SEMA_M7 (SPM_BASE + 0x49C) +#define SPM_MAS_PAUSE_MM_MASK_B (SPM_BASE + 0x4A0) +#define SPM_MAS_PAUSE_MCU_MASK_B (SPM_BASE + 0x4A4) +#define SRAM_DREQ_ACK (SPM_BASE + 0x4AC) +#define SRAM_DREQ_CON (SPM_BASE + 0x4B0) +#define SRAM_DREQ_CON_SET (SPM_BASE + 0x4B4) +#define SRAM_DREQ_CON_CLR (SPM_BASE + 0x4B8) +#define SPM2EMI_ENTER_ULPM (SPM_BASE + 0x4BC) +#define SPM_SSPM_IRQ (SPM_BASE + 0x4C0) +#define SPM2PMCU_INT (SPM_BASE + 0x4C4) +#define SPM2PMCU_INT_SET (SPM_BASE + 0x4C8) +#define SPM2PMCU_INT_CLR (SPM_BASE + 0x4CC) +#define SPM2PMCU_MAILBOX_0 (SPM_BASE + 0x4D0) +#define SPM2PMCU_MAILBOX_1 (SPM_BASE + 0x4D4) +#define SPM2PMCU_MAILBOX_2 (SPM_BASE + 0x4D8) +#define SPM2PMCU_MAILBOX_3 (SPM_BASE + 0x4DC) +#define PMCU2SPM_INT (SPM_BASE + 0x4E0) +#define PMCU2SPM_INT_SET (SPM_BASE + 0x4E4) +#define PMCU2SPM_INT_CLR (SPM_BASE + 0x4E8) +#define PMCU2SPM_MAILBOX_0 (SPM_BASE + 0x4EC) +#define PMCU2SPM_MAILBOX_1 (SPM_BASE + 0x4F0) +#define PMCU2SPM_MAILBOX_2 (SPM_BASE + 0x4F4) +#define PMCU2SPM_MAILBOX_3 (SPM_BASE + 0x4F8) +#define PMCU2SPM_CFG (SPM_BASE + 0x4FC) +#define MP0_CPU0_IRQ_MASK (SPM_BASE + 0x500) +#define MP0_CPU1_IRQ_MASK (SPM_BASE + 0x504) +#define MP0_CPU2_IRQ_MASK (SPM_BASE + 0x508) +#define MP0_CPU3_IRQ_MASK (SPM_BASE + 0x50C) +#define MP1_CPU0_IRQ_MASK (SPM_BASE + 0x510) +#define MP1_CPU1_IRQ_MASK (SPM_BASE + 0x514) +#define MP1_CPU2_IRQ_MASK (SPM_BASE + 0x518) +#define MP1_CPU3_IRQ_MASK (SPM_BASE + 0x51C) +#define MP0_CPU0_WFI_EN (SPM_BASE + 0x530) +#define MP0_CPU1_WFI_EN (SPM_BASE + 0x534) +#define MP0_CPU2_WFI_EN (SPM_BASE + 0x538) +#define MP0_CPU3_WFI_EN (SPM_BASE + 0x53C) +#define MP1_CPU0_WFI_EN (SPM_BASE + 0x540) +#define MP1_CPU1_WFI_EN (SPM_BASE + 0x544) +#define MP1_CPU2_WFI_EN (SPM_BASE + 0x548) +#define MP1_CPU3_WFI_EN (SPM_BASE + 0x54C) +#define MP0_L2CFLUSH (SPM_BASE + 0x554) +#define MP1_L2CFLUSH (SPM_BASE + 0x558) +#define CPU_PTPOD2_CON (SPM_BASE + 0x560) +#define ROOT_CPUTOP_ADDR (SPM_BASE + 0x570) +#define ROOT_CORE_ADDR (SPM_BASE + 0x574) +#define CPU_SPARE_CON (SPM_BASE + 0x580) +#define CPU_SPARE_CON_SET (SPM_BASE + 0x584) +#define CPU_SPARE_CON_CLR (SPM_BASE + 0x588) +#define SPM2SW_MAILBOX_0 (SPM_BASE + 0x5D0) +#define SPM2SW_MAILBOX_1 (SPM_BASE + 0x5D4) +#define SPM2SW_MAILBOX_2 (SPM_BASE + 0x5D8) +#define SPM2SW_MAILBOX_3 (SPM_BASE + 0x5DC) +#define SW2SPM_INT (SPM_BASE + 0x5E0) +#define SW2SPM_INT_SET (SPM_BASE + 0x5E4) +#define SW2SPM_INT_CLR (SPM_BASE + 0x5E8) +#define SW2SPM_MAILBOX_0 (SPM_BASE + 0x5EC) +#define SW2SPM_MAILBOX_1 (SPM_BASE + 0x5F0) +#define SW2SPM_MAILBOX_2 (SPM_BASE + 0x5F4) +#define SW2SPM_MAILBOX_3 (SPM_BASE + 0x5F8) +#define SW2SPM_CFG (SPM_BASE + 0x5FC) +#define SPM_SW_FLAG (SPM_BASE + 0x600) +#define SPM_SW_DEBUG (SPM_BASE + 0x604) +#define SPM_SW_RSV_0 (SPM_BASE + 0x608) +#define SPM_SW_RSV_1 (SPM_BASE + 0x60C) +#define SPM_SW_RSV_2 (SPM_BASE + 0x610) +#define SPM_SW_RSV_3 (SPM_BASE + 0x614) +#define SPM_SW_RSV_4 (SPM_BASE + 0x618) +#define SPM_SW_RSV_5 (SPM_BASE + 0x61C) +#define SPM_RSV_CON (SPM_BASE + 0x620) +#define SPM_RSV_STA (SPM_BASE + 0x624) +#define SPM_RSV_CON1 (SPM_BASE + 0x628) +#define SPM_RSV_STA1 (SPM_BASE + 0x62C) +#define SPM_PASR_DPD_0 (SPM_BASE + 0x630) +#define SPM_PASR_DPD_1 (SPM_BASE + 0x634) +#define SPM_PASR_DPD_2 (SPM_BASE + 0x638) +#define SPM_PASR_DPD_3 (SPM_BASE + 0x63C) +#define SPM_SPARE_CON (SPM_BASE + 0x640) +#define SPM_SPARE_CON_SET (SPM_BASE + 0x644) +#define SPM_SPARE_CON_CLR (SPM_BASE + 0x648) +#define SPM_SW_RSV_6 (SPM_BASE + 0x64C) +#define SPM_SW_RSV_7 (SPM_BASE + 0x650) +#define SPM_SW_RSV_8 (SPM_BASE + 0x654) +#define SPM_SW_RSV_9 (SPM_BASE + 0x658) +#define SPM_SW_RSV_10 (SPM_BASE + 0x65C) +#define SPM_SW_RSV_18 (SPM_BASE + 0x67C) +#define SPM_SW_RSV_19 (SPM_BASE + 0x680) +#define DVFSRC_EVENT_MASK_CON (SPM_BASE + 0x690) +#define DVFSRC_EVENT_FORCE_ON (SPM_BASE + 0x694) +#define DVFSRC_EVENT_SEL (SPM_BASE + 0x698) +#define SPM_DVFS_EVENT_STA (SPM_BASE + 0x69C) +#define SPM_DVFS_EVENT_STA1 (SPM_BASE + 0x6A0) +#define SPM_DVFS_LEVEL (SPM_BASE + 0x6A4) +#define DVFS_ABORT_STA (SPM_BASE + 0x6A8) +#define DVFS_ABORT_OTHERS_MASK (SPM_BASE + 0x6AC) +#define SPM_DFS_LEVEL (SPM_BASE + 0x6B0) +#define SPM_DVS_LEVEL (SPM_BASE + 0x6B4) +#define SPM_DVFS_MISC (SPM_BASE + 0x6B8) +#define SPARE_SRC_REQ_MASK (SPM_BASE + 0x6C0) +#define SCP_VCORE_LEVEL (SPM_BASE + 0x6C4) +#define SC_MM_CK_SEL_CON (SPM_BASE + 0x6C8) +#define SPARE_ACK_STA (SPM_BASE + 0x6F0) +#define SPARE_ACK_MASK (SPM_BASE + 0x6F4) +#define SPM_DVFS_CON1 (SPM_BASE + 0x700) +#define SPM_DVFS_CON1_STA (SPM_BASE + 0x704) +#define SPM_DVFS_CMD0 (SPM_BASE + 0x710) +#define SPM_DVFS_CMD1 (SPM_BASE + 0x714) +#define SPM_DVFS_CMD2 (SPM_BASE + 0x718) +#define SPM_DVFS_CMD3 (SPM_BASE + 0x71C) +#define SPM_DVFS_CMD4 (SPM_BASE + 0x720) +#define SPM_DVFS_CMD5 (SPM_BASE + 0x724) +#define SPM_DVFS_CMD6 (SPM_BASE + 0x728) +#define SPM_DVFS_CMD7 (SPM_BASE + 0x72C) +#define SPM_DVFS_CMD8 (SPM_BASE + 0x730) +#define SPM_DVFS_CMD9 (SPM_BASE + 0x734) +#define SPM_DVFS_CMD10 (SPM_BASE + 0x738) +#define SPM_DVFS_CMD11 (SPM_BASE + 0x73C) +#define SPM_DVFS_CMD12 (SPM_BASE + 0x740) +#define SPM_DVFS_CMD13 (SPM_BASE + 0x744) +#define SPM_DVFS_CMD14 (SPM_BASE + 0x748) +#define SPM_DVFS_CMD15 (SPM_BASE + 0x74C) +#define WDT_LATCH_SPARE0_FIX (SPM_BASE + 0x780) +#define WDT_LATCH_SPARE1_FIX (SPM_BASE + 0x784) +#define WDT_LATCH_SPARE2_FIX (SPM_BASE + 0x788) +#define WDT_LATCH_SPARE3_FIX (SPM_BASE + 0x78C) +#define SPARE_ACK_IN_FIX (SPM_BASE + 0x790) +#define DCHA_LATCH_RSV0_FIX (SPM_BASE + 0x794) +#define DCHB_LATCH_RSV0_FIX (SPM_BASE + 0x798) +#define PCM_WDT_LATCH_0 (SPM_BASE + 0x800) +#define PCM_WDT_LATCH_1 (SPM_BASE + 0x804) +#define PCM_WDT_LATCH_2 (SPM_BASE + 0x808) +#define PCM_WDT_LATCH_3 (SPM_BASE + 0x80C) +#define PCM_WDT_LATCH_4 (SPM_BASE + 0x810) +#define PCM_WDT_LATCH_5 (SPM_BASE + 0x814) +#define PCM_WDT_LATCH_6 (SPM_BASE + 0x818) +#define PCM_WDT_LATCH_7 (SPM_BASE + 0x81C) +#define PCM_WDT_LATCH_8 (SPM_BASE + 0x820) +#define PCM_WDT_LATCH_9 (SPM_BASE + 0x824) +#define WDT_LATCH_SPARE0 (SPM_BASE + 0x828) +#define WDT_LATCH_SPARE1 (SPM_BASE + 0x82C) +#define WDT_LATCH_SPARE2 (SPM_BASE + 0x830) +#define WDT_LATCH_SPARE3 (SPM_BASE + 0x834) +#define PCM_WDT_LATCH_10 (SPM_BASE + 0x838) +#define PCM_WDT_LATCH_11 (SPM_BASE + 0x83C) +#define DCHA_GATING_LATCH_0 (SPM_BASE + 0x840) +#define DCHA_GATING_LATCH_1 (SPM_BASE + 0x844) +#define DCHA_GATING_LATCH_2 (SPM_BASE + 0x848) +#define DCHA_GATING_LATCH_3 (SPM_BASE + 0x84C) +#define DCHA_GATING_LATCH_4 (SPM_BASE + 0x850) +#define DCHA_GATING_LATCH_5 (SPM_BASE + 0x854) +#define DCHA_GATING_LATCH_6 (SPM_BASE + 0x858) +#define DCHA_GATING_LATCH_7 (SPM_BASE + 0x85C) +#define DCHB_GATING_LATCH_0 (SPM_BASE + 0x860) +#define DCHB_GATING_LATCH_1 (SPM_BASE + 0x864) +#define DCHB_GATING_LATCH_2 (SPM_BASE + 0x868) +#define DCHB_GATING_LATCH_3 (SPM_BASE + 0x86C) +#define DCHB_GATING_LATCH_4 (SPM_BASE + 0x870) +#define DCHB_GATING_LATCH_5 (SPM_BASE + 0x874) +#define DCHB_GATING_LATCH_6 (SPM_BASE + 0x878) +#define DCHB_GATING_LATCH_7 (SPM_BASE + 0x87C) +#define DCHA_LATCH_RSV0 (SPM_BASE + 0x880) +#define DCHB_LATCH_RSV0 (SPM_BASE + 0x884) +#define PCM_WDT_LATCH_12 (SPM_BASE + 0x888) +#define PCM_WDT_LATCH_13 (SPM_BASE + 0x88C) +#define SPM_PC_TRACE_CON (SPM_BASE + 0x8C0) +#define SPM_PC_TRACE_G0 (SPM_BASE + 0x8C4) +#define SPM_PC_TRACE_G1 (SPM_BASE + 0x8C8) +#define SPM_PC_TRACE_G2 (SPM_BASE + 0x8CC) +#define SPM_PC_TRACE_G3 (SPM_BASE + 0x8D0) +#define SPM_PC_TRACE_G4 (SPM_BASE + 0x8D4) +#define SPM_PC_TRACE_G5 (SPM_BASE + 0x8D8) +#define SPM_PC_TRACE_G6 (SPM_BASE + 0x8DC) +#define SPM_PC_TRACE_G7 (SPM_BASE + 0x8E0) +#define SPM_ACK_CHK_CON (SPM_BASE + 0x900) +#define SPM_ACK_CHK_PC (SPM_BASE + 0x904) +#define SPM_ACK_CHK_SEL (SPM_BASE + 0x908) +#define SPM_ACK_CHK_TIMER (SPM_BASE + 0x90C) +#define SPM_ACK_CHK_STA (SPM_BASE + 0x910) +#define SPM_ACK_CHK_LATCH (SPM_BASE + 0x914) +#define SPM_ACK_CHK_CON2 (SPM_BASE + 0x920) +#define SPM_ACK_CHK_PC2 (SPM_BASE + 0x924) +#define SPM_ACK_CHK_SEL2 (SPM_BASE + 0x928) +#define SPM_ACK_CHK_TIMER2 (SPM_BASE + 0x92C) +#define SPM_ACK_CHK_STA2 (SPM_BASE + 0x930) +#define SPM_ACK_CHK_LATCH2 (SPM_BASE + 0x934) +#define SPM_ACK_CHK_CON3 (SPM_BASE + 0x940) +#define SPM_ACK_CHK_PC3 (SPM_BASE + 0x944) +#define SPM_ACK_CHK_SEL3 (SPM_BASE + 0x948) +#define SPM_ACK_CHK_TIMER3 (SPM_BASE + 0x94C) +#define SPM_ACK_CHK_STA3 (SPM_BASE + 0x950) +#define SPM_ACK_CHK_LATCH3 (SPM_BASE + 0x954) +#define SPM_ACK_CHK_CON4 (SPM_BASE + 0x960) +#define SPM_ACK_CHK_PC4 (SPM_BASE + 0x964) +#define SPM_ACK_CHK_SEL4 (SPM_BASE + 0x968) +#define SPM_ACK_CHK_TIMER4 (SPM_BASE + 0x96C) +#define SPM_ACK_CHK_STA4 (SPM_BASE + 0x970) +#define SPM_ACK_CHK_LATCH4 (SPM_BASE + 0x974) + +/* POWERON_CONFIG_EN (0x10006000+0x000) */ +#define BCLK_CG_EN_LSB (1U << 0) /* 1b */ +#define MD_BCLK_CG_EN_LSB (1U << 1) /* 1b */ +#define PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* SPM_POWER_ON_VAL0 (0x10006000+0x004) */ +#define POWER_ON_VAL0_LSB (1U << 0) /* 32b */ +/* SPM_POWER_ON_VAL1 (0x10006000+0x008) */ +#define POWER_ON_VAL1_LSB (1U << 0) /* 32b */ +/* SPM_CLK_CON (0x10006000+0x00C) */ +#define SYSCLK0_EN_CTRL_LSB (1U << 0) /* 2b */ +#define SYSCLK1_EN_CTRL_LSB (1U << 2) /* 2b */ +#define SYS_SETTLE_SEL_LSB (1U << 4) /* 1b */ +#define SPM_LOCK_INFRA_DCM_LSB (1U << 5) /* 1b */ +#define EXT_SRCCLKEN_MASK_LSB (1U << 6) /* 3b */ +#define CXO32K_REMOVE_EN_MD1_LSB (1U << 9) /* 1b */ +#define CXO32K_REMOVE_EN_MD2_LSB (1U << 10) /* 1b */ +#define CLKSQ0_SEL_CTRL_LSB (1U << 11) /* 1b */ +#define CLKSQ1_SEL_CTRL_LSB (1U << 12) /* 1b */ +#define SRCLKEN0_EN_LSB (1U << 13) /* 1b */ +#define SRCLKEN1_EN_LSB (1U << 14) /* 1b */ +#define SCP_DCM_EN_LSB (1U << 15) /* 1b */ +#define SYSCLK0_SRC_MASK_B_LSB (1U << 16) /* 7b */ +#define SYSCLK1_SRC_MASK_B_LSB (1U << 23) /* 7b */ +/* SPM_CLK_SETTLE (0x10006000+0x010) */ +#define SYSCLK_SETTLE_LSB (1U << 0) /* 28b */ +/* SPM_AP_STANDBY_CON (0x10006000+0x014) */ +#define WFI_OP_LSB (1U << 0) /* 1b */ +#define MP0_CPUTOP_IDLE_MASK_LSB (1U << 1) /* 1b */ +#define MP1_CPUTOP_IDLE_MASK_LSB (1U << 2) /* 1b */ +#define MCUSYS_IDLE_MASK_LSB (1U << 4) /* 1b */ +#define MM_MASK_B_LSB (1U << 16) /* 2b */ +#define MD_DDR_EN_0_DBC_EN_LSB (1U << 18) /* 1b */ +#define MD_DDR_EN_1_DBC_EN_LSB (1U << 19) /* 1b */ +#define MD_MASK_B_LSB (1U << 20) /* 2b */ +#define SSPM_MASK_B_LSB (1U << 22) /* 1b */ +#define SCP_MASK_B_LSB (1U << 23) /* 1b */ +#define SRCCLKENI_MASK_B_LSB (1U << 24) /* 1b */ +#define MD_APSRC_1_SEL_LSB (1U << 25) /* 1b */ +#define MD_APSRC_0_SEL_LSB (1U << 26) /* 1b */ +#define CONN_DDR_EN_DBC_EN_LSB (1U << 27) /* 1b */ +#define CONN_MASK_B_LSB (1U << 28) /* 1b */ +#define CONN_APSRC_SEL_LSB (1U << 29) /* 1b */ +/* PCM_CON0 (0x10006000+0x018) */ +#define PCM_KICK_L_LSB (1U << 0) /* 1b */ +#define IM_KICK_L_LSB (1U << 1) /* 1b */ +#define PCM_CK_EN_LSB (1U << 2) /* 1b */ +#define EN_IM_SLEEP_DVS_LSB (1U << 3) /* 1b */ +#define IM_AUTO_PDN_EN_LSB (1U << 4) /* 1b */ +#define PCM_SW_RESET_LSB (1U << 15) /* 1b */ +#define PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* PCM_CON1 (0x10006000+0x01C) */ +#define IM_SLAVE_LSB (1U << 0) /* 1b */ +#define IM_SLEEP_LSB (1U << 1) /* 1b */ +#define MIF_APBEN_LSB (1U << 3) /* 1b */ +#define IM_PDN_LSB (1U << 4) /* 1b */ +#define PCM_TIMER_EN_LSB (1U << 5) /* 1b */ +#define IM_NONRP_EN_LSB (1U << 6) /* 1b */ +#define DIS_MIF_PROT_LSB (1U << 7) /* 1b */ +#define PCM_WDT_EN_LSB (1U << 8) /* 1b */ +#define PCM_WDT_WAKE_MODE_LSB (1U << 9) /* 1b */ +#define SPM_SRAM_SLEEP_B_LSB (1U << 10) /* 1b */ +#define SPM_SRAM_ISOINT_B_LSB (1U << 11) /* 1b */ +#define EVENT_LOCK_EN_LSB (1U << 12) /* 1b */ +#define SRCCLKEN_FAST_RESP_LSB (1U << 13) /* 1b */ +#define SCP_APB_INTERNAL_EN_LSB (1U << 14) /* 1b */ +#define PROJECT_CODE_LSB (1U << 16) /* 16b */ +/* PCM_IM_PTR (0x10006000+0x020) */ +#define PCM_IM_PTR_LSB (1U << 0) /* 32b */ +/* PCM_IM_LEN (0x10006000+0x024) */ +#define PCM_IM_LEN_LSB (1U << 0) /* 13b */ +/* PCM_REG_DATA_INI (0x10006000+0x028) */ +#define PCM_REG_DATA_INI_LSB (1U << 0) /* 32b */ +/* PCM_PWR_IO_EN (0x10006000+0x02C) */ +#define PCM_PWR_IO_EN_LSB (1U << 0) /* 8b */ +#define PCM_RF_SYNC_EN_LSB (1U << 16) /* 8b */ +/* PCM_TIMER_VAL (0x10006000+0x030) */ +#define PCM_TIMER_VAL_LSB (1U << 0) /* 32b */ +/* PCM_WDT_VAL (0x10006000+0x034) */ +#define PCM_WDT_VAL_LSB (1U << 0) /* 32b */ +/* PCM_IM_HOST_RW_PTR (0x10006000+0x038) */ +#define PCM_IM_HOST_RW_PTR_LSB (1U << 0) /* 12b */ +#define PCM_IM_HOST_W_EN_LSB (1U << 30) /* 1b */ +#define PCM_IM_HOST_EN_LSB (1U << 31) /* 1b */ +/* PCM_IM_HOST_RW_DAT (0x10006000+0x03C) */ +#define PCM_IM_HOST_RW_DAT_LSB (1U << 0) /* 32b */ +/* PCM_EVENT_VECTOR0 (0x10006000+0x040) */ +#define PCM_EVENT_VECTOR_0_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_0_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_0_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_0_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR1 (0x10006000+0x044) */ +#define PCM_EVENT_VECTOR_1_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_1_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_1_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_1_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR2 (0x10006000+0x048) */ +#define PCM_EVENT_VECTOR_2_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_2_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_2_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_2_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR3 (0x10006000+0x04C) */ +#define PCM_EVENT_VECTOR_3_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_3_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_3_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_3_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR4 (0x10006000+0x050) */ +#define PCM_EVENT_VECTOR_4_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_4_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_4_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_4_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR5 (0x10006000+0x054) */ +#define PCM_EVENT_VECTOR_5_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_5_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_5_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_5_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR6 (0x10006000+0x058) */ +#define PCM_EVENT_VECTOR_6_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_6_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_6_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_6_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR7 (0x10006000+0x05C) */ +#define PCM_EVENT_VECTOR_7_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_7_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_7_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_7_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR8 (0x10006000+0x060) */ +#define PCM_EVENT_VECTOR_8_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_8_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_8_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_8_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR9 (0x10006000+0x064) */ +#define PCM_EVENT_VECTOR_9_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_9_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_9_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_9_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR10 (0x10006000+0x068) */ +#define PCM_EVENT_VECTOR_10_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_10_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_10_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_10_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR11 (0x10006000+0x06C) */ +#define PCM_EVENT_VECTOR_11_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_11_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_11_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_11_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR12 (0x10006000+0x070) */ +#define PCM_EVENT_VECTOR_12_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_12_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_12_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_12_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR13 (0x10006000+0x074) */ +#define PCM_EVENT_VECTOR_13_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_13_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_13_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_13_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR14 (0x10006000+0x078) */ +#define PCM_EVENT_VECTOR_14_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_14_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_14_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_14_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR15 (0x10006000+0x07C) */ +#define PCM_EVENT_VECTOR_15_LSB (1U << 0) /* 6b */ +#define PCM_EVENT_RESUME_15_LSB (1U << 6) /* 1b */ +#define PCM_EVENT_IMMEDIA_15_LSB (1U << 7) /* 1b */ +#define PCM_EVENT_VECTPC_15_LSB (1U << 16) /* 11b */ +/* PCM_EVENT_VECTOR_EN (0x10006000+0x080) */ +#define PCM_EVENT_VECTOR_EN_LSB (1U << 0) /* 16b */ +/* SPM_SRAM_RSV_CON (0x10006000+0x088) */ +#define SPM_SRAM_SLEEP_B_ECO_EN_LSB (1U << 0) /* 1b */ +/* SPM_SWINT (0x10006000+0x08C) */ +#define SPM_SWINT_LSB (1U << 0) /* 10b */ +/* SPM_SWINT_SET (0x10006000+0x090) */ +#define SPM_SWINT_SET_LSB (1U << 0) /* 10b */ +/* SPM_SWINT_CLR (0x10006000+0x094) */ +#define SPM_SWINT_CLR_LSB (1U << 0) /* 10b */ +/* SPM_SCP_MAILBOX (0x10006000+0x098) */ +#define SPM_SCP_MAILBOX_LSB (1U << 0) /* 32b */ +/* SCP_SPM_MAILBOX (0x10006000+0x09C) */ +#define SCP_SPM_MAILBOX_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CON (0x10006000+0x0A0) */ +#define TWAM_ENABLE_LSB (1U << 0) /* 1b */ +#define TWAM_SPEED_MODE_ENABLE_LSB (1U << 1) /* 1b */ +#define TWAM_SW_RST_LSB (1U << 2) /* 1b */ +#define TWAM_MON_TYPE0_LSB (1U << 4) /* 2b */ +#define TWAM_MON_TYPE1_LSB (1U << 6) /* 2b */ +#define TWAM_MON_TYPE2_LSB (1U << 8) /* 2b */ +#define TWAM_MON_TYPE3_LSB (1U << 10) /* 2b */ +#define TWAM_SIGNAL_SEL0_LSB (1U << 12) /* 5b */ +#define TWAM_SIGNAL_SEL1_LSB (1U << 17) /* 5b */ +#define TWAM_SIGNAL_SEL2_LSB (1U << 22) /* 5b */ +#define TWAM_SIGNAL_SEL3_LSB (1U << 27) /* 5b */ +/* SPM_TWAM_WINDOW_LEN (0x10006000+0x0A4) */ +#define TWAM_WINDOW_LEN_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_IDLE_SEL (0x10006000+0x0A8) */ +#define TWAM_IDLE_SEL_LSB (1U << 0) /* 5b */ +/* SPM_SCP_IRQ (0x10006000+0x0AC) */ +#define SPM_SCP_IRQ_LSB (1U << 0) /* 1b */ +#define SPM_SCP_IRQ_SEL_LSB (1U << 4) /* 1b */ +/* SPM_CPU_WAKEUP_EVENT (0x10006000+0x0B0) */ +#define SPM_CPU_WAKEUP_EVENT_LSB (1U << 0) /* 1b */ +/* SPM_IRQ_MASK (0x10006000+0x0B4) */ +#define SPM_TWAM_IRQ_MASK_LSB (1U << 2) /* 1b */ +#define PCM_IRQ_ROOT_MASK_LSB (1U << 3) /* 1b */ +#define SPM_IRQ_MASK_LSB (1U << 8) /* 10b */ +/* SPM_SRC_REQ (0x10006000+0x0B8) */ +#define SPM_APSRC_REQ_LSB (1U << 0) /* 1b */ +#define SPM_F26M_REQ_LSB (1U << 1) /* 1b */ +#define SPM_INFRA_REQ_LSB (1U << 3) /* 1b */ +#define SPM_VRF18_REQ_LSB (1U << 4) /* 1b */ +#define SPM_DDREN_REQ_LSB (1U << 7) /* 1b */ +#define SPM_RSV_SRC_REQ_LSB (1U << 8) /* 3b */ +#define SPM_DDREN_2_REQ_LSB (1U << 11) /* 1b */ +#define CPU_MD_DVFS_SOP_FORCE_ON_LSB (1U << 16) /* 1b */ +/* SPM_SRC_MASK (0x10006000+0x0BC) */ +#define CSYSPWREQ_MASK_LSB (1U << 0) /* 1b */ +#define CCIF0_MD_EVENT_MASK_B_LSB (1U << 1) /* 1b */ +#define CCIF0_AP_EVENT_MASK_B_LSB (1U << 2) /* 1b */ +#define CCIF1_MD_EVENT_MASK_B_LSB (1U << 3) /* 1b */ +#define CCIF1_AP_EVENT_MASK_B_LSB (1U << 4) /* 1b */ +#define CCIF2_MD_EVENT_MASK_B_LSB (1U << 5) /* 1b */ +#define CCIF2_AP_EVENT_MASK_B_LSB (1U << 6) /* 1b */ +#define CCIF3_MD_EVENT_MASK_B_LSB (1U << 7) /* 1b */ +#define CCIF3_AP_EVENT_MASK_B_LSB (1U << 8) /* 1b */ +#define MD_SRCCLKENA_0_INFRA_MASK_B_LSB (1U << 9) /* 1b */ +#define MD_SRCCLKENA_1_INFRA_MASK_B_LSB (1U << 10) /* 1b */ +#define CONN_SRCCLKENA_INFRA_MASK_B_LSB (1U << 11) /* 1b */ +#define UFS_INFRA_REQ_MASK_B_LSB (1U << 12) /* 1b */ +#define SRCCLKENI_INFRA_MASK_B_LSB (1U << 13) /* 1b */ +#define MD_APSRC_REQ_0_INFRA_MASK_B_LSB (1U << 14) /* 1b */ +#define MD_APSRC_REQ_1_INFRA_MASK_B_LSB (1U << 15) /* 1b */ +#define CONN_APSRCREQ_INFRA_MASK_B_LSB (1U << 16) /* 1b */ +#define UFS_SRCCLKENA_MASK_B_LSB (1U << 17) /* 1b */ +#define MD_VRF18_REQ_0_MASK_B_LSB (1U << 18) /* 1b */ +#define MD_VRF18_REQ_1_MASK_B_LSB (1U << 19) /* 1b */ +#define UFS_VRF18_REQ_MASK_B_LSB (1U << 20) /* 1b */ +#define GCE_VRF18_REQ_MASK_B_LSB (1U << 21) /* 1b */ +#define CONN_INFRA_REQ_MASK_B_LSB (1U << 22) /* 1b */ +#define GCE_APSRC_REQ_MASK_B_LSB (1U << 23) /* 1b */ +#define DISP0_APSRC_REQ_MASK_B_LSB (1U << 24) /* 1b */ +#define DISP1_APSRC_REQ_MASK_B_LSB (1U << 25) /* 1b */ +#define MFG_REQ_MASK_B_LSB (1U << 26) /* 1b */ +#define VDEC_REQ_MASK_B_LSB (1U << 27) /* 1b */ +/* SPM_SRC2_MASK (0x10006000+0x0C0) */ +#define MD_DDR_EN_0_MASK_B_LSB (1U << 0) /* 1b */ +#define MD_DDR_EN_1_MASK_B_LSB (1U << 1) /* 1b */ +#define CONN_DDR_EN_MASK_B_LSB (1U << 2) /* 1b */ +#define DDREN_SSPM_APSRC_REQ_MASK_B_LSB (1U << 3) /* 1b */ +#define DDREN_SCP_APSRC_REQ_MASK_B_LSB (1U << 4) /* 1b */ +#define DISP0_DDREN_MASK_B_LSB (1U << 5) /* 1b */ +#define DISP1_DDREN_MASK_B_LSB (1U << 6) /* 1b */ +#define GCE_DDREN_MASK_B_LSB (1U << 7) /* 1b */ +#define DDREN_EMI_SELF_REFRESH_CH0_MASK_B_LSB (1U << 8) /* 1b */ +#define DDREN_EMI_SELF_REFRESH_CH1_MASK_B_LSB (1U << 9) /* 1b */ +/* SPM_WAKEUP_EVENT_MASK (0x10006000+0x0C4) */ +#define SPM_WAKEUP_EVENT_MASK_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_EVENT_EXT_MASK (0x10006000+0x0C8) */ +#define SPM_WAKEUP_EVENT_EXT_MASK_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_EVENT_CLEAR (0x10006000+0x0CC) */ +#define SPM_TWAM_EVENT_CLEAR_LSB (1U << 0) /* 1b */ +/* SCP_CLK_CON (0x10006000+0x0D0) */ +#define SCP_26M_CK_SEL_LSB (1U << 0) /* 1b */ +#define SCP_SECURE_V_REQ_MASK_LSB (1U << 1) /* 1b */ +#define SCP_SLP_REQ_LSB (1U << 2) /* 1b */ +#define SCP_SLP_ACK_LSB (1U << 3) /* 1b */ +/* PCM_DEBUG_CON (0x10006000+0x0D4) */ +#define PCM_DEBUG_OUT_ENABLE_LSB (1U << 0) /* 1b */ +/* DDR_EN_DBC_LEN (0x10006000+0x0D8) */ +#define MD_DDR_EN_0_DBC_LEN_LSB (1U << 0) /* 10b */ +#define MD_DDR_EN_1_DBC_LEN_LSB (1U << 10) /* 10b */ +#define CONN_DDR_EN_DBC_LEN_LSB (1U << 20) /* 10b */ +/* AHB_BUS_CON (0x10006000+0x0DC) */ +#define AHB_HADDR_EXT_LSB (1U << 0) /* 2b */ +#define REG_AHB_LOCK_LSB (1U << 8) /* 1b */ +/* SPM_SRC3_MASK (0x10006000+0x0E0) */ +#define MD_DDR_EN_2_0_MASK_B_LSB (1U << 0) /* 1b */ +#define MD_DDR_EN_2_1_MASK_B_LSB (1U << 1) /* 1b */ +#define CONN_DDR_EN_2_MASK_B_LSB (1U << 2) /* 1b */ +#define DDREN2_SSPM_APSRC_REQ_MASK_B_LSB (1U << 3) /* 1b */ +#define DDREN2_SCP_APSRC_REQ_MASK_B_LSB (1U << 4) /* 1b */ +#define DISP0_DDREN2_MASK_B_LSB (1U << 5) /* 1b */ +#define DISP1_DDREN2_MASK_B_LSB (1U << 6) /* 1b */ +#define GCE_DDREN2_MASK_B_LSB (1U << 7) /* 1b */ +#define DDREN2_EMI_SELF_REFRESH_CH0_MASK_B_LSB (1U << 8) /* 1b */ +#define DDREN2_EMI_SELF_REFRESH_CH1_MASK_B_LSB (1U << 9) /* 1b */ +/* DDR_EN_EMI_DBC_CON (0x10006000+0x0E4) */ +#define EMI_SELF_REFRESH_CH0_DBC_LEN_LSB (1U << 0) /* 10b */ +#define EMI_SELF_REFRESH_CH0_DBC_EN_LSB (1U << 10) /* 1b */ +#define EMI_SELF_REFRESH_CH1_DBC_LEN_LSB (1U << 16) /* 10b */ +#define EMI_SELF_REFRESH_CH1_DBC_EN_LSB (1U << 26) /* 1b */ +/* SSPM_CLK_CON (0x10006000+0x0E8) */ +#define SSPM_26M_CK_SEL_LSB (1U << 0) /* 1b */ +/* PCM_REG0_DATA (0x10006000+0x100) */ +#define PCM_REG0_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG1_DATA (0x10006000+0x104) */ +#define PCM_REG1_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG2_DATA (0x10006000+0x108) */ +#define PCM_REG2_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG3_DATA (0x10006000+0x10C) */ +#define PCM_REG3_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG4_DATA (0x10006000+0x110) */ +#define PCM_REG4_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG5_DATA (0x10006000+0x114) */ +#define PCM_REG5_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG6_DATA (0x10006000+0x118) */ +#define PCM_REG6_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG7_DATA (0x10006000+0x11C) */ +#define PCM_REG7_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG8_DATA (0x10006000+0x120) */ +#define PCM_REG8_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG9_DATA (0x10006000+0x124) */ +#define PCM_REG9_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG10_DATA (0x10006000+0x128) */ +#define PCM_REG10_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG11_DATA (0x10006000+0x12C) */ +#define PCM_REG11_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG12_DATA (0x10006000+0x130) */ +#define PCM_REG12_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG13_DATA (0x10006000+0x134) */ +#define PCM_REG13_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG14_DATA (0x10006000+0x138) */ +#define PCM_REG14_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG15_DATA (0x10006000+0x13C) */ +#define PCM_REG15_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG12_MASK_B_STA (0x10006000+0x140) */ +#define PCM_REG12_MASK_B_STA_LSB (1U << 0) /* 32b */ +/* PCM_REG12_EXT_DATA (0x10006000+0x144) */ +#define PCM_REG12_EXT_DATA_LSB (1U << 0) /* 32b */ +/* PCM_REG12_EXT_MASK_B_STA (0x10006000+0x148) */ +#define PCM_REG12_EXT_MASK_B_STA_LSB (1U << 0) /* 32b */ +/* PCM_EVENT_REG_STA (0x10006000+0x14C) */ +#define PCM_EVENT_REG_STA_LSB (1U << 0) /* 32b */ +/* PCM_TIMER_OUT (0x10006000+0x150) */ +#define PCM_TIMER_OUT_LSB (1U << 0) /* 32b */ +/* PCM_WDT_OUT (0x10006000+0x154) */ +#define PCM_WDT_OUT_LSB (1U << 0) /* 32b */ +/* SPM_IRQ_STA (0x10006000+0x158) */ +#define SPM_ACK_CHK_WAKEUP_LSB (1U << 1) /* 1b */ +#define TWAM_IRQ_LSB (1U << 2) /* 1b */ +#define PCM_IRQ_LSB (1U << 3) /* 1b */ +/* #define SPM_SWINT_LSB (1U << 4) */ /* 10b */ +/* SPM_WAKEUP_STA (0x10006000+0x15C) */ +#define SPM_WAKEUP_EVENT_STA_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_EXT_STA (0x10006000+0x160) */ +#define SPM_WAKEUP_EVENT_EXT_STA_LSB (1U << 0) /* 32b */ +/* SPM_WAKEUP_MISC (0x10006000+0x164) */ +#define SPM_WAKEUP_EVENT_MISC_LSB (1U << 0) /* 30b */ +#define SPM_PWRAP_IRQ_ACK_LSB (1U << 30) /* 1b */ +#define SPM_PWRAP_IRQ_LSB (1U << 31) /* 1b */ +/* BUS_PROTECT_RDY (0x10006000+0x168) */ +#define BUS_PROTECT_RDY_LSB (1U << 0) /* 32b */ +/* BUS_PROTECT2_RDY (0x10006000+0x16C) */ +#define BUS_PROTECT2_RDY_LSB (1U << 0) /* 32b */ +/* SUBSYS_IDLE_STA (0x10006000+0x170) */ +#define SUBSYS_IDLE_STA_LSB (1U << 0) /* 32b */ +/* CPU_IDLE_STA (0x10006000+0x174) */ +#define MP0_CPU0_STANDBYWFI_AFTER_SEL_LSB (1U << 0) /* 1b */ +#define MP0_CPU1_STANDBYWFI_AFTER_SEL_LSB (1U << 1) /* 1b */ +#define MP0_CPU2_STANDBYWFI_AFTER_SEL_LSB (1U << 2) /* 1b */ +#define MP0_CPU3_STANDBYWFI_AFTER_SEL_LSB (1U << 3) /* 1b */ +#define MP1_CPU0_STANDBYWFI_AFTER_SEL_LSB (1U << 4) /* 1b */ +#define MP1_CPU1_STANDBYWFI_AFTER_SEL_LSB (1U << 5) /* 1b */ +#define MP1_CPU2_STANDBYWFI_AFTER_SEL_LSB (1U << 6) /* 1b */ +#define MP1_CPU3_STANDBYWFI_AFTER_SEL_LSB (1U << 7) /* 1b */ +#define MP0_CPU0_STANDBYWFI_LSB (1U << 10) /* 1b */ +#define MP0_CPU1_STANDBYWFI_LSB (1U << 11) /* 1b */ +#define MP0_CPU2_STANDBYWFI_LSB (1U << 12) /* 1b */ +#define MP0_CPU3_STANDBYWFI_LSB (1U << 13) /* 1b */ +#define MP1_CPU0_STANDBYWFI_LSB (1U << 14) /* 1b */ +#define MP1_CPU1_STANDBYWFI_LSB (1U << 15) /* 1b */ +#define MP1_CPU2_STANDBYWFI_LSB (1U << 16) /* 1b */ +#define MP1_CPU3_STANDBYWFI_LSB (1U << 17) /* 1b */ +#define MP0_CPUTOP_IDLE_LSB (1U << 20) /* 1b */ +#define MP1_CPUTOP_IDLE_LSB (1U << 21) /* 1b */ +#define MCU_BIU_IDLE_LSB (1U << 22) /* 1b */ +#define MCUSYS_IDLE_LSB (1U << 23) /* 1b */ +/* PCM_FSM_STA (0x10006000+0x178) */ +#define EXEC_INST_OP_LSB (1U << 0) /* 4b */ +#define PC_STATE_LSB (1U << 4) /* 3b */ +#define IM_STATE_LSB (1U << 7) /* 3b */ +#define MASTER_STATE_LSB (1U << 10) /* 5b */ +#define EVENT_FSM_LSB (1U << 15) /* 3b */ +#define PCM_CLK_SEL_STA_LSB (1U << 18) /* 3b */ +#define PCM_KICK_LSB (1U << 21) /* 1b */ +#define IM_KICK_LSB (1U << 22) /* 1b */ +#define EXT_SRCCLKEN_STA_LSB (1U << 23) /* 2b */ +#define EXT_SRCVOLTEN_STA_LSB (1U << 25) /* 1b */ +/* SRC_REQ_STA (0x10006000+0x17C) */ +#define SRC_REQ_STA_LSB (1U << 0) /* 32b */ +/* PWR_STATUS (0x10006000+0x180) */ +#define PWR_STATUS_LSB (1U << 0) /* 32b */ +/* PWR_STATUS_2ND (0x10006000+0x184) */ +#define PWR_STATUS_2ND_LSB (1U << 0) /* 32b */ +/* CPU_PWR_STATUS (0x10006000+0x188) */ +#define CPU_PWR_STATUS_LSB (1U << 0) /* 32b */ +/* CPU_PWR_STATUS_2ND (0x10006000+0x18C) */ +#define CPU_PWR_STATUS_2ND_LSB (1U << 0) /* 32b */ +/* MISC_STA (0x10006000+0x190) */ +#define MM_DVFS_HALT_AF_MASK_LSB (1U << 0) /* 5b */ +/* SPM_SRC_RDY_STA (0x10006000+0x194) */ +#define SPM_INFRA_SRC_ACK_LSB (1U << 0) /* 1b */ +#define SPM_VRF18_SRC_ACK_LSB (1U << 1) /* 1b */ +/* DRAMC_DBG_LATCH (0x10006000+0x19C) */ +#define DRAMC_DEBUG_LATCH_STATUS_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA0 (0x10006000+0x1A0) */ +#define SPM_TWAM_LAST_STA0_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA1 (0x10006000+0x1A4) */ +#define SPM_TWAM_LAST_STA1_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA2 (0x10006000+0x1A8) */ +#define SPM_TWAM_LAST_STA2_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_LAST_STA3 (0x10006000+0x1AC) */ +#define SPM_TWAM_LAST_STA3_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA0 (0x10006000+0x1B0) */ +#define SPM_TWAM_CURR_STA0_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA1 (0x10006000+0x1B4) */ +#define SPM_TWAM_CURR_STA1_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA2 (0x10006000+0x1B8) */ +#define SPM_TWAM_CURR_STA2_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_CURR_STA3 (0x10006000+0x1BC) */ +#define SPM_TWAM_CURR_STA3_LSB (1U << 0) /* 32b */ +/* SPM_TWAM_TIMER_OUT (0x10006000+0x1C0) */ +#define SPM_TWAM_TIMER_OUT_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_STA (0x10006000+0x1C8) */ +#define MD_DVFS_ERROR_STATUS_LSB (1U << 0) /* 1b */ +/* BUS_PROTECT3_RDY (0x10006000+0x1CC) */ +#define BUS_PROTECT_MM_RDY_LSB (1U << 0) /* 16b */ +#define BUS_PROTECT_MCU_RDY_LSB (1U << 16) /* 16b */ +/* SRC_DDREN_STA (0x10006000+0x1E0) */ +#define SRC_DDREN_STA_LSB (1U << 0) /* 32b */ +/* MCU_PWR_CON (0x10006000+0x200) */ +#define MCU_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MCU_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MCU_PWR_ON_LSB (1U << 2) /* 1b */ +#define MCU_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MCU_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MCU_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MCU_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MCU_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MCU_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MCU_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MCU_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MCU_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPUTOP_PWR_CON (0x10006000+0x204) */ +#define MP0_CPUTOP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP0_CPUTOP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP0_CPUTOP_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP0_CPUTOP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP0_CPUTOP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP0_CPUTOP_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP0_CPUTOP_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP0_CPUTOP_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP0_CPUTOP_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP0_CPUTOP_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP0_CPUTOP_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP0_CPUTOP_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPU0_PWR_CON (0x10006000+0x208) */ +#define MP0_CPU0_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP0_CPU0_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP0_CPU0_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP0_CPU0_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP0_CPU0_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP0_CPU0_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP0_CPU0_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP0_CPU0_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP0_CPU0_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP0_CPU0_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP0_CPU0_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP0_CPU0_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPU1_PWR_CON (0x10006000+0x20C) */ +#define MP0_CPU1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP0_CPU1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP0_CPU1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP0_CPU1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP0_CPU1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP0_CPU1_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP0_CPU1_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP0_CPU1_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP0_CPU1_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP0_CPU1_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP0_CPU1_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP0_CPU1_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPU2_PWR_CON (0x10006000+0x210) */ +#define MP0_CPU2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP0_CPU2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP0_CPU2_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP0_CPU2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP0_CPU2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP0_CPU2_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP0_CPU2_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP0_CPU2_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP0_CPU2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP0_CPU2_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP0_CPU2_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP0_CPU2_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPU3_PWR_CON (0x10006000+0x214) */ +#define MP0_CPU3_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP0_CPU3_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP0_CPU3_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP0_CPU3_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP0_CPU3_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP0_CPU3_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP0_CPU3_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP0_CPU3_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP0_CPU3_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP0_CPU3_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP0_CPU3_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP0_CPU3_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP1_CPUTOP_PWR_CON (0x10006000+0x218) */ +#define MP1_CPUTOP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP1_CPUTOP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP1_CPUTOP_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP1_CPUTOP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP1_CPUTOP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP1_CPUTOP_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP1_CPUTOP_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP1_CPUTOP_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP1_CPUTOP_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP1_CPUTOP_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP1_CPUTOP_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP1_CPUTOP_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP1_CPU0_PWR_CON (0x10006000+0x21C) */ +#define MP1_CPU0_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP1_CPU0_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP1_CPU0_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP1_CPU0_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP1_CPU0_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP1_CPU0_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP1_CPU0_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP1_CPU0_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP1_CPU0_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP1_CPU0_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP1_CPU0_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP1_CPU0_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP1_CPU1_PWR_CON (0x10006000+0x220) */ +#define MP1_CPU1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP1_CPU1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP1_CPU1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP1_CPU1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP1_CPU1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP1_CPU1_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP1_CPU1_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP1_CPU1_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP1_CPU1_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP1_CPU1_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP1_CPU1_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP1_CPU1_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP1_CPU2_PWR_CON (0x10006000+0x224) */ +#define MP1_CPU2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP1_CPU2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP1_CPU2_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP1_CPU2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP1_CPU2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP1_CPU2_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP1_CPU2_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP1_CPU2_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP1_CPU2_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP1_CPU2_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP1_CPU2_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP1_CPU2_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP1_CPU3_PWR_CON (0x10006000+0x228) */ +#define MP1_CPU3_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MP1_CPU3_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MP1_CPU3_PWR_ON_LSB (1U << 2) /* 1b */ +#define MP1_CPU3_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MP1_CPU3_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MP1_CPU3_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define MP1_CPU3_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define MP1_CPU3_SRAM_PD_SLPB_CLAMP_LSB (1U << 7) /* 1b */ +#define MP1_CPU3_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define MP1_CPU3_SRAM_SLEEP_B_LSB (1U << 12) /* 1b */ +#define SC_MP1_CPU3_SRAM_PDN_ACK_LSB (1U << 24) /* 1b */ +#define SC_MP1_CPU3_SRAM_SLEEP_B_ACK_LSB (1U << 28) /* 1b */ +/* MP0_CPUTOP_L2_PDN (0x10006000+0x240) */ +#define MP0_CPUTOP_L2_SRAM_PDN_LSB (1U << 0) /* 1b */ +#define MP0_CPUTOP_L2_SRAM_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP0_CPUTOP_L2_SLEEP_B (0x10006000+0x244) */ +#define MP0_CPUTOP_L2_SRAM_SLEEP_B_LSB (1U << 0) /* 1b */ +#define MP0_CPUTOP_L2_SRAM_SLEEP_B_ACK_LSB (1U << 8) /* 1b */ +/* MP0_CPU0_L1_PDN (0x10006000+0x248) */ +#define MP0_CPU0_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP0_CPU0_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP0_CPU1_L1_PDN (0x10006000+0x24C) */ +#define MP0_CPU1_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP0_CPU1_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP0_CPU2_L1_PDN (0x10006000+0x250) */ +#define MP0_CPU2_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP0_CPU2_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP0_CPU3_L1_PDN (0x10006000+0x254) */ +#define MP0_CPU3_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP0_CPU3_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPUTOP_L2_PDN (0x10006000+0x258) */ +#define MP1_CPUTOP_L2_SRAM_PDN_LSB (1U << 0) /* 1b */ +#define MP1_CPUTOP_L2_SRAM_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPUTOP_L2_SLEEP_B (0x10006000+0x25C) */ +#define MP1_CPUTOP_L2_SRAM_SLEEP_B_LSB (1U << 0) /* 1b */ +#define MP1_CPUTOP_L2_SRAM_SLEEP_B_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPU0_L1_PDN (0x10006000+0x260) */ +#define MP1_CPU0_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP1_CPU0_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPU1_L1_PDN (0x10006000+0x264) */ +#define MP1_CPU1_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP1_CPU1_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPU2_L1_PDN (0x10006000+0x268) */ +#define MP1_CPU2_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP1_CPU2_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* MP1_CPU3_L1_PDN (0x10006000+0x26C) */ +#define MP1_CPU3_L1_PDN_LSB (1U << 0) /* 1b */ +#define MP1_CPU3_L1_PDN_ACK_LSB (1U << 8) /* 1b */ +/* CPU_EXT_BUCK_ISO (0x10006000+0x290) */ +#define MP0_EXT_BUCK_ISO_LSB (1U << 0) /* 1b */ +#define MP1_EXT_BUCK_ISO_LSB (1U << 1) /* 1b */ +#define MP_EXT_BUCK_ISO_LSB (1U << 2) /* 1b */ +/* DUMMY1_PWR_CON (0x10006000+0x2B0) */ +#define DUMMY1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DUMMY1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DUMMY1_PWR_ON_LSB (1U << 2) /* 1b */ +#define DUMMY1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DUMMY1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +/* BYPASS_SPMC (0x10006000+0x2B4) */ +#define BYPASS_CPU_SPMC_MODE_LSB (1U << 0) /* 1b */ +/* SPMC_DORMANT_ENABLE (0x10006000+0x2B8) */ +#define MP0_SPMC_SRAM_DORMANT_EN_LSB (1U << 0) /* 1b */ +#define MP1_SPMC_SRAM_DORMANT_EN_LSB (1U << 1) /* 1b */ +/* ARMPLL_CLK_CON (0x10006000+0x2BC) */ +#define REG_SC_ARM_FHC_PAUSE_LSB (1U << 0) /* 3b */ +#define REG_SC_ARM_CLK_OFF_LSB (1U << 3) /* 3b */ +#define REG_SC_ARMPLLOUT_OFF_LSB (1U << 6) /* 3b */ +#define REG_SC_ARMPLL_OFF_LSB (1U << 9) /* 3b */ +#define REG_SC_ARMPLL_S_OFF_LSB (1U << 12) /* 3b */ +/* SPMC_IN_RET (0x10006000+0x2C0) */ +#define SPMC_STATUS_LSB (1U << 0) /* 8b */ +/* VDE_PWR_CON (0x10006000+0x300) */ +#define VDE_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VDE_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VDE_PWR_ON_LSB (1U << 2) /* 1b */ +#define VDE_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VDE_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VDE_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VDE_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* VEN_PWR_CON (0x10006000+0x304) */ +#define VEN_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VEN_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VEN_PWR_ON_LSB (1U << 2) /* 1b */ +#define VEN_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VEN_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VEN_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VEN_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* ISP_PWR_CON (0x10006000+0x308) */ +#define ISP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define ISP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define ISP_PWR_ON_LSB (1U << 2) /* 1b */ +#define ISP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define ISP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define ISP_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define ISP_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* DIS_PWR_CON (0x10006000+0x30C) */ +#define DIS_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DIS_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DIS_PWR_ON_LSB (1U << 2) /* 1b */ +#define DIS_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DIS_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DIS_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define DIS_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* MFG_CORE1_PWR_CON (0x10006000+0x310) */ +#define MFG_CORE1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG_CORE1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG_CORE1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG_CORE1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG_CORE1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG_CORE1_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define MFG_CORE1_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* AUDIO_PWR_CON (0x10006000+0x314) */ +#define AUD_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define AUD_PWR_ISO_LSB (1U << 1) /* 1b */ +#define AUD_PWR_ON_LSB (1U << 2) /* 1b */ +#define AUD_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define AUD_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define AUD_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define AUD_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* IFR_PWR_CON (0x10006000+0x318) */ +#define IFR_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define IFR_PWR_ISO_LSB (1U << 1) /* 1b */ +#define IFR_PWR_ON_LSB (1U << 2) /* 1b */ +#define IFR_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define IFR_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define IFR_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define IFR_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* DPY_PWR_CON (0x10006000+0x31C) */ +#define DPY_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define DPY_PWR_ISO_LSB (1U << 1) /* 1b */ +#define DPY_PWR_ON_LSB (1U << 2) /* 1b */ +#define DPY_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define DPY_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define DPY_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define DPY_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* MD1_PWR_CON (0x10006000+0x320) */ +#define MD1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MD1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MD1_PWR_ON_LSB (1U << 2) /* 1b */ +#define MD1_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MD1_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MD1_SRAM_PDN_LSB (1U << 8) /* 1b */ +/* VPU_TOP_PWR_CON (0x10006000+0x324) */ +#define VPU_TOP_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VPU_TOP_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VPU_TOP_PWR_ON_LSB (1U << 2) /* 1b */ +#define VPU_TOP_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VPU_TOP_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VPU_TOP_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define VPU_TOP_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define VPU_TOP_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VPU_TOP_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +#define VPU_TOP_SRAM_SLPB_LSB (1U << 16) /* 4b */ +#define VPU_TOP_SRAM_SLPB_ACK_LSB (1U << 28) /* 4b */ +/* CONN_PWR_CON (0x10006000+0x32C) */ +#define CONN_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CONN_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CONN_PWR_ON_LSB (1U << 2) /* 1b */ +#define CONN_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CONN_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CONN_SRAM_PDN_LSB (1U << 8) /* 1b */ +#define CONN_SRAM_PDN_ACK_LSB (1U << 12) /* 1b */ +/* VPU_CORE2_PWR_CON (0x10006000+0x330) */ +#define VPU_CORE2_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VPU_CORE2_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VPU_CORE2_PWR_ON_LSB (1U << 2) /* 1b */ +#define VPU_CORE2_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define VPU_CORE2_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VPU_CORE2_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define VPU_CORE2_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define VPU_CORE2_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VPU_CORE2_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +#define VPU_CORE2_SRAM_SLPB_LSB (1U << 16) /* 4b */ +#define VPU_CORE2_SRAM_SLPB_ACK_LSB (1U << 28) /* 4b */ +/* MFG_ASYNC_PWR_CON (0x10006000+0x334) */ +#define MFG_ASYNC_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG_ASYNC_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG_ASYNC_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG_ASYNC_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG_ASYNC_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG_ASYNC_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define MFG_ASYNC_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* MFG_PWR_CON (0x10006000+0x338) */ +#define MFG_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define MFG_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* VPU_CORE0_PWR_CON (0x10006000+0x33C) */ +#define VPU_CORE0_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VPU_CORE0_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VPU_CORE0_PWR_ON_LSB (1U << 2) /* 1b */ +#define VPU_CORE0_ON_2ND_LSB (1U << 3) /* 1b */ +#define VPU_CORE0_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VPU_CORE0_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define VPU_CORE0_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define VPU_CORE0_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VPU_CORE0_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +#define VPU_CORE0_SRAM_SLPB_LSB (1U << 16) /* 4b */ +#define VPU_CORE0_SRAM_SLPB_ACK_LSB (1U << 28) /* 4b */ +/* VPU_CORE1_PWR_CON (0x10006000+0x340) */ +#define VPU_CORE1_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define VPU_CORE1_PWR_ISO_LSB (1U << 1) /* 1b */ +#define VPU_CORE1_PWR_ON_LSB (1U << 2) /* 1b */ +#define VPU_CORE1_ON_2ND_LSB (1U << 3) /* 1b */ +#define VPU_CORE1_CLK_DIS_LSB (1U << 4) /* 1b */ +#define VPU_CORE1_SRAM_CKISO_LSB (1U << 5) /* 1b */ +#define VPU_CORE1_SRAM_ISOINT_B_LSB (1U << 6) /* 1b */ +#define VPU_CORE1_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define VPU_CORE1_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +#define VPU_CORE1_SRAM_SLPB_LSB (1U << 16) /* 4b */ +#define VPU_CORE1_SRAM_SLPB_ACK_LSB (1U << 28) /* 4b */ +/* CAM_PWR_CON (0x10006000+0x344) */ +#define CAM_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define CAM_PWR_ISO_LSB (1U << 1) /* 1b */ +#define CAM_PWR_ON_LSB (1U << 2) /* 1b */ +#define CAM_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define CAM_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define CAM_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define CAM_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* MFG_2D_PWR_CON (0x10006000+0x348) */ +#define MFG_2D_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG_2D_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG_2D_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG_2D_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG_2D_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG_2D_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define MFG_2D_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* MFG_CORE0_PWR_CON (0x10006000+0x34C) */ +#define MFG_CORE0_PWR_RST_B_LSB (1U << 0) /* 1b */ +#define MFG_CORE0_PWR_ISO_LSB (1U << 1) /* 1b */ +#define MFG_CORE0_PWR_ON_LSB (1U << 2) /* 1b */ +#define MFG_CORE0_PWR_ON_2ND_LSB (1U << 3) /* 1b */ +#define MFG_CORE0_PWR_CLK_DIS_LSB (1U << 4) /* 1b */ +#define MFG_CORE0_SRAM_PDN_LSB (1U << 8) /* 4b */ +#define MFG_CORE0_SRAM_PDN_ACK_LSB (1U << 12) /* 4b */ +/* SYSRAM_CON (0x10006000+0x350) */ +#define IFR_SRAMROM_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define IFR_SRAMROM_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define IFR_SRAMROM_SRAM_SLEEP_B_LSB (1U << 4) /* 8b */ +#define IFR_SRAMROM_SRAM_PDN_LSB (1U << 16) /* 8b */ +/* SYSROM_CON (0x10006000+0x354) */ +#define IFR_SRAMROM_ROM_PDN_LSB (1U << 0) /* 6b */ +/* SSPM_SRAM_CON (0x10006000+0x358) */ +#define SSPM_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define SSPM_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define SSPM_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define SSPM_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* SCP_SRAM_CON (0x10006000+0x35C) */ +#define SCP_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define SCP_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define SCP_SRAM_SLEEP_B_LSB (1U << 4) /* 1b */ +#define SCP_SRAM_PDN_LSB (1U << 16) /* 1b */ +/* UFS_SRAM_CON (0x10006000+0x36C) */ +#define UFS_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define UFS_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define UFS_SRAM_SLEEP_B_LSB (1U << 4) /* 5b */ +#define UFS_SRAM_PDN_LSB (1U << 16) /* 5b */ +/* DUMMY_SRAM_CON (0x10006000+0x380) */ +#define DUMMY_SRAM_CKISO_LSB (1U << 0) /* 1b */ +#define DUMMY_SRAM_ISOINT_B_LSB (1U << 1) /* 1b */ +#define DUMMY_SRAM_SLEEP_B_LSB (1U << 4) /* 8b */ +#define DUMMY_SRAM_PDN_LSB (1U << 16) /* 8b */ +/* MD_EXT_BUCK_ISO_CON (0x10006000+0x390) */ +#define VMODEM_BUCK_ELS_EN_LSB (1U << 0) /* 1b */ +#define VMD_BUCK_ELS_EN_LSB (1U << 1) /* 1b */ +/* MD_SRAM_ISO_CON (0x10006000+0x394) */ +#define MD1_SRAM_ISOINT_B_LSB (1U << 0) /* 1b */ +/* MD_EXTRA_PWR_CON (0x10006000+0x398) */ +#define MD1_PWR_PROT_REQ_STA_LSB (1U << 0) /* 1b */ +#define MD2_PWR_PROT_REQ_STA_LSB (1U << 1) /* 1b */ +/* EXT_BUCK_CON (0x10006000+0x3A0) */ +#define RG_VA09_ON_LSB (1U << 0) /* 1b */ +/* MBIST_EFUSE_REPAIR_ACK_STA (0x10006000+0x3D0) */ +#define MBIST_EFUSE_REPAIR_ACK_STA_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CON (0x10006000+0x400) */ +#define SPM_DVFS_CON_LSB (1U << 0) /* 4b */ +#define SPM_DVFS_ACK_LSB (1U << 30) /* 2b */ +/* SPM_MDBSI_CON (0x10006000+0x404) */ +#define SPM_MDBSI_CON_LSB (1U << 0) /* 3b */ +/* SPM_MAS_PAUSE_MASK_B (0x10006000+0x408) */ +#define SPM_MAS_PAUSE_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_MAS_PAUSE2_MASK_B (0x10006000+0x40C) */ +#define SPM_MAS_PAUSE2_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_BSI_GEN (0x10006000+0x410) */ +#define SPM_BSI_START_LSB (1U << 0) /* 1b */ +/* SPM_BSI_EN_SR (0x10006000+0x414) */ +#define SPM_BSI_EN_SR_LSB (1U << 0) /* 32b */ +/* SPM_BSI_CLK_SR (0x10006000+0x418) */ +#define SPM_BSI_CLK_SR_LSB (1U << 0) /* 32b */ +/* SPM_BSI_D0_SR (0x10006000+0x41C) */ +#define SPM_BSI_D0_SR_LSB (1U << 0) /* 32b */ +/* SPM_BSI_D1_SR (0x10006000+0x420) */ +#define SPM_BSI_D1_SR_LSB (1U << 0) /* 32b */ +/* SPM_BSI_D2_SR (0x10006000+0x424) */ +#define SPM_BSI_D2_SR_LSB (1U << 0) /* 32b */ +/* SPM_AP_SEMA (0x10006000+0x428) */ +#define SPM_AP_SEMA_LSB (1U << 0) /* 1b */ +/* SPM_SPM_SEMA (0x10006000+0x42C) */ +#define SPM_SPM_SEMA_LSB (1U << 0) /* 1b */ +/* AP_MDSRC_REQ (0x10006000+0x430) */ +#define AP_MDSMSRC_REQ_LSB (1U << 0) /* 1b */ +#define AP_L1SMSRC_REQ_LSB (1U << 1) /* 1b */ +#define AP_MD2SRC_REQ_LSB (1U << 2) /* 1b */ +#define AP_MDSMSRC_ACK_LSB (1U << 4) /* 1b */ +#define AP_L1SMSRC_ACK_LSB (1U << 5) /* 1b */ +#define AP_MD2SRC_ACK_LSB (1U << 6) /* 1b */ +/* SPM2MD_DVFS_CON (0x10006000+0x438) */ +#define SPM2MD_DVFS_CON_LSB (1U << 0) /* 32b */ +/* MD2SPM_DVFS_CON (0x10006000+0x43C) */ +#define MD2SPM_DVFS_CON_LSB (1U << 0) /* 32b */ +/* DRAMC_DPY_CLK_SW_CON_RSV (0x10006000+0x440) */ +#define SPM2DRAMC_SHUFFLE_START_LSB (1U << 0) /* 1b */ +#define SPM2DRAMC_SHUFFLE_SWITCH_LSB (1U << 1) /* 1b */ +#define SPM2DPY_DIV2_SYNC_LSB (1U << 2) /* 1b */ +#define SPM2DPY_1PLL_SWITCH_LSB (1U << 3) /* 1b */ +#define SPM2DPY_TEST_CK_MUX_LSB (1U << 4) /* 1b */ +#define SPM2DPY_ASYNC_MODE_LSB (1U << 5) /* 1b */ +#define SPM2TOP_ASYNC_MODE_LSB (1U << 6) /* 1b */ +/* DPY_LP_CON (0x10006000+0x444) */ +#define SC_DDRPHY_LP_SIGNALS_LSB (1U << 0) /* 3b */ +/* CPU_DVFS_REQ (0x10006000+0x448) */ +#define CPU_DVFS_REQ_LSB (1U << 0) /* 32b */ +/* SPM_PLL_CON (0x10006000+0x44C) */ +#define SC_MAINPLLOUT_OFF_LSB (1U << 0) /* 1b */ +#define SC_UNIPLLOUT_OFF_LSB (1U << 1) /* 1b */ +#define SC_MAINPLL_OFF_LSB (1U << 4) /* 1b */ +#define SC_UNIPLL_OFF_LSB (1U << 5) /* 1b */ +#define SC_MAINPLL_S_OFF_LSB (1U << 8) /* 1b */ +#define SC_UNIPLL_S_OFF_LSB (1U << 9) /* 1b */ +#define SC_SMI_CK_OFF_LSB (1U << 16) /* 1b */ +#define SC_SSPMK_CK_OFF_LSB (1U << 17) /* 1b */ +/* SPM_EMI_BW_MODE (0x10006000+0x450) */ +#define EMI_BW_MODE_LSB (1U << 0) /* 1b */ +#define EMI_BOOST_MODE_LSB (1U << 1) /* 1b */ +#define EMI_BW_MODE_2_LSB (1U << 2) /* 1b */ +#define EMI_BOOST_MODE_2_LSB (1U << 3) /* 1b */ +/* AP2MD_PEER_WAKEUP (0x10006000+0x454) */ +#define AP2MD_PEER_WAKEUP_LSB (1U << 0) /* 1b */ +/* ULPOSC_CON (0x10006000+0x458) */ +#define ULPOSC_EN_LSB (1U << 0) /* 1b */ +#define ULPOSC_RST_LSB (1U << 1) /* 1b */ +#define ULPOSC_CG_EN_LSB (1U << 2) /* 1b */ +#define ULPOSC_CLK_SEL_LSB (1U << 3) /* 1b */ +/* SPM2MM_CON (0x10006000+0x45C) */ +#define SPM2MM_FORCE_ULTRA_LSB (1U << 0) /* 1b */ +#define SPM2MM_DBL_OSTD_ACT_LSB (1U << 1) /* 1b */ +#define SPM2MM_ULTRAREQ_LSB (1U << 2) /* 1b */ +#define SPM2MD_ULTRAREQ_LSB (1U << 3) /* 1b */ +#define SPM2ISP_ULTRAREQ_LSB (1U << 4) /* 1b */ +#define MM2SPM_FORCE_ULTRA_ACK_LSB (1U << 16) /* 1b */ +#define MM2SPM_DBL_OSTD_ACT_ACK_LSB (1U << 17) /* 1b */ +#define SPM2ISP_ULTRAACK_D2T_LSB (1U << 18) /* 1b */ +#define SPM2MM_ULTRAACK_D2T_LSB (1U << 19) /* 1b */ +#define SPM2MD_ULTRAACK_D2T_LSB (1U << 20) /* 1b */ +/* DRAMC_DPY_CLK_SW_CON_SEL (0x10006000+0x460) */ +#define SW_DR_GATE_RETRY_EN_SEL_LSB (1U << 0) /* 2b */ +#define SW_EMI_CLK_OFF_SEL_LSB (1U << 2) /* 2b */ +#define SW_DPY_MODE_SW_SEL_LSB (1U << 4) /* 2b */ +#define SW_DMSUS_OFF_SEL_LSB (1U << 6) /* 2b */ +#define SW_MEM_CK_OFF_SEL_LSB (1U << 8) /* 2b */ +#define SW_DPY_2ND_DLL_EN_SEL_LSB (1U << 10) /* 2b */ +#define SW_DPY_DLL_EN_SEL_LSB (1U << 12) /* 2b */ +#define SW_DPY_DLL_CK_EN_SEL_LSB (1U << 14) /* 2b */ +#define SW_DPY_VREF_EN_SEL_LSB (1U << 16) /* 2b */ +#define SW_PHYPLL_EN_SEL_LSB (1U << 18) /* 2b */ +#define SW_DDRPHY_FB_CK_EN_SEL_LSB (1U << 20) /* 2b */ +#define SEPERATE_PHY_PWR_SEL_LSB (1U << 23) /* 1b */ +#define SW_DMDRAMCSHU_ACK_SEL_LSB (1U << 24) /* 2b */ +#define SW_EMI_CLK_OFF_ACK_SEL_LSB (1U << 26) /* 2b */ +#define SW_DR_SHORT_QUEUE_ACK_SEL_LSB (1U << 28) /* 2b */ +#define SW_DRAMC_DFS_STA_SEL_LSB (1U << 30) /* 2b */ +/* DRAMC_DPY_CLK_SW_CON (0x10006000+0x464) */ +#define SW_DR_GATE_RETRY_EN_LSB (1U << 0) /* 2b */ +#define SW_EMI_CLK_OFF_LSB (1U << 2) /* 2b */ +#define SW_DPY_MODE_SW_LSB (1U << 4) /* 2b */ +#define SW_DMSUS_OFF_LSB (1U << 6) /* 2b */ +#define SW_MEM_CK_OFF_LSB (1U << 8) /* 2b */ +#define SW_DPY_2ND_DLL_EN_LSB (1U << 10) /* 2b */ +#define SW_DPY_DLL_EN_LSB (1U << 12) /* 2b */ +#define SW_DPY_DLL_CK_EN_LSB (1U << 14) /* 2b */ +#define SW_DPY_VREF_EN_LSB (1U << 16) /* 2b */ +#define SW_PHYPLL_EN_LSB (1U << 18) /* 2b */ +#define SW_DDRPHY_FB_CK_EN_LSB (1U << 20) /* 2b */ +#define SC_DR_SHU_EN_ACK_LSB (1U << 24) /* 2b */ +#define EMI_CLK_OFF_ACK_LSB (1U << 26) /* 2b */ +#define SC_DR_SHORT_QUEUE_ACK_LSB (1U << 28) /* 2b */ +#define SC_DRAMC_DFS_STA_LSB (1U << 30) /* 2b */ +/* SPM_S1_MODE_CH (0x10006000+0x468) */ +#define SPM_S1_MODE_CH_LSB (1U << 0) /* 2b */ +#define S1_EMI_CK_SWITCH_LSB (1U << 8) /* 2b */ +/* EMI_SELF_REFRESH_CH_STA (0x10006000+0x46C) */ +#define EMI_SELF_REFRESH_CH_LSB (1U << 0) /* 2b */ +/* DRAMC_DPY_CLK_SW_CON_SEL2 (0x10006000+0x470) */ +#define SW_PHYPLL_SHU_EN_SEL_LSB (1U << 0) /* 1b */ +#define SW_PHYPLL2_SHU_EN_SEL_LSB (1U << 1) /* 1b */ +#define SW_PHYPLL_MODE_SW_SEL_LSB (1U << 2) /* 1b */ +#define SW_PHYPLL2_MODE_SW_SEL_LSB (1U << 3) /* 1b */ +#define SW_DR_SHORT_QUEUE_SEL_LSB (1U << 4) /* 1b */ +#define SW_DR_SHU_EN_SEL_LSB (1U << 5) /* 1b */ +#define SW_DR_SHU_LEVEL_SEL_LSB (1U << 6) /* 1b */ +#define SW_DPY_BCLK_ENABLE_SEL_LSB (1U << 8) /* 2b */ +#define SW_SHU_RESTORE_SEL_LSB (1U << 10) /* 2b */ +#define SW_DPHY_PRECAL_UP_SEL_LSB (1U << 12) /* 2b */ +#define SW_DPHY_RXDLY_TRACK_EN_SEL_LSB (1U << 14) /* 2b */ +#define SW_TX_TRACKING_DIS_SEL_LSB (1U << 16) /* 2b */ +/* DRAMC_DPY_CLK_SW_CON2 (0x10006000+0x474) */ +#define SW_PHYPLL_SHU_EN_LSB (1U << 0) /* 1b */ +#define SW_PHYPLL2_SHU_EN_LSB (1U << 1) /* 1b */ +#define SW_PHYPLL_MODE_SW_LSB (1U << 2) /* 1b */ +#define SW_PHYPLL2_MODE_SW_LSB (1U << 3) /* 1b */ +#define SW_DR_SHORT_QUEUE_LSB (1U << 4) /* 1b */ +#define SW_DR_SHU_EN_LSB (1U << 5) /* 1b */ +#define SW_DR_SHU_LEVEL_LSB (1U << 6) /* 2b */ +#define SW_DPY_BCLK_ENABLE_LSB (1U << 8) /* 2b */ +#define SW_SHU_RESTORE_LSB (1U << 10) /* 2b */ +#define SW_DPHY_PRECAL_UP_LSB (1U << 12) /* 2b */ +#define SW_DPHY_RXDLY_TRACK_EN_LSB (1U << 14) /* 2b */ +#define SW_TX_TRACKING_DIS_LSB (1U << 16) /* 2b */ +/* DRAMC_DMYRD_CON (0x10006000+0x478) */ +#define DRAMC_DMYRD_EN_CH0_LSB (1U << 0) /* 1b */ +#define DRAMC_DMYRD_INTV_SEL_CH0_LSB (1U << 1) /* 1b */ +#define DRAMC_DMYRD_EN_MOD_SEL_CH0_LSB (1U << 2) /* 1b */ +#define DRAMC_DMYRD_EN_CH1_LSB (1U << 8) /* 1b */ +#define DRAMC_DMYRD_INTV_SEL_CH1_LSB (1U << 9) /* 1b */ +#define DRAMC_DMYRD_EN_MOD_SEL_CH1_LSB (1U << 10) /* 1b */ +/* SPM_DRS_CON (0x10006000+0x47C) */ +#define SPM_DRS_DIS_REQ_CH0_LSB (1U << 0) /* 1b */ +#define SPM_DRS_DIS_REQ_CH1_LSB (1U << 1) /* 1b */ +#define SPM_DRS_DIS_ACK_CH0_LSB (1U << 8) /* 1b */ +#define SPM_DRS_DIS_ACK_CH1_LSB (1U << 9) /* 1b */ +/* SPM_SEMA_M0 (0x10006000+0x480) */ +#define SPM_SEMA_M0_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M1 (0x10006000+0x484) */ +#define SPM_SEMA_M1_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M2 (0x10006000+0x488) */ +#define SPM_SEMA_M2_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M3 (0x10006000+0x48C) */ +#define SPM_SEMA_M3_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M4 (0x10006000+0x490) */ +#define SPM_SEMA_M4_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M5 (0x10006000+0x494) */ +#define SPM_SEMA_M5_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M6 (0x10006000+0x498) */ +#define SPM_SEMA_M6_LSB (1U << 0) /* 8b */ +/* SPM_SEMA_M7 (0x10006000+0x49C) */ +#define SPM_SEMA_M7_LSB (1U << 0) /* 8b */ +/* SPM_MAS_PAUSE_MM_MASK_B (0x10006000+0x4A0) */ +#define SPM_MAS_PAUSE_MM_MASK_B_LSB (1U << 0) /* 16b */ +/* SPM_MAS_PAUSE_MCU_MASK_B (0x10006000+0x4A4) */ +#define SPM_MAS_PAUSE_MCU_MASK_B_LSB (1U << 0) /* 16b */ +/* SRAM_DREQ_ACK (0x10006000+0x4AC) */ +#define SRAM_DREQ_ACK_LSB (1U << 0) /* 16b */ +/* SRAM_DREQ_CON (0x10006000+0x4B0) */ +#define SRAM_DREQ_CON_LSB (1U << 0) /* 16b */ +/* SRAM_DREQ_CON_SET (0x10006000+0x4B4) */ +#define SRAM_DREQ_CON_SET_LSB (1U << 0) /* 16b */ +/* SRAM_DREQ_CON_CLR (0x10006000+0x4B8) */ +#define SRAM_DREQ_CON_CLR_LSB (1U << 0) /* 16b */ +/* SPM2EMI_ENTER_ULPM (0x10006000+0x4BC) */ +#define SPM2EMI_ENTER_ULPM_LSB (1U << 0) /* 1b */ +/* SPM_SSPM_IRQ (0x10006000+0x4C0) */ +#define SPM_SSPM_IRQ_LSB (1U << 0) /* 1b */ +#define SPM_SSPM_IRQ_SEL_LSB (1U << 4) /* 1b */ +/* SPM2PMCU_INT (0x10006000+0x4C4) */ +#define SPM2PMCU_INT_LSB (1U << 0) /* 4b */ +/* SPM2PMCU_INT_SET (0x10006000+0x4C8) */ +#define SPM2PMCU_INT_SET_LSB (1U << 0) /* 4b */ +/* SPM2PMCU_INT_CLR (0x10006000+0x4CC) */ +#define SPM2PMCU_INT_CLR_LSB (1U << 0) /* 4b */ +/* SPM2PMCU_MAILBOX_0 (0x10006000+0x4D0) */ +#define SPM2PMCU_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_1 (0x10006000+0x4D4) */ +#define SPM2PMCU_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_2 (0x10006000+0x4D8) */ +#define SPM2PMCU_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SPM2PMCU_MAILBOX_3 (0x10006000+0x4DC) */ +#define SPM2PMCU_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_INT (0x10006000+0x4E0) */ +#define PMCU2SPM_INT_LSB (1U << 0) /* 4b */ +/* PMCU2SPM_INT_SET (0x10006000+0x4E4) */ +#define PMCU2SPM_INT_SET_LSB (1U << 0) /* 4b */ +/* PMCU2SPM_INT_CLR (0x10006000+0x4E8) */ +#define PMCU2SPM_INT_CLR_LSB (1U << 0) /* 4b */ +/* PMCU2SPM_MAILBOX_0 (0x10006000+0x4EC) */ +#define PMCU2SPM_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_1 (0x10006000+0x4F0) */ +#define PMCU2SPM_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_2 (0x10006000+0x4F4) */ +#define PMCU2SPM_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_MAILBOX_3 (0x10006000+0x4F8) */ +#define PMCU2SPM_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* PMCU2SPM_CFG (0x10006000+0x4FC) */ +#define PMCU2SPM_INT_MASK_B_LSB (1U << 0) /* 4b */ +#define SPM_PMCU_MAILBOX_REQ_LSB (1U << 8) /* 1b */ +/* MP0_CPU0_IRQ_MASK (0x10006000+0x500) */ +#define MP0_CPU0_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU0_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU1_IRQ_MASK (0x10006000+0x504) */ +#define MP0_CPU1_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU1_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU2_IRQ_MASK (0x10006000+0x508) */ +#define MP0_CPU2_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU2_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU3_IRQ_MASK (0x10006000+0x50C) */ +#define MP0_CPU3_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP0_CPU3_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU0_IRQ_MASK (0x10006000+0x510) */ +#define MP1_CPU0_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU0_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU1_IRQ_MASK (0x10006000+0x514) */ +#define MP1_CPU1_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU1_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU2_IRQ_MASK (0x10006000+0x518) */ +#define MP1_CPU2_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU2_AUX_LSB (1U << 8) /* 11b */ +/* MP1_CPU3_IRQ_MASK (0x10006000+0x51C) */ +#define MP1_CPU3_IRQ_MASK_LSB (1U << 0) /* 1b */ +#define MP1_CPU3_AUX_LSB (1U << 8) /* 11b */ +/* MP0_CPU0_WFI_EN (0x10006000+0x530) */ +#define MP0_CPU0_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU1_WFI_EN (0x10006000+0x534) */ +#define MP0_CPU1_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU2_WFI_EN (0x10006000+0x538) */ +#define MP0_CPU2_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_CPU3_WFI_EN (0x10006000+0x53C) */ +#define MP0_CPU3_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP1_CPU0_WFI_EN (0x10006000+0x540) */ +#define MP1_CPU0_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP1_CPU1_WFI_EN (0x10006000+0x544) */ +#define MP1_CPU1_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP1_CPU2_WFI_EN (0x10006000+0x548) */ +#define MP1_CPU2_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP1_CPU3_WFI_EN (0x10006000+0x54C) */ +#define MP1_CPU3_WFI_EN_LSB (1U << 0) /* 1b */ +/* MP0_L2CFLUSH (0x10006000+0x554) */ +#define MP0_L2CFLUSH_REQ_LSB (1U << 0) /* 1b */ +#define MP0_L2CFLUSH_DONE_LSB (1U << 4) /* 1b */ +/* MP1_L2CFLUSH (0x10006000+0x558) */ +#define MP1_L2CFLUSH_REQ_LSB (1U << 0) /* 1b */ +#define MP1_L2CFLUSH_DONE_LSB (1U << 4) /* 1b */ +/* CPU_PTPOD2_CON (0x10006000+0x560) */ +#define MP0_PTPOD2_FBB_EN_LSB (1U << 0) /* 1b */ +#define MP1_PTPOD2_FBB_EN_LSB (1U << 1) /* 1b */ +#define MP0_PTPOD2_SPARK_EN_LSB (1U << 2) /* 1b */ +#define MP1_PTPOD2_SPARK_EN_LSB (1U << 3) /* 1b */ +#define MP0_PTPOD2_FBB_ACK_LSB (1U << 4) /* 1b */ +#define MP1_PTPOD2_FBB_ACK_LSB (1U << 5) /* 1b */ +/* ROOT_CPUTOP_ADDR (0x10006000+0x570) */ +#define ROOT_CPUTOP_ADDR_LSB (1U << 0) /* 32b */ +/* ROOT_CORE_ADDR (0x10006000+0x574) */ +#define ROOT_CORE_ADDR_LSB (1U << 0) /* 32b */ +/* CPU_SPARE_CON (0x10006000+0x580) */ +#define CPU_SPARE_CON_LSB (1U << 0) /* 32b */ +/* CPU_SPARE_CON_SET (0x10006000+0x584) */ +#define CPU_SPARE_CON_SET_LSB (1U << 0) /* 32b */ +/* CPU_SPARE_CON_CLR (0x10006000+0x588) */ +#define CPU_SPARE_CON_CLR_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_0 (0x10006000+0x5D0) */ +#define SPM2SW_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_1 (0x10006000+0x5D4) */ +#define SPM2SW_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_2 (0x10006000+0x5D8) */ +#define SPM2SW_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SPM2SW_MAILBOX_3 (0x10006000+0x5DC) */ +#define SPM2SW_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* SW2SPM_INT (0x10006000+0x5E0) */ +#define SW2SPM_INT_LSB (1U << 0) /* 4b */ +/* SW2SPM_INT_SET (0x10006000+0x5E4) */ +#define SW2SPM_INT_SET_LSB (1U << 0) /* 4b */ +/* SW2SPM_INT_CLR (0x10006000+0x5E8) */ +#define SW2SPM_INT_CLR_LSB (1U << 0) /* 4b */ +/* SW2SPM_MAILBOX_0 (0x10006000+0x5EC) */ +#define SW2SPM_MAILBOX_0_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_1 (0x10006000+0x5F0) */ +#define SW2SPM_MAILBOX_1_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_2 (0x10006000+0x5F4) */ +#define SW2SPM_MAILBOX_2_LSB (1U << 0) /* 32b */ +/* SW2SPM_MAILBOX_3 (0x10006000+0x5F8) */ +#define SW2SPM_MAILBOX_3_LSB (1U << 0) /* 32b */ +/* SW2SPM_CFG (0x10006000+0x5FC) */ +#define SWU2SPM_INT_MASK_B_LSB (1U << 0) /* 4b */ +#define SPM_SW_MAILBOX_REQ_LSB (1U << 8) /* 1b */ +/* SPM_SW_FLAG (0x10006000+0x600) */ +#define SPM_SW_FLAG_LSB (1U << 0) /* 32b */ +/* SPM_SW_DEBUG (0x10006000+0x604) */ +#define SPM_SW_DEBUG_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_0 (0x10006000+0x608) */ +#define SPM_SW_RSV_0_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_1 (0x10006000+0x60C) */ +#define SPM_SW_RSV_1_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_2 (0x10006000+0x610) */ +#define SPM_SW_RSV_2_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_3 (0x10006000+0x614) */ +#define SPM_SW_RSV_3_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_4 (0x10006000+0x618) */ +#define SPM_SW_RSV_4_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_5 (0x10006000+0x61C) */ +#define SPM_SW_RSV_5_LSB (1U << 0) /* 32b */ +/* SPM_RSV_CON (0x10006000+0x620) */ +#define SPM_RSV_CON_LSB (1U << 0) /* 16b */ +/* SPM_RSV_STA (0x10006000+0x624) */ +#define SPM_RSV_STA_LSB (1U << 0) /* 16b */ +/* SPM_RSV_CON1 (0x10006000+0x628) */ +#define SPM_RSV_CON1_LSB (1U << 0) /* 16b */ +/* SPM_RSV_STA1 (0x10006000+0x62C) */ +#define SPM_RSV_STA1_LSB (1U << 0) /* 16b */ +/* SPM_PASR_DPD_0 (0x10006000+0x630) */ +#define SPM_PASR_DPD_0_LSB (1U << 0) /* 32b */ +/* SPM_PASR_DPD_1 (0x10006000+0x634) */ +#define SPM_PASR_DPD_1_LSB (1U << 0) /* 32b */ +/* SPM_PASR_DPD_2 (0x10006000+0x638) */ +#define SPM_PASR_DPD_2_LSB (1U << 0) /* 32b */ +/* SPM_PASR_DPD_3 (0x10006000+0x63C) */ +#define SPM_PASR_DPD_3_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON (0x10006000+0x640) */ +#define SPM_SPARE_CON_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON_SET (0x10006000+0x644) */ +#define SPM_SPARE_CON_SET_LSB (1U << 0) /* 32b */ +/* SPM_SPARE_CON_CLR (0x10006000+0x648) */ +#define SPM_SPARE_CON_CLR_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_6 (0x10006000+0x64C) */ +#define SPM_SW_RSV_6_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_7 (0x10006000+0x650) */ +#define SPM_SW_RSV_7_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_8 (0x10006000+0x654) */ +#define SPM_SW_RSV_8_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_9 (0x10006000+0x658) */ +#define SPM_SW_RSV_9_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_10 (0x10006000+0x65C) */ +#define SPM_SW_RSV_10_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_18 (0x10006000+0x67C) */ +#define SPM_SW_RSV_18_LSB (1U << 0) /* 32b */ +/* SPM_SW_RSV_19 (0x10006000+0x680) */ +#define SPM_SW_RSV_19_LSB (1U << 0) /* 32b */ +/* DVFSRC_EVENT_MASK_CON (0x10006000+0x690) */ +#define DVFSRC_EVENT_MASK_B_LSB (1U << 0) /* 16b */ +#define DVFSRC_EVENT_TRIGGER_MASK_B_LSB (1U << 16) /* 1b */ +/* DVFSRC_EVENT_FORCE_ON (0x10006000+0x694) */ +#define DVFSRC_EVENT_FORCE_ON_LSB (1U << 0) /* 16b */ +#define DVFSRC_EVENT_TRIGGER_FORCE_ON_LSB (1U << 16) /* 1b */ +/* DVFSRC_EVENT_SEL (0x10006000+0x698) */ +#define DVFSRC_EVENT_SEL_LSB (1U << 0) /* 16b */ +/* SPM_DVFS_EVENT_STA (0x10006000+0x69C) */ +#define SPM_DVFS_EVENT_STA_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_EVENT_STA1 (0x10006000+0x6A0) */ +#define SPM_DVFS_EVENT_STA1_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_LEVEL (0x10006000+0x6A4) */ +#define SPM_DVFS_LEVEL_LSB (1U << 0) /* 16b */ +/* DVFS_ABORT_STA (0x10006000+0x6A8) */ +#define RC2SPM_EVENT_ABORT_D2T_LSB (1U << 0) /* 16b */ +#define RC2SPM_EVENT_ABORT_MASK_OR_LSB (1U << 16) /* 1b */ +/* DVFS_ABORT_OTHERS_MASK (0x10006000+0x6AC) */ +#define DVFS_ABORT_OTHERS_MASK_B_LSB (1U << 0) /* 16b */ +/* SPM_DFS_LEVEL (0x10006000+0x6B0) */ +#define SPM_DFS_LEVEL_LSB (1U << 0) /* 4b */ +/* SPM_DVS_LEVEL (0x10006000+0x6B4) */ +#define SPM_VCORE_LEVEL_LSB (1U << 0) /* 8b */ +#define SPM_VSRAM_LEVEL_LSB (1U << 8) /* 8b */ +#define SPM_VMODEM_LEVEL_LSB (1U << 16) /* 8b */ +/* SPM_DVFS_MISC (0x10006000+0x6B8) */ +#define MSDC_DVFS_REQUEST_LSB (1U << 0) /* 1b */ +#define MSDC_DVFS_LEVEL_LSB (1U << 1) /* 4b */ +#define SDIO_READY_TO_SPM_LSB (1U << 7) /* 1b */ +#define MD2AP_CENTRAL_BUCK_GEAR_REQ_D2T_LSB (1U << 8) /* 1b */ +#define MD2AP_CENTRAL_BUCK_GEAR_RDY_D2T_LSB (1U << 9) /* 1b */ +/* SPARE_SRC_REQ_MASK (0x10006000+0x6C0) */ +#define SPARE1_DDREN_MASK_B_LSB (1U << 0) /* 1b */ +#define SPARE1_APSRC_REQ_MASK_B_LSB (1U << 1) /* 1b */ +#define SPARE1_VRF18_REQ_MASK_B_LSB (1U << 2) /* 1b */ +#define SPARE1_INFRA_REQ_MASK_B_LSB (1U << 3) /* 1b */ +#define SPARE1_SRCCLKENA_MASK_B_LSB (1U << 4) /* 1b */ +#define SPARE1_DDREN_2_MASK_B_LSB (1U << 5) /* 1b */ +#define SPARE2_DDREN_MASK_B_LSB (1U << 8) /* 1b */ +#define SPARE2_APSRC_REQ_MASK_B_LSB (1U << 9) /* 1b */ +#define SPARE2_VRF18_REQ_MASK_B_LSB (1U << 10) /* 1b */ +#define SPARE2_INFRA_REQ_MASK_B_LSB (1U << 11) /* 1b */ +#define SPARE2_SRCCLKENA_MASK_B_LSB (1U << 12) /* 1b */ +#define SPARE2_DDREN_2_MASK_B_LSB (1U << 13) /* 1b */ +/* SCP_VCORE_LEVEL (0x10006000+0x6C4) */ +#define SCP_VCORE_LEVEL_LSB (1U << 0) /* 8b */ +/* SC_MM_CK_SEL_CON (0x10006000+0x6C8) */ +#define SC_MM_CK_SEL_LSB (1U << 0) /* 4b */ +#define SC_MM_CK_SEL_EN_LSB (1U << 4) /* 1b */ +/* SPARE_ACK_STA (0x10006000+0x6F0) */ +#define SPARE_ACK_SYNC_LSB (1U << 0) /* 32b */ +/* SPARE_ACK_MASK (0x10006000+0x6F4) */ +#define SPARE_ACK_MASK_B_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CON1 (0x10006000+0x700) */ +#define SPM_DVFS_CON1_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CON1_STA (0x10006000+0x704) */ +#define SPM_DVFS_CON1_STA_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD0 (0x10006000+0x710) */ +#define SPM_DVFS_CMD0_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD1 (0x10006000+0x714) */ +#define SPM_DVFS_CMD1_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD2 (0x10006000+0x718) */ +#define SPM_DVFS_CMD2_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD3 (0x10006000+0x71C) */ +#define SPM_DVFS_CMD3_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD4 (0x10006000+0x720) */ +#define SPM_DVFS_CMD4_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD5 (0x10006000+0x724) */ +#define SPM_DVFS_CMD5_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD6 (0x10006000+0x728) */ +#define SPM_DVFS_CMD6_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD7 (0x10006000+0x72C) */ +#define SPM_DVFS_CMD7_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD8 (0x10006000+0x730) */ +#define SPM_DVFS_CMD8_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD9 (0x10006000+0x734) */ +#define SPM_DVFS_CMD9_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD10 (0x10006000+0x738) */ +#define SPM_DVFS_CMD10_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD11 (0x10006000+0x73C) */ +#define SPM_DVFS_CMD11_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD12 (0x10006000+0x740) */ +#define SPM_DVFS_CMD12_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD13 (0x10006000+0x744) */ +#define SPM_DVFS_CMD13_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD14 (0x10006000+0x748) */ +#define SPM_DVFS_CMD14_LSB (1U << 0) /* 32b */ +/* SPM_DVFS_CMD15 (0x10006000+0x74C) */ +#define SPM_DVFS_CMD15_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE0_FIX (0x10006000+0x780) */ +#define WDT_LATCH_SPARE0_FIX_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE1_FIX (0x10006000+0x784) */ +#define WDT_LATCH_SPARE1_FIX_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE2_FIX (0x10006000+0x788) */ +#define WDT_LATCH_SPARE2_FIX_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE3_FIX (0x10006000+0x78C) */ +#define WDT_LATCH_SPARE3_FIX_LSB (1U << 0) /* 32b */ +/* SPARE_ACK_IN_FIX (0x10006000+0x790) */ +#define SPARE_ACK_IN_FIX_LSB (1U << 0) /* 32b */ +/* DCHA_LATCH_RSV0_FIX (0x10006000+0x794) */ +#define DCHA_LATCH_RSV0_FIX_LSB (1U << 0) /* 32b */ +/* DCHB_LATCH_RSV0_FIX (0x10006000+0x798) */ +#define DCHB_LATCH_RSV0_FIX_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_0 (0x10006000+0x800) */ +#define PCM_WDT_LATCH_0_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_1 (0x10006000+0x804) */ +#define PCM_WDT_LATCH_1_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_2 (0x10006000+0x808) */ +#define PCM_WDT_LATCH_2_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_3 (0x10006000+0x80C) */ +#define PCM_WDT_LATCH_3_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_4 (0x10006000+0x810) */ +#define PCM_WDT_LATCH_4_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_5 (0x10006000+0x814) */ +#define PCM_WDT_LATCH_5_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_6 (0x10006000+0x818) */ +#define PCM_WDT_LATCH_6_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_7 (0x10006000+0x81C) */ +#define PCM_WDT_LATCH_7_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_8 (0x10006000+0x820) */ +#define PCM_WDT_LATCH_8_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_9 (0x10006000+0x824) */ +#define PCM_WDT_LATCH_9_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE0 (0x10006000+0x828) */ +#define WDT_LATCH_SPARE0_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE1 (0x10006000+0x82C) */ +#define WDT_LATCH_SPARE1_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE2 (0x10006000+0x830) */ +#define WDT_LATCH_SPARE2_LSB (1U << 0) /* 32b */ +/* WDT_LATCH_SPARE3 (0x10006000+0x834) */ +#define WDT_LATCH_SPARE3_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_10 (0x10006000+0x838) */ +#define PCM_WDT_LATCH_10_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_11 (0x10006000+0x83C) */ +#define PCM_WDT_LATCH_11_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_0 (0x10006000+0x840) */ +#define DCHA_GATING_LATCH_0_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_1 (0x10006000+0x844) */ +#define DCHA_GATING_LATCH_1_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_2 (0x10006000+0x848) */ +#define DCHA_GATING_LATCH_2_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_3 (0x10006000+0x84C) */ +#define DCHA_GATING_LATCH_3_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_4 (0x10006000+0x850) */ +#define DCHA_GATING_LATCH_4_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_5 (0x10006000+0x854) */ +#define DCHA_GATING_LATCH_5_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_6 (0x10006000+0x858) */ +#define DCHA_GATING_LATCH_6_LSB (1U << 0) /* 32b */ +/* DCHA_GATING_LATCH_7 (0x10006000+0x85C) */ +#define DCHA_GATING_LATCH_7_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_0 (0x10006000+0x860) */ +#define DCHB_GATING_LATCH_0_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_1 (0x10006000+0x864) */ +#define DCHB_GATING_LATCH_1_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_2 (0x10006000+0x868) */ +#define DCHB_GATING_LATCH_2_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_3 (0x10006000+0x86C) */ +#define DCHB_GATING_LATCH_3_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_4 (0x10006000+0x870) */ +#define DCHB_GATING_LATCH_4_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_5 (0x10006000+0x874) */ +#define DCHB_GATING_LATCH_5_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_6 (0x10006000+0x878) */ +#define DCHB_GATING_LATCH_6_LSB (1U << 0) /* 32b */ +/* DCHB_GATING_LATCH_7 (0x10006000+0x87C) */ +#define DCHB_GATING_LATCH_7_LSB (1U << 0) /* 32b */ +/* DCHA_LATCH_RSV0 (0x10006000+0x880) */ +#define DCHA_LATCH_RSV0_LSB (1U << 0) /* 32b */ +/* DCHB_LATCH_RSV0 (0x10006000+0x884) */ +#define DCHB_LATCH_RSV0_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_12 (0x10006000+0x888) */ +#define PCM_WDT_LATCH_12_LSB (1U << 0) /* 32b */ +/* PCM_WDT_LATCH_13 (0x10006000+0x88C) */ +#define PCM_WDT_LATCH_13_LSB (1U << 0) /* 32b */ +/* SPM_PC_TRACE_CON (0x10006000+0x8C0) */ +#define SPM_PC_TRACE_OFFSET_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE_HW_EN_LSB (1U << 16) /* 1b */ +#define SPM_PC_TRACE_SW_LSB (1U << 17) /* 1b */ +/* SPM_PC_TRACE_G0 (0x10006000+0x8C4) */ +#define SPM_PC_TRACE0_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE1_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G1 (0x10006000+0x8C8) */ +#define SPM_PC_TRACE2_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE3_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G2 (0x10006000+0x8CC) */ +#define SPM_PC_TRACE4_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE5_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G3 (0x10006000+0x8D0) */ +#define SPM_PC_TRACE6_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE7_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G4 (0x10006000+0x8D4) */ +#define SPM_PC_TRACE8_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE9_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G5 (0x10006000+0x8D8) */ +#define SPM_PC_TRACE10_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE11_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G6 (0x10006000+0x8DC) */ +#define SPM_PC_TRACE12_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE13_LSB (1U << 16) /* 12b */ +/* SPM_PC_TRACE_G7 (0x10006000+0x8E0) */ +#define SPM_PC_TRACE14_LSB (1U << 0) /* 12b */ +#define SPM_PC_TRACE15_LSB (1U << 16) /* 12b */ +/* SPM_ACK_CHK_CON (0x10006000+0x900) */ +#define SPM_ACK_CHK_SW_EN_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL_LSB (1U << 15) /* 1b */ +#define SPM_ACK_CHK_SWINT_EN_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_PC (0x10006000+0x904) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL (0x10006000+0x908) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER (0x10006000+0x90C) */ +#define SPM_ACK_CHK_TIMER_VAL_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA (0x10006000+0x910) */ +#define SPM_ACK_CHK_STA_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_LATCH (0x10006000+0x914) */ +#define SPM_ACK_CHK_LATCH_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON2 (0x10006000+0x920) */ +#define SPM_ACK_CHK_SW_EN2_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL2_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER2_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ2_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN2_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN2_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN2_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN2_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN2_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE2_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL2_LSB (1U << 15) /* 1b */ +#define SPM_ACK_CHK_SWINT_EN2_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_PC2 (0x10006000+0x924) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL2_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL2_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL2 (0x10006000+0x928) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL2_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL2_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL2_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL2_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER2 (0x10006000+0x92C) */ +#define SPM_ACK_CHK_TIMER_VAL2_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER2_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA2 (0x10006000+0x930) */ +#define SPM_ACK_CHK_STA2_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_LATCH2 (0x10006000+0x934) */ +#define SPM_ACK_CHK_LATCH2_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON3 (0x10006000+0x940) */ +#define SPM_ACK_CHK_SW_EN3_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL3_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER3_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ3_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN3_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN3_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN3_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN3_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN3_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE3_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL3_LSB (1U << 15) /* 1b */ +#define SPM_ACK_CHK_SWINT_EN3_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_PC3 (0x10006000+0x944) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL3_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL3_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL3 (0x10006000+0x948) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL3_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL3_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL3_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL3_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER3 (0x10006000+0x94C) */ +#define SPM_ACK_CHK_TIMER_VAL3_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER3_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA3 (0x10006000+0x950) */ +#define SPM_ACK_CHK_STA3_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_LATCH3 (0x10006000+0x954) */ +#define SPM_ACK_CHK_LATCH3_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_CON4 (0x10006000+0x960) */ +#define SPM_ACK_CHK_SW_EN4_LSB (1U << 0) /* 1b */ +#define SPM_ACK_CHK_CLR_ALL4_LSB (1U << 1) /* 1b */ +#define SPM_ACK_CHK_CLR_TIMER4_LSB (1U << 2) /* 1b */ +#define SPM_ACK_CHK_CLR_IRQ4_LSB (1U << 3) /* 1b */ +#define SPM_ACK_CHK_STA_EN4_LSB (1U << 4) /* 1b */ +#define SPM_ACK_CHK_WAKEUP_EN4_LSB (1U << 5) /* 1b */ +#define SPM_ACK_CHK_WDT_EN4_LSB (1U << 6) /* 1b */ +#define SPM_ACK_CHK_LOCK_PC_TRACE_EN4_LSB (1U << 7) /* 1b */ +#define SPM_ACK_CHK_HW_EN4_LSB (1U << 8) /* 1b */ +#define SPM_ACK_CHK_HW_MODE4_LSB (1U << 9) /* 3b */ +#define SPM_ACK_CHK_FAIL4_LSB (1U << 15) /* 1b */ +#define SPM_ACK_CHK_SWINT_EN4_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_PC4 (0x10006000+0x964) */ +#define SPM_ACK_CHK_HW_TRIG_PC_VAL4_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_HW_TARG_PC_VAL4_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_SEL4 (0x10006000+0x968) */ +#define SPM_ACK_CHK_HW_TRIG_SIGNAL_SEL4_LSB (1U << 0) /* 5b */ +#define SPM_ACK_CHK_HW_TRIG_GROUP_SEL4_LSB (1U << 5) /* 3b */ +#define SPM_ACK_CHK_HW_TARG_SIGNAL_SEL4_LSB (1U << 16) /* 5b */ +#define SPM_ACK_CHK_HW_TARG_GROUP_SEL4_LSB (1U << 21) /* 3b */ +/* SPM_ACK_CHK_TIMER4 (0x10006000+0x96C) */ +#define SPM_ACK_CHK_TIMER_VAL4_LSB (1U << 0) /* 16b */ +#define SPM_ACK_CHK_TIMER4_LSB (1U << 16) /* 16b */ +/* SPM_ACK_CHK_STA4 (0x10006000+0x970) */ +#define SPM_ACK_CHK_STA4_LSB (1U << 0) /* 32b */ +/* SPM_ACK_CHK_LATCH4 (0x10006000+0x974) */ +#define SPM_ACK_CHK_LATCH4_LSB (1U << 0) /* 32b */ + +/* --- SPM Flag Define --- */ +#define SPM_FLAG_DIS_CPU_PDN (1U << 0) +#define SPM_FLAG_DIS_INFRA_PDN (1U << 1) +#define SPM_FLAG_DIS_DDRPHY_PDN (1U << 2) +#define SPM_FLAG_DIS_VCORE_DVS (1U << 3) +#define SPM_FLAG_DIS_VCORE_DFS (1U << 4) +#define SPM_FLAG_DIS_COMMON_SCENARIO (1U << 5) +#define SPM_FLAG_DIS_BUS_CLOCK_OFF (1U << 6) +#define SPM_FLAG_DIS_ATF_ABORT (1U << 7) +#define SPM_FLAG_KEEP_CSYSPWRUPACK_HIGH (1U << 8) +#define SPM_FLAG_DIS_VPROC_VSRAM_DVS (1U << 9) +#define SPM_FLAG_RUN_COMMON_SCENARIO (1U << 10) +#define SPM_FLAG_EN_MET_DEBUG_USAGE (1U << 11) +#define SPM_FLAG_SODI_CG_MODE (1U << 12) +#define SPM_FLAG_SODI_NO_EVENT (1U << 13) +#define SPM_FLAG_ENABLE_SODI3 (1U << 14) +#define SPM_FLAG_DISABLE_MMSYS_DVFS (1U << 15) +#define SPM_FLAG_DIS_SYSRAM_SLEEP (1U << 16) +#define SPM_FLAG_DIS_SSPM_SRAM_SLEEP (1U << 17) +#define SPM_FLAG_DIS_VMODEM_DVS (1U << 18) +#define SPM_FLAG_SUSPEND_OPTION (1U << 19) +#define SPM_FLAG_DEEPIDLE_OPTION (1U << 20) +#define SPM_FLAG_SODI_OPTION (1U << 21) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT22 (1U << 22) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT23 (1U << 23) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT24 (1U << 24) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT25 (1U << 25) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT26 (1U << 26) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT27 (1U << 27) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT28 (1U << 28) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT29 (1U << 29) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT30 (1U << 30) +#define SPM_FLAG_SPM_FLAG_DONT_TOUCH_BIT31 (1U << 31) + +/* --- SPM Flag1 Define --- */ +#define SPM_FLAG1_RESERVED_BIT0 (1U << 0) +#define SPM_FLAG1_ENABLE_CPU_DORMANT (1U << 1) +#define SPM_FLAG1_ENABLE_CPU_SLEEP_VOLT (1U << 2) +#define SPM_FLAG1_DISABLE_PWRAP_CLK_SWITCH (1U << 3) +#define SPM_FLAG1_DISABLE_ULPOSC_OFF (1U << 4) +#define SPM_FLAG1_VCORE_LP_0P7V (1U << 5) +#define SPM_FLAG1_DISABLE_MCDSR (1U << 6) +#define SPM_FLAG1_DISABLE_NO_RESUME (1U << 7) +#define SPM_FLAG1_BIG_BUCK_OFF_ENABLE (1U << 8) +#define SPM_FLAG1_BIG_BUCK_ON_ENABLE (1U << 9) +#define SPM_FLAG1_RESERVED_BIT10 (1U << 10) +#define SPM_FLAG1_RESERVED_BIT11 (1U << 11) +#define SPM_FLAG1_RESERVED_BIT12 (1U << 12) +#define SPM_FLAG1_RESERVED_BIT13 (1U << 13) +#define SPM_FLAG1_RESERVED_BIT14 (1U << 14) +#define SPM_FLAG1_DIS_ARMPLL_OFF (1U << 15) +#define SPM_FLAG1_DIS_AXI_BUS_TO_26M (1U << 16) +#define SPM_FLAG1_DIS_IMP_DIS (1U << 17) +#define SPM_FLAG1_DIS_IMP_COPY (1U << 18) +#define SPM_FLAG1_DIS_EMI_TOGGLE_WORKAROUND (1U << 19) +#define SPM_FLAG1_DIS_DRAM_ENTER_SREF (1U << 20) +#define SPM_FLAG1_DIS_DRAM_DLL_OFF (1U << 21) +#define SPM_FLAG1_DIS_PHYPLL_OFF (1U << 22) +#define SPM_FLAG1_DIS_MPLL_OFF (1U << 23) +#define SPM_FLAG1_DIS_SYSPLL_OFF (1U << 24) +#define SPM_FLAG1_DIS_TOP_AXI_CLK_OFF (1U << 25) +#define SPM_FLAG1_DIS_PCM_26M_SWITCH (1U << 26) +#define SPM_FLAG1_DIS_CKSQ_OFF (1U << 27) +#define SPM_FLAG1_DIS_SRCVOLTEN_OFF (1U << 28) +#define SPM_FLAG1_DIS_CHB_CG_FREE_EN (1U << 29) +#define SPM_FLAG1_DIS_CHA_DCM_RES (1U << 30) +#define SPM_FLAG1_DIS_SW_MR4 (1U << 31) + +/* --- SPM DEBUG Define --- */ +#define SPM_DBG_DEBUG_IDX_26M_WAKE (1U << 0) +#define SPM_DBG_DEBUG_IDX_26M_SLEEP (1U << 1) +#define SPM_DBG_DEBUG_IDX_INFRA_WAKE (1U << 2) +#define SPM_DBG_DEBUG_IDX_INFRA_SLEEP (1U << 3) +#define SPM_DBG_DEBUG_IDX_APSRC_WAKE (1U << 4) +#define SPM_DBG_DEBUG_IDX_APSRC_SLEEP (1U << 5) +#define SPM_DBG_DEBUG_IDX_VRF18_WAKE (1U << 6) +#define SPM_DBG_DEBUG_IDX_VRF18_SLEEP (1U << 7) +#define SPM_DBG_DEBUG_IDX_DDREN_WAKE (1U << 8) +#define SPM_DBG_DEBUG_IDX_DDREN_SLEEP (1U << 9) +#define SPM_DBG_DEBUG_IDX_NFC_CKBUF_ON (1U << 10) +#define SPM_DBG_DEBUG_IDX_NFC_CKBUF_OFF (1U << 11) +#define SPM_DBG_DEBUG_IDX_CPU_PDN (1U << 12) +#define SPM_DBG_DEBUG_IDX_DPD (1U << 13) +#define SPM_DBG_DEBUG_IDX_CONN_CKBUF_ON (1U << 14) +#define SPM_DBG_DEBUG_IDX_CONN_CKBUF_OFF (1U << 15) +#define SPM_DBG_DEBUG_IDX_VCORE_DVFS_START (1U << 16) +#define SPM_DBG_DEBUG_IDX_DDREN2_WAKE (1U << 17) +#define SPM_DBG_DEBUG_IDX_DDREN2_SLEEP (1U << 18) +#define SPM_DBG_DEBUG_IDX_SSPM_WFI (1U << 19) +#define SPM_DBG_DEBUG_IDX_SSPM_SRAM_SLP (1U << 20) +#define SPM_DBG_RESERVED_BIT21 (1U << 21) +#define SPM_DBG_RESERVED_BIT22 (1U << 22) +#define SPM_DBG_RESERVED_BIT23 (1U << 23) +#define SPM_DBG_RESERVED_BIT24 (1U << 24) +#define SPM_DBG_RESERVED_BIT25 (1U << 25) +#define SPM_DBG_RESERVED_BIT26 (1U << 26) +#define SPM_DBG_SODI1_FLAG (1U << 27) +#define SPM_DBG_SODI3_FLAG (1U << 28) +#define SPM_DBG_VCORE_DVFS_FLAG (1U << 29) +#define SPM_DBG_DEEPIDLE_FLAG (1U << 30) +#define SPM_DBG_SUSPEND_FLAG (1U << 31) + +/* --- SPM DEBUG1 Define --- */ +#define SPM_DBG1_DRAM_SREF_ACK_TO (1U << 0) +#define SPM_DBG1_PWRAP_SLEEP_ACK_TO (1U << 1) +#define SPM_DBG1_PWRAP_SPI_ACK_TO (1U << 2) +#define SPM_DBG1_DRAM_GATE_ERR_DDREN_WAKEUP (1U << 3) +#define SPM_DBG1_DRAM_GATE_ERR_LEAVE_LP_SCN (1U << 4) +#define SPM_DBG1_RESERVED_BIT5 (1U << 5) +#define SPM_DBG1_RESERVED_BIT6 (1U << 6) +#define SPM_DBG1_RESERVED_BIT7 (1U << 7) +#define SPM_DBG1_RESERVED_BIT8 (1U << 8) +#define SPM_DBG1_RESERVED_BIT9 (1U << 9) +#define SPM_DBG1_RESERVED_BIT10 (1U << 10) +#define SPM_DBG1_RESERVED_BIT11 (1U << 11) +#define SPM_DBG1_RESERVED_BIT12 (1U << 12) +#define SPM_DBG1_RESERVED_BIT13 (1U << 13) +#define SPM_DBG1_RESERVED_BIT14 (1U << 14) +#define SPM_DBG1_RESERVED_BIT15 (1U << 15) +#define SPM_DBG1_RESERVED_BIT16 (1U << 16) +#define SPM_DBG1_RESERVED_BIT17 (1U << 17) +#define SPM_DBG1_RESERVED_BIT18 (1U << 18) +#define SPM_DBG1_RESERVED_BIT19 (1U << 19) +#define SPM_DBG1_RESERVED_BIT20 (1U << 20) +#define SPM_DBG1_RESERVED_BIT21 (1U << 21) +#define SPM_DBG1_RESERVED_BIT22 (1U << 22) +#define SPM_DBG1_RESERVED_BIT23 (1U << 23) +#define SPM_DBG1_RESERVED_BIT24 (1U << 24) +#define SPM_DBG1_RESERVED_BIT25 (1U << 25) +#define SPM_DBG1_RESERVED_BIT26 (1U << 26) +#define SPM_DBG1_RESERVED_BIT27 (1U << 27) +#define SPM_DBG1_RESERVED_BIT28 (1U << 28) +#define SPM_DBG1_RESERVED_BIT29 (1U << 29) +#define SPM_DBG1_RESERVED_BIT30 (1U << 30) +#define SPM_DBG1_RESERVED_BIT31 (1U << 31) + +/* --- R0 Define --- */ +#define R0_SC_26M_CK_OFF (1U << 0) +#define R0_BIT1 (1U << 1) +#define R0_SC_MEM_CK_OFF (1U << 2) +#define R0_SC_AXI_CK_OFF (1U << 3) +#define R0_SC_DR_GATE_RETRY_EN_PCM (1U << 4) +#define R0_SC_MD26M_CK_OFF (1U << 5) +#define R0_SC_DPY_MODE_SW_PCM (1U << 6) +#define R0_SC_DMSUS_OFF_PCM (1U << 7) +#define R0_SC_DPY_2ND_DLL_EN_PCM (1U << 8) +#define R0_BIT9 (1U << 9) +#define R0_SC_MPLLOUT_OFF (1U << 10) +#define R0_SC_TX_TRACKING_DIS (1U << 11) +#define R0_SC_DPY_DLL_EN_PCM (1U << 12) +#define R0_SC_DPY_DLL_CK_EN_PCM (1U << 13) +#define R0_SC_DPY_VREF_EN_PCM (1U << 14) +#define R0_SC_PHYPLL_EN_PCM (1U << 15) +#define R0_SC_DDRPHY_FB_CK_EN_PCM (1U << 16) +#define R0_SC_DPY_BCLK_ENABLE (1U << 17) +#define R0_SC_MPLL_OFF (1U << 18) +#define R0_SC_SHU_RESTORE (1U << 19) +#define R0_SC_CKSQ0_OFF (1U << 20) +#define R0_SC_CKSQ1_OFF (1U << 21) +#define R0_SC_DR_SHU_EN_PCM (1U << 22) +#define R0_SC_DPHY_PRECAL_UP (1U << 23) +#define R0_SC_MPLL_S_OFF (1U << 24) +#define R0_SC_DPHY_RXDLY_TRACK_EN (1U << 25) +#define R0_SC_PHYPLL_SHU_EN_PCM (1U << 26) +#define R0_SC_PHYPLL2_SHU_EN_PCM (1U << 27) +#define R0_SC_PHYPLL_MODE_SW_PCM (1U << 28) +#define R0_SC_PHYPLL2_MODE_SW_PCM (1U << 29) +#define R0_SC_DR_SHU_LEVEL_PCM0 (1U << 30) +#define R0_SC_DR_SHU_LEVEL_PCM1 (1U << 31) + +/* --- R7 Define --- */ +#define R7_PWRAP_SLEEP_REQ (1U << 0) +#define R7_EMI_CLK_OFF_REQ (1U << 1) +#define R7_TOP_MAS_PAU_REQ (1U << 2) +#define R7_SPM2CKSYS_MEM_CK_MUX_UPDATE (1U << 3) +#define R7_PCM_CK_SEL0 (1U << 4) +#define R7_PCM_CK_SEL1 (1U << 5) +#define R7_SPM2RC_DVS_DONE (1U << 6) +#define R7_FREQH_PAUSE_MPLL (1U << 7) +#define R7_SC_26M_CK_SEL (1U << 8) +#define R7_PCM_TIMER_SET (1U << 9) +#define R7_PCM_TIMER_CLR (1U << 10) +#define R7_SRCVOLTEN (1U << 11) +#define R7_CSYSPWRUPACK (1U << 12) +#define R7_IM_SLEEP_ENABLE (1U << 13) +#define R7_SRCCLKENO_0 (1U << 14) +#define R7_SYSRST (1U << 15) +#define R7_MD_APSRC_ACK (1U << 16) +#define R7_CPU_SYS_TIMER_CLK_SEL (1U << 17) +#define R7_SC_AXI_DCM_DIS (1U << 18) +#define R7_FREQH_PAUSE_MAIN (1U << 19) +#define R7_FREQH_PAUSE_MEM (1U << 20) +#define R7_SRCCLKENO_1 (1U << 21) +#define R7_WDT_KICK_P (1U << 22) +#define R7_SPM2RC_EVENT_ABORT_ACK (1U << 23) +#define R7_WAKEUP_EXT_W_SEL (1U << 24) +#define R7_WAKEUP_EXT_R_SEL (1U << 25) +#define R7_PMIC_IRQ_REQ_EN (1U << 26) +#define R7_FORCE_26M_WAKE (1U << 27) +#define R7_FORCE_APSRC_WAKE (1U << 28) +#define R7_FORCE_INFRA_WAKE (1U << 29) +#define R7_FORCE_VRF18_WAKE (1U << 30) +#define R7_SC_DR_SHORT_QUEUE_PCM (1U << 31) + +/* --- R12 Define --- */ +#define R12_PCM_TIMER (1U << 0) +#define R12_SSPM_WDT_EVENT_B (1U << 1) +#define R12_KP_IRQ_B (1U << 2) +#define R12_APWDT_EVENT_B (1U << 3) +#define R12_APXGPT1_EVENT_B (1U << 4) +#define R12_CONN2AP_SPM_WAKEUP_B (1U << 5) +#define R12_EINT_EVENT_B (1U << 6) +#define R12_CONN_WDT_IRQ_B (1U << 7) +#define R12_CCIF0_EVENT_B (1U << 8) +#define R12_LOWBATTERY_IRQ_B (1U << 9) +#define R12_SSPM_SPM_IRQ_B (1U << 10) +#define R12_SCP_SPM_IRQ_B (1U << 11) +#define R12_SCP_WDT_EVENT_B (1U << 12) +#define R12_PCM_WDT_WAKEUP_B (1U << 13) +#define R12_USB_CDSC_B (1U << 14) +#define R12_USB_POWERDWN_B (1U << 15) +#define R12_SYS_TIMER_EVENT_B (1U << 16) +#define R12_EINT_EVENT_SECURE_B (1U << 17) +#define R12_CCIF1_EVENT_B (1U << 18) +#define R12_UART0_IRQ_B (1U << 19) +#define R12_AFE_IRQ_MCU_B (1U << 20) +#define R12_THERM_CTRL_EVENT_B (1U << 21) +#define R12_SYS_CIRQ_IRQ_B (1U << 22) +#define R12_MD2AP_PEER_EVENT_B (1U << 23) +#define R12_CSYSPWREQ_B (1U << 24) +#define R12_MD1_WDT_B (1U << 25) +#define R12_CLDMA_EVENT_B (1U << 26) +#define R12_SEJ_WDT_GPT_B (1U << 27) +#define R12_ALL_SSPM_WAKEUP_B (1U << 28) +#define R12_CPU_IRQ_B (1U << 29) +#define R12_CPU_WFI_AND_B (1U << 30) +#define R12_MCUSYS_IDLE_TO_EMI_ALL_B (1U << 31) + +/* --- R12ext Define --- */ +#define R12EXT_26M_WAKE (1U << 0) +#define R12EXT_26M_SLEEP (1U << 1) +#define R12EXT_INFRA_WAKE (1U << 2) +#define R12EXT_INFRA_SLEEP (1U << 3) +#define R12EXT_APSRC_WAKE (1U << 4) +#define R12EXT_APSRC_SLEEP (1U << 5) +#define R12EXT_VRF18_WAKE (1U << 6) +#define R12EXT_VRF18_SLEEP (1U << 7) +#define R12EXT_DVFS_ALL_STATE (1U << 8) +#define R12EXT_DVFS_LEVEL_STATE0 (1U << 9) +#define R12EXT_DVFS_LEVEL_STATE1 (1U << 10) +#define R12EXT_DVFS_LEVEL_STATE2 (1U << 11) +#define R12EXT_DDREN_WAKE (1U << 12) +#define R12EXT_DDREN_SLEEP (1U << 13) +#define R12EXT_NFC_CLK_BUF_WAKE (1U << 14) +#define R12EXT_NFC_CLK_BUF_SLEEP (1U << 15) +#define R12EXT_CONN_CLK_BUF_WAKE (1U << 16) +#define R12EXT_CONN_CLK_BUF_SLEEP (1U << 17) +#define R12EXT_MD_DVFS_ERROR_STATUS (1U << 18) +#define R12EXT_DVFS_LEVEL_STATE3 (1U << 19) +#define R12EXT_DVFS_LEVEL_STATE4 (1U << 20) +#define R12EXT_DVFS_LEVEL_STATE5 (1U << 21) +#define R12EXT_DVFS_LEVEL_STATE6 (1U << 22) +#define R12EXT_DVFS_LEVEL_STATE7 (1U << 23) +#define R12EXT_DVFS_LEVEL_STATE8 (1U << 24) +#define R12EXT_DVFS_LEVEL_STATE9 (1U << 25) +#define R12EXT_DVFS_LEVEL_STATE_G0 (1U << 26) +#define R12EXT_DVFS_LEVEL_STATE_G1 (1U << 27) +#define R12EXT_DVFS_LEVEL_STATE_G2 (1U << 28) +#define R12EXT_DVFS_LEVEL_STATE_G3 (1U << 29) +#define R12EXT_HYBRID_DDREN_SLEEP (1U << 30) +#define R12EXT_HYBRID_DDREN_WAKE (1U << 31) + +/* --- R13 Define --- */ +#define R13_EXT_SRCCLKENI_0 (1U << 0) +#define R13_EXT_SRCCLKENI_1 (1U << 1) +#define R13_MD1_SRCCLKENA (1U << 2) +#define R13_MD1_APSRC_REQ (1U << 3) +#define R13_CONN_DDR_EN (1U << 4) +#define R13_MD2_SRCCLKENA (1U << 5) +#define R13_SSPM_SRCCLKENA (1U << 6) +#define R13_SSPM_APSRC_REQ (1U << 7) +#define R13_MD_STATE (1U << 8) +#define R13_EMI_CLK_OFF_2_ACK (1U << 9) +#define R13_MM_STATE (1U << 10) +#define R13_SSPM_STATE (1U << 11) +#define R13_MD_DDR_EN (1U << 12) +#define R13_CONN_STATE (1U << 13) +#define R13_CONN_SRCCLKENA (1U << 14) +#define R13_CONN_APSRC_REQ (1U << 15) +#define R13_SLEEP_EVENT_STA (1U << 16) +#define R13_WAKE_EVENT_STA (1U << 17) +#define R13_EMI_IDLE (1U << 18) +#define R13_CSYSPWRUPREQ (1U << 19) +#define R13_PWRAP_SLEEP_ACK (1U << 20) +#define R13_EMI_CLK_OFF_ACK_ALL (1U << 21) +#define R13_TOP_MAS_PAU_ACK (1U << 22) +#define R13_SW_DMDRAMCSHU_ACK_ALL (1U << 23) +#define R13_RC2SPM_EVENT_ABORT_MASK_OR (1U << 24) +#define R13_DR_SHORT_QUEUE_ACK_ALL (1U << 25) +#define R13_INFRA_AUX_IDLE (1U << 26) +#define R13_DVFS_ALL_STATE (1U << 27) +#define R13_RC2SPM_EVENT_ABORT_OR (1U << 28) +#define R13_DRAMC_SPCMD_APSRC_REQ (1U << 29) +#define R13_MD1_VRF18_REQ (1U << 30) +#define R13_C2K_VRF18_REQ (1U << 31) + +#define is_cpu_pdn(flags) (!((flags) & SPM_FLAG_DIS_CPU_PDN)) +#define is_infra_pdn(flags) (!((flags) & SPM_FLAG_DIS_INFRA_PDN)) +#define is_ddrphy_pdn(flags) (!((flags) & SPM_FLAG_DIS_DDRPHY_PDN)) + +#define MP0_SPMC_SRAM_DORMANT_EN (1<<0) +#define MP1_SPMC_SRAM_DORMANT_EN (1<<1) +#define MP2_SPMC_SRAM_DORMANT_EN (1<<2) + +#define EVENT_VEC(event, resume, imme, pc) \ + (((pc) << 16) | \ + (!!(imme) << 7) | \ + (!!(resume) << 6) | \ + ((event) & 0x3f)) + +#define SPM_PROJECT_CODE 0xb16 +#define SPM_REGWR_CFG_KEY (SPM_PROJECT_CODE << 16) + +/************************************** + * Config and Parameter + **************************************/ +#define POWER_ON_VAL1_DEF 0x00015800 +#define PCM_FSM_STA_DEF 0x00108490 +#define SPM_WAKEUP_EVENT_MASK_DEF 0xF0F92218 +#define PCM_WDT_TIMEOUT (30 * 32768) /* 30s */ +#define PCM_TIMER_MAX (0xffffffff - PCM_WDT_TIMEOUT) + +/************************************** + * Define and Declare + **************************************/ +/* PCM_PWR_IO_EN */ +#define PCM_PWRIO_EN_R0 (1U << 0) +#define PCM_PWRIO_EN_R7 (1U << 7) +#define PCM_RF_SYNC_R0 (1U << 16) +#define PCM_RF_SYNC_R6 (1U << 22) +#define PCM_RF_SYNC_R7 (1U << 23) + +/* SPM_SWINT */ +#define PCM_SW_INT0 (1U << 0) +#define PCM_SW_INT1 (1U << 1) +#define PCM_SW_INT2 (1U << 2) +#define PCM_SW_INT3 (1U << 3) +#define PCM_SW_INT4 (1U << 4) +#define PCM_SW_INT5 (1U << 5) +#define PCM_SW_INT6 (1U << 6) +#define PCM_SW_INT7 (1U << 7) +#define PCM_SW_INT8 (1U << 8) +#define PCM_SW_INT9 (1U << 9) +#define PCM_SW_INT_ALL (PCM_SW_INT9 | PCM_SW_INT8 | PCM_SW_INT7 | \ + PCM_SW_INT6 | PCM_SW_INT5 | PCM_SW_INT4 | \ + PCM_SW_INT3 | PCM_SW_INT2 | PCM_SW_INT1 | \ + PCM_SW_INT0) +/* SPM_IRQ_MASK */ +#define ISRM_TWAM (1U << 2) +#define ISRM_PCM_RETURN (1U << 3) +#define ISRM_RET_IRQ0 (1U << 8) +#define ISRM_RET_IRQ1 (1U << 9) +#define ISRM_RET_IRQ2 (1U << 10) +#define ISRM_RET_IRQ3 (1U << 11) +#define ISRM_RET_IRQ4 (1U << 12) +#define ISRM_RET_IRQ5 (1U << 13) +#define ISRM_RET_IRQ6 (1U << 14) +#define ISRM_RET_IRQ7 (1U << 15) +#define ISRM_RET_IRQ8 (1U << 16) +#define ISRM_RET_IRQ9 (1U << 17) +#define ISRM_RET_IRQ_AUX (ISRM_RET_IRQ9 | ISRM_RET_IRQ8 | \ + ISRM_RET_IRQ7 | ISRM_RET_IRQ6 | \ + ISRM_RET_IRQ5 | ISRM_RET_IRQ4 | \ + ISRM_RET_IRQ3 | ISRM_RET_IRQ2 | \ + ISRM_RET_IRQ1) +#define ISRM_ALL_EXC_TWAM (ISRM_RET_IRQ_AUX) +#define ISRM_ALL (ISRM_ALL_EXC_TWAM | ISRM_TWAM) + +/* SPM_IRQ_STA */ +#define ISRS_TWAM (1U << 2) +#define ISRS_PCM_RETURN (1U << 3) +#define ISRS_SW_INT0 (1U << 4) +#define ISRC_TWAM ISRS_TWAM +#define ISRC_ALL_EXC_TWAM ISRS_PCM_RETURN +#define ISRC_ALL (ISRC_ALL_EXC_TWAM | ISRC_TWAM) + +/* SPM_WAKEUP_MISC */ +#define WAKE_MISC_TWAM (1U << 18) +#define WAKE_MISC_PCM_TIMER (1U << 19) +#define WAKE_MISC_CPU_WAKE (1U << 20) + +enum SPM_WAKE_SRC_LIST { + WAKE_SRC_R12_PCM_TIMER = (1U << 0), + WAKE_SRC_R12_SSPM_WDT_EVENT_B = (1U << 1), + WAKE_SRC_R12_KP_IRQ_B = (1U << 2), + WAKE_SRC_R12_APWDT_EVENT_B = (1U << 3), + WAKE_SRC_R12_APXGPT1_EVENT_B = (1U << 4), + WAKE_SRC_R12_CONN2AP_SPM_WAKEUP_B = (1U << 5), + WAKE_SRC_R12_EINT_EVENT_B = (1U << 6), + WAKE_SRC_R12_CONN_WDT_IRQ_B = (1U << 7), + WAKE_SRC_R12_CCIF0_EVENT_B = (1U << 8), + WAKE_SRC_R12_LOWBATTERY_IRQ_B = (1U << 9), + WAKE_SRC_R12_SSPM_SPM_IRQ_B = (1U << 10), + WAKE_SRC_R12_SCP_SPM_IRQ_B = (1U << 11), + WAKE_SRC_R12_SCP_WDT_EVENT_B = (1U << 12), + WAKE_SRC_R12_PCM_WDT_WAKEUP_B = (1U << 13), + WAKE_SRC_R12_USB_CDSC_B = (1U << 14), + WAKE_SRC_R12_USB_POWERDWN_B = (1U << 15), + WAKE_SRC_R12_SYS_TIMER_EVENT_B = (1U << 16), + WAKE_SRC_R12_EINT_EVENT_SECURE_B = (1U << 17), + WAKE_SRC_R12_CCIF1_EVENT_B = (1U << 18), + WAKE_SRC_R12_UART0_IRQ_B = (1U << 19), + WAKE_SRC_R12_AFE_IRQ_MCU_B = (1U << 20), + WAKE_SRC_R12_THERM_CTRL_EVENT_B = (1U << 21), + WAKE_SRC_R12_SYS_CIRQ_IRQ_B = (1U << 22), + WAKE_SRC_R12_MD2AP_PEER_EVENT_B = (1U << 23), + WAKE_SRC_R12_CSYSPWREQ_B = (1U << 24), + WAKE_SRC_R12_MD1_WDT_B = (1U << 25), + WAKE_SRC_R12_CLDMA_EVENT_B = (1U << 26), + WAKE_SRC_R12_SEJ_WDT_GPT_B = (1U << 27), + WAKE_SRC_R12_ALL_SSPM_WAKEUP_B = (1U << 28), + WAKE_SRC_R12_CPU_IRQ_B = (1U << 29), + WAKE_SRC_R12_CPU_WFI_AND_B = (1U << 30), +}; + +struct pcm_desc { + const char *version; + const uint32_t *base; + const uint32_t base_dma; + const uint32_t size; + const uint32_t sess; + const uint32_t replace; + const uint32_t addr_2nd; + const uint32_t reserved; + + uint32_t vec0; + uint32_t vec1; + uint32_t vec2; + uint32_t vec3; + uint32_t vec4; + uint32_t vec5; + uint32_t vec6; + uint32_t vec7; + uint32_t vec8; + uint32_t vec9; + uint32_t vec10; + uint32_t vec11; + uint32_t vec12; + uint32_t vec13; + uint32_t vec14; + uint32_t vec15; +}; + +struct pwr_ctrl { + uint32_t pcm_flags; + uint32_t pcm_flags1; + uint32_t timer_val; + uint32_t wake_src; + + /* SPM_AP_STANDBY_CON */ + uint8_t wfi_op; + uint8_t mp0_cputop_idle_mask; + uint8_t mp1_cputop_idle_mask; + uint8_t mcusys_idle_mask; + uint8_t mm_mask_b; + uint8_t md_ddr_en_0_dbc_en; + uint8_t md_ddr_en_1_dbc_en; + uint8_t md_mask_b; + uint8_t sspm_mask_b; + uint8_t scp_mask_b; + uint8_t srcclkeni_mask_b; + uint8_t md_apsrc_1_sel; + uint8_t md_apsrc_0_sel; + uint8_t conn_ddr_en_dbc_en; + uint8_t conn_mask_b; + uint8_t conn_apsrc_sel; + + /* SPM_SRC_REQ */ + uint8_t spm_apsrc_req; + uint8_t spm_f26m_req; + uint8_t spm_infra_req; + uint8_t spm_vrf18_req; + uint8_t spm_ddren_req; + uint8_t spm_rsv_src_req; + uint8_t spm_ddren_2_req; + uint8_t cpu_md_dvfs_sop_force_on; + + /* SPM_SRC_MASK */ + uint8_t csyspwreq_mask; + uint8_t ccif0_md_event_mask_b; + uint8_t ccif0_ap_event_mask_b; + uint8_t ccif1_md_event_mask_b; + uint8_t ccif1_ap_event_mask_b; + uint8_t ccif2_md_event_mask_b; + uint8_t ccif2_ap_event_mask_b; + uint8_t ccif3_md_event_mask_b; + uint8_t ccif3_ap_event_mask_b; + uint8_t md_srcclkena_0_infra_mask_b; + uint8_t md_srcclkena_1_infra_mask_b; + uint8_t conn_srcclkena_infra_mask_b; + uint8_t ufs_infra_req_mask_b; + uint8_t srcclkeni_infra_mask_b; + uint8_t md_apsrc_req_0_infra_mask_b; + uint8_t md_apsrc_req_1_infra_mask_b; + uint8_t conn_apsrcreq_infra_mask_b; + uint8_t ufs_srcclkena_mask_b; + uint8_t md_vrf18_req_0_mask_b; + uint8_t md_vrf18_req_1_mask_b; + uint8_t ufs_vrf18_req_mask_b; + uint8_t gce_vrf18_req_mask_b; + uint8_t conn_infra_req_mask_b; + uint8_t gce_apsrc_req_mask_b; + uint8_t disp0_apsrc_req_mask_b; + uint8_t disp1_apsrc_req_mask_b; + uint8_t mfg_req_mask_b; + uint8_t vdec_req_mask_b; + + /* SPM_SRC2_MASK */ + uint8_t md_ddr_en_0_mask_b; + uint8_t md_ddr_en_1_mask_b; + uint8_t conn_ddr_en_mask_b; + uint8_t ddren_sspm_apsrc_req_mask_b; + uint8_t ddren_scp_apsrc_req_mask_b; + uint8_t disp0_ddren_mask_b; + uint8_t disp1_ddren_mask_b; + uint8_t gce_ddren_mask_b; + uint8_t ddren_emi_self_refresh_ch0_mask_b; + uint8_t ddren_emi_self_refresh_ch1_mask_b; + + /* SPM_WAKEUP_EVENT_MASK */ + uint32_t spm_wakeup_event_mask; + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + uint32_t spm_wakeup_event_ext_mask; + + /* SPM_SRC3_MASK */ + uint8_t md_ddr_en_2_0_mask_b; + uint8_t md_ddr_en_2_1_mask_b; + uint8_t conn_ddr_en_2_mask_b; + uint8_t ddren2_sspm_apsrc_req_mask_b; + uint8_t ddren2_scp_apsrc_req_mask_b; + uint8_t disp0_ddren2_mask_b; + uint8_t disp1_ddren2_mask_b; + uint8_t gce_ddren2_mask_b; + uint8_t ddren2_emi_self_refresh_ch0_mask_b; + uint8_t ddren2_emi_self_refresh_ch1_mask_b; + + uint8_t mp0_cpu0_wfi_en; + uint8_t mp0_cpu1_wfi_en; + uint8_t mp0_cpu2_wfi_en; + uint8_t mp0_cpu3_wfi_en; + + uint8_t mp1_cpu0_wfi_en; + uint8_t mp1_cpu1_wfi_en; + uint8_t mp1_cpu2_wfi_en; + uint8_t mp1_cpu3_wfi_en; +}; + +struct wake_status { + uint32_t assert_pc; + uint32_t r12; + uint32_t r12_ext; + uint32_t raw_sta; + uint32_t raw_ext_sta; + uint32_t wake_misc; + uint32_t timer_out; + uint32_t r13; + uint32_t r15; + uint32_t idle_sta; + uint32_t req_sta; + uint32_t debug_flag; + uint32_t debug_flag1; + uint32_t event_reg; + uint32_t isr; + uint32_t sw_flag; + uint32_t sw_flag1; + uint32_t log_index; +}; + +typedef struct spm_data { + unsigned int cmd; + union { + struct { + unsigned int sys_timestamp_l; + unsigned int sys_timestamp_h; + unsigned int sys_src_clk_l; + unsigned int sys_src_clk_h; + unsigned int spm_opt; + } suspend; + struct { + unsigned int args1; + unsigned int args2; + unsigned int args3; + unsigned int args4; + unsigned int args5; + unsigned int args6; + unsigned int args7; + } args; + } u; +} spm_data_t; + +enum { + SPM_SUSPEND, + SPM_RESUME +}; + +extern void spm_disable_pcm_timer(void); +extern void spm_set_bootaddr(unsigned long bootaddr); +extern void spm_set_cpu_status(int cpu); +extern void spm_set_power_control(const struct pwr_ctrl *pwrctrl); +extern void spm_set_wakeup_event(const struct pwr_ctrl *pwrctrl); +extern void spm_set_pcm_flags(const struct pwr_ctrl *pwrctrl); +extern void spm_send_cpu_wakeup_event(void); +extern void spm_get_wakeup_status(struct wake_status *wakesta); +extern void spm_clean_after_wakeup(void); +extern void spm_output_wake_reason(struct wake_status *wakesta, + const char *scenario); +extern void spm_set_pcm_wdt(int en); +extern void spm_lock_get(void); +extern void spm_lock_release(void); +extern void spm_boot_init(void); +extern const char *spm_get_firmware_version(void); + +#endif /* SPM_H */ diff --git a/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.c b/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.c new file mode 100644 index 000000000..ce8527263 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/debug.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <spm.h> +#include <spm_pmic_wrap.h> +#include <lib/libc/string.h> + +#define SLEEP_REG_MD_SPM_DVFS_CMD20 (SLEEP_REG_MD_BASE + 0x010) +#define SLEEP_REG_MD_SPM_DVFS_CMD21 (SLEEP_REG_MD_BASE + 0x014) +#define SLEEP_REG_MD_SPM_DVFS_CMD22 (SLEEP_REG_MD_BASE + 0x018) +#define SLEEP_REG_MD_SPM_DVFS_CMD23 (SLEEP_REG_MD_BASE + 0x01C) + +/* PMIC_WRAP -> PMIC MT6358 */ +#define VCORE_BASE_UV 50000 +#define VOLT_TO_PMIC_VAL(volt) (((volt) - VCORE_BASE_UV + 625 - 1) / 625) +#define PMIC_VAL_TO_VOLT(pmic) (((pmic) * 625) + VCORE_BASE_UV) + +#define DEFAULT_VOLT_VSRAM (100000) +#define DEFAULT_VOLT_VCORE (100000) +#define NR_PMIC_WRAP_CMD (NR_IDX_ALL) +#define MAX_RETRY_COUNT (100) +#define SPM_DATA_SHIFT (16) + +#define BUCK_VCORE_ELR0 0x14AA +#define BUCK_VPROC12_CON0 0x1408 +#define BUCK_VPROC11_CON0 0x1388 +#define TOP_SPI_CON0 0x044C +#define LDO_VSRAM_PROC12_CON0 0x1B88 +#define LDO_VSRAM_PROC11_CON0 0x1B46 +#define BUCK_VMODEM_ELR0 0x15A6 + +struct pmic_wrap_cmd { + unsigned long cmd_addr; + unsigned long cmd_wdata; +}; + +struct pmic_wrap_setting { + enum pmic_wrap_phase_id phase; + struct pmic_wrap_cmd addr[NR_PMIC_WRAP_CMD]; + struct { + struct { + unsigned long cmd_addr; + unsigned long cmd_wdata; + } _[NR_PMIC_WRAP_CMD]; + const int nr_idx; + } set[NR_PMIC_WRAP_PHASE]; +}; + +static struct pmic_wrap_setting pw = { + .phase = NR_PMIC_WRAP_PHASE, + .addr = {{0, 0} }, + .set[PMIC_WRAP_PHASE_ALLINONE] = { + ._[CMD_0] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(70000),}, + ._[CMD_1] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(80000),}, + ._[CMD_2] = {BUCK_VPROC12_CON0, 0x3,}, + ._[CMD_3] = {BUCK_VPROC12_CON0, 0x1,}, + ._[CMD_4] = {BUCK_VPROC11_CON0, 0x3,}, + ._[CMD_5] = {BUCK_VPROC11_CON0, 0x1,}, + ._[CMD_6] = {TOP_SPI_CON0, 0x1,}, + ._[CMD_7] = {TOP_SPI_CON0, 0x0,}, + ._[CMD_8] = {BUCK_VPROC12_CON0, 0x0,}, + ._[CMD_9] = {BUCK_VPROC12_CON0, 0x1,}, + ._[CMD_10] = {BUCK_VPROC11_CON0, 0x0,}, + ._[CMD_11] = {BUCK_VPROC11_CON0, 0x1,}, + ._[CMD_12] = {LDO_VSRAM_PROC12_CON0, 0x0,}, + ._[CMD_13] = {LDO_VSRAM_PROC12_CON0, 0x1,}, + ._[CMD_14] = {LDO_VSRAM_PROC11_CON0, 0x0,}, + ._[CMD_15] = {LDO_VSRAM_PROC11_CON0, 0x1,}, + ._[CMD_20] = {BUCK_VMODEM_ELR0, VOLT_TO_PMIC_VAL(55000),}, + ._[CMD_21] = {BUCK_VCORE_ELR0, VOLT_TO_PMIC_VAL(60000),}, + ._[CMD_22] = {LDO_VSRAM_PROC11_CON0, 0x3,}, + ._[CMD_23] = {LDO_VSRAM_PROC11_CON0, 0x1,}, + .nr_idx = NR_IDX_ALL + } +}; + +void _mt_spm_pmic_table_init(void) +{ + struct pmic_wrap_cmd pwrap_cmd_default[NR_PMIC_WRAP_CMD] = { + {(uint32_t)SPM_DVFS_CMD0, (uint32_t)SPM_DVFS_CMD0,}, + {(uint32_t)SPM_DVFS_CMD1, (uint32_t)SPM_DVFS_CMD1,}, + {(uint32_t)SPM_DVFS_CMD2, (uint32_t)SPM_DVFS_CMD2,}, + {(uint32_t)SPM_DVFS_CMD3, (uint32_t)SPM_DVFS_CMD3,}, + {(uint32_t)SPM_DVFS_CMD4, (uint32_t)SPM_DVFS_CMD4,}, + {(uint32_t)SPM_DVFS_CMD5, (uint32_t)SPM_DVFS_CMD5,}, + {(uint32_t)SPM_DVFS_CMD6, (uint32_t)SPM_DVFS_CMD6,}, + {(uint32_t)SPM_DVFS_CMD7, (uint32_t)SPM_DVFS_CMD7,}, + {(uint32_t)SPM_DVFS_CMD8, (uint32_t)SPM_DVFS_CMD8,}, + {(uint32_t)SPM_DVFS_CMD9, (uint32_t)SPM_DVFS_CMD9,}, + {(uint32_t)SPM_DVFS_CMD10, (uint32_t)SPM_DVFS_CMD10,}, + {(uint32_t)SPM_DVFS_CMD11, (uint32_t)SPM_DVFS_CMD11,}, + {(uint32_t)SPM_DVFS_CMD12, (uint32_t)SPM_DVFS_CMD12,}, + {(uint32_t)SPM_DVFS_CMD13, (uint32_t)SPM_DVFS_CMD13,}, + {(uint32_t)SPM_DVFS_CMD14, (uint32_t)SPM_DVFS_CMD14,}, + {(uint32_t)SPM_DVFS_CMD15, (uint32_t)SPM_DVFS_CMD15,}, + {(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD20, + (uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD20,}, + {(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD21, + (uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD21,}, + {(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD22, + (uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD22,}, + {(uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD23, + (uint32_t)SLEEP_REG_MD_SPM_DVFS_CMD23,} + }; + + memcpy(pw.addr, pwrap_cmd_default, sizeof(pwrap_cmd_default)); +} + +void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase) +{ + uint32_t idx, addr, data; + + if (phase >= NR_PMIC_WRAP_PHASE) + return; + + if (pw.phase == phase) + return; + + if (pw.addr[0].cmd_addr == 0) + _mt_spm_pmic_table_init(); + + pw.phase = phase; + + mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | + BCLK_CG_EN_LSB | MD_BCLK_CG_EN_LSB); + for (idx = 0; idx < pw.set[phase].nr_idx; idx++) { + addr = pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT; + data = pw.set[phase]._[idx].cmd_wdata; + mmio_write_32(pw.addr[idx].cmd_addr, addr | data); + } +} + +void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, uint32_t idx, + uint32_t cmd_wdata) +{ + uint32_t addr; + + if (phase >= NR_PMIC_WRAP_PHASE) + return; + + if (idx >= pw.set[phase].nr_idx) + return; + + pw.set[phase]._[idx].cmd_wdata = cmd_wdata; + + mmio_write_32(POWERON_CONFIG_EN, SPM_REGWR_CFG_KEY | + BCLK_CG_EN_LSB | MD_BCLK_CG_EN_LSB); + if (pw.phase == phase) { + addr = pw.set[phase]._[idx].cmd_addr << SPM_DATA_SHIFT; + mmio_write_32(pw.addr[idx].cmd_addr, addr | cmd_wdata); + } +} + +uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, uint32_t idx) +{ + if (phase >= NR_PMIC_WRAP_PHASE) + return 0; + + if (idx >= pw.set[phase].nr_idx) + return 0; + + return pw.set[phase]._[idx].cmd_wdata; +} + diff --git a/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.h b/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.h new file mode 100644 index 000000000..194d34717 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm_pmic_wrap.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/**************************************************************** + * Auto generated by DE, please DO NOT modify this file directly. + *****************************************************************/ + +#ifndef SPM_PMIC_WRAP__H +#define SPM_PMIC_WRAP__H + +enum pmic_wrap_phase_id { + PMIC_WRAP_PHASE_ALLINONE, + NR_PMIC_WRAP_PHASE +}; + +/* IDX mapping */ +enum { + CMD_0, /* 0x0 *//* PMIC_WRAP_PHASE_ALLINONE */ + CMD_1, /* 0x1 */ + CMD_2, /* 0x2 */ + CMD_3, /* 0x3 */ + CMD_4, /* 0x4 */ + CMD_5, /* 0x5 */ + CMD_6, /* 0x6 */ + CMD_7, /* 0x7 */ + CMD_8, /* 0x8 */ + CMD_9, /* 0x9 */ + CMD_10, /* 0xA */ + CMD_11, /* 0xB */ + CMD_12, /* 0xC */ + CMD_13, /* 0xD */ + CMD_14, /* 0xE */ + CMD_15, /* 0xF */ + CMD_20, /* 0x14 */ + CMD_21, /* 0x15 */ + CMD_22, /* 0x16 */ + CMD_23, /* 0x17 */ + NR_IDX_ALL +}; + +/* APIs */ +void mt_spm_pmic_wrap_set_phase(enum pmic_wrap_phase_id phase); +void mt_spm_pmic_wrap_set_cmd(enum pmic_wrap_phase_id phase, + uint32_t idx, uint32_t cmd_wdata); +uint64_t mt_spm_pmic_wrap_get_cmd(enum pmic_wrap_phase_id phase, uint32_t idx); +#endif /* SPM_PMIC_WRAP__H */ + diff --git a/plat/mediatek/mt8183/drivers/spm/spm_suspend.c b/plat/mediatek/mt8183/drivers/spm/spm_suspend.c new file mode 100644 index 000000000..b9ac19f1f --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm_suspend.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <mt_gic_v3.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <pmic.h> +#include <spm.h> +#include <uart.h> + +#define SPM_SYSCLK_SETTLE 99 + +#define WAKE_SRC_FOR_SUSPEND \ + (WAKE_SRC_R12_PCM_TIMER | \ + WAKE_SRC_R12_SSPM_WDT_EVENT_B | \ + WAKE_SRC_R12_KP_IRQ_B | \ + WAKE_SRC_R12_CONN2AP_SPM_WAKEUP_B | \ + WAKE_SRC_R12_EINT_EVENT_B | \ + WAKE_SRC_R12_CONN_WDT_IRQ_B | \ + WAKE_SRC_R12_CCIF0_EVENT_B | \ + WAKE_SRC_R12_SSPM_SPM_IRQ_B | \ + WAKE_SRC_R12_SCP_SPM_IRQ_B | \ + WAKE_SRC_R12_SCP_WDT_EVENT_B | \ + WAKE_SRC_R12_USB_CDSC_B | \ + WAKE_SRC_R12_USB_POWERDWN_B | \ + WAKE_SRC_R12_SYS_TIMER_EVENT_B | \ + WAKE_SRC_R12_EINT_EVENT_SECURE_B | \ + WAKE_SRC_R12_CCIF1_EVENT_B | \ + WAKE_SRC_R12_MD2AP_PEER_EVENT_B | \ + WAKE_SRC_R12_MD1_WDT_B | \ + WAKE_SRC_R12_CLDMA_EVENT_B | \ + WAKE_SRC_R12_SEJ_WDT_GPT_B) + +#define SLP_PCM_FLAGS \ + (SPM_FLAG_DIS_VCORE_DVS | SPM_FLAG_DIS_VCORE_DFS | \ + SPM_FLAG_DIS_ATF_ABORT | SPM_FLAG_DISABLE_MMSYS_DVFS | \ + SPM_FLAG_DIS_INFRA_PDN | SPM_FLAG_SUSPEND_OPTION) + +#define SLP_PCM_FLAGS1 \ + (SPM_FLAG1_DISABLE_MCDSR) + +static const struct pwr_ctrl suspend_ctrl = { + .wake_src = WAKE_SRC_FOR_SUSPEND, + .pcm_flags = SLP_PCM_FLAGS, + .pcm_flags1 = SLP_PCM_FLAGS1, + + /* SPM_AP_STANDBY_CON */ + .wfi_op = 0x1, + .mp0_cputop_idle_mask = 0, + .mp1_cputop_idle_mask = 0, + .mcusys_idle_mask = 0, + .mm_mask_b = 0, + .md_ddr_en_0_dbc_en = 0x1, + .md_ddr_en_1_dbc_en = 0, + .md_mask_b = 0x1, + .sspm_mask_b = 0x1, + .scp_mask_b = 0x1, + .srcclkeni_mask_b = 0x1, + .md_apsrc_1_sel = 0, + .md_apsrc_0_sel = 0, + .conn_ddr_en_dbc_en = 0x1, + .conn_mask_b = 0x1, + .conn_apsrc_sel = 0, + + /* SPM_SRC_REQ */ + .spm_apsrc_req = 0, + .spm_f26m_req = 0, + .spm_infra_req = 0, + .spm_vrf18_req = 0, + .spm_ddren_req = 0, + .spm_rsv_src_req = 0, + .spm_ddren_2_req = 0, + .cpu_md_dvfs_sop_force_on = 0, + + /* SPM_SRC_MASK */ + .csyspwreq_mask = 0x1, + .ccif0_md_event_mask_b = 0x1, + .ccif0_ap_event_mask_b = 0x1, + .ccif1_md_event_mask_b = 0x1, + .ccif1_ap_event_mask_b = 0x1, + .ccif2_md_event_mask_b = 0x1, + .ccif2_ap_event_mask_b = 0x1, + .ccif3_md_event_mask_b = 0x1, + .ccif3_ap_event_mask_b = 0x1, + .md_srcclkena_0_infra_mask_b = 0x1, + .md_srcclkena_1_infra_mask_b = 0, + .conn_srcclkena_infra_mask_b = 0, + .ufs_infra_req_mask_b = 0, + .srcclkeni_infra_mask_b = 0, + .md_apsrc_req_0_infra_mask_b = 0x1, + .md_apsrc_req_1_infra_mask_b = 0x1, + .conn_apsrcreq_infra_mask_b = 0x1, + .ufs_srcclkena_mask_b = 0, + .md_vrf18_req_0_mask_b = 0, + .md_vrf18_req_1_mask_b = 0, + .ufs_vrf18_req_mask_b = 0, + .gce_vrf18_req_mask_b = 0, + .conn_infra_req_mask_b = 0x1, + .gce_apsrc_req_mask_b = 0, + .disp0_apsrc_req_mask_b = 0, + .disp1_apsrc_req_mask_b = 0, + .mfg_req_mask_b = 0, + .vdec_req_mask_b = 0, + + /* SPM_SRC2_MASK */ + .md_ddr_en_0_mask_b = 0x1, + .md_ddr_en_1_mask_b = 0, + .conn_ddr_en_mask_b = 0x1, + .ddren_sspm_apsrc_req_mask_b = 0x1, + .ddren_scp_apsrc_req_mask_b = 0x1, + .disp0_ddren_mask_b = 0x1, + .disp1_ddren_mask_b = 0x1, + .gce_ddren_mask_b = 0x1, + .ddren_emi_self_refresh_ch0_mask_b = 0, + .ddren_emi_self_refresh_ch1_mask_b = 0, + + /* SPM_WAKEUP_EVENT_MASK */ + .spm_wakeup_event_mask = 0xF1782218, + + /* SPM_WAKEUP_EVENT_EXT_MASK */ + .spm_wakeup_event_ext_mask = 0xFFFFFFFF, + + /* SPM_SRC3_MASK */ + .md_ddr_en_2_0_mask_b = 0x1, + .md_ddr_en_2_1_mask_b = 0, + .conn_ddr_en_2_mask_b = 0x1, + .ddren2_sspm_apsrc_req_mask_b = 0x1, + .ddren2_scp_apsrc_req_mask_b = 0x1, + .disp0_ddren2_mask_b = 0, + .disp1_ddren2_mask_b = 0, + .gce_ddren2_mask_b = 0, + .ddren2_emi_self_refresh_ch0_mask_b = 0, + .ddren2_emi_self_refresh_ch1_mask_b = 0, + + .mp0_cpu0_wfi_en = 0x1, + .mp0_cpu1_wfi_en = 0x1, + .mp0_cpu2_wfi_en = 0x1, + .mp0_cpu3_wfi_en = 0x1, + + .mp1_cpu0_wfi_en = 0x1, + .mp1_cpu1_wfi_en = 0x1, + .mp1_cpu2_wfi_en = 0x1, + .mp1_cpu3_wfi_en = 0x1 +}; + +static uint32_t spm_set_sysclk_settle(void) +{ + mmio_write_32(SPM_CLK_SETTLE, SPM_SYSCLK_SETTLE); + return mmio_read_32(SPM_CLK_SETTLE); +} + +void go_to_sleep_before_wfi(void) +{ + int cpu = MPIDR_AFFLVL0_VAL(read_mpidr()); + uint32_t settle; + + settle = spm_set_sysclk_settle(); + spm_set_cpu_status(cpu); + spm_set_power_control(&suspend_ctrl); + spm_set_wakeup_event(&suspend_ctrl); + spm_set_pcm_flags(&suspend_ctrl); + spm_send_cpu_wakeup_event(); + spm_set_pcm_wdt(0); + spm_disable_pcm_timer(); + + if (is_infra_pdn(suspend_ctrl.pcm_flags)) + mt_uart_save(); + + if (!mt_console_uart_cg_status()) + console_switch_state(CONSOLE_FLAG_BOOT); + + INFO("cpu%d: \"%s\", wakesrc = 0x%x, pcm_con1 = 0x%x\n", + cpu, spm_get_firmware_version(), suspend_ctrl.wake_src, + mmio_read_32(PCM_CON1)); + INFO("settle = %u, sec = %u, sw_flag = 0x%x 0x%x, src_req = 0x%x\n", + settle, mmio_read_32(PCM_TIMER_VAL) / 32768, + suspend_ctrl.pcm_flags, suspend_ctrl.pcm_flags1, + mmio_read_32(SPM_SRC_REQ)); + + if (!mt_console_uart_cg_status()) + console_switch_state(CONSOLE_FLAG_RUNTIME); +} + +static void go_to_sleep_after_wfi(void) +{ + struct wake_status spm_wakesta; + + if (is_infra_pdn(suspend_ctrl.pcm_flags)) + mt_uart_restore(); + + spm_set_pcm_wdt(0); + spm_get_wakeup_status(&spm_wakesta); + spm_clean_after_wakeup(); + + if (!mt_console_uart_cg_status()) + console_switch_state(CONSOLE_FLAG_BOOT); + + spm_output_wake_reason(&spm_wakesta, "suspend"); + + if (!mt_console_uart_cg_status()) + console_switch_state(CONSOLE_FLAG_RUNTIME); +} + +static void spm_enable_armpll_l(void) +{ + /* power on */ + mmio_setbits_32(ARMPLL_L_PWR_CON0, 0x1); + + /* clear isolation */ + mmio_clrbits_32(ARMPLL_L_PWR_CON0, 0x2); + + /* enable pll */ + mmio_setbits_32(ARMPLL_L_CON0, 0x1); + + /* Add 20us delay for turning on PLL */ + udelay(20); +} + +static void spm_disable_armpll_l(void) +{ + /* disable pll */ + mmio_clrbits_32(ARMPLL_L_CON0, 0x1); + + /* isolation */ + mmio_setbits_32(ARMPLL_L_PWR_CON0, 0x2); + + /* power off */ + mmio_clrbits_32(ARMPLL_L_PWR_CON0, 0x1); +} + +void spm_system_suspend(void) +{ + spm_disable_armpll_l(); + bcpu_enable(0); + bcpu_sram_enable(0); + spm_lock_get(); + go_to_sleep_before_wfi(); + spm_lock_release(); +} + +void spm_system_suspend_finish(void) +{ + spm_lock_get(); + go_to_sleep_after_wfi(); + spm_lock_release(); + spm_enable_armpll_l(); + bcpu_sram_enable(1); + bcpu_enable(1); +} diff --git a/plat/mediatek/mt8183/drivers/spm/spm_suspend.h b/plat/mediatek/mt8183/drivers/spm/spm_suspend.h new file mode 100644 index 000000000..e127c2e7e --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spm/spm_suspend.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __SPM_SUSPEND_H__ +#define __SPM_SUSPEND_H__ + +void spm_system_suspend(void); +void spm_system_suspend_finish(void); + +#endif /* __SPM_SUSPEND_H__*/ diff --git a/plat/mediatek/mt8183/drivers/spmc/mtspmc.c b/plat/mediatek/mt8183/drivers/spmc/mtspmc.c new file mode 100644 index 000000000..ac8e1b47d --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spmc/mtspmc.c @@ -0,0 +1,366 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <arch_helpers.h> +#include <cortex_a53.h> +#include <cortex_a73.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <platform_def.h> +#include <mcucfg.h> +#include <spm.h> +#include <drivers/delay_timer.h> +#include <mtspmc.h> + +#include "mtspmc_private.h" + + +static void set_retention(int cluster, int tick) +{ + uint64_t cpuectlr; + + if (cluster) + cpuectlr = read_a73_cpuectlr_el1(); + else + cpuectlr = read_a53_cpuectlr_el1(); + + cpuectlr &= ~0x7ULL; + cpuectlr |= tick & 0x7; + + if (cluster) + write_a73_cpuectlr_el1(cpuectlr); + else + write_a53_cpuectlr_el1(cpuectlr); +} + +void spm_enable_cpu_auto_off(int cluster, int cpu) +{ + uintptr_t reg = per_cpu(cluster, cpu, MCUCFG_SPARK); + + set_retention(cluster, 1); + mmio_clrbits_32(reg, SW_NO_WAIT_Q); +} + +void spm_disable_cpu_auto_off(int cluster, int cpu) +{ + uintptr_t reg = per_cpu(cluster, cpu, MCUCFG_SPARK); + + mmio_setbits_32(reg, SW_NO_WAIT_Q); + set_retention(cluster, 0); +} + +void spm_set_cpu_power_off(int cluster, int cpu) +{ + mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON); +} + +void spm_enable_cluster_auto_off(int cluster) +{ + assert(cluster); + + mmio_clrbits_32(MCUCFG_MP2_SPMC, SW_NO_WAIT_Q); + mmio_clrbits_32(MCUCFG_MP2_COQ, BIT(0)); + + mmio_clrbits_32(SPM_SPMC_DORMANT_ENABLE, MP1_SPMC_SRAM_DORMANT_EN); + + mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON); +} + +void mcucfg_set_bootaddr(int cluster, int cpu, uintptr_t bootaddr) +{ + uintptr_t reg; + const uintptr_t mp2_bootreg[] = { + MCUCFG_MP2_RVADDR0, MCUCFG_MP2_RVADDR1, + MCUCFG_MP2_RVADDR2, MCUCFG_MP2_RVADDR3 }; + + if (cluster) { + assert(cpu >= 0 && cpu < 4); + reg = mp2_bootreg[cpu]; + } else { + reg = per_cpu(cluster, cpu, MCUCFG_BOOTADDR); + } + + mmio_write_32(reg, bootaddr); +} + +uintptr_t mcucfg_get_bootaddr(int cluster, int cpu) +{ + uintptr_t reg; + const uintptr_t mp2_bootreg[] = { + MCUCFG_MP2_RVADDR0, MCUCFG_MP2_RVADDR1, + MCUCFG_MP2_RVADDR2, MCUCFG_MP2_RVADDR3 }; + + if (cluster) { + assert(cpu >= 0 && cpu < 4); + reg = mp2_bootreg[cpu]; + } else { + reg = per_cpu(cluster, cpu, MCUCFG_BOOTADDR); + } + + return mmio_read_32(reg); +} + +void mcucfg_init_archstate(int cluster, int cpu, int arm64) +{ + uintptr_t reg; + int i; + + reg = per_cluster(cluster, MCUCFG_INITARCH); + i = cluster ? 16 : 12; + + mmio_setbits_32(reg, (arm64 & 1) << (i + cpu)); +} + +/** + * Return power state of specified subsystem + * + * @mask: mask to SPM_PWR_STATUS to query the power state + * of one subsystem. + * RETURNS: + * 0 (the subsys was powered off) + * 1 (the subsys was powered on) + */ +int spm_get_powerstate(uint32_t mask) +{ + return mmio_read_32(SPM_PWR_STATUS) & mask; +} + +int spm_get_cluster_powerstate(int cluster) +{ + uint32_t mask; + + mask = cluster ? PWR_STATUS_MP1_CPUTOP : PWR_STATUS_MP0_CPUTOP; + + return spm_get_powerstate(mask); +} + +int spm_get_cpu_powerstate(int cluster, int cpu) +{ + uint32_t i; + + /* + * a quick way to specify the mask of cpu[0-3]/cpu[4-7] in PWR_STATUS + * register which are the BITS[9:12](MP0_CPU0~3) and + * BITS[16:19](MP1_CPU0~3) + */ + i = (cluster) ? 16 : 9; + i = 1 << (i + cpu); + + return spm_get_powerstate(i); +} + +int spmc_init(void) +{ + /* enable SPM register control */ + mmio_write_32(SPM_POWERON_CONFIG_EN, + PROJECT_CODE | MD_BCLK_CG_EN | BCLK_CG_EN); + +#if SPMC_MODE == 1 + INFO("SPM: enable SPMC mode\n"); + + /* 0: SPMC mode 1: Legacy mode */ + mmio_write_32(SPM_BYPASS_SPMC, 0); + + mmio_clrbits_32(per_cluster(0, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON_2ND); + + mmio_clrbits_32(per_cpu(0, 0, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + + mmio_setbits_32(per_cpu(0, 1, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + mmio_setbits_32(per_cpu(0, 2, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + mmio_setbits_32(per_cpu(0, 3, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); +#endif + + mmio_clrbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON_2ND); + mmio_setbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_RST_B); + mmio_clrbits_32(per_cluster(1, SPM_CLUSTER_PWR), PWRCTRL_PWR_CLK_DIS); + + mmio_clrbits_32(per_cpu(1, 0, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(1, 1, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(1, 2, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + mmio_clrbits_32(per_cpu(1, 3, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + + mmio_setbits_32(per_cpu(1, 0, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + mmio_setbits_32(per_cpu(1, 1, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + mmio_setbits_32(per_cpu(1, 2, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + mmio_setbits_32(per_cpu(1, 3, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + + return 0; +} + +/** + * Power on a core with specified cluster and core index + * + * @cluster: the cluster ID of the CPU which to be powered on + * @cpu: the CPU ID of the CPU which to be powered on + */ +void spm_poweron_cpu(int cluster, int cpu) +{ + INFO("spmc: power on core %d.%d\n", cluster, cpu); + + /* STA_POWER_ON */ + /* Start to turn on MP0_CPU0 */ + + /* Set PWR_RST_B = 1 */ + mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + + /* Set PWR_ON = 1 */ + mmio_setbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON); + + /* Wait until MP0_CPU0_PWR_STA_MASK = 1 */ + while (!spm_get_cpu_powerstate(cluster, cpu)) + ; + + /* Finish to turn on MP0_CPU0 */ + INFO("spmc: power on core %d.%d successfully\n", cluster, cpu); +} + +/** + * Power off a core with specified cluster and core index + * + * @cluster: the cluster ID of the CPU which to be powered off + * @cpu: the CPU ID of the CPU which to be powered off + */ +void spm_poweroff_cpu(int cluster, int cpu) +{ + INFO("spmc: power off core %d.%d\n", cluster, cpu); + + /* Start to turn off MP0_CPU0 */ + /* Set PWR_ON_2ND = 0 */ + mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON_2ND); + + /* Set PWR_ON = 0 */ + mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_ON); + + /* Wait until MP0_CPU0_PWR_STA_MASK = 0 */ + while (spm_get_cpu_powerstate(cluster, cpu)) + ; + + /* Set PWR_RST_B = 0 */ + mmio_clrbits_32(per_cpu(cluster, cpu, SPM_CPU_PWR), PWRCTRL_PWR_RST_B); + + /* Finish to turn off MP0_CPU0 */ + INFO("spmc: power off core %d.%d successfully\n", cluster, cpu); +} + +/** + * Power off a cluster with specified index + * + * @cluster: the cluster index which to be powered off + */ +void spm_poweroff_cluster(int cluster) +{ + uint32_t mask; + uint32_t pwr_rst_ctl; + + INFO("spmc: power off cluster %d\n", cluster); + + /* Start to turn off MP0_CPUTOP */ + /* Set bus protect - step1 : 0 */ + mask = (cluster) ? MP1_CPUTOP_PROT_STEP1_0_MASK : + MP0_CPUTOP_PROT_STEP1_0_MASK; + mmio_write_32(INFRA_TOPAXI_PROTECTEN_1_SET, mask); + + while ((mmio_read_32(INFRA_TOPAXI_PROTECTEN_STA1_1) & mask) != mask) + ; + + /* Set PWR_ON_2ND = 0 */ + mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), + PWRCTRL_PWR_ON_2ND); + + /* SPMC_DORMANT_ENABLE[0]=0 */ + mask = (cluster) ? MP1_SPMC_SRAM_DORMANT_EN : MP0_SPMC_SRAM_DORMANT_EN; + mmio_clrbits_32(SPM_SPMC_DORMANT_ENABLE, mask); + + /* Set PWR_ON = 0" */ + mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON); + + /* Wait until MP0_CPUTOP_PWR_STA_MASK = 0 */ + while (spm_get_cluster_powerstate(cluster)) + ; + + /* NOTE + * Following flow only for BIG core cluster. It was from + * application note but not covered in mtcmos_ctrl.c + */ + if (cluster) { + pwr_rst_ctl = mmio_read_32(MCUCFG_MP2_PWR_RST_CTL); + mmio_write_32(MCUCFG_MP2_PWR_RST_CTL, + (pwr_rst_ctl & ~SW_RST_B) | TOPAON_APB_MASK); + } + + /* CPU_EXT_BUCK_ISO[0]=1 */ + if (cluster) + mmio_setbits_32(SPM_CPU_EXT_BUCK_ISO, MP1_EXT_BUCK_ISO); + + /* Finish to turn off MP0_CPUTOP */ + INFO("spmc: power off cluster %d successfully\n", cluster); +} + +/** + * Power on a cluster with specified index + * + * @cluster: the cluster index which to be powered on + */ +void spm_poweron_cluster(int cluster) +{ + uint32_t mask; + uint32_t pwr_rst_ctl; + + INFO("spmc: power on cluster %d\n", cluster); + + /* Start to turn on MP1_CPUTOP */ + + /* NOTE + * Following flow only for BIG core cluster. It was from + * application note but not covered in mtcmos_ctrl.c + */ + if (cluster) { + mmio_clrbits_32(MCUCFG_MP2_PWR_RST_CTL, SW_RST_B); + + /* CPU_EXT_BUCK_ISO[1]=0 */ + /* Set mp<n>_vproc_ext_off to 0 to release vproc isolation control */ + mmio_clrbits_32(SPM_CPU_EXT_BUCK_ISO, MP1_EXT_BUCK_ISO); + + /* NOTE + * Following flow only for BIG core cluster. It was from + * application note but not covered in mtcmos_ctrl.c + */ + pwr_rst_ctl = mmio_read_32(MCUCFG_MP2_PWR_RST_CTL); + mmio_write_32(MCUCFG_MP2_PWR_RST_CTL, + (pwr_rst_ctl | SW_RST_B) & ~TOPAON_APB_MASK); + } + + /* Set PWR_ON_2ND = 0 */ + mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), + PWRCTRL_PWR_ON_2ND); + + /* Set PWR_RST_B = 1 */ + mmio_setbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), + PWRCTRL_PWR_RST_B); + + /* Set PWR_CLK_DIS = 0 */ + mmio_clrbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), + PWRCTRL_PWR_CLK_DIS); + + /* Set PWR_ON = 1 */ + mmio_setbits_32(per_cluster(cluster, SPM_CLUSTER_PWR), PWRCTRL_PWR_ON); + + /* Wait until MP1_CPUTOP_PWR_STA_MASK = 1 */ + while (!spm_get_cluster_powerstate(cluster)) + ; + + /* Release bus protect - step1 : 0 */ + mask = (cluster) ? MP1_CPUTOP_PROT_STEP1_0_MASK : + MP0_CPUTOP_PROT_STEP1_0_MASK; + mmio_write_32(INFRA_TOPAXI_PROTECTEN_1_CLR, mask); + + /* Finish to turn on MP1_CPUTOP */ + INFO("spmc: power on cluster %d successfully\n", cluster); +} diff --git a/plat/mediatek/mt8183/drivers/spmc/mtspmc.h b/plat/mediatek/mt8183/drivers/spmc/mtspmc.h new file mode 100644 index 000000000..4cf3bcfb3 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spmc/mtspmc.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTSPMC_H +#define MTSPMC_H + +/* + * CONFIG_SPMC_MODE: Select CPU power control mode. + * + * 0: Legacy + * Control power flow from SW through SPM register (MP*_PWR_CON). + * 1: HW + * Control power flow from SPMC. Most control flow and timing are handled + * by SPMC. + */ +#define SPMC_MODE 1 + +int spmc_init(void); + +void spm_poweron_cpu(int cluster, int cpu); +void spm_poweroff_cpu(int cluster, int cpu); + +void spm_poweroff_cluster(int cluster); +void spm_poweron_cluster(int cluster); + +int spm_get_cpu_powerstate(int cluster, int cpu); +int spm_get_cluster_powerstate(int cluster); +int spm_get_powerstate(uint32_t mask); + +void spm_enable_cpu_auto_off(int cluster, int cpu); +void spm_disable_cpu_auto_off(int cluster, int cpu); +void spm_set_cpu_power_off(int cluster, int cpu); +void spm_enable_cluster_auto_off(int cluster); + +void mcucfg_init_archstate(int cluster, int cpu, int arm64); +void mcucfg_set_bootaddr(int cluster, int cpu, uintptr_t bootaddr); +uintptr_t mcucfg_get_bootaddr(int cluster, int cpu); + +#endif /* MTSPMC_H */ diff --git a/plat/mediatek/mt8183/drivers/spmc/mtspmc_private.h b/plat/mediatek/mt8183/drivers/spmc/mtspmc_private.h new file mode 100644 index 000000000..2228e63f2 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/spmc/mtspmc_private.h @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MTSPMC_PRIVATE_H +#define MTSPMC_PRIVATE_H + +/* + * per_cpu/cluster helper + */ +struct per_cpu_reg { + int cluster_addr; + int cpu_stride; +}; + +#define per_cpu(cluster, cpu, reg) (reg[cluster].cluster_addr + \ + (cpu << reg[cluster].cpu_stride)) +#define per_cluster(cluster, reg) (reg[cluster].cluster_addr) + +/* SPMC related registers */ +#define SPM_POWERON_CONFIG_EN (SPM_BASE + 0x000) +/* bit-fields of SPM_POWERON_CONFIG_EN */ +#define BCLK_CG_EN (1 << 0) +#define MD_BCLK_CG_EN (1 << 1) +#define PROJECT_CODE (0xb16 << 16) + +#define SPM_PWR_STATUS (SPM_BASE + 0x180) +#define SPM_PWR_STATUS_2ND (SPM_BASE + 0x184) + +#define SPM_BYPASS_SPMC (SPM_BASE + 0x2b4) +#define SPM_SPMC_DORMANT_ENABLE (SPM_BASE + 0x2b8) + +#define SPM_MP0_CPUTOP_PWR_CON (SPM_BASE + 0x204) +#define SPM_MP0_CPU0_PWR_CON (SPM_BASE + 0x208) +#define SPM_MP0_CPU1_PWR_CON (SPM_BASE + 0x20C) +#define SPM_MP0_CPU2_PWR_CON (SPM_BASE + 0x210) +#define SPM_MP0_CPU3_PWR_CON (SPM_BASE + 0x214) +#define SPM_MP1_CPUTOP_PWR_CON (SPM_BASE + 0x218) +#define SPM_MP1_CPU0_PWR_CON (SPM_BASE + 0x21C) +#define SPM_MP1_CPU1_PWR_CON (SPM_BASE + 0x220) +#define SPM_MP1_CPU2_PWR_CON (SPM_BASE + 0x224) +#define SPM_MP1_CPU3_PWR_CON (SPM_BASE + 0x228) +#define SPM_MP0_CPUTOP_L2_PDN (SPM_BASE + 0x240) +#define SPM_MP0_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x244) +#define SPM_MP0_CPU0_L1_PDN (SPM_BASE + 0x248) +#define SPM_MP0_CPU1_L1_PDN (SPM_BASE + 0x24C) +#define SPM_MP0_CPU2_L1_PDN (SPM_BASE + 0x250) +#define SPM_MP0_CPU3_L1_PDN (SPM_BASE + 0x254) +#define SPM_MP1_CPUTOP_L2_PDN (SPM_BASE + 0x258) +#define SPM_MP1_CPUTOP_L2_SLEEP_B (SPM_BASE + 0x25C) +#define SPM_MP1_CPU0_L1_PDN (SPM_BASE + 0x260) +#define SPM_MP1_CPU1_L1_PDN (SPM_BASE + 0x264) +#define SPM_MP1_CPU2_L1_PDN (SPM_BASE + 0x268) +#define SPM_MP1_CPU3_L1_PDN (SPM_BASE + 0x26C) + +#define SPM_CPU_EXT_BUCK_ISO (SPM_BASE + 0x290) +/* bit-fields of SPM_CPU_EXT_BUCK_ISO */ +#define MP0_EXT_BUCK_ISO (1 << 0) +#define MP1_EXT_BUCK_ISO (1 << 1) +#define MP_EXT_BUCK_ISO (1 << 2) + +/* bit-fields of SPM_PWR_STATUS */ +#define PWR_STATUS_MD (1 << 0) +#define PWR_STATUS_CONN (1 << 1) +#define PWR_STATUS_DDRPHY (1 << 2) +#define PWR_STATUS_DISP (1 << 3) +#define PWR_STATUS_MFG (1 << 4) +#define PWR_STATUS_ISP (1 << 5) +#define PWR_STATUS_INFRA (1 << 6) +#define PWR_STATUS_VDEC (1 << 7) +#define PWR_STATUS_MP0_CPUTOP (1 << 8) +#define PWR_STATUS_MP0_CPU0 (1 << 9) +#define PWR_STATUS_MP0_CPU1 (1 << 10) +#define PWR_STATUS_MP0_CPU2 (1 << 11) +#define PWR_STATUS_MP0_CPU3 (1 << 12) +#define PWR_STATUS_MCUSYS (1 << 14) +#define PWR_STATUS_MP1_CPUTOP (1 << 15) +#define PWR_STATUS_MP1_CPU0 (1 << 16) +#define PWR_STATUS_MP1_CPU1 (1 << 17) +#define PWR_STATUS_MP1_CPU2 (1 << 18) +#define PWR_STATUS_MP1_CPU3 (1 << 19) +#define PWR_STATUS_VEN (1 << 21) +#define PWR_STATUS_MFG_ASYNC (1 << 23) +#define PWR_STATUS_AUDIO (1 << 24) +#define PWR_STATUS_C2K (1 << 28) +#define PWR_STATUS_MD_INFRA (1 << 29) + + +/* bit-fields of SPM_*_PWR_CON */ +#define PWRCTRL_PWR_RST_B (1 << 0) +#define PWRCTRL_PWR_ISO (1 << 1) +#define PWRCTRL_PWR_ON (1 << 2) +#define PWRCTRL_PWR_ON_2ND (1 << 3) +#define PWRCTRL_PWR_CLK_DIS (1 << 4) +#define PWRCTRL_PWR_SRAM_CKISO (1 << 5) +#define PWRCTRL_PWR_SRAM_ISOINT_B (1 << 6) +#define PWRCTRL_PWR_SRAM_PD_SLPB_CLAMP (1 << 7) +#define PWRCTRL_PWR_SRAM_PDN (1 << 8) +#define PWRCTRL_PWR_SRAM_SLEEP_B (1 << 12) +#define PWRCTRL_PWR_SRAM_PDN_ACK (1 << 24) +#define PWRCTRL_PWR_SRAM_SLEEP_B_ACK (1 << 28) + +/* per_cpu registers for SPM_MP?_CPU?_PWR_CON */ +static const struct per_cpu_reg SPM_CPU_PWR[] = { + [0] = { .cluster_addr = SPM_MP0_CPU0_PWR_CON, .cpu_stride = 2 }, + [1] = { .cluster_addr = SPM_MP1_CPU0_PWR_CON, .cpu_stride = 2 }, +}; + +/* per_cluster registers for SPM_MP?_CPUTOP_PWR_CON */ +static const struct per_cpu_reg SPM_CLUSTER_PWR[] = { + [0] = { .cluster_addr = SPM_MP0_CPUTOP_PWR_CON }, + [1] = { .cluster_addr = SPM_MP1_CPUTOP_PWR_CON }, +}; + +/* APB Module infracfg_ao */ +#define INFRA_TOPAXI_PROTECTEN_1 (INFRACFG_AO_BASE + 0x250) +#define INFRA_TOPAXI_PROTECTEN_STA1_1 (INFRACFG_AO_BASE + 0x258) +#define INFRA_TOPAXI_PROTECTEN_1_SET (INFRACFG_AO_BASE + 0x2A8) +#define INFRA_TOPAXI_PROTECTEN_1_CLR (INFRACFG_AO_BASE + 0x2AC) + +/* bit-fields of INFRA_TOPAXI_PROTECTEN_1_SET */ +#define MP0_CPUTOP_PROT_STEP1_0_MASK ((1 << 10)|(1 << 12)| \ + (1 << 13)|(1 << 26)) +#define MP1_CPUTOP_PROT_STEP1_0_MASK ((1 << 11)|(1 << 14)| \ + (1 << 15)|(1 << 27)) + +/* bit-fields of INFRA_TOPAXI_PROTECTEN_STA1_1 */ +#define MP0_CPUTOP_PROT_STEP1_0_ACK_MASK ((1 << 10)|(1 << 12)| \ + (1 << 13)|(1 << 26)) +#define MP1_CPUTOP_PROT_STEP1_0_ACK_MASK ((1 << 11)|(1 << 14)| \ + (1 << 15)|(1 << 27)) + + +/* + * MCU configuration registers + */ + +/* bit-fields of MCUCFG_MP?_AXI_CONFIG */ +#define MCUCFG_AXI_CONFIG_BROADCASTINNER (1 << 0) +#define MCUCFG_AXI_CONFIG_BROADCASTOUTER (1 << 1) +#define MCUCFG_AXI_CONFIG_BROADCASTCACHEMAINT (1 << 2) +#define MCUCFG_AXI_CONFIG_SYSBARDISABLE (1 << 3) +#define MCUCFG_AXI_CONFIG_ACINACTM (1 << 4) +#define MCUCFG_AXI_CONFIG_AINACTS (1 << 5) + + +#define MCUCFG_MP0_MISC_CONFIG2 ((uintptr_t)&mt8183_mcucfg->mp0_misc_config[2]) +#define MCUCFG_MP0_MISC_CONFIG3 ((uintptr_t)&mt8183_mcucfg->mp0_misc_config[3]) +#define MCUCFG_MP1_MISC_CONFIG2 ((uintptr_t)&mt8183_mcucfg->mp1_misc_config[2]) +#define MCUCFG_MP1_MISC_CONFIG3 ((uintptr_t)&mt8183_mcucfg->mp1_misc_config[3]) + +#define MCUCFG_CPUSYS0_SPARKVRETCNTRL (MCUCFG_BASE + 0x1c00) +/* bit-fields of MCUCFG_CPUSYS0_SPARKVRETCNTRL */ +#define CPU0_SPARK_VRET_CTRL (0x3f << 0) +#define CPU1_SPARK_VRET_CTRL (0x3f << 8) +#define CPU2_SPARK_VRET_CTRL (0x3f << 16) +#define CPU3_SPARK_VRET_CTRL (0x3f << 24) + +/* SPARK control in little cores */ +#define MCUCFG_CPUSYS0_CPU0_SPMC_CTL (MCUCFG_BASE + 0x1c30) +#define MCUCFG_CPUSYS0_CPU1_SPMC_CTL (MCUCFG_BASE + 0x1c34) +#define MCUCFG_CPUSYS0_CPU2_SPMC_CTL (MCUCFG_BASE + 0x1c38) +#define MCUCFG_CPUSYS0_CPU3_SPMC_CTL (MCUCFG_BASE + 0x1c3c) +/* bit-fields of MCUCFG_CPUSYS0_CPU?_SPMC_CTL */ +#define SW_SPARK_EN (1 << 0) +#define SW_NO_WAIT_Q (1 << 1) + +/* the MCUCFG which BIG cores used is at (MCUCFG_BASE + 0x2000) */ +#define MCUCFG_MP2_BASE (MCUCFG_BASE + 0x2000) +#define MCUCFG_MP2_PWR_RST_CTL (MCUCFG_MP2_BASE + 0x8) +/* bit-fields of MCUCFG_MP2_PWR_RST_CTL */ +#define SW_RST_B (1 << 0) +#define TOPAON_APB_MASK (1 << 1) + +#define MCUCFG_MP2_CPUCFG (MCUCFG_MP2_BASE + 0x208) + +#define MCUCFG_MP2_RVADDR0 (MCUCFG_MP2_BASE + 0x290) +#define MCUCFG_MP2_RVADDR1 (MCUCFG_MP2_BASE + 0x298) +#define MCUCFG_MP2_RVADDR2 (MCUCFG_MP2_BASE + 0x2c0) +#define MCUCFG_MP2_RVADDR3 (MCUCFG_MP2_BASE + 0x2c8) + +/* SPMC control */ +#define MCUCFG_MP0_SPMC (MCUCFG_BASE + 0x788) +#define MCUCFG_MP2_SPMC (MCUCFG_MP2_BASE + 0x2a0) +#define MCUCFG_MP2_COQ (MCUCFG_MP2_BASE + 0x2bC) + +/* per_cpu registers for MCUCFG_MP?_MISC_CONFIG2 */ +static const struct per_cpu_reg MCUCFG_BOOTADDR[] = { + [0] = { .cluster_addr = MCUCFG_MP0_MISC_CONFIG2, .cpu_stride = 3 }, +}; + +/* per_cpu registers for MCUCFG_MP?_MISC_CONFIG3 */ +static const struct per_cpu_reg MCUCFG_INITARCH[] = { + [0] = { .cluster_addr = MCUCFG_MP0_MISC_CONFIG3 }, + [1] = { .cluster_addr = MCUCFG_MP2_CPUCFG }, +}; + +/* SPARK control in BIG cores */ +#define MCUCFG_MP2_PTP3_CPU0_SPMC0 (MCUCFG_MP2_BASE + 0x430) +#define MCUCFG_MP2_PTP3_CPU0_SPMC1 (MCUCFG_MP2_BASE + 0x434) +#define MCUCFG_MP2_PTP3_CPU1_SPMC0 (MCUCFG_MP2_BASE + 0x438) +#define MCUCFG_MP2_PTP3_CPU1_SPMC1 (MCUCFG_MP2_BASE + 0x43c) +#define MCUCFG_MP2_PTP3_CPU2_SPMC0 (MCUCFG_MP2_BASE + 0x440) +#define MCUCFG_MP2_PTP3_CPU2_SPMC1 (MCUCFG_MP2_BASE + 0x444) +#define MCUCFG_MP2_PTP3_CPU3_SPMC0 (MCUCFG_MP2_BASE + 0x448) +#define MCUCFG_MP2_PTP3_CPU3_SPMC1 (MCUCFG_MP2_BASE + 0x44c) +/* bit-fields of MCUCFG_MP2_PTP3_CPU?_SPMC? */ +#define SW_SPARK_EN (1 << 0) +#define SW_NO_WAIT_Q (1 << 1) + +#define MCUCFG_MP2_SPARK2LDO (MCUCFG_MP2_BASE + 0x700) +/* bit-fields of MCUCFG_MP2_SPARK2LDO */ +#define SPARK_VRET_CTRL (0x3f << 0) +#define CPU0_SPARK_LDO_AMUXSEL (0xf << 6) +#define CPU1_SPARK_LDO_AMUXSEL (0xf << 10) +#define CPU2_SPARK_LDO_AMUXSEL (0xf << 14) +#define CPU3_SPARK_LDO_AMUXSEL (0xf << 18) + +/* per_cpu registers for SPARK */ +static const struct per_cpu_reg MCUCFG_SPARK[] = { + [0] = { .cluster_addr = MCUCFG_CPUSYS0_CPU0_SPMC_CTL, .cpu_stride = 2 }, + [1] = { .cluster_addr = MCUCFG_MP2_PTP3_CPU0_SPMC0, .cpu_stride = 3 }, +}; + +/* per_cpu registers for SPARK2LDO */ +static const struct per_cpu_reg MCUCFG_SPARK2LDO[] = { + [0] = { .cluster_addr = MCUCFG_CPUSYS0_SPARKVRETCNTRL }, + [1] = { .cluster_addr = MCUCFG_MP2_SPARK2LDO }, +}; + +#endif /* MTSPMC_PRIVATE_H */ diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.c b/plat/mediatek/mt8183/drivers/sspm/sspm.c new file mode 100644 index 000000000..391763818 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/sspm/sspm.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include <arch_helpers.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <errno.h> +#include <lib/mmio.h> +#include <sspm.h> + +static void memcpy_to_sspm(uint32_t dst, uint32_t *src, uint32_t len) +{ + while (len--) { + mmio_write_32(dst, *src); + dst += sizeof(uint32_t); + src++; + } +} + +static void memcpy_from_sspm(uint32_t *dst, uint32_t src, uint32_t len) +{ + while (len--) { + *dst = mmio_read_32(src); + dst++; + src += sizeof(uint32_t); + } +} + +int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len) +{ + if (slot >= 32) { + ERROR("%s:slot = %d\n", __func__, slot); + return -EINVAL; + } + + if (data) + memcpy_from_sspm(data, + MBOX3_BASE + slot * 4, + len); + + return 0; +} + +int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len) +{ + if (slot >= 32) { + ERROR("%s:slot = %d\n", __func__, slot); + return -EINVAL; + } + + if (data) + memcpy_to_sspm(MBOX3_BASE + slot * 4, + data, + len); + + return 0; +} + +static int sspm_ipi_check_ack(uint32_t id) +{ + int ret = 0; + + if (id == IPI_ID_PLATFORM) { + if ((mmio_read_32(MBOX0_BASE + MBOX_IN_IRQ_OFS) & 0x1) == 0x1) + ret = -EINPROGRESS; + } else if (id == IPI_ID_SUSPEND) { + if ((mmio_read_32(MBOX1_BASE + MBOX_IN_IRQ_OFS) & 0x2) == 0x2) + ret = -EINPROGRESS; + } else { + ERROR("%s: id = %d\n", __func__, id); + ret = -EINVAL; + } + + return ret; +} + +int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data) +{ + int ret = 0; + + ret = sspm_ipi_check_ack(id); + if (ret) + return ret; + + if (id == IPI_ID_PLATFORM) { + memcpy_to_sspm(MBOX0_BASE + PINR_OFFSET_PLATFORM * 4, + data, + PINR_SIZE_PLATFORM); + dsb(); + mmio_write_32(MBOX0_BASE + MBOX_OUT_IRQ_OFS, 0x1); + } else if (id == IPI_ID_SUSPEND) { + memcpy_to_sspm(MBOX1_BASE + PINR_OFFSET_SUSPEND * 4, + data, + PINR_SIZE_SUSPEND); + dsb(); + mmio_write_32(MBOX1_BASE + MBOX_OUT_IRQ_OFS, + 0x2); + } + + return 0; +} + +int sspm_ipi_recv_non_blocking(uint32_t id, uint32_t *data, uint32_t len) +{ + int ret = 0; + + ret = sspm_ipi_check_ack(id); + if (ret == -EINPROGRESS) { + if (id == IPI_ID_PLATFORM) { + memcpy_from_sspm(data, + MBOX0_BASE + PINR_OFFSET_PLATFORM * 4, + len); + dsb(); + /* clear interrupt bit*/ + mmio_write_32(MBOX0_BASE + MBOX_IN_IRQ_OFS, + 0x1); + ret = 0; + } else if (id == IPI_ID_SUSPEND) { + memcpy_from_sspm(data, + MBOX1_BASE + PINR_OFFSET_SUSPEND * 4, + len); + dsb(); + /* clear interrupt bit*/ + mmio_write_32(MBOX1_BASE + MBOX_IN_IRQ_OFS, + 0x2); + ret = 0; + } + } else if (ret == 0) { + ret = -EBUSY; + } + + return ret; +} + +int sspm_alive_show(void) +{ + uint32_t ipi_data, count; + int ret = 0; + + count = 5; + ipi_data = 0xdead; + + if (sspm_ipi_send_non_blocking(IPI_ID_PLATFORM, &ipi_data) != 0) { + ERROR("sspm init send fail! ret=%d\n", ret); + return -1; + } + + while (sspm_ipi_recv_non_blocking(IPI_ID_PLATFORM, + &ipi_data, + sizeof(ipi_data)) + && count) { + mdelay(100); + count--; + } + + return (ipi_data == 1) ? 0 : -1; +} diff --git a/plat/mediatek/mt8183/drivers/sspm/sspm.h b/plat/mediatek/mt8183/drivers/sspm/sspm.h new file mode 100644 index 000000000..2c2cc10ea --- /dev/null +++ b/plat/mediatek/mt8183/drivers/sspm/sspm.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef __SSPM_H__ +#define __SSPM_H__ +/* These should sync with sspm.bin */ +#define IPI_ID_PLATFORM 0 +#define IPI_ID_SUSPEND 6 +#define PINR_OFFSET_PLATFORM 0 +#define PINR_SIZE_PLATFORM 3 +#define PINR_OFFSET_SUSPEND 2 +#define PINR_SIZE_SUSPEND 8 + +#define MBOX0_BASE 0x10450000 +#define MBOX1_BASE 0x10460000 +#define MBOX3_BASE 0x10480000 +#define MBOX_OUT_IRQ_OFS 0x1000 +#define MBOX_IN_IRQ_OFS 0x1004 + +#define SHAREMBOX_OFFSET_MCDI 0 +#define SHAREMBOX_SIZE_MCDI 20 +#define SHAREMBOX_OFFSET_SUSPEND 26 +#define SHAREMBOX_SIZE_SUSPEND 6 + +int sspm_mbox_read(uint32_t slot, uint32_t *data, uint32_t len); +int sspm_mbox_write(uint32_t slot, uint32_t *data, uint32_t len); +int sspm_ipi_send_non_blocking(uint32_t id, uint32_t *data); +int sspm_ipi_recv_non_blocking(uint32_t slot, uint32_t *data, uint32_t len); +int sspm_alive_show(void); +#endif /* __SSPM_H__ */ diff --git a/plat/mediatek/mt8183/drivers/uart/uart.c b/plat/mediatek/mt8183/drivers/uart/uart.c new file mode 100644 index 000000000..3c6a98036 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/uart/uart.c @@ -0,0 +1,111 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <lib/mmio.h> +#include <uart.h> + +static struct mt_uart uart_save_addr[DRV_SUPPORT_UART_PORTS]; + +static const unsigned int uart_base_addr[DRV_SUPPORT_UART_PORTS] = { + UART0_BASE, + UART1_BASE +}; + +void mt_uart_restore(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + /* Must NOT print any debug log before UART restore */ + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart = &uart_save_addr[uart_idx]; + base = uart->base; + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + mmio_write_32(UART_EFR(base), uart->registers.efr); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_FCR(base), uart->registers.fcr); + + /* baudrate */ + mmio_write_32(UART_HIGHSPEED(base), uart->registers.highspeed); + mmio_write_32(UART_FRACDIV_L(base), uart->registers.fracdiv_l); + mmio_write_32(UART_FRACDIV_M(base), uart->registers.fracdiv_m); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + mmio_write_32(UART_DLL(base), uart->registers.dll); + mmio_write_32(UART_DLH(base), uart->registers.dlh); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + mmio_write_32(UART_SAMPLE_COUNT(base), + uart->registers.sample_count); + mmio_write_32(UART_SAMPLE_POINT(base), + uart->registers.sample_point); + mmio_write_32(UART_GUARD(base), uart->registers.guard); + + /* flow control */ + mmio_write_32(UART_ESCAPE_EN(base), uart->registers.escape_en); + mmio_write_32(UART_MCR(base), uart->registers.mcr); + mmio_write_32(UART_IER(base), uart->registers.ier); + mmio_write_32(UART_SCR(base), uart->registers.scr); + } +} + +void mt_uart_save(void) +{ + int uart_idx = UART_PORT0; + struct mt_uart *uart; + unsigned long base; + + for (uart_idx = UART_PORT0; uart_idx < HW_SUPPORT_UART_PORTS; + uart_idx++) { + + uart_save_addr[uart_idx].base = uart_base_addr[uart_idx]; + base = uart_base_addr[uart_idx]; + uart = &uart_save_addr[uart_idx]; + uart->registers.lcr = mmio_read_32(UART_LCR(base)); + + mmio_write_32(UART_LCR(base), UART_LCR_MODE_B); + uart->registers.efr = mmio_read_32(UART_EFR(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.fcr = mmio_read_32(UART_FCR_RD(base)); + + /* baudrate */ + uart->registers.highspeed = mmio_read_32(UART_HIGHSPEED(base)); + uart->registers.fracdiv_l = mmio_read_32(UART_FRACDIV_L(base)); + uart->registers.fracdiv_m = mmio_read_32(UART_FRACDIV_M(base)); + mmio_write_32(UART_LCR(base), + uart->registers.lcr | UART_LCR_DLAB); + uart->registers.dll = mmio_read_32(UART_DLL(base)); + uart->registers.dlh = mmio_read_32(UART_DLH(base)); + mmio_write_32(UART_LCR(base), uart->registers.lcr); + uart->registers.sample_count = mmio_read_32( + UART_SAMPLE_COUNT(base)); + uart->registers.sample_point = mmio_read_32( + UART_SAMPLE_POINT(base)); + uart->registers.guard = mmio_read_32(UART_GUARD(base)); + + /* flow control */ + uart->registers.escape_en = mmio_read_32(UART_ESCAPE_EN(base)); + uart->registers.mcr = mmio_read_32(UART_MCR(base)); + uart->registers.ier = mmio_read_32(UART_IER(base)); + uart->registers.scr = mmio_read_32(UART_SCR(base)); + } +} + +void mt_console_uart_cg(int on) +{ + if (on) + mmio_write_32(UART_CLOCK_GATE_CLR, UART0_CLOCK_GATE_BIT); + else + mmio_write_32(UART_CLOCK_GATE_SET, UART0_CLOCK_GATE_BIT); +} + +int mt_console_uart_cg_status(void) +{ + return mmio_read_32(UART_CLOCK_GATE_STA) & UART0_CLOCK_GATE_BIT; +} diff --git a/plat/mediatek/mt8183/drivers/uart/uart.h b/plat/mediatek/mt8183/drivers/uart/uart.h new file mode 100644 index 000000000..be04c3509 --- /dev/null +++ b/plat/mediatek/mt8183/drivers/uart/uart.h @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __UART_H__ +#define __UART_H__ + +#include <platform_def.h> + +/* UART HW information */ +#define HW_SUPPORT_UART_PORTS 2 +#define DRV_SUPPORT_UART_PORTS 2 + +/* console UART clock cg */ +#define UART_CLOCK_GATE_SET (INFRACFG_AO_BASE + 0x80) +#define UART_CLOCK_GATE_CLR (INFRACFG_AO_BASE + 0x84) +#define UART_CLOCK_GATE_STA (INFRACFG_AO_BASE + 0x90) +#define UART0_CLOCK_GATE_BIT (1U<<22) +#define UART1_CLOCK_GATE_BIT (1U<<23) + +/* UART registers */ +#define UART_RBR(_baseaddr) (_baseaddr + 0x0) +#define UART_THR(_baseaddr) (_baseaddr + 0x0) +#define UART_IER(_baseaddr) (_baseaddr + 0x4) +#define UART_IIR(_baseaddr) (_baseaddr + 0x8) +#define UART_FCR(_baseaddr) (_baseaddr + 0x8) +#define UART_LCR(_baseaddr) (_baseaddr + 0xc) +#define UART_MCR(_baseaddr) (_baseaddr + 0x10) +#define UART_LSR(_baseaddr) (_baseaddr + 0x14) +#define UART_MSR(_baseaddr) (_baseaddr + 0x18) +#define UART_SCR(_baseaddr) (_baseaddr + 0x1c) +#define UART_DLL(_baseaddr) (_baseaddr + 0x0) +#define UART_DLH(_baseaddr) (_baseaddr + 0x4) +#define UART_EFR(_baseaddr) (_baseaddr + 0x8) +#define UART_XON1(_baseaddr) (_baseaddr + 0x10) +#define UART_XON2(_baseaddr) (_baseaddr + 0x14) +#define UART_XOFF1(_baseaddr) (_baseaddr + 0x18) +#define UART_XOFF2(_baseaddr) (_baseaddr + 0x1c) +#define UART_AUTOBAUD(_baseaddr) (_baseaddr + 0x20) +#define UART_HIGHSPEED(_baseaddr) (_baseaddr + 0x24) +#define UART_SAMPLE_COUNT(_baseaddr) (_baseaddr + 0x28) +#define UART_SAMPLE_POINT(_baseaddr) (_baseaddr + 0x2c) +#define UART_AUTOBAUD_REG(_baseaddr) (_baseaddr + 0x30) +#define UART_RATE_FIX_REG(_baseaddr) (_baseaddr + 0x34) +#define UART_AUTO_BAUDSAMPLE(_baseaddr) (_baseaddr + 0x38) +#define UART_GUARD(_baseaddr) (_baseaddr + 0x3c) +#define UART_ESCAPE_DAT(_baseaddr) (_baseaddr + 0x40) +#define UART_ESCAPE_EN(_baseaddr) (_baseaddr + 0x44) +#define UART_SLEEP_EN(_baseaddr) (_baseaddr + 0x48) +#define UART_DMA_EN(_baseaddr) (_baseaddr + 0x4c) +#define UART_RXTRI_AD(_baseaddr) (_baseaddr + 0x50) +#define UART_FRACDIV_L(_baseaddr) (_baseaddr + 0x54) +#define UART_FRACDIV_M(_baseaddr) (_baseaddr + 0x58) +#define UART_FCR_RD(_baseaddr) (_baseaddr + 0x5C) +#define UART_USB_RX_SEL(_baseaddr) (_baseaddr + 0xB0) +#define UART_SLEEP_REQ(_baseaddr) (_baseaddr + 0xB4) +#define UART_SLEEP_ACK(_baseaddr) (_baseaddr + 0xB8) +#define UART_SPM_SEL(_baseaddr) (_baseaddr + 0xBC) +#define UART_LCR_DLAB 0x0080 +#define UART_LCR_MODE_B 0x00bf + +enum uart_port_ID { + UART_PORT0 = 0, + UART_PORT1 +}; + +struct mt_uart_register { + unsigned int dll; + unsigned int dlh; + unsigned int ier; + unsigned int lcr; + unsigned int mcr; + unsigned int fcr; + unsigned int lsr; + unsigned int scr; + unsigned int efr; + unsigned int highspeed; + unsigned int sample_count; + unsigned int sample_point; + unsigned int fracdiv_l; + unsigned int fracdiv_m; + unsigned int escape_en; + unsigned int guard; + unsigned int rx_sel; +}; + +struct mt_uart { + unsigned long base; + struct mt_uart_register registers; +}; + +/* external API */ +void mt_uart_save(void); +void mt_uart_restore(void); +void mt_console_uart_cg(int on); +int mt_console_uart_cg_status(void); + +#endif /* __UART_H__ */ diff --git a/plat/mediatek/mt8183/include/mcucfg.h b/plat/mediatek/mt8183/include/mcucfg.h index 83ee88fac..6b03818d0 100644 --- a/plat/mediatek/mt8183/include/mcucfg.h +++ b/plat/mediatek/mt8183/include/mcucfg.h @@ -28,51 +28,141 @@ struct mt8183_mcucfg_regs { uint32_t mp0_rw_rsvd0; /* 0x6C */ uint32_t mp0_rw_rsvd1; /* 0x70 */ uint32_t mp0_ro_rsvd; /* 0x74 */ - uint32_t reserved0_0[98]; /* 0x78 */ - uint32_t mp1_ca7l_cache_config; /* 0x200 */ - uint32_t mp1_miscdbg; /* 0x204 */ - uint32_t reserved0_1[9]; /* 0x208 */ - uint32_t mp1_axi_config; /* 0x22C */ - uint32_t mp1_misc_config[10]; /* 0x230 */ - uint32_t reserved0_2[3]; /* 0x258 */ - uint32_t mp1_ca7l_misc_config; /* 0x264 */ - uint32_t reserved0_3[310]; /* 0x268 */ + uint32_t reserved0_0; /* 0x78 */ + uint32_t mp0_l2_cache_parity1_rdata; /* 0x7C */ + uint32_t mp0_l2_cache_parity2_rdata; /* 0x80 */ + uint32_t reserved0_1; /* 0x84 */ + uint32_t mp0_rgu_dcm_config; /* 0x88 */ + uint32_t mp0_ca53_specific_ctrl; /* 0x8C */ + uint32_t mp0_esr_case; /* 0x90 */ + uint32_t mp0_esr_mask; /* 0x94 */ + uint32_t mp0_esr_trig_en; /* 0x98 */ + uint32_t reserved_0_2; /* 0x9C */ + uint32_t mp0_ses_cg_en; /* 0xA0 */ + uint32_t reserved0_3[216]; /* 0xA4 */ + uint32_t mp_dbg_ctrl; /* 0x404 */ + uint32_t reserved0_4[34]; /* 0x408 */ + uint32_t mp_dfd_ctrl; /* 0x490 */ + uint32_t dfd_cnt_l; /* 0x494 */ + uint32_t dfd_cnt_h; /* 0x498 */ + uint32_t misccfg_ro_rsvd; /* 0x49C */ + uint32_t reserved0_5[24]; /* 0x4A0 */ + uint32_t mp1_rst_status; /* 0x500 */ + uint32_t mp1_dbg_ctrl; /* 0x504 */ + uint32_t mp1_dbg_flag; /* 0x508 */ + uint32_t mp1_ca7l_ir_mon; /* 0x50C */ + uint32_t reserved0_6[32]; /* 0x510 */ + uint32_t mcusys_dbg_mon_sel_a; /* 0x590 */ + uint32_t mcucys_dbg_mon; /* 0x594 */ + uint32_t misccfg_sec_voi_status0; /* 0x598 */ + uint32_t misccfg_sec_vio_status1; /* 0x59C */ + uint32_t reserved0_7[18]; /* 0x5A0 */ + uint32_t gic500_int_mask; /* 0x5E8 */ + uint32_t core_rst_en_latch; /* 0x5EC */ + uint32_t reserved0_8[3]; /* 0x5F0 */ + uint32_t dbg_core_ret; /* 0x5FC */ + uint32_t mcusys_config_a; /* 0x600 */ + uint32_t mcusys_config1_a; /* 0x604 */ + uint32_t mcusys_gic_prebase_a; /* 0x608 */ + uint32_t mcusys_pinmux; /* 0x60C */ + uint32_t sec_range0_start; /* 0x610 */ + uint32_t sec_range0_end; /* 0x614 */ + uint32_t sec_range_enable; /* 0x618 */ + uint32_t l2c_mm_base; /* 0x61C */ + uint32_t reserved0_9[8]; /* 0x620 */ + uint32_t aclken_div; /* 0x640 */ + uint32_t pclken_div; /* 0x644 */ + uint32_t l2c_sram_ctrl; /* 0x648 */ + uint32_t armpll_jit_ctrl; /* 0x64C */ + uint32_t cci_addrmap; /* 0x650 */ + uint32_t cci_config; /* 0x654 */ + uint32_t cci_periphbase; /* 0x658 */ + uint32_t cci_nevntcntovfl; /* 0x65C */ + uint32_t cci_clk_ctrl; /* 0x660 */ + uint32_t cci_acel_s1_ctrl; /* 0x664 */ + uint32_t mcusys_bus_fabric_dcm_ctrl; /* 0x668 */ + uint32_t mcu_misc_dcm_ctrl; /* 0x66C */ + uint32_t xgpt_ctl; /* 0x670 */ + uint32_t xgpt_idx; /* 0x674 */ + uint32_t reserved0_10[3]; /* 0x678 */ + uint32_t mcusys_rw_rsvd0; /* 0x684 */ + uint32_t mcusys_rw_rsvd1; /* 0x688 */ + uint32_t reserved0_11[13]; /* 0x68C */ + uint32_t gic_500_delsel_ctl; /* 0x6C0 */ + uint32_t etb_delsel_ctl; /* 0x6C4 */ + uint32_t etb_rst_ctl; /* 0x6C8 */ + uint32_t reserved0_12[29]; /* 0x6CC */ uint32_t cci_adb400_dcm_config; /* 0x740 */ uint32_t sync_dcm_config; /* 0x744 */ - uint32_t reserved0_4[16]; /* 0x748 */ - uint32_t mp0_cputop_spmc_ctl; /* 0x788 */ - uint32_t mp1_cputop_spmc_ctl; /* 0x78C */ - uint32_t mp1_cputop_spmc_sram_ctl; /* 0x790 */ - uint32_t reserved0_5[23]; /* 0x794 */ + uint32_t reserved0_13; /* 0x748 */ + uint32_t sync_dcm_cluster_config; /* 0x74C */ + uint32_t sw_udi; /* 0x750 */ + uint32_t reserved0_14; /* 0x754 */ + uint32_t gic_sync_dcm; /* 0x758 */ + uint32_t big_dbg_pwr_ctrl; /* 0x75C */ + uint32_t gic_cpu_periphbase; /* 0x760 */ + uint32_t axi_cpu_config; /* 0x764 */ + uint32_t reserved0_15[2]; /* 0x768 */ + uint32_t mcsib_sys_ctrl1; /* 0x770 */ + uint32_t mcsib_sys_ctrl2; /* 0x774 */ + uint32_t mcsib_sys_ctrl3; /* 0x778 */ + uint32_t mcsib_sys_ctrl4; /* 0x77C */ + uint32_t mcsib_dbg_ctrl1; /* 0x780 */ + uint32_t pwrmcu_apb2to1; /* 0x784 */ + uint32_t mp0_spmc; /* 0x788 */ + uint32_t reserved0_16; /* 0x78C */ + uint32_t mp0_spmc_sram_ctl; /* 0x790 */ + uint32_t reserved0_17; /* 0x794 */ + uint32_t mp0_sw_rst_wait_cycle; /* 0x798 */ + uint32_t reserved0_18; /* 0x79C */ + uint32_t mp0_pll_divider_cfg; /* 0x7A0 */ + uint32_t reserved0_19; /* 0x7A4 */ + uint32_t mp2_pll_divider_cfg; /* 0x7A8 */ + uint32_t reserved0_20[5]; /* 0x7AC */ + uint32_t bus_pll_divider_cfg; /* 0x7C0 */ + uint32_t reserved0_21[7]; /* 0x7C4 */ + uint32_t clusterid_aff1; /* 0x7E0 */ + uint32_t clusterid_aff2; /* 0x7E4 */ + uint32_t reserved0_22[2]; /* 0x7E8 */ uint32_t l2_cfg_mp0; /* 0x7F0 */ uint32_t l2_cfg_mp1; /* 0x7F4 */ - uint32_t reserved0_6[1282]; /* 0x7F8 */ + uint32_t reserved0_23[218]; /* 0x7F8 */ + uint32_t mscib_dcm_en; /* 0xB60 */ + uint32_t reserved0_24[1063]; /* 0xB64 */ uint32_t cpusys0_sparkvretcntrl; /* 0x1C00 */ uint32_t cpusys0_sparken; /* 0x1C04 */ uint32_t cpusys0_amuxsel; /* 0x1C08 */ - uint32_t reserved0_7[9]; /* 0x1C0C */ + uint32_t reserved0_25[9]; /* 0x1C0C */ uint32_t cpusys0_cpu0_spmc_ctl; /* 0x1C30 */ uint32_t cpusys0_cpu1_spmc_ctl; /* 0x1C34 */ uint32_t cpusys0_cpu2_spmc_ctl; /* 0x1C38 */ uint32_t cpusys0_cpu3_spmc_ctl; /* 0x1C3C */ - uint32_t reserved0_8[370]; /* 0x1C40 */ + uint32_t reserved0_26[8]; /* 0x1C40 */ + uint32_t mp0_sync_dcm_cgavg_ctrl; /* 0x1C60 */ + uint32_t mp0_sync_dcm_cgavg_fact; /* 0x1C64 */ + uint32_t mp0_sync_dcm_cgavg_rfact; /* 0x1C68 */ + uint32_t mp0_sync_dcm_cgavg; /* 0x1C6C */ + uint32_t mp0_l2_parity_clr; /* 0x1C70 */ + uint32_t reserved0_27[357]; /* 0x1C74 */ uint32_t mp2_cpucfg; /* 0x2208 */ uint32_t mp2_axi_config; /* 0x220C */ - uint32_t reserved0_9[36]; /* 0x2210 */ - uint32_t mp2_cputop_spm_ctl; /* 0x22A0 */ - uint32_t mp2_cputop_spm_sta; /* 0x22A4 */ - uint32_t reserved0_10[98]; /* 0x22A8 */ - uint32_t cpusys2_cpu0_spmc_ctl; /* 0x2430 */ - uint32_t cpusys2_cpu0_spmc_sta; /* 0x2434 */ - uint32_t cpusys2_cpu1_spmc_ctl; /* 0x2438 */ - uint32_t cpusys2_cpu1_spmc_sta; /* 0x243C */ - uint32_t reserved0_11[176]; /* 0x2440 */ + uint32_t reserved0_28[25]; /* 0x2210 */ + uint32_t mp2_sync_dcm; /* 0x2274 */ + uint32_t reserved0_29[10]; /* 0x2278 */ + uint32_t ptp3_cputop_spmc0; /* 0x22A0 */ + uint32_t ptp3_cputop_spmc1; /* 0x22A4 */ + uint32_t reserved0_30[98]; /* 0x22A8 */ + uint32_t ptp3_cpu0_spmc0; /* 0x2430 */ + uint32_t ptp3_cpu0_spmc1; /* 0x2434 */ + uint32_t ptp3_cpu1_spmc0; /* 0x2438 */ + uint32_t ptp3_cpu1_spmc1; /* 0x243C */ + uint32_t ptp3_cpu2_spmc0; /* 0x2440 */ + uint32_t ptp3_cpu2_spmc1; /* 0x2444 */ + uint32_t ptp3_cpu3_spmc0; /* 0x2448 */ + uint32_t ptp3_cpu3_spmc1; /* 0x244C */ + uint32_t ptp3_cpux_spmc; /* 0x2450 */ + uint32_t reserved0_31[171]; /* 0x2454 */ uint32_t spark2ld0; /* 0x2700 */ - uint32_t reserved0_12[1355]; /* 0x2704 */ - uint32_t cpusys1_cpu0_spmc_ctl; /* 0x3C30 */ - uint32_t cpusys1_cpu1_spmc_ctl; /* 0x3C34 */ - uint32_t cpusys1_cpu2_spmc_ctl; /* 0x3C38 */ - uint32_t cpusys1_cpu3_spmc_ctl; /* 0x3C3C */ }; static struct mt8183_mcucfg_regs *const mt8183_mcucfg = (void *)MCUCFG_BASE; @@ -244,4 +334,235 @@ enum { MP1_L2RSTDISABLE = 1 << MP1_L2RSTDISABLE_SHIFT }; +/* bus pll divider dcm related */ +enum { + BUS_PLLDIVIDER_DCM_DBC_CNT_0_SHIFT = 11, + BUS_PLLDIV_ARMWFI_DCM_EN_SHIFT = 24, + BUS_PLLDIV_ARMWFE_DCM_EN_SHIFT = 25, + + BUS_PLLDIV_DCM = (1 << BUS_PLLDIVIDER_DCM_DBC_CNT_0_SHIFT) | + (1 << BUS_PLLDIV_ARMWFI_DCM_EN_SHIFT) | + (1 << BUS_PLLDIV_ARMWFE_DCM_EN_SHIFT) +}; + +/* mp0 pll divider dcm related */ +enum { + MP0_PLLDIV_DCM_DBC_CNT_0_SHIFT = 11, + MP0_PLLDIV_ARMWFI_DCM_EN_SHIFT = 24, + MP0_PLLDIV_ARMWFE_DCM_EN_SHIFT = 25, + MP0_PLLDIV_LASTCORE_IDLE_EN_SHIFT = 31, + MP0_PLLDIV_DCM = (1 << MP0_PLLDIV_DCM_DBC_CNT_0_SHIFT) | + (1 << MP0_PLLDIV_ARMWFI_DCM_EN_SHIFT) | + (1 << MP0_PLLDIV_ARMWFE_DCM_EN_SHIFT) | + (1u << MP0_PLLDIV_LASTCORE_IDLE_EN_SHIFT) +}; + +/* mp2 pll divider dcm related */ +enum { + MP2_PLLDIV_DCM_DBC_CNT_0_SHIFT = 11, + MP2_PLLDIV_ARMWFI_DCM_EN_SHIFT = 24, + MP2_PLLDIV_ARMWFE_DCM_EN_SHIFT = 25, + MP2_PLLDIV_LASTCORE_IDLE_EN_SHIFT = 31, + MP2_PLLDIV_DCM = (1 << MP2_PLLDIV_DCM_DBC_CNT_0_SHIFT) | + (1 << MP2_PLLDIV_ARMWFI_DCM_EN_SHIFT) | + (1 << MP2_PLLDIV_ARMWFE_DCM_EN_SHIFT) | + (1u << MP2_PLLDIV_LASTCORE_IDLE_EN_SHIFT) +}; + +/* mcsib dcm related */ +enum { + MCSIB_CACTIVE_SEL_SHIFT = 0, + MCSIB_DCM_EN_SHIFT = 16, + + MCSIB_CACTIVE_SEL_MASK = 0xffff << MCSIB_CACTIVE_SEL_SHIFT, + MCSIB_CACTIVE_SEL = 0xffff << MCSIB_CACTIVE_SEL_SHIFT, + + MCSIB_DCM_MASK = 0xffffu << MCSIB_DCM_EN_SHIFT, + MCSIB_DCM = 0xffffu << MCSIB_DCM_EN_SHIFT, +}; + +/* cci adb400 dcm related */ +enum { + CCI_M0_ADB400_DCM_EN_SHIFT = 0, + CCI_M1_ADB400_DCM_EN_SHIFT = 1, + CCI_M2_ADB400_DCM_EN_SHIFT = 2, + CCI_S2_ADB400_DCM_EN_SHIFT = 3, + CCI_S3_ADB400_DCM_EN_SHIFT = 4, + CCI_S4_ADB400_DCM_EN_SHIFT = 5, + CCI_S5_ADB400_DCM_EN_SHIFT = 6, + ACP_S3_ADB400_DCM_EN_SHIFT = 11, + + CCI_ADB400_DCM_MASK = (1 << CCI_M0_ADB400_DCM_EN_SHIFT) | + (1 << CCI_M1_ADB400_DCM_EN_SHIFT) | + (1 << CCI_M2_ADB400_DCM_EN_SHIFT) | + (1 << CCI_S2_ADB400_DCM_EN_SHIFT) | + (1 << CCI_S4_ADB400_DCM_EN_SHIFT) | + (1 << CCI_S4_ADB400_DCM_EN_SHIFT) | + (1 << CCI_S5_ADB400_DCM_EN_SHIFT) | + (1 << ACP_S3_ADB400_DCM_EN_SHIFT), + CCI_ADB400_DCM = (1 << CCI_M0_ADB400_DCM_EN_SHIFT) | + (1 << CCI_M1_ADB400_DCM_EN_SHIFT) | + (1 << CCI_M2_ADB400_DCM_EN_SHIFT) | + (0 << CCI_S2_ADB400_DCM_EN_SHIFT) | + (0 << CCI_S4_ADB400_DCM_EN_SHIFT) | + (0 << CCI_S4_ADB400_DCM_EN_SHIFT) | + (0 << CCI_S5_ADB400_DCM_EN_SHIFT) | + (1 << ACP_S3_ADB400_DCM_EN_SHIFT) +}; + +/* sync dcm related */ +enum { + CCI_SYNC_DCM_DIV_EN_SHIFT = 0, + CCI_SYNC_DCM_UPDATE_TOG_SHIFT = 1, + CCI_SYNC_DCM_DIV_SEL_SHIFT = 2, + MP0_SYNC_DCM_DIV_EN_SHIFT = 10, + MP0_SYNC_DCM_UPDATE_TOG_SHIFT = 11, + MP0_SYNC_DCM_DIV_SEL_SHIFT = 12, + + SYNC_DCM_MASK = (1 << CCI_SYNC_DCM_DIV_EN_SHIFT) | + (1 << CCI_SYNC_DCM_UPDATE_TOG_SHIFT) | + (0x7f << CCI_SYNC_DCM_DIV_SEL_SHIFT) | + (1 << MP0_SYNC_DCM_DIV_EN_SHIFT) | + (1 << MP0_SYNC_DCM_UPDATE_TOG_SHIFT) | + (0x7f << MP0_SYNC_DCM_DIV_SEL_SHIFT), + SYNC_DCM = (1 << CCI_SYNC_DCM_DIV_EN_SHIFT) | + (1 << CCI_SYNC_DCM_UPDATE_TOG_SHIFT) | + (0 << CCI_SYNC_DCM_DIV_SEL_SHIFT) | + (1 << MP0_SYNC_DCM_DIV_EN_SHIFT) | + (1 << MP0_SYNC_DCM_UPDATE_TOG_SHIFT) | + (0 << MP0_SYNC_DCM_DIV_SEL_SHIFT) +}; + +/* mcu bus dcm related */ +enum { + MCU_BUS_DCM_EN_SHIFT = 8, + MCU_BUS_DCM = 1 << MCU_BUS_DCM_EN_SHIFT +}; + +/* mcusys bus fabric dcm related */ +enum { + ACLK_INFRA_DYNAMIC_CG_EN_SHIFT = 0, + EMI2_ADB400_S_DCM_CTRL_SHIFT = 1, + ACLK_GPU_DYNAMIC_CG_EN_SHIFT = 2, + ACLK_PSYS_DYNAMIC_CG_EN_SHIFT = 3, + MP0_ADB400_S_DCM_CTRL_SHIFT = 4, + MP0_ADB400_M_DCM_CTRL_SHIFT = 5, + MP1_ADB400_S_DCM_CTRL_SHIFT = 6, + MP1_ADB400_M_DCM_CTRL_SHIFT = 7, + EMICLK_EMI_DYNAMIC_CG_EN_SHIFT = 8, + INFRACLK_INFRA_DYNAMIC_CG_EN_SHIFT = 9, + EMICLK_GPU_DYNAMIC_CG_EN_SHIFT = 10, + INFRACLK_PSYS_DYNAMIC_CG_EN_SHIFT = 11, + EMICLK_EMI1_DYNAMIC_CG_EN_SHIFT = 12, + EMI1_ADB400_S_DCM_CTRL_SHIFT = 16, + MP2_ADB400_M_DCM_CTRL_SHIFT = 17, + MP0_ICC_AXI_STREAM_ARCH_CG_SHIFT = 18, + MP1_ICC_AXI_STREAM_ARCH_CG_SHIFT = 19, + MP2_ICC_AXI_STREAM_ARCH_CG_SHIFT = 20, + L2_SHARE_ADB400_DCM_CTRL_SHIFT = 21, + MP1_AGGRESS_DCM_CTRL_SHIFT = 22, + MP0_AGGRESS_DCM_CTRL_SHIFT = 23, + MP0_ADB400_ACP_S_DCM_CTRL_SHIFT = 24, + MP0_ADB400_ACP_M_DCM_CTRL_SHIFT = 25, + MP1_ADB400_ACP_S_DCM_CTRL_SHIFT = 26, + MP1_ADB400_ACP_M_DCM_CTRL_SHIFT = 27, + MP3_ADB400_M_DCM_CTRL_SHIFT = 28, + MP3_ICC_AXI_STREAM_ARCH_CG_SHIFT = 29, + + MCUSYS_BUS_FABRIC_DCM_MASK = (1 << ACLK_INFRA_DYNAMIC_CG_EN_SHIFT) | + (1 << EMI2_ADB400_S_DCM_CTRL_SHIFT) | + (1 << ACLK_GPU_DYNAMIC_CG_EN_SHIFT) | + (1 << ACLK_PSYS_DYNAMIC_CG_EN_SHIFT) | + (1 << MP0_ADB400_S_DCM_CTRL_SHIFT) | + (1 << MP0_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_S_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_M_DCM_CTRL_SHIFT) | + (1 << EMICLK_EMI_DYNAMIC_CG_EN_SHIFT) | + (1 << INFRACLK_INFRA_DYNAMIC_CG_EN_SHIFT) | + (1 << EMICLK_GPU_DYNAMIC_CG_EN_SHIFT) | + (1 << INFRACLK_PSYS_DYNAMIC_CG_EN_SHIFT) | + (1 << EMICLK_EMI1_DYNAMIC_CG_EN_SHIFT) | + (1 << EMI1_ADB400_S_DCM_CTRL_SHIFT) | + (1 << MP2_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP0_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << MP1_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << MP2_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << L2_SHARE_ADB400_DCM_CTRL_SHIFT) | + (1 << MP1_AGGRESS_DCM_CTRL_SHIFT) | + (1 << MP0_AGGRESS_DCM_CTRL_SHIFT) | + (1 << MP0_ADB400_ACP_S_DCM_CTRL_SHIFT) | + (1 << MP0_ADB400_ACP_M_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_ACP_S_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_ACP_M_DCM_CTRL_SHIFT) | + (1 << MP3_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP3_ICC_AXI_STREAM_ARCH_CG_SHIFT), + + MCUSYS_BUS_FABRIC_DCM = (1 << ACLK_INFRA_DYNAMIC_CG_EN_SHIFT) | + (1 << EMI2_ADB400_S_DCM_CTRL_SHIFT) | + (1 << ACLK_GPU_DYNAMIC_CG_EN_SHIFT) | + (1 << ACLK_PSYS_DYNAMIC_CG_EN_SHIFT) | + (0 << MP0_ADB400_S_DCM_CTRL_SHIFT) | + (0 << MP0_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_S_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_M_DCM_CTRL_SHIFT) | + (1 << EMICLK_EMI_DYNAMIC_CG_EN_SHIFT) | + (1 << INFRACLK_INFRA_DYNAMIC_CG_EN_SHIFT) | + (1 << EMICLK_GPU_DYNAMIC_CG_EN_SHIFT) | + (1 << INFRACLK_PSYS_DYNAMIC_CG_EN_SHIFT) | + (1 << EMICLK_EMI1_DYNAMIC_CG_EN_SHIFT) | + (1 << EMI1_ADB400_S_DCM_CTRL_SHIFT) | + (0 << MP2_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP0_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << MP1_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << MP2_ICC_AXI_STREAM_ARCH_CG_SHIFT) | + (1 << L2_SHARE_ADB400_DCM_CTRL_SHIFT) | + (1 << MP1_AGGRESS_DCM_CTRL_SHIFT) | + (1 << MP0_AGGRESS_DCM_CTRL_SHIFT) | + (1 << MP0_ADB400_ACP_S_DCM_CTRL_SHIFT) | + (1 << MP0_ADB400_ACP_M_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_ACP_S_DCM_CTRL_SHIFT) | + (1 << MP1_ADB400_ACP_M_DCM_CTRL_SHIFT) | + (1 << MP3_ADB400_M_DCM_CTRL_SHIFT) | + (1 << MP3_ICC_AXI_STREAM_ARCH_CG_SHIFT) +}; + +/* l2c_sram dcm related */ +enum { + L2C_SRAM_DCM_EN_SHIFT = 0, + L2C_SRAM_DCM = 1 << L2C_SRAM_DCM_EN_SHIFT +}; + +/* mcu misc dcm related */ +enum { + MP0_CNTVALUEB_DCM_EN_SHIFT = 0, + MP_CNTVALUEB_DCM_EN = 8, + + CNTVALUEB_DCM = (1 << MP0_CNTVALUEB_DCM_EN_SHIFT) | + (1 << MP_CNTVALUEB_DCM_EN) +}; + +/* sync dcm cluster config related */ +enum { + MP0_SYNC_DCM_STALL_WR_EN_SHIFT = 7, + MCUSYS_MAX_ACCESS_LATENCY_SHIFT = 24, + + MCU0_SYNC_DCM_STALL_WR_EN = 1 << MP0_SYNC_DCM_STALL_WR_EN_SHIFT, + + MCUSYS_MAX_ACCESS_LATENCY_MASK = 0xf << MCUSYS_MAX_ACCESS_LATENCY_SHIFT, + MCUSYS_MAX_ACCESS_LATENCY = 0x5 << MCUSYS_MAX_ACCESS_LATENCY_SHIFT +}; + +/* cpusys rgu dcm related */ +enum { + CPUSYS_RGU_DCM_CONFIG_SHIFT = 0, + + CPUSYS_RGU_DCM_CINFIG = 1 << CPUSYS_RGU_DCM_CONFIG_SHIFT +}; + +/* mp2 sync dcm related */ +enum { + MP2_DCM_EN_SHIFT = 0, + + MP2_DCM_EN = 1 << MP2_DCM_EN_SHIFT +}; #endif /* MT8183_MCUCFG_H */ diff --git a/plat/mediatek/mt8183/include/mt_gic_v3.h b/plat/mediatek/mt8183/include/mt_gic_v3.h index e2706f46a..b6fc29bbd 100644 --- a/plat/mediatek/mt8183/include/mt_gic_v3.h +++ b/plat/mediatek/mt8183/include/mt_gic_v3.h @@ -9,26 +9,25 @@ #include <lib/mmio.h> -enum irq_schedule_mode { - SW_MODE, - HW_MODE -}; - #define GIC_INT_MASK (MCUCFG_BASE + 0x5e8) #define GIC500_ACTIVE_SEL_SHIFT 3 #define GIC500_ACTIVE_SEL_MASK (0x7 << GIC500_ACTIVE_SEL_SHIFT) #define GIC500_ACTIVE_CPU_SHIFT 16 #define GIC500_ACTIVE_CPU_MASK (0xff << GIC500_ACTIVE_CPU_SHIFT) +#define NR_INT_POL_CTL 20 + void mt_gic_driver_init(void); void mt_gic_init(void); void mt_gic_set_pending(uint32_t irq); uint32_t mt_gic_get_pending(uint32_t irq); void mt_gic_cpuif_enable(void); void mt_gic_cpuif_disable(void); -void mt_gic_pcpu_init(void); -void mt_gic_irq_save(void); -void mt_gic_irq_restore(void); +void mt_gic_rdistif_init(void); +void mt_gic_distif_save(void); +void mt_gic_distif_restore(void); +void mt_gic_rdistif_save(void); +void mt_gic_rdistif_restore(void); void mt_gic_sync_dcm_enable(void); void mt_gic_sync_dcm_disable(void); diff --git a/plat/mediatek/mt8183/include/plat_dcm.h b/plat/mediatek/mt8183/include/plat_dcm.h new file mode 100644 index 000000000..afa9b63e8 --- /dev/null +++ b/plat/mediatek/mt8183/include/plat_dcm.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_DCM_H +#define PLAT_DCM_H + +#define MP2_SYNC_DCM (MCUCFG_BASE + 0x2274) +#define MP2_SYNC_DCM_MASK (0x1 << 0) +#define MP2_SYNC_DCM_ON (0x1 << 0) +#define MP2_SYNC_DCM_OFF (0x0 << 0) + +extern uint64_t plat_dcm_mcsi_a_addr; +extern uint32_t plat_dcm_mcsi_a_val; +extern int plat_dcm_initiated; + +extern void plat_dcm_mcsi_a_backup(void); +extern void plat_dcm_mcsi_a_restore(void); +extern void plat_dcm_rgu_enable(void); +extern void plat_dcm_restore_cluster_on(unsigned long mpidr); +extern void plat_dcm_msg_handler(uint64_t x1); +extern unsigned long plat_dcm_get_enabled_cnt(uint64_t type); +extern void plat_dcm_init(void); + +#define ALL_DCM_TYPE (ARMCORE_DCM_TYPE | MCUSYS_DCM_TYPE \ + | STALL_DCM_TYPE | BIG_CORE_DCM_TYPE \ + | GIC_SYNC_DCM_TYPE | RGU_DCM_TYPE \ + | INFRA_DCM_TYPE \ + | DDRPHY_DCM_TYPE | EMI_DCM_TYPE | DRAMC_DCM_TYPE \ + | MCSI_DCM_TYPE) + +enum { + ARMCORE_DCM_TYPE = (1U << 0), + MCUSYS_DCM_TYPE = (1U << 1), + INFRA_DCM_TYPE = (1U << 2), + PERI_DCM_TYPE = (1U << 3), + EMI_DCM_TYPE = (1U << 4), + DRAMC_DCM_TYPE = (1U << 5), + DDRPHY_DCM_TYPE = (1U << 6), + STALL_DCM_TYPE = (1U << 7), + BIG_CORE_DCM_TYPE = (1U << 8), + GIC_SYNC_DCM_TYPE = (1U << 9), + LAST_CORE_DCM_TYPE = (1U << 10), + RGU_DCM_TYPE = (1U << 11), + TOPCKG_DCM_TYPE = (1U << 12), + LPDMA_DCM_TYPE = (1U << 13), + MCSI_DCM_TYPE = (1U << 14), + NR_DCM_TYPE = 15, +}; + +#endif /* PLAT_DCM_H */
\ No newline at end of file diff --git a/plat/mediatek/mt8183/include/plat_debug.h b/plat/mediatek/mt8183/include/plat_debug.h index e51a6ea83..c9d73cc83 100644 --- a/plat/mediatek/mt8183/include/plat_debug.h +++ b/plat/mediatek/mt8183/include/plat_debug.h @@ -24,8 +24,6 @@ #define BIT_CA15M_L2PARITY_EN (1 << 1) #define BIT_CA15M_LASTPC_DIS (1 << 8) -#define MP1_CPUTOP_PWR_CON 0x10006218 - #define MCU_ALL_PWR_ON_CTRL 0x0c530b58 #define PLAT_MTK_CIRCULAR_BUFFER_UNLOCK 0xefab4133 #define PLAT_MTK_CIRCULAR_BUFFER_LOCK 0xefab4134 diff --git a/plat/mediatek/mt8183/include/platform_def.h b/plat/mediatek/mt8183/include/platform_def.h index bc9022bb4..49a0f805e 100644 --- a/plat/mediatek/mt8183/include/platform_def.h +++ b/plat/mediatek/mt8183/include/platform_def.h @@ -25,6 +25,7 @@ #define MCUCFG_BASE 0x0c530000 #define CFG_SF_CTRL 0x0c510014 #define CFG_SF_INI 0x0c510010 +#define EMI_BASE (IO_PHYS + 0x219000) #define EMI_MPU_BASE (IO_PHYS + 0x226000) #define TRNG_base (IO_PHYS + 0x20f000) #define MT_GIC_BASE 0x0c000000 @@ -38,9 +39,17 @@ #define INFRACFG_AO_BASE (IO_PHYS + 0x1000) +#define TOPCKGEN_BASE (IO_PHYS + 0x0) +#define CLK_SCP_CFG_0 (TOPCKGEN_BASE + 0x200) +#define CLK_SCP_CFG_1 (TOPCKGEN_BASE + 0x204) + #define APMIXEDSYS (IO_PHYS + 0xC000) +#define AP_PLL_CON3 (APMIXEDSYS + 0xC) +#define AP_PLL_CON4 (APMIXEDSYS + 0x10) +#define AP_PLL_CON6 (APMIXEDSYS + 0x18) #define ARMPLL_LL_CON0 (APMIXEDSYS + 0x200) #define ARMPLL_L_CON0 (APMIXEDSYS + 0x210) +#define ARMPLL_L_PWR_CON0 (APMIXEDSYS + 0x21c) #define MAINPLL_CON0 (APMIXEDSYS + 0x220) #define CCIPLL_CON0 (APMIXEDSYS + 0x290) @@ -74,6 +83,7 @@ #define MT_L2_WRITE_ACCESS_RATE (MCUCFG_BASE + 0x604) #define MP0_CA7L_CACHE_CONFIG (MCUCFG_BASE + 0x7f0) #define MP1_CA7L_CACHE_CONFIG (MCUCFG_BASE + 0x7f4) +#define EMI_WFIFO (MCUCFG_BASE + 0x0b5c) /******************************************************************************* * GIC related constants @@ -87,6 +97,7 @@ * UART related constants ******************************************************************************/ #define UART0_BASE (IO_PHYS + 0x01002000) +#define UART1_BASE (IO_PHYS + 0x01003000) #define UART_BAUDRATE 115200 #define UART_CLOCK 26000000 @@ -257,13 +268,13 @@ INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ #define PLAT_MAX_OFF_STATE U(2) #define PLATFORM_CACHE_LINE_SIZE 64 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 4 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) @@ -273,7 +284,7 @@ INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ ******************************************************************************/ #define TZRAM_BASE 0x54600000 -#define TZRAM_SIZE 0x00020000 +#define TZRAM_SIZE 0x00030000 /******************************************************************************* * BL31 specific defines. @@ -291,7 +302,7 @@ INTR_PROP_DESC(MT_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, grp, \ ******************************************************************************/ #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#define MAX_XLAT_TABLES 4 +#define MAX_XLAT_TABLES 16 #define MAX_MMAP_REGIONS 16 /******************************************************************************* diff --git a/plat/mediatek/mt8183/include/sspm_reg.h b/plat/mediatek/mt8183/include/sspm_reg.h new file mode 100644 index 000000000..3f1ac869c --- /dev/null +++ b/plat/mediatek/mt8183/include/sspm_reg.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef __SSPM_REG_H__ +#define __SSPM_REG_H__ + +#include "platform_def.h" + +#define SSPM_CFGREG_RSV_RW_REG0 (SSPM_CFGREG_BASE + 0x0100) +#define SSPM_CFGREG_ACAO_INT_SET (SSPM_CFGREG_BASE + 0x00D8) +#define SSPM_CFGREG_ACAO_INT_CLR (SSPM_CFGREG_BASE + 0x00DC) +#define SSPM_CFGREG_ACAO_WAKEUP_EN (SSPM_CFGREG_BASE + 0x0204) + +#define STANDBYWFI_EN(n) (1 << (n + 8)) +#define GIC_IRQOUT_EN(n) (1 << (n + 0)) + +#define NF_MCDI_MBOX 19 +#define MCDI_MBOX_CLUSTER_0_CAN_POWER_OFF 0 +#define MCDI_MBOX_CLUSTER_1_CAN_POWER_OFF 1 +#define MCDI_MBOX_BUCK_POWER_OFF_MASK 2 +#define MCDI_MBOX_CLUSTER_0_ATF_ACTION_DONE 3 +#define MCDI_MBOX_CLUSTER_1_ATF_ACTION_DONE 4 +#define MCDI_MBOX_BOOTADDR 5 +#define MCDI_MBOX_PAUSE_ACTION 6 +#define MCDI_MBOX_AVAIL_CPU_MASK 7 +#define MCDI_MBOX_CPU_CLUSTER_PWR_STAT 8 +#define MCDI_MBOX_ACTION_STAT 9 +#define MCDI_MBOX_CLUSTER_0_CNT 10 +#define MCDI_MBOX_CLUSTER_1_CNT 11 +#define MCDI_MBOX_CPU_ISOLATION_MASK 12 +#define MCDI_MBOX_PAUSE_ACK 13 +#define MCDI_MBOX_PENDING_ON_EVENT 14 +#define MCDI_MBOX_PROF_CMD 15 +#define MCDI_MBOX_DRCC_CALI_DONE 16 +#define MCDI_MBOX_HP_CMD 17 +#define MCDI_MBOX_HP_ACK 18 + +#endif /* __SSPM_REG_H__ */ diff --git a/plat/mediatek/mt8183/plat_dcm.c b/plat/mediatek/mt8183/plat_dcm.c new file mode 100644 index 000000000..8ee77f108 --- /dev/null +++ b/plat/mediatek/mt8183/plat_dcm.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2019, MediaTek Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <lib/bakery_lock.h> +#include <drivers/console.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <plat_dcm.h> +#include <plat_private.h> +#include <plat_dcm.h> +#include <plat/common/platform.h> +#include <platform_def.h> +#include <mtk_plat_common.h> + +#define PWR_STATUS (SPM_BASE + 0x180) + +uint64_t plat_dcm_mcsi_a_addr; +uint32_t plat_dcm_mcsi_a_val; +static int plat_dcm_init_type; +static unsigned int dcm_big_core_cnt; +int plat_dcm_initiated; + +#define PWR_STA_BIG_MP_MASK (0x1 << 15) + +DEFINE_BAKERY_LOCK(dcm_lock); + +void dcm_lock_init(void) +{ + bakery_lock_init(&dcm_lock); +} + +void dcm_lock_get(void) +{ + bakery_lock_get(&dcm_lock); +} + +void dcm_lock_release(void) +{ + bakery_lock_release(&dcm_lock); +} + +void plat_dcm_mcsi_a_backup(void) +{ +} + +void plat_dcm_mcsi_a_restore(void) +{ +} + +void plat_dcm_rgu_enable(void) +{ +} + +void plat_dcm_big_core_sync(short on) +{ + /* Check if Big cluster power is existed */ + if (!(mmio_read_32(PWR_STATUS) & PWR_STA_BIG_MP_MASK)) + return; + + if (on) { + mmio_write_32(MP2_SYNC_DCM, + (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK) + | MP2_SYNC_DCM_ON); + dcm_big_core_cnt++; + } else + mmio_write_32(MP2_SYNC_DCM, + (mmio_read_32(MP2_SYNC_DCM) & ~MP2_SYNC_DCM_MASK) + | MP2_SYNC_DCM_OFF); +} + +void plat_dcm_restore_cluster_on(unsigned long mpidr) +{ + unsigned long cluster_id = + (mpidr & MPIDR_CLUSTER_MASK) >> MPIDR_AFFINITY_BITS; + + switch (cluster_id) { + case 0x1: + dcm_lock_get(); + if (plat_dcm_init_type & BIG_CORE_DCM_TYPE) + plat_dcm_big_core_sync(1); + else + plat_dcm_big_core_sync(0); + dcm_lock_release(); + break; + default: + break; + } +} + +void plat_dcm_msg_handler(uint64_t x1) +{ + plat_dcm_init_type = x1 & ALL_DCM_TYPE; +} + +unsigned long plat_dcm_get_enabled_cnt(uint64_t type) +{ + switch (type) { + case BIG_CORE_DCM_TYPE: + return dcm_big_core_cnt; + default: + return 0; + } +} + +void plat_dcm_init(void) +{ + dcm_lock_init(); +} diff --git a/plat/mediatek/mt8183/plat_debug.c b/plat/mediatek/mt8183/plat_debug.c index 51816dba1..2f0b67dc0 100644 --- a/plat/mediatek/mt8183/plat_debug.c +++ b/plat/mediatek/mt8183/plat_debug.c @@ -9,6 +9,7 @@ #include <lib/mmio.h> #include <plat_debug.h> #include <platform_def.h> +#include <spm.h> void circular_buffer_setup(void) { diff --git a/plat/mediatek/mt8183/plat_mt_gic.c b/plat/mediatek/mt8183/plat_mt_gic.c index 21443799f..35792b2e1 100644 --- a/plat/mediatek/mt8183/plat_mt_gic.c +++ b/plat/mediatek/mt8183/plat_mt_gic.c @@ -1,33 +1,28 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> #include <common/bl_common.h> #include <common/debug.h> #include <drivers/arm/gicv3.h> #include <bl31/interrupt_mgmt.h> -#include <../drivers/arm/gic/v3/gicv3_private.h> #include <mt_gic_v3.h> #include <mtk_plat_common.h> +#include "../drivers/arm/gic/v3/gicv3_private.h" #include "plat_private.h" #include <plat/common/platform.h> #include <platform_def.h> #include <stdint.h> #include <stdio.h> -#define NR_INT_POL_CTL 20 - uintptr_t rdistif_base_addrs[PLATFORM_CORE_COUNT]; +static uint32_t rdist_has_saved[PLATFORM_CORE_COUNT]; -/* - * We save and restore the GICv3 context on system suspend. Allocate the - * data in the designated EL3 Secure carve-out memory - */ -gicv3_redist_ctx_t rdist_ctx __section("arm_el3_tzc_dram"); -gicv3_dist_ctx_t dist_ctx __section("arm_el3_tzc_dram"); - +/* we save and restore the GICv3 context on system suspend */ +gicv3_dist_ctx_t dist_ctx; static unsigned int mt_mpidr_to_core_pos(u_register_t mpidr) { @@ -42,26 +37,15 @@ gicv3_driver_data_t mt_gicv3_data = { .mpidr_to_core_pos = mt_mpidr_to_core_pos, }; -void setup_int_schedule_mode(enum irq_schedule_mode mode, - unsigned int active_cpu) -{ - assert(mode <= HW_MODE); - assert(active_cpu <= 0xFF); - - if (mode == HW_MODE) { - mmio_write_32(GIC_INT_MASK, - (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK)) - | (0x1 << GIC500_ACTIVE_SEL_SHIFT)); - } else if (mode == SW_MODE) { - mmio_write_32(GIC_INT_MASK, - (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_SEL_MASK))); - } +struct gic_chip_data { + unsigned int saved_group; + unsigned int saved_enable; + unsigned int saved_conf0; + unsigned int saved_conf1; + unsigned int saved_grpmod; +}; - mmio_write_32(GIC_INT_MASK, - (mmio_read_32(GIC_INT_MASK) & ~(GIC500_ACTIVE_CPU_MASK)) - | (active_cpu << GIC500_ACTIVE_CPU_SHIFT)); - return; -} +static struct gic_chip_data gic_data; void clear_sec_pol_ctl_en(void) { @@ -79,29 +63,11 @@ void mt_gic_driver_init(void) gicv3_driver_init(&mt_gicv3_data); } -void mt_gic_init(void) -{ - gicv3_distif_init(); - gicv3_rdistif_init(plat_my_core_pos()); - gicv3_cpuif_enable(plat_my_core_pos()); - - setup_int_schedule_mode(SW_MODE, 0xf); - clear_sec_pol_ctl_en(); -} - void mt_gic_set_pending(uint32_t irq) { gicv3_set_interrupt_pending(irq, plat_my_core_pos()); } -uint32_t mt_gic_get_pending(uint32_t irq) -{ - uint32_t bit = 1 << (irq % 32); - - return (mmio_read_32(gicv3_driver_data->gicd_base + - GICD_ISPENDR + irq / 32 * 4) & bit) ? 1 : 0; -} - void mt_gic_cpuif_enable(void) { gicv3_cpuif_enable(plat_my_core_pos()); @@ -112,35 +78,83 @@ void mt_gic_cpuif_disable(void) gicv3_cpuif_disable(plat_my_core_pos()); } -void mt_gic_pcpu_init(void) +void mt_gic_rdistif_init(void) { - gicv3_rdistif_init(plat_my_core_pos()); + unsigned int proc_num; + unsigned int index; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + /* set all SGI/PPI as non-secure GROUP1 by default */ + mmio_write_32(gicr_base + GICR_IGROUPR0, ~0U); + mmio_write_32(gicr_base + GICR_IGRPMODR0, 0x0); + + /* setup the default PPI/SGI priorities */ + for (index = 0; index < TOTAL_PCPU_INTR_NUM; index += 4U) + gicr_write_ipriorityr(gicr_base, index, + GICD_IPRIORITYR_DEF_VAL); } -void mt_gic_irq_save(void) +void mt_gic_distif_save(void) { - gicv3_rdistif_save(plat_my_core_pos(), &rdist_ctx); gicv3_distif_save(&dist_ctx); } -void mt_gic_irq_restore(void) +void mt_gic_distif_restore(void) { gicv3_distif_init_restore(&dist_ctx); - gicv3_rdistif_init_restore(plat_my_core_pos(), &rdist_ctx); } -void mt_gic_sync_dcm_enable(void) +void mt_gic_rdistif_save(void) +{ + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + + gic_data.saved_group = mmio_read_32(gicr_base + GICR_IGROUPR0); + gic_data.saved_enable = mmio_read_32(gicr_base + GICR_ISENABLER0); + gic_data.saved_conf0 = mmio_read_32(gicr_base + GICR_ICFGR0); + gic_data.saved_conf1 = mmio_read_32(gicr_base + GICR_ICFGR1); + gic_data.saved_grpmod = mmio_read_32(gicr_base + GICR_IGRPMODR0); + + rdist_has_saved[proc_num] = 1; +} + +void mt_gic_rdistif_restore(void) { - unsigned int val = mmio_read_32(GIC_SYNC_DCM); + unsigned int proc_num; + uintptr_t gicr_base; + + proc_num = plat_my_core_pos(); + if (rdist_has_saved[proc_num] == 1) { + gicr_base = gicv3_driver_data->rdistif_base_addrs[proc_num]; + mmio_write_32(gicr_base + GICR_IGROUPR0, gic_data.saved_group); + mmio_write_32(gicr_base + GICR_ISENABLER0, gic_data.saved_enable); + mmio_write_32(gicr_base + GICR_ICFGR0, gic_data.saved_conf0); + mmio_write_32(gicr_base + GICR_ICFGR1, gic_data.saved_conf1); + mmio_write_32(gicr_base + GICR_IGRPMODR0, gic_data.saved_grpmod); + } +} - val &= ~GIC_SYNC_DCM_MASK; - mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_ON); +void mt_gic_sync_dcm_enable(void) +{ + mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_ON); } void mt_gic_sync_dcm_disable(void) { - unsigned int val = mmio_read_32(GIC_SYNC_DCM); + mmio_clrsetbits_32(GIC_SYNC_DCM, GIC_SYNC_DCM_MASK, GIC_SYNC_DCM_OFF); +} + +void mt_gic_init(void) +{ + gicv3_distif_init(); + gicv3_cpuif_enable(plat_my_core_pos()); + mt_gic_rdistif_init(); - val &= ~GIC_SYNC_DCM_MASK; - mmio_write_32(GIC_SYNC_DCM, val | GIC_SYNC_DCM_OFF); + clear_sec_pol_ctl_en(); } diff --git a/plat/mediatek/mt8183/plat_pm.c b/plat/mediatek/mt8183/plat_pm.c index dd54d7040..6094a17be 100644 --- a/plat/mediatek/mt8183/plat_pm.c +++ b/plat/mediatek/mt8183/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, MediaTek Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,33 +15,575 @@ /* mediatek platform specific headers */ #include <platform_def.h> #include <scu.h> +#include <mt_gic_v3.h> +#include <mtk_mcdi.h> #include <mtk_plat_common.h> -#include <power_tracer.h> +#include <mtgpio.h> +#include <mtspmc.h> +#include <plat_dcm.h> +#include <plat_debug.h> +#include <plat_params.h> #include <plat_private.h> +#include <power_tracer.h> +#include <pmic.h> +#include <spm.h> +#include <spm_suspend.h> +#include <sspm.h> +#include <rtc.h> + +/* Local power state for power domains in Run state. */ +#define MTK_LOCAL_STATE_RUN 0 +/* Local power state for retention. */ +#define MTK_LOCAL_STATE_RET 1 +/* Local power state for OFF/power-down. */ +#define MTK_LOCAL_STATE_OFF 2 + +#if PSCI_EXTENDED_STATE_ID +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define MTK_LOCAL_PSTATE_WIDTH 4 +#define MTK_LOCAL_PSTATE_MASK ((1 << MTK_LOCAL_PSTATE_WIDTH) - 1) + +/* Macros to construct the composite power state */ + +/* Make composite power state parameter till power level 0 */ + +#define mtk_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | ((type) << PSTATE_TYPE_SHIFT)) + +#else /* !PSCI_EXTENDED_STATE_ID */ + +#define mtk_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type) \ + (((lvl0_state) << PSTATE_ID_SHIFT) | \ + ((pwr_lvl) << PSTATE_PWR_LVL_SHIFT) | \ + ((type) << PSTATE_TYPE_SHIFT)) + +#endif /* PSCI_EXTENDED_STATE_ID */ + +/* Make composite power state parameter till power level 1 */ +#define mtk_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type) \ + (((lvl1_state) << MTK_LOCAL_PSTATE_WIDTH) | \ + mtk_make_pwrstate_lvl0(lvl0_state, pwr_lvl, type)) + +/* Make composite power state parameter till power level 2 */ +#define mtk_make_pwrstate_lvl2( \ + lvl2_state, lvl1_state, lvl0_state, pwr_lvl, type) \ + (((lvl2_state) << (MTK_LOCAL_PSTATE_WIDTH * 2)) | \ + mtk_make_pwrstate_lvl1(lvl1_state, lvl0_state, pwr_lvl, type)) + +#define MTK_PWR_LVL0 0 +#define MTK_PWR_LVL1 1 +#define MTK_PWR_LVL2 2 + +/* Macros to read the MTK power domain state */ +#define MTK_CORE_PWR_STATE(state) (state)->pwr_domain_state[MTK_PWR_LVL0] +#define MTK_CLUSTER_PWR_STATE(state) (state)->pwr_domain_state[MTK_PWR_LVL1] +#define MTK_SYSTEM_PWR_STATE(state) ((PLAT_MAX_PWR_LVL > MTK_PWR_LVL1) ? \ + (state)->pwr_domain_state[MTK_PWR_LVL2] : 0) + +#if PSCI_EXTENDED_STATE_ID +/* + * The table storing the valid idle power states. Ensure that the + * array entries are populated in ascending order of state-id to + * enable us to use binary search during power state validation. + * The table must be terminated by a NULL entry. + */ +const unsigned int mtk_pm_idle_states[] = { + /* State-id - 0x001 */ + mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_RUN, + MTK_LOCAL_STATE_RET, MTK_PWR_LVL0, PSTATE_TYPE_STANDBY), + /* State-id - 0x002 */ + mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_RUN, + MTK_LOCAL_STATE_OFF, MTK_PWR_LVL0, PSTATE_TYPE_POWERDOWN), + /* State-id - 0x022 */ + mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_RUN, MTK_LOCAL_STATE_OFF, + MTK_LOCAL_STATE_OFF, MTK_PWR_LVL1, PSTATE_TYPE_POWERDOWN), +#if PLAT_MAX_PWR_LVL > MTK_PWR_LVL1 + /* State-id - 0x222 */ + mtk_make_pwrstate_lvl2(MTK_LOCAL_STATE_OFF, MTK_LOCAL_STATE_OFF, + MTK_LOCAL_STATE_OFF, MTK_PWR_LVL2, PSTATE_TYPE_POWERDOWN), +#endif + 0, +}; +#endif + +#define CPU_IDX(cluster, cpu) ((cluster << 2) + cpu) +#define ON true +#define OFF false + +/* Pause MCDI when CPU hotplug */ +static bool HP_SSPM_PAUSE; +/* CPU Hotplug by SSPM */ +static bool HP_SSPM_CTRL = true; +/* Turn off cluster when CPU hotplug off */ +static bool HP_CLUSTER_OFF = true; +/* Turn off cluster when CPU MCDI off */ +static bool MCDI_C2 = true; +/* Enable MCDI */ +static bool MCDI_SSPM = true; + +static uintptr_t secure_entrypoint; + +static void mp1_L2_desel_config(void) +{ + mmio_write_64(MCUCFG_BASE + 0x2200, 0x2092c820); + + dsb(); +} + +static bool clst_single_pwr(int cluster, int cpu) +{ + uint32_t cpu_mask[2] = {0x00001e00, 0x000f0000}; + uint32_t cpu_pwr_bit[] = {9, 10, 11, 12, 16, 17, 18, 19}; + int my_idx = (cluster << 2) + cpu; + uint32_t pwr_stat = mmio_read_32(0x10006180); + + return !(pwr_stat & (cpu_mask[cluster] & ~BIT(cpu_pwr_bit[my_idx]))); +} + +static bool clst_single_on(int cluster, int cpu) +{ + uint32_t cpu_mask[2] = {0x0f, 0xf0}; + int my_idx = (cluster << 2) + cpu; + uint32_t on_stat = mcdi_avail_cpu_mask_read(); + + return !(on_stat & (cpu_mask[cluster] & ~BIT(my_idx))); +} + +static void plat_cpu_pwrdwn_common(void) +{ + /* Prevent interrupts from spuriously waking up this cpu */ + mt_gic_rdistif_save(); + mt_gic_cpuif_disable(); +} + +static void plat_cpu_pwron_common(void) +{ + /* Enable the gic cpu interface */ + mt_gic_cpuif_enable(); + mt_gic_rdistif_init(); + mt_gic_rdistif_restore(); +} + +static void plat_cluster_pwrdwn_common(uint64_t mpidr, int cluster) +{ + if (cluster > 0) + mt_gic_sync_dcm_enable(); + + /* Disable coherency */ + plat_mtk_cci_disable(); + disable_scu(mpidr); +} + +static void plat_cluster_pwron_common(uint64_t mpidr, int cluster) +{ + if (cluster > 0) { + l2c_parity_check_setup(); + circular_buffer_setup(); + mp1_L2_desel_config(); + mt_gic_sync_dcm_disable(); + } + + /* Enable coherency */ + enable_scu(mpidr); + plat_mtk_cci_enable(); + /* Enable big core dcm */ + plat_dcm_restore_cluster_on(mpidr); + /* Enable rgu dcm */ + plat_dcm_rgu_enable(); +} + +static void plat_cpu_standby(plat_local_state_t cpu_state) +{ + u_register_t scr; + + scr = read_scr_el3(); + write_scr_el3(scr | SCR_IRQ_BIT | SCR_FIQ_BIT); + + isb(); + dsb(); + wfi(); + + write_scr_el3(scr); +} + +static void mcdi_ctrl_before_hotplug_on(int cluster, int cpu) +{ + if (!HP_SSPM_CTRL && HP_SSPM_PAUSE && MCDI_SSPM) { + mcdi_pause_clr(cluster, CPU_IDX(cluster, cpu), OFF); + mcdi_pause_set(cluster, CPU_IDX(cluster, cpu), ON); + } +} + +static void mcdi_ctrl_before_hotplug_off(int cluster, int cpu, bool cluster_off) +{ + if (!HP_SSPM_CTRL && HP_SSPM_PAUSE && MCDI_SSPM) + mcdi_pause_set(cluster_off ? cluster : -1, + CPU_IDX(cluster, cpu), OFF); +} + +static void mcdi_ctrl_cluster_cpu_off(int cluster, int cpu, bool cluster_off) +{ + if (MCDI_SSPM) { + sspm_set_bootaddr(secure_entrypoint); + + sspm_standbywfi_irq_enable(CPU_IDX(cluster, cpu)); + + if (cluster_off) + sspm_cluster_pwr_off_notify(cluster); + else + sspm_cluster_pwr_on_notify(cluster); + } +} + +static void mcdi_ctrl_suspend(void) +{ + if (MCDI_SSPM) + mcdi_pause(); +} + +static void mcdi_ctrl_resume(void) +{ + if (MCDI_SSPM) + mcdi_unpause(); +} + +static void hotplug_ctrl_cluster_on(int cluster, int cpu) +{ + if (HP_SSPM_CTRL && MCDI_SSPM) { + mcdi_hotplug_clr(cluster, CPU_IDX(cluster, cpu), OFF); + mcdi_hotplug_set(cluster, -1, ON); + mcdi_hotplug_wait_ack(cluster, -1, ON); + } else { + /* power on cluster */ + if (!spm_get_cluster_powerstate(cluster)) + spm_poweron_cluster(cluster); + } +} + +static void hotplug_ctrl_cpu_on(int cluster, int cpu) +{ + if (HP_SSPM_CTRL && MCDI_SSPM) + mcdi_hotplug_set(cluster, CPU_IDX(cluster, cpu), ON); + else + spm_poweron_cpu(cluster, cpu); +} + +static void hotplug_ctrl_cpu_on_finish(int cluster, int cpu) +{ + spm_disable_cpu_auto_off(cluster, cpu); + + if (HP_SSPM_CTRL && MCDI_SSPM) + mcdi_hotplug_clr(cluster, CPU_IDX(cluster, cpu), ON); + else if (HP_SSPM_PAUSE && MCDI_SSPM) + mcdi_pause_clr(cluster, CPU_IDX(cluster, cpu), ON); + + mcdi_avail_cpu_mask_set(BIT(CPU_IDX(cluster, cpu))); +} + +static void hotplug_ctrl_cluster_cpu_off(int cluster, int cpu, bool cluster_off) +{ + mcdi_avail_cpu_mask_clr(BIT(CPU_IDX(cluster, cpu))); + + if (HP_SSPM_CTRL && MCDI_SSPM) { + mcdi_hotplug_set(cluster_off ? cluster : -1, + CPU_IDX(cluster, cpu), OFF); + } else { + spm_enable_cpu_auto_off(cluster, cpu); + + if (cluster_off) + spm_enable_cluster_auto_off(cluster); + + spm_set_cpu_power_off(cluster, cpu); + } +} + +static int plat_mtk_power_domain_on(unsigned long mpidr) +{ + int cpu = MPIDR_AFFLVL0_VAL(mpidr); + int cluster = MPIDR_AFFLVL1_VAL(mpidr); + int clst_pwr = spm_get_cluster_powerstate(cluster); + unsigned int i; + + mcdi_ctrl_before_hotplug_on(cluster, cpu); + hotplug_ctrl_cluster_on(cluster, cpu); + + if (clst_pwr == 0) { + /* init cpu reset arch as AARCH64 of cluster */ + for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) { + mcucfg_init_archstate(cluster, i, 1); + mcucfg_set_bootaddr(cluster, i, secure_entrypoint); + } + } + + hotplug_ctrl_cpu_on(cluster, cpu); + + return PSCI_E_SUCCESS; +} + +static void plat_mtk_power_domain_off(const psci_power_state_t *state) +{ + uint64_t mpidr = read_mpidr(); + int cpu = MPIDR_AFFLVL0_VAL(mpidr); + int cluster = MPIDR_AFFLVL1_VAL(mpidr); + const plat_local_state_t *pds = state->pwr_domain_state; + bool afflvl1 = (pds[MPIDR_AFFLVL1] == MTK_LOCAL_STATE_OFF); + bool cluster_off = (HP_CLUSTER_OFF && afflvl1 && + clst_single_on(cluster, cpu)); + + plat_cpu_pwrdwn_common(); + + if (cluster_off) + plat_cluster_pwrdwn_common(mpidr, cluster); + + mcdi_ctrl_before_hotplug_off(cluster, cpu, cluster_off); + hotplug_ctrl_cluster_cpu_off(cluster, cpu, cluster_off); +} + +static void plat_mtk_power_domain_on_finish(const psci_power_state_t *state) +{ + uint64_t mpidr = read_mpidr(); + int cpu = MPIDR_AFFLVL0_VAL(mpidr); + int cluster = MPIDR_AFFLVL1_VAL(mpidr); + const plat_local_state_t *pds = state->pwr_domain_state; + bool afflvl1 = (pds[MPIDR_AFFLVL1] == MTK_LOCAL_STATE_OFF); + + if (afflvl1) + plat_cluster_pwron_common(mpidr, cluster); + + plat_cpu_pwron_common(); + + hotplug_ctrl_cpu_on_finish(cluster, cpu); +} + +static void plat_mtk_power_domain_suspend(const psci_power_state_t *state) +{ + uint64_t mpidr = read_mpidr(); + int cpu = MPIDR_AFFLVL0_VAL(mpidr); + int cluster = MPIDR_AFFLVL1_VAL(mpidr); + const plat_local_state_t *pds = state->pwr_domain_state; + bool afflvl1 = (pds[MPIDR_AFFLVL1] == MTK_LOCAL_STATE_OFF); + bool afflvl2 = (pds[MPIDR_AFFLVL2] == MTK_LOCAL_STATE_OFF); + bool cluster_off = MCDI_C2 && afflvl1 && clst_single_pwr(cluster, cpu); + + plat_cpu_pwrdwn_common(); + + plat_dcm_mcsi_a_backup(); + + if (cluster_off || afflvl2) + plat_cluster_pwrdwn_common(mpidr, cluster); + + if (afflvl2) { + spm_data_t spm_d = { .cmd = SPM_SUSPEND }; + uint32_t *d = (uint32_t *)&spm_d; + uint32_t l = sizeof(spm_d) / sizeof(uint32_t); + + mcdi_ctrl_suspend(); + + spm_set_bootaddr(secure_entrypoint); + + if (MCDI_SSPM) + sspm_ipi_send_non_blocking(IPI_ID_SUSPEND, d); + + spm_system_suspend(); + + if (MCDI_SSPM) + while (sspm_ipi_recv_non_blocking(IPI_ID_SUSPEND, d, l)) + ; + + mt_gic_distif_save(); + } else { + mcdi_ctrl_cluster_cpu_off(cluster, cpu, cluster_off); + } +} + +static void plat_mtk_power_domain_suspend_finish(const psci_power_state_t *state) +{ + uint64_t mpidr = read_mpidr(); + int cluster = MPIDR_AFFLVL1_VAL(mpidr); + const plat_local_state_t *pds = state->pwr_domain_state; + bool afflvl2 = (pds[MPIDR_AFFLVL2] == MTK_LOCAL_STATE_OFF); + + if (afflvl2) { + spm_data_t spm_d = { .cmd = SPM_RESUME }; + uint32_t *d = (uint32_t *)&spm_d; + uint32_t l = sizeof(spm_d) / sizeof(uint32_t); + + mt_gic_init(); + mt_gic_distif_restore(); + mt_gic_rdistif_restore(); + + mmio_write_32(EMI_WFIFO, 0xf); + + if (MCDI_SSPM) + sspm_ipi_send_non_blocking(IPI_ID_SUSPEND, d); + + spm_system_suspend_finish(); + + if (MCDI_SSPM) + while (sspm_ipi_recv_non_blocking(IPI_ID_SUSPEND, d, l)) + ; + + mcdi_ctrl_resume(); + } else { + plat_cpu_pwron_common(); + } + + plat_cluster_pwron_common(mpidr, cluster); + + plat_dcm_mcsi_a_restore(); +} + +#if PSCI_EXTENDED_STATE_ID + +static int plat_mtk_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + unsigned int state_id; + int i; + + assert(req_state); + + if (!MCDI_SSPM) + return PSCI_E_INVALID_PARAMS; + + /* + * Currently we are using a linear search for finding the matching + * entry in the idle power state array. This can be made a binary + * search if the number of entries justify the additional complexity. + */ + for (i = 0; !!mtk_pm_idle_states[i]; i++) { + if (power_state == mtk_pm_idle_states[i]) + break; + } + + /* Return error if entry not found in the idle state array */ + if (!mtk_pm_idle_states[i]) + return PSCI_E_INVALID_PARAMS; + + i = 0; + state_id = psci_get_pstate_id(power_state); + + /* Parse the State ID and populate the state info parameter */ + while (state_id) { + req_state->pwr_domain_state[i++] = state_id & + MTK_LOCAL_PSTATE_MASK; + state_id >>= MTK_LOCAL_PSTATE_WIDTH; + } + + return PSCI_E_SUCCESS; +} + +#else /* if !PSCI_EXTENDED_STATE_ID */ + +static int plat_mtk_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + int pstate = psci_get_pstate_type(power_state); + int pwr_lvl = psci_get_pstate_pwrlvl(power_state); + int i; + + assert(req_state); + + if (pwr_lvl > PLAT_MAX_PWR_LVL) + return PSCI_E_INVALID_PARAMS; + + /* Sanity check the requested state */ + if (pstate == PSTATE_TYPE_STANDBY) { + /* + * It's possible to enter standby only on power level 0 + * Ignore any other power level. + */ + if (pwr_lvl != 0) + return PSCI_E_INVALID_PARAMS; + + req_state->pwr_domain_state[MTK_PWR_LVL0] = MTK_LOCAL_STATE_RET; + } else if (!MCDI_SSPM) { + return PSCI_E_INVALID_PARAMS; + } else { + for (i = 0; i <= pwr_lvl; i++) + req_state->pwr_domain_state[i] = MTK_LOCAL_STATE_OFF; + } + + return PSCI_E_SUCCESS; +} + +#endif /* PSCI_EXTENDED_STATE_ID */ + +/******************************************************************************* + * MTK handlers to shutdown/reboot the system + ******************************************************************************/ +static void __dead2 plat_mtk_system_off(void) +{ + INFO("MTK System Off\n"); + + rtc_power_off_sequence(); + wk_pmic_enable_sdn_delay(); + pmic_power_off(); + + wfi(); + ERROR("MTK System Off: operation not handled.\n"); + panic(); +} + +static void __dead2 plat_mtk_system_reset(void) +{ + struct bl_aux_gpio_info *gpio_reset = plat_get_mtk_gpio_reset(); + + INFO("MTK System Reset\n"); + + mt_set_gpio_out(gpio_reset->index, gpio_reset->polarity); + + wfi(); + ERROR("MTK System Reset: operation not handled.\n"); + panic(); +} + +static void plat_mtk_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + assert(PLAT_MAX_PWR_LVL >= 2); + + for (int i = MPIDR_AFFLVL0; i <= PLAT_MAX_PWR_LVL; i++) + req_state->pwr_domain_state[i] = MTK_LOCAL_STATE_OFF; +} /******************************************************************************* * MTK_platform handler called when an affinity instance is about to be turned * on. The level and mpidr determine the affinity instance. ******************************************************************************/ -static uintptr_t secure_entrypoint; - static const plat_psci_ops_t plat_plat_pm_ops = { - .cpu_standby = NULL, - .pwr_domain_on = NULL, - .pwr_domain_on_finish = NULL, - .pwr_domain_off = NULL, - .pwr_domain_suspend = NULL, - .pwr_domain_suspend_finish = NULL, - .system_off = NULL, - .system_reset = NULL, - .validate_power_state = NULL, - .get_sys_suspend_power_state = NULL, + .cpu_standby = plat_cpu_standby, + .pwr_domain_on = plat_mtk_power_domain_on, + .pwr_domain_on_finish = plat_mtk_power_domain_on_finish, + .pwr_domain_off = plat_mtk_power_domain_off, + .pwr_domain_suspend = plat_mtk_power_domain_suspend, + .pwr_domain_suspend_finish = plat_mtk_power_domain_suspend_finish, + .system_off = plat_mtk_system_off, + .system_reset = plat_mtk_system_reset, + .validate_power_state = plat_mtk_validate_power_state, + .get_sys_suspend_power_state = plat_mtk_get_sys_suspend_power_state }; int plat_setup_psci_ops(uintptr_t sec_entrypoint, const plat_psci_ops_t **psci_ops) { + unsigned int i; + *psci_ops = &plat_plat_pm_ops; secure_entrypoint = sec_entrypoint; + + /* Init cpu reset arch as AARCH64 of cluster 0 */ + for (i = 0; i < PLATFORM_MAX_CPUS_PER_CLUSTER; i++) { + mcucfg_init_archstate(0, i, 1); + mcucfg_set_bootaddr(0, i, secure_entrypoint); + } + + if (!check_mcdi_ctl_stat()) { + HP_SSPM_CTRL = false; + MCDI_SSPM = false; + } + return 0; } diff --git a/plat/mediatek/mt8183/platform.mk b/plat/mediatek/mt8183/platform.mk index f0a598a38..597e18b90 100644 --- a/plat/mediatek/mt8183/platform.mk +++ b/plat/mediatek/mt8183/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2019, MediaTek Inc. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -9,6 +9,16 @@ MTK_PLAT_SOC := ${MTK_PLAT}/${PLAT} PLAT_INCLUDES := -I${MTK_PLAT}/common/ \ -I${MTK_PLAT_SOC}/drivers/ \ + -I${MTK_PLAT_SOC}/drivers/emi_mpu/ \ + -I${MTK_PLAT_SOC}/drivers/devapc/ \ + -I${MTK_PLAT_SOC}/drivers/mcdi/ \ + -I${MTK_PLAT_SOC}/drivers/spmc/ \ + -I${MTK_PLAT_SOC}/drivers/gpio/ \ + -I${MTK_PLAT_SOC}/drivers/pmic/ \ + -I${MTK_PLAT_SOC}/drivers/spm/ \ + -I${MTK_PLAT_SOC}/drivers/sspm/ \ + -I${MTK_PLAT_SOC}/drivers/rtc/ \ + -I${MTK_PLAT_SOC}/drivers/uart/ \ -I${MTK_PLAT_SOC}/include/ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/aarch64/xlat_tables.c \ @@ -27,20 +37,37 @@ BL31_SOURCES += common/desc_image_load.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/gpio/gpio.c \ drivers/ti/uart/aarch64/16550_console.S \ + lib/bl_aux_params/bl_aux_params.c \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a73.S \ plat/common/plat_gicv3.c \ ${MTK_PLAT}/common/mtk_plat_common.c \ + ${MTK_PLAT}/common/drivers/pmic_wrap/pmic_wrap_init.c \ + ${MTK_PLAT}/common/drivers/rtc/rtc_common.c \ + ${MTK_PLAT}/common/params_setup.c \ ${MTK_PLAT_SOC}/aarch64/plat_helpers.S \ ${MTK_PLAT_SOC}/aarch64/platform_common.c \ + ${MTK_PLAT_SOC}/drivers/devapc/devapc.c \ ${MTK_PLAT_SOC}/drivers/mcsi/mcsi.c \ + ${MTK_PLAT_SOC}/drivers/pmic/pmic.c \ + ${MTK_PLAT_SOC}/drivers/rtc/rtc.c \ + ${MTK_PLAT_SOC}/drivers/mcdi/mtk_mcdi.c \ + ${MTK_PLAT_SOC}/drivers/spmc/mtspmc.c \ + ${MTK_PLAT_SOC}/drivers/spm/spm.c \ + ${MTK_PLAT_SOC}/drivers/spm/spm_pmic_wrap.c \ + ${MTK_PLAT_SOC}/drivers/spm/spm_suspend.c \ + ${MTK_PLAT_SOC}/drivers/gpio/mtgpio.c \ + ${MTK_PLAT_SOC}/drivers/uart/uart.c \ + ${MTK_PLAT_SOC}/drivers/emi_mpu/emi_mpu.c \ ${MTK_PLAT_SOC}/plat_pm.c \ ${MTK_PLAT_SOC}/plat_topology.c \ ${MTK_PLAT_SOC}/plat_mt_gic.c \ + ${MTK_PLAT_SOC}/plat_dcm.c \ ${MTK_PLAT_SOC}/bl31_plat_setup.c \ ${MTK_PLAT_SOC}/plat_debug.c \ - ${MTK_PLAT_SOC}/scu.c + ${MTK_PLAT_SOC}/scu.c \ + ${MTK_PLAT_SOC}/drivers/sspm/sspm.c # Enable workarounds for selected Cortex-A53 erratas. ERRATA_A53_826319 := 0 @@ -57,3 +84,5 @@ MULTI_CONSOLE_API := 1 MACH_MT8183 := 1 $(eval $(call add_define,MACH_MT8183)) +include lib/coreboot/coreboot.mk + diff --git a/plat/meson/gxbb/aarch64/gxbb_helpers.S b/plat/meson/gxbb/aarch64/gxbb_helpers.S deleted file mode 100644 index 760d6c46d..000000000 --- a/plat/meson/gxbb/aarch64/gxbb_helpers.S +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <arch.h> -#include <asm_macros.S> -#include <assert_macros.S> -#include <platform_def.h> - - .globl plat_crash_console_flush - .globl plat_crash_console_init - .globl plat_crash_console_putc - .globl platform_mem_init - .globl plat_is_my_cpu_primary - .globl plat_my_core_pos - .globl plat_reset_handler - .globl plat_gxbb_calc_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_my_core_pos(void); - * ----------------------------------------------------- - */ -func plat_my_core_pos - mrs x0, mpidr_el1 - b plat_gxbb_calc_core_pos -endfunc plat_my_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr); - * ----------------------------------------------------- - */ -func plat_gxbb_calc_core_pos - and x0, x0, #MPIDR_CPU_MASK - ret -endfunc plat_gxbb_calc_core_pos - - /* ----------------------------------------------------- - * unsigned int plat_is_my_cpu_primary(void); - * ----------------------------------------------------- - */ -func plat_is_my_cpu_primary - mrs x0, mpidr_el1 - and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) - cmp x0, #GXBB_PRIMARY_CPU - cset w0, eq - ret -endfunc plat_is_my_cpu_primary - - /* --------------------------------------------- - * void platform_mem_init(void); - * --------------------------------------------- - */ -func platform_mem_init - ret -endfunc platform_mem_init - - /* --------------------------------------------- - * int plat_crash_console_init(void) - * --------------------------------------------- - */ -func plat_crash_console_init - mov_imm x0, GXBB_UART0_AO_BASE - mov_imm x1, GXBB_UART0_AO_CLK_IN_HZ - mov_imm x2, GXBB_UART_BAUDRATE - b console_meson_init -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(int c) - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - mov_imm x1, GXBB_UART0_AO_BASE - b console_meson_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - mov_imm x0, GXBB_UART0_AO_BASE - b console_meson_core_flush -endfunc plat_crash_console_flush - - /* --------------------------------------------- - * void plat_reset_handler(void); - * --------------------------------------------- - */ -func plat_reset_handler - ret -endfunc plat_reset_handler diff --git a/plat/meson/gxbb/gxbb_def.h b/plat/meson/gxbb/gxbb_def.h deleted file mode 100644 index 3e27097c3..000000000 --- a/plat/meson/gxbb/gxbb_def.h +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GXBB_DEF_H -#define GXBB_DEF_H - -#include <lib/utils_def.h> - -/******************************************************************************* - * System oscillator - ******************************************************************************/ -#define GXBB_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ - -/******************************************************************************* - * Memory regions - ******************************************************************************/ -#define GXBB_NSDRAM0_BASE UL(0x01000000) -#define GXBB_NSDRAM0_SIZE UL(0x0F000000) - -#define GXBB_NSDRAM1_BASE UL(0x10000000) -#define GXBB_NSDRAM1_SIZE UL(0x00100000) - -#define BL31_BASE UL(0x10100000) -#define BL31_SIZE UL(0x000C0000) -#define BL31_LIMIT (BL31_BASE + BL31_SIZE) - -/* Shared memory used for SMC services */ -#define GXBB_SHARE_MEM_INPUT_BASE UL(0x100FE000) -#define GXBB_SHARE_MEM_OUTPUT_BASE UL(0x100FF000) - -#define GXBB_SEC_DEVICE0_BASE UL(0xC0000000) -#define GXBB_SEC_DEVICE0_SIZE UL(0x09000000) - -#define GXBB_SEC_DEVICE1_BASE UL(0xD0040000) -#define GXBB_SEC_DEVICE1_SIZE UL(0x00008000) - -#define GXBB_TZRAM_BASE UL(0xD9000000) -#define GXBB_TZRAM_SIZE UL(0x00014000) -/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */ - -/* Mailboxes */ -#define GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xD9013800) -#define GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xD9013A00) -#define GXBB_PSCI_MAILBOX_BASE UL(0xD9013F00) - -#define GXBB_TZROM_BASE UL(0xD9040000) -#define GXBB_TZROM_SIZE UL(0x00010000) - -#define GXBB_SEC_DEVICE2_BASE UL(0xDA000000) -#define GXBB_SEC_DEVICE2_SIZE UL(0x00200000) - -#define GXBB_SEC_DEVICE3_BASE UL(0xDA800000) -#define GXBB_SEC_DEVICE3_SIZE UL(0x00200000) - -/******************************************************************************* - * GIC-400 and interrupt handling related constants - ******************************************************************************/ -#define GXBB_GICD_BASE UL(0xC4301000) -#define GXBB_GICC_BASE UL(0xC4302000) - -#define IRQ_SEC_PHY_TIMER 29 - -#define IRQ_SEC_SGI_0 8 -#define IRQ_SEC_SGI_1 9 -#define IRQ_SEC_SGI_2 10 -#define IRQ_SEC_SGI_3 11 -#define IRQ_SEC_SGI_4 12 -#define IRQ_SEC_SGI_5 13 -#define IRQ_SEC_SGI_6 14 -#define IRQ_SEC_SGI_7 15 - -/******************************************************************************* - * UART definitions - ******************************************************************************/ -#define GXBB_UART0_AO_BASE UL(0xC81004C0) -#define GXBB_UART0_AO_CLK_IN_HZ GXBB_OSC24M_CLK_IN_HZ -#define GXBB_UART_BAUDRATE U(115200) - -/******************************************************************************* - * Memory-mapped I/O Registers - ******************************************************************************/ -#define GXBB_AO_TIMESTAMP_CNTL UL(0xC81000B4) - -#define GXBB_SYS_CPU_CFG7 UL(0xC8834664) - -#define GXBB_AO_RTI_STATUS_REG3 UL(0xDA10001C) - -#define GXBB_HIU_MAILBOX_SET_0 UL(0xDA83C404) -#define GXBB_HIU_MAILBOX_STAT_0 UL(0xDA83C408) -#define GXBB_HIU_MAILBOX_CLR_0 UL(0xDA83C40C) -#define GXBB_HIU_MAILBOX_SET_3 UL(0xDA83C428) -#define GXBB_HIU_MAILBOX_STAT_3 UL(0xDA83C42C) -#define GXBB_HIU_MAILBOX_CLR_3 UL(0xDA83C430) - -/******************************************************************************* - * System Monitor Call IDs and arguments - ******************************************************************************/ -#define GXBB_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) -#define GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) - -#define GXBB_SM_EFUSE_READ U(0x82000030) -#define GXBB_SM_EFUSE_USER_MAX U(0x82000033) - -#define GXBB_SM_JTAG_ON U(0x82000040) -#define GXBB_SM_JTAG_OFF U(0x82000041) - -#define GXBB_JTAG_STATE_ON U(0) -#define GXBB_JTAG_STATE_OFF U(1) - -#define GXBB_JTAG_M3_AO U(0) -#define GXBB_JTAG_M3_EE U(1) -#define GXBB_JTAG_A53_AO U(2) -#define GXBB_JTAG_A53_EE U(3) - -#endif /* GXBB_DEF_H */ diff --git a/plat/meson/gxbb/gxbb_efuse.c b/plat/meson/gxbb/gxbb_efuse.c deleted file mode 100644 index edea5426c..000000000 --- a/plat/meson/gxbb/gxbb_efuse.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include "gxbb_private.h" - -#define EFUSE_BASE 0x140 -#define EFUSE_SIZE 0xC0 - -uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size) -{ - if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE) - return 0; - - return scpi_efuse_read(dst, offset + EFUSE_BASE, size); -} - -uint64_t gxbb_efuse_user_max(void) -{ - return EFUSE_SIZE; -} diff --git a/plat/meson/gxbb/gxbb_mhu.c b/plat/meson/gxbb/gxbb_mhu.c deleted file mode 100644 index 903ef411c..000000000 --- a/plat/meson/gxbb/gxbb_mhu.c +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <lib/bakery_lock.h> -#include <lib/mmio.h> - -static DEFINE_BAKERY_LOCK(mhu_lock); - -void mhu_secure_message_start(void) -{ - bakery_lock_get(&mhu_lock); - - while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0) - ; -} - -void mhu_secure_message_send(uint32_t msg) -{ - mmio_write_32(GXBB_HIU_MAILBOX_SET_3, msg); - - while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0) - ; -} - -uint32_t mhu_secure_message_wait(void) -{ - uint32_t val; - - do { - val = mmio_read_32(GXBB_HIU_MAILBOX_STAT_0); - } while (val == 0); - - return val; -} - -void mhu_secure_message_end(void) -{ - mmio_write_32(GXBB_HIU_MAILBOX_CLR_0, 0xFFFFFFFF); - - bakery_lock_release(&mhu_lock); -} - -void mhu_secure_init(void) -{ - bakery_lock_init(&mhu_lock); - - mmio_write_32(GXBB_HIU_MAILBOX_CLR_3, 0xFFFFFFFF); -} diff --git a/plat/meson/gxbb/gxbb_private.h b/plat/meson/gxbb/gxbb_private.h deleted file mode 100644 index 910a42c1c..000000000 --- a/plat/meson/gxbb/gxbb_private.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GXBB_PRIVATE_H -#define GXBB_PRIVATE_H - -#include <stdint.h> - -/* Utility functions */ -unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr); -void gxbb_console_init(void); -void gxbb_setup_page_tables(void); - -/* MHU functions */ -void mhu_secure_message_start(void); -void mhu_secure_message_send(uint32_t msg); -uint32_t mhu_secure_message_wait(void); -void mhu_secure_message_end(void); -void mhu_secure_init(void); - -/* SCPI functions */ -void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, - uint32_t cluster_state, uint32_t css_state); -uint32_t scpi_sys_power_state(uint64_t system_state); -void scpi_jtag_set_state(uint32_t state, uint8_t select); -uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size); -void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, - uint32_t arg2, uint32_t arg3); - -/* Peripherals */ -void gxbb_thermal_unknown(void); -uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size); -uint64_t gxbb_efuse_user_max(void); - -#endif /* GXBB_PRIVATE_H */ diff --git a/plat/meson/gxbb/gxbb_scpi.c b/plat/meson/gxbb/gxbb_scpi.c deleted file mode 100644 index 83eeda29d..000000000 --- a/plat/meson/gxbb/gxbb_scpi.c +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <string.h> - -#include <platform_def.h> - -#include <lib/mmio.h> -#include <plat/common/platform.h> - -#include "gxbb_private.h" - -#define SIZE_SHIFT 20 -#define SIZE_MASK 0x1FF - -/* - * Note: The Amlogic SCP firmware uses the legacy SCPI protocol. - */ -#define SCPI_CMD_SET_CSS_POWER_STATE 0x04 -#define SCPI_CMD_SET_SYS_POWER_STATE 0x08 - -#define SCPI_CMD_JTAG_SET_STATE 0xC0 -#define SCPI_CMD_EFUSE_READ 0xC2 - -static inline uint32_t scpi_cmd(uint32_t command, uint32_t size) -{ - return command | (size << SIZE_SHIFT); -} - -void scpi_secure_message_send(uint32_t command, uint32_t size) -{ - mhu_secure_message_send(scpi_cmd(command, size)); -} - -uint32_t scpi_secure_message_receive(void **message_out, size_t *size_out) -{ - uint32_t response = mhu_secure_message_wait(); - - size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; - - response &= ~(SIZE_MASK << SIZE_SHIFT); - - if (size_out != NULL) - *size_out = size; - - if (message_out != NULL) - *message_out = (void *)GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD; - - return response; -} - -void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, - uint32_t cluster_state, uint32_t css_state) -{ - uint32_t state = (mpidr & 0x0F) | /* CPU ID */ - ((mpidr & 0xF00) >> 4) | /* Cluster ID */ - (cpu_state << 8) | - (cluster_state << 12) | - (css_state << 16); - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, state); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} - -uint32_t scpi_sys_power_state(uint64_t system_state) -{ - uint32_t *response; - size_t size; - - mhu_secure_message_start(); - mmio_write_8(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1)); - scpi_secure_message_receive((void *)&response, &size); - mhu_secure_message_end(); - - return *response; -} - -void scpi_jtag_set_state(uint32_t state, uint8_t select) -{ - assert(state <= GXBB_JTAG_STATE_OFF); - - if (select > GXBB_JTAG_A53_EE) { - WARN("BL31: Invalid JTAG select (0x%x).\n", select); - return; - } - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, - (state << 8) | (uint32_t)select); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} - -uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size) -{ - uint32_t *response; - size_t resp_size; - - if (size > 0x1FC) - return 0; - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, base); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_EFUSE_READ, 8)); - scpi_secure_message_receive((void *)&response, &resp_size); - mhu_secure_message_end(); - - /* - * response[0] is the size of the response message. - * response[1 ... N] are the contents. - */ - if (*response != 0) - memcpy(dst, response + 1, *response); - - return *response; -} - -void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, - uint32_t arg2, uint32_t arg3) -{ - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3); - mhu_secure_message_send(scpi_cmd(0xC3, 16)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} diff --git a/plat/meson/gxbb/gxbb_sip_svc.c b/plat/meson/gxbb/gxbb_sip_svc.c deleted file mode 100644 index 63c7dba15..000000000 --- a/plat/meson/gxbb/gxbb_sip_svc.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include <platform_def.h> - -#include <common/debug.h> -#include <common/runtime_svc.h> -#include <lib/mmio.h> - -#include "gxbb_private.h" - -/******************************************************************************* - * This function is responsible for handling all SiP calls - ******************************************************************************/ -static uintptr_t gxbb_sip_handler(uint32_t smc_fid, - u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, - void *cookie, void *handle, - u_register_t flags) -{ - switch (smc_fid) { - - case GXBB_SM_GET_SHARE_MEM_INPUT_BASE: - SMC_RET1(handle, GXBB_SHARE_MEM_INPUT_BASE); - - case GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE: - SMC_RET1(handle, GXBB_SHARE_MEM_OUTPUT_BASE); - - case GXBB_SM_EFUSE_READ: - { - void *dst = (void *)GXBB_SHARE_MEM_OUTPUT_BASE; - uint64_t ret = gxbb_efuse_read(dst, (uint32_t)x1, x2); - - SMC_RET1(handle, ret); - } - case GXBB_SM_EFUSE_USER_MAX: - SMC_RET1(handle, gxbb_efuse_user_max()); - - case GXBB_SM_JTAG_ON: - scpi_jtag_set_state(GXBB_JTAG_STATE_ON, x1); - SMC_RET1(handle, 0); - - case GXBB_SM_JTAG_OFF: - scpi_jtag_set_state(GXBB_JTAG_STATE_OFF, x1); - SMC_RET1(handle, 0); - - default: - ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid); - break; - } - - SMC_RET1(handle, SMC_UNK); -} - -DECLARE_RT_SVC( - gxbb_sip_handler, - - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - gxbb_sip_handler -); diff --git a/plat/meson/gxbb/gxbb_topology.c b/plat/meson/gxbb/gxbb_topology.c deleted file mode 100644 index eec2d34d4..000000000 --- a/plat/meson/gxbb/gxbb_topology.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include <platform_def.h> - -#include <arch.h> - -#include "gxbb_private.h" - -/* The power domain tree descriptor */ -static unsigned char power_domain_tree_desc[] = { - /* Number of root nodes */ - PLATFORM_CLUSTER_COUNT, - /* Number of children for the first node */ - PLATFORM_CLUSTER0_CORE_COUNT -}; - -/******************************************************************************* - * This function returns the ARM default topology tree information. - ******************************************************************************/ -const unsigned char *plat_get_power_domain_tree_desc(void) -{ - return power_domain_tree_desc; -} - -/******************************************************************************* - * This function implements a part of the critical interface between the psci - * generic layer and the platform that allows the former to query the platform - * to convert an MPIDR to a unique linear index. An error code (-1) is returned - * in case the MPIDR is invalid. - ******************************************************************************/ -int plat_core_pos_by_mpidr(u_register_t mpidr) -{ - unsigned int cluster_id, cpu_id; - - mpidr &= MPIDR_AFFINITY_MASK; - if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK)) - return -1; - - cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK; - cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK; - - if (cluster_id >= PLATFORM_CLUSTER_COUNT) - return -1; - - if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) - return -1; - - return plat_gxbb_calc_core_pos(mpidr); -} diff --git a/plat/meson/gxbb/include/plat_macros.S b/plat/meson/gxbb/include/plat_macros.S deleted file mode 100644 index c721c21b6..000000000 --- a/plat/meson/gxbb/include/plat_macros.S +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef PLAT_MACROS_S -#define PLAT_MACROS_S - -#include <drivers/arm/gicv2.h> -#include <platform_def.h> - -.section .rodata.gic_reg_name, "aS" - -gicc_regs: - .asciz "gicc_hppir", "gicc_ahppir", "gicc_ctlr", "" -gicd_pend_reg: - .asciz "gicd_ispendr regs (Offsets 0x200 - 0x278)\n Offset:\t\t\tvalue\n" -newline: - .asciz "\n" -spacer: - .asciz ":\t\t0x" - - /* --------------------------------------------- - * The below required platform porting macro - * prints out relevant GIC and CCI registers - * whenever an unhandled exception is taken in - * BL31. - * Clobbers: x0 - x10, x16, x17, sp - * --------------------------------------------- - */ - .macro plat_crash_print_regs - - /* GICC registers */ - - mov_imm x17, GXBB_GICC_BASE - - adr x6, gicc_regs - ldr w8, [x17, #GICC_HPPIR] - ldr w9, [x17, #GICC_AHPPIR] - ldr w10, [x17, #GICC_CTLR] - bl str_in_crash_buf_print - - /* GICD registers */ - - mov_imm x16, GXBB_GICD_BASE - - add x7, x16, #GICD_ISPENDR - adr x4, gicd_pend_reg - bl asm_print_str - -gicd_ispendr_loop: - sub x4, x7, x16 - cmp x4, #0x280 - b.eq exit_print_gic_regs - bl asm_print_hex - - adr x4, spacer - bl asm_print_str - - ldr x4, [x7], #8 - bl asm_print_hex - - adr x4, newline - bl asm_print_str - b gicd_ispendr_loop -exit_print_gic_regs: - - .endm - -#endif /* PLAT_MACROS_S */ diff --git a/plat/meson/gxbb/platform.mk b/plat/meson/gxbb/platform.mk deleted file mode 100644 index 9e65040b9..000000000 --- a/plat/meson/gxbb/platform.mk +++ /dev/null @@ -1,69 +0,0 @@ -# -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -include lib/xlat_tables_v2/xlat_tables.mk - -PLAT_INCLUDES := -Iplat/meson/gxbb/include - -GXBB_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c - -PLAT_BL_COMMON_SOURCES := drivers/meson/console/aarch64/meson_console.S \ - plat/meson/gxbb/gxbb_common.c \ - plat/meson/gxbb/gxbb_topology.c \ - ${XLAT_TABLES_LIB_SRCS} - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - plat/common/plat_psci_common.c \ - plat/meson/gxbb/aarch64/gxbb_helpers.S \ - plat/meson/gxbb/gxbb_bl31_setup.c \ - plat/meson/gxbb/gxbb_efuse.c \ - plat/meson/gxbb/gxbb_mhu.c \ - plat/meson/gxbb/gxbb_pm.c \ - plat/meson/gxbb/gxbb_scpi.c \ - plat/meson/gxbb/gxbb_sip_svc.c \ - plat/meson/gxbb/gxbb_thermal.c \ - ${GXBB_GIC_SOURCES} - -# Tune compiler for Cortex-A53 -ifeq ($(notdir $(CC)),armclang) - TF_CFLAGS_aarch64 += -mcpu=cortex-a53 -else ifneq ($(findstring clang,$(notdir $(CC))),) - TF_CFLAGS_aarch64 += -mcpu=cortex-a53 -else - TF_CFLAGS_aarch64 += -mtune=cortex-a53 -endif - -# Build config flags -# ------------------ - -# Enable all errata workarounds for Cortex-A53 -ERRATA_A53_826319 := 1 -ERRATA_A53_835769 := 1 -ERRATA_A53_836870 := 1 -ERRATA_A53_843419 := 1 -ERRATA_A53_855873 := 1 - -WORKAROUND_CVE_2017_5715 := 0 - -# Have different sections for code and rodata -SEPARATE_CODE_AND_RODATA := 1 - -# Use Coherent memory -USE_COHERENT_MEM := 1 - -# Verify build config -# ------------------- - -ifneq (${RESET_TO_BL31}, 0) - $(error Error: gxbb needs RESET_TO_BL31=0) -endif - -ifeq (${ARCH},aarch32) - $(error Error: AArch32 not supported on gxbb) -endif diff --git a/plat/meson/gxl/gxl_def.h b/plat/meson/gxl/gxl_def.h deleted file mode 100644 index 089fa8db9..000000000 --- a/plat/meson/gxl/gxl_def.h +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GXBB_DEF_H -#define GXBB_DEF_H - -#include <lib/utils_def.h> - -/******************************************************************************* - * System oscillator - ******************************************************************************/ -#define GXBB_OSC24M_CLK_IN_HZ ULL(24000000) /* 24 MHz */ - -/******************************************************************************* - * Memory regions - ******************************************************************************/ -#define GXBB_NSDRAM0_BASE UL(0x01000000) -#define GXBB_NSDRAM0_SIZE UL(0x0F000000) - -#define GXBB_NSDRAM1_BASE UL(0x10000000) -#define GXBB_NSDRAM1_SIZE UL(0x00100000) - -#define BL31_BASE UL(0x05100000) -#define BL31_SIZE UL(0x000C0000) -#define BL31_LIMIT (BL31_BASE + BL31_SIZE) - -/* Shared memory used for SMC services */ -#define GXBB_SHARE_MEM_INPUT_BASE UL(0x050FE000) -#define GXBB_SHARE_MEM_OUTPUT_BASE UL(0x050FF000) - -#define GXBB_SEC_DEVICE0_BASE UL(0xC0000000) -#define GXBB_SEC_DEVICE0_SIZE UL(0x09000000) - -#define GXBB_SEC_DEVICE1_BASE UL(0xD0040000) -#define GXBB_SEC_DEVICE1_SIZE UL(0x00008000) - -#define GXBB_TZRAM_BASE UL(0xD9000000) -#define GXBB_TZRAM_SIZE UL(0x00014000) -/* Top 0xC000 bytes (up to 0xD9020000) used by BL2 */ - -/* Mailboxes */ -#define GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD UL(0xD9013800) -#define GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD UL(0xD9013A00) -#define GXBB_PSCI_MAILBOX_BASE UL(0xD9013F00) - -// * [ 1K] 0xD901_3800 - 0xD901_3BFF Secure Mailbox (3) -// * [ 1K] 0xD901_3400 - 0xD901_37FF High Mailbox (2) * -// * [ 1K] 0xD901_3000 - 0xD901_33FF High Mailbox (1) * - -#define GXBB_TZROM_BASE UL(0xD9040000) -#define GXBB_TZROM_SIZE UL(0x00010000) - -#define GXBB_SEC_DEVICE2_BASE UL(0xDA000000) -#define GXBB_SEC_DEVICE2_SIZE UL(0x00200000) - -#define GXBB_SEC_DEVICE3_BASE UL(0xDA800000) -#define GXBB_SEC_DEVICE3_SIZE UL(0x00200000) - -/******************************************************************************* - * GIC-400 and interrupt handling related constants - ******************************************************************************/ -#define GXBB_GICD_BASE UL(0xC4301000) -#define GXBB_GICC_BASE UL(0xC4302000) - -#define IRQ_SEC_PHY_TIMER 29 - -#define IRQ_SEC_SGI_0 8 -#define IRQ_SEC_SGI_1 9 -#define IRQ_SEC_SGI_2 10 -#define IRQ_SEC_SGI_3 11 -#define IRQ_SEC_SGI_4 12 -#define IRQ_SEC_SGI_5 13 -#define IRQ_SEC_SGI_6 14 -#define IRQ_SEC_SGI_7 15 - -/******************************************************************************* - * UART definitions - ******************************************************************************/ -#define GXBB_UART0_AO_BASE UL(0xC81004C0) -#define GXBB_UART0_AO_CLK_IN_HZ GXBB_OSC24M_CLK_IN_HZ -#define GXBB_UART_BAUDRATE U(115200) - -/******************************************************************************* - * Memory-mapped I/O Registers - ******************************************************************************/ -#define GXBB_AO_TIMESTAMP_CNTL UL(0xC81000B4) - -#define GXBB_SYS_CPU_CFG7 UL(0xC8834664) - -#define GXBB_AO_RTI_STATUS_REG3 UL(0xDA10001C) -#define GXBB_AO_RTI_SCP_STAT UL(0xDA10023C) -#define GXBB_AO_RTI_SCP_READY_OFF U(0x14) -#define GXBB_A0_RTI_SCP_READY_MASK U(3) -#define GXBB_AO_RTI_SCP_IS_READY(v) \ - ((((v) >> GXBB_AO_RTI_SCP_READY_OFF) & \ - GXBB_A0_RTI_SCP_READY_MASK) == GXBB_A0_RTI_SCP_READY_MASK) - -#define GXBB_HIU_MAILBOX_SET_0 UL(0xDA83C404) -#define GXBB_HIU_MAILBOX_STAT_0 UL(0xDA83C408) -#define GXBB_HIU_MAILBOX_CLR_0 UL(0xDA83C40C) -#define GXBB_HIU_MAILBOX_SET_3 UL(0xDA83C428) -#define GXBB_HIU_MAILBOX_STAT_3 UL(0xDA83C42C) -#define GXBB_HIU_MAILBOX_CLR_3 UL(0xDA83C430) - -/******************************************************************************* - * System Monitor Call IDs and arguments - ******************************************************************************/ -#define GXBB_SM_GET_SHARE_MEM_INPUT_BASE U(0x82000020) -#define GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE U(0x82000021) - -#define GXBB_SM_EFUSE_READ U(0x82000030) -#define GXBB_SM_EFUSE_USER_MAX U(0x82000033) - -#define GXBB_SM_JTAG_ON U(0x82000040) -#define GXBB_SM_JTAG_OFF U(0x82000041) - -#define GXBB_JTAG_STATE_ON U(0) -#define GXBB_JTAG_STATE_OFF U(1) - -#define GXBB_JTAG_M3_AO U(0) -#define GXBB_JTAG_M3_EE U(1) -#define GXBB_JTAG_A53_AO U(2) -#define GXBB_JTAG_A53_EE U(3) - -#endif /* GXBB_DEF_H */ diff --git a/plat/meson/gxl/gxl_efuse.c b/plat/meson/gxl/gxl_efuse.c deleted file mode 100644 index b17d1b8e3..000000000 --- a/plat/meson/gxl/gxl_efuse.c +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include "gxl_private.h" - -#define EFUSE_BASE 0x140 -#define EFUSE_SIZE 0xC0 - -uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size) -{ - if ((uint64_t)(offset + size) > (uint64_t)EFUSE_SIZE) - return 0; - - return scpi_efuse_read(dst, offset + EFUSE_BASE, size); -} - -uint64_t gxbb_efuse_user_max(void) -{ - return EFUSE_SIZE; -} diff --git a/plat/meson/gxl/gxl_mhu.c b/plat/meson/gxl/gxl_mhu.c deleted file mode 100644 index 4c1d5b600..000000000 --- a/plat/meson/gxl/gxl_mhu.c +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <lib/bakery_lock.h> -#include <lib/mmio.h> -#include <platform_def.h> - -static DEFINE_BAKERY_LOCK(mhu_lock); - -void mhu_secure_message_start(void) -{ - bakery_lock_get(&mhu_lock); - - while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0) - ; -} - -void mhu_secure_message_send(uint32_t msg) -{ - mmio_write_32(GXBB_HIU_MAILBOX_SET_3, msg); - - while (mmio_read_32(GXBB_HIU_MAILBOX_STAT_3) != 0) - ; -} - -uint32_t mhu_secure_message_wait(void) -{ - uint32_t val; - - do { - val = mmio_read_32(GXBB_HIU_MAILBOX_STAT_0); - } while (val == 0); - - return val; -} - -void mhu_secure_message_end(void) -{ - mmio_write_32(GXBB_HIU_MAILBOX_CLR_0, 0xFFFFFFFF); - - bakery_lock_release(&mhu_lock); -} - -void mhu_secure_init(void) -{ - bakery_lock_init(&mhu_lock); - - mmio_write_32(GXBB_HIU_MAILBOX_CLR_3, 0xFFFFFFFF); -} diff --git a/plat/meson/gxl/gxl_private.h b/plat/meson/gxl/gxl_private.h deleted file mode 100644 index 913cbf653..000000000 --- a/plat/meson/gxl/gxl_private.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#ifndef GXBB_PRIVATE_H -#define GXBB_PRIVATE_H - -#include <stdint.h> -#include <stddef.h> - -/* Utility functions */ -unsigned int plat_gxbb_calc_core_pos(u_register_t mpidr); -void gxbb_console_init(void); -void gxbb_setup_page_tables(void); - -/* MHU functions */ -void mhu_secure_message_start(void); -void mhu_secure_message_send(uint32_t msg); -uint32_t mhu_secure_message_wait(void); -void mhu_secure_message_end(void); -void mhu_secure_init(void); - -/* SCPI functions */ -void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, - uint32_t cluster_state, uint32_t css_state); -uint32_t scpi_sys_power_state(uint64_t system_state); -void scpi_jtag_set_state(uint32_t state, uint8_t select); -uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size); -void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, - uint32_t arg2, uint32_t arg3); -void scpi_upload_scp_fw(uintptr_t addr, size_t size, int send); - -/* Peripherals */ -void gxbb_thermal_unknown(void); -uint64_t gxbb_efuse_read(void *dst, uint32_t offset, uint32_t size); -uint64_t gxbb_efuse_user_max(void); - -#endif /* GXBB_PRIVATE_H */ diff --git a/plat/meson/gxl/gxl_scpi.c b/plat/meson/gxl/gxl_scpi.c deleted file mode 100644 index 13d652436..000000000 --- a/plat/meson/gxl/gxl_scpi.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <lib/mmio.h> -#include <plat/common/platform.h> -#include <platform_def.h> -#include <string.h> -#include <crypto/sha_dma.h> - -#include "gxl_private.h" - -#define SIZE_SHIFT 20 -#define SIZE_MASK 0x1FF -#define SIZE_FWBLK 0x200UL - -/* - * Note: The Amlogic SCP firmware uses the legacy SCPI protocol. - */ -#define SCPI_CMD_SET_CSS_POWER_STATE 0x04 -#define SCPI_CMD_SET_SYS_POWER_STATE 0x08 - -#define SCPI_CMD_JTAG_SET_STATE 0xC0 -#define SCPI_CMD_EFUSE_READ 0xC2 - -#define SCPI_CMD_COPY_FW 0xd4 -#define SCPI_CMD_SET_FW_ADDR 0xd3 -#define SCPI_CMD_FW_SIZE 0xd2 - -static inline uint32_t scpi_cmd(uint32_t command, uint32_t size) -{ - return command | (size << SIZE_SHIFT); -} - -static void scpi_secure_message_send(uint32_t command, uint32_t size) -{ - mhu_secure_message_send(scpi_cmd(command, size)); -} - -uint32_t scpi_secure_message_receive(void **message_out, size_t *size_out) -{ - uint32_t response = mhu_secure_message_wait(); - - size_t size = (response >> SIZE_SHIFT) & SIZE_MASK; - - response &= ~(SIZE_MASK << SIZE_SHIFT); - - if (size_out != NULL) - *size_out = size; - - if (message_out != NULL) - *message_out = (void *)GXBB_MHU_SECURE_SCP_TO_AP_PAYLOAD; - - return response; -} - -void scpi_set_css_power_state(u_register_t mpidr, uint32_t cpu_state, - uint32_t cluster_state, uint32_t css_state) -{ - uint32_t state = (mpidr & 0x0F) | /* CPU ID */ - ((mpidr & 0xF00) >> 4) | /* Cluster ID */ - (cpu_state << 8) | - (cluster_state << 12) | - (css_state << 16); - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, state); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_CSS_POWER_STATE, 4)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} - -uint32_t scpi_sys_power_state(uint64_t system_state) -{ - uint32_t *response; - size_t size; - - mhu_secure_message_start(); - mmio_write_8(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, system_state); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_SET_SYS_POWER_STATE, 1)); - scpi_secure_message_receive((void *)&response, &size); - mhu_secure_message_end(); - - return *response; -} - -void scpi_jtag_set_state(uint32_t state, uint8_t select) -{ - assert(state <= GXBB_JTAG_STATE_OFF); - - if (select > GXBB_JTAG_A53_EE) { - WARN("BL31: Invalid JTAG select (0x%x).\n", select); - return; - } - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, - (state << 8) | (uint32_t)select); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_JTAG_SET_STATE, 4)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} - -uint32_t scpi_efuse_read(void *dst, uint32_t base, uint32_t size) -{ - uint32_t *response; - size_t resp_size; - - if (size > 0x1FC) - return 0; - - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, base); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 4, size); - mhu_secure_message_send(scpi_cmd(SCPI_CMD_EFUSE_READ, 8)); - scpi_secure_message_receive((void *)&response, &resp_size); - mhu_secure_message_end(); - - /* - * response[0] is the size of the response message. - * response[1 ... N] are the contents. - */ - if (*response != 0) - memcpy(dst, response + 1, *response); - - return *response; -} - -void scpi_unknown_thermal(uint32_t arg0, uint32_t arg1, - uint32_t arg2, uint32_t arg3) -{ - mhu_secure_message_start(); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x0, arg0); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x4, arg1); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0x8, arg2); - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD + 0xC, arg3); - mhu_secure_message_send(scpi_cmd(0xC3, 16)); - mhu_secure_message_wait(); - mhu_secure_message_end(); -} - -static inline void scpi_copy_scp_data(uint8_t *data, size_t len) -{ - void *dst = (void *)GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD; - size_t sz; - - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); - scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); - mhu_secure_message_wait(); - - for (sz = 0; sz < len; sz += SIZE_FWBLK) { - memcpy(dst, data + sz, MIN(SIZE_FWBLK, len - sz)); - mhu_secure_message_send(SCPI_CMD_COPY_FW); - } -} - -static inline void scpi_set_scp_addr(uint64_t addr, size_t len) -{ - volatile uint64_t *dst = (uint64_t *)GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD; - - /* - * It is ok as GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD is mapped as - * non cachable - */ - *dst = addr; - scpi_secure_message_send(SCPI_CMD_SET_FW_ADDR, sizeof(addr)); - mhu_secure_message_wait(); - - mmio_write_32(GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD, len); - scpi_secure_message_send(SCPI_CMD_FW_SIZE, len); - mhu_secure_message_wait(); -} - -static inline void scpi_send_fw_hash(uint8_t hash[], size_t len) -{ - void *dst = (void *)GXBB_MHU_SECURE_AP_TO_SCP_PAYLOAD; - - memcpy(dst, hash, len); - mhu_secure_message_send(0xd0); - mhu_secure_message_send(0xd1); - mhu_secure_message_send(0xd5); - mhu_secure_message_end(); -} - -/** - * Upload a FW to SCP. - * - * @param addr: firmware data address - * @param size: size of firmware - * @param send: If set, actually copy the firmware in SCP memory otherwise only - * send the firmware address. - */ -void scpi_upload_scp_fw(uintptr_t addr, size_t size, int send) -{ - struct asd_ctx ctx; - - asd_sha_init(&ctx, ASM_SHA256); - asd_sha_update(&ctx, (void *)addr, size); - asd_sha_finalize(&ctx); - - mhu_secure_message_start(); - if (send == 0) - scpi_set_scp_addr(addr, size); - else - scpi_copy_scp_data((void *)addr, size); - - scpi_send_fw_hash(ctx.digest, sizeof(ctx.digest)); -} diff --git a/plat/meson/gxl/gxl_sip_svc.c b/plat/meson/gxl/gxl_sip_svc.c deleted file mode 100644 index 74fbc80e4..000000000 --- a/plat/meson/gxl/gxl_sip_svc.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <common/debug.h> -#include <lib/mmio.h> -#include <platform_def.h> -#include <common/runtime_svc.h> -#include <stdint.h> - -#include "gxl_private.h" - -/******************************************************************************* - * This function is responsible for handling all SiP calls - ******************************************************************************/ -static uintptr_t gxbb_sip_handler(uint32_t smc_fid, - u_register_t x1, u_register_t x2, - u_register_t x3, u_register_t x4, - void *cookie, void *handle, - u_register_t flags) -{ - switch (smc_fid) { - - case GXBB_SM_GET_SHARE_MEM_INPUT_BASE: - SMC_RET1(handle, GXBB_SHARE_MEM_INPUT_BASE); - - case GXBB_SM_GET_SHARE_MEM_OUTPUT_BASE: - SMC_RET1(handle, GXBB_SHARE_MEM_OUTPUT_BASE); - - case GXBB_SM_EFUSE_READ: - { - void *dst = (void *)GXBB_SHARE_MEM_OUTPUT_BASE; - uint64_t ret = gxbb_efuse_read(dst, (uint32_t)x1, x2); - - SMC_RET1(handle, ret); - } - case GXBB_SM_EFUSE_USER_MAX: - SMC_RET1(handle, gxbb_efuse_user_max()); - - case GXBB_SM_JTAG_ON: - scpi_jtag_set_state(GXBB_JTAG_STATE_ON, x1); - SMC_RET1(handle, 0); - - case GXBB_SM_JTAG_OFF: - scpi_jtag_set_state(GXBB_JTAG_STATE_OFF, x1); - SMC_RET1(handle, 0); - - default: - ERROR("BL31: Unhandled SIP SMC: 0x%08x\n", smc_fid); - break; - } - - SMC_RET1(handle, SMC_UNK); -} - -DECLARE_RT_SVC( - gxbb_sip_handler, - - OEN_SIP_START, - OEN_SIP_END, - SMC_TYPE_FAST, - NULL, - gxbb_sip_handler -); diff --git a/plat/meson/gxl/gxl_thermal.c b/plat/meson/gxl/gxl_thermal.c deleted file mode 100644 index 3af1c6dc6..000000000 --- a/plat/meson/gxl/gxl_thermal.c +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <stdint.h> - -#include "gxl_private.h" - -static int32_t modules_initialized = -1; - -/******************************************************************************* - * Unknown commands related to something thermal-related - ******************************************************************************/ -void gxbb_thermal_unknown(void) -{ - uint16_t ret; - - if (modules_initialized == -1) { - scpi_efuse_read(&ret, 0, 2); - modules_initialized = ret; - } - - scpi_unknown_thermal(10, 2, /* thermal */ - 13, 1); /* thermalver */ -} diff --git a/plat/meson/gxl/platform.mk b/plat/meson/gxl/platform.mk deleted file mode 100644 index a788e9639..000000000 --- a/plat/meson/gxl/platform.mk +++ /dev/null @@ -1,87 +0,0 @@ -# -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. -# -# SPDX-License-Identifier: BSD-3-Clause -# - -include lib/xlat_tables_v2/xlat_tables.mk - -DOIMAGEPATH ?= tools/meson -DOIMAGETOOL ?= ${DOIMAGEPATH}/doimage - -PLAT_INCLUDES := -Iinclude/drivers/meson/ \ - -Iinclude/drivers/meson/gxl \ - -Iplat/meson/gxl/include - -GXBB_GIC_SOURCES := drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v2/gicv2_main.c \ - drivers/arm/gic/v2/gicv2_helpers.c \ - plat/common/plat_gicv2.c - -PLAT_BL_COMMON_SOURCES := drivers/meson/console/aarch64/meson_console.S \ - plat/meson/gxl/gxl_common.c \ - plat/meson/gxl/gxl_topology.c \ - ${XLAT_TABLES_LIB_SRCS} - -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ - plat/common/plat_psci_common.c \ - plat/meson/gxl/aarch64/gxl_helpers.S \ - plat/meson/gxl/gxl_bl31_setup.c \ - plat/meson/gxl/gxl_efuse.c \ - plat/meson/gxl/gxl_mhu.c \ - plat/meson/gxl/gxl_pm.c \ - plat/meson/gxl/gxl_scpi.c \ - plat/meson/gxl/gxl_sip_svc.c \ - plat/meson/gxl/gxl_thermal.c \ - drivers/meson/gxl/crypto/sha_dma.c \ - ${GXBB_GIC_SOURCES} - -# Tune compiler for Cortex-A53 -ifeq ($(notdir $(CC)),armclang) - TF_CFLAGS_aarch64 += -mcpu=cortex-a53 -else ifneq ($(findstring clang,$(notdir $(CC))),) - TF_CFLAGS_aarch64 += -mcpu=cortex-a53 -else - TF_CFLAGS_aarch64 += -mtune=cortex-a53 -endif - -# Build config flags -# ------------------ - -# Enable all errata workarounds for Cortex-A53 -ERRATA_A53_855873 := 1 -ERRATA_A53_819472 := 1 -ERRATA_A53_824069 := 1 -ERRATA_A53_827319 := 1 - -WORKAROUND_CVE_2017_5715 := 0 - -# Have different sections for code and rodata -SEPARATE_CODE_AND_RODATA := 1 - -# Use Coherent memory -USE_COHERENT_MEM := 1 - -# Verify build config -# ------------------- - -ifneq (${RESET_TO_BL31}, 0) - $(error Error: gxl needs RESET_TO_BL31=0) -endif - -ifeq (${ARCH},aarch32) - $(error Error: AArch32 not supported on gxl) -endif - -all: ${BUILD_PLAT}/bl31.img -distclean realclean clean: cleanimage - -cleanimage: - ${Q}${MAKE} -C ${DOIMAGEPATH} clean - -${DOIMAGETOOL}: - ${Q}${MAKE} -C ${DOIMAGEPATH} - -${BUILD_PLAT}/bl31.img: ${BUILD_PLAT}/bl31.bin ${DOIMAGETOOL} - ${DOIMAGETOOL} ${BUILD_PLAT}/bl31.bin ${BUILD_PLAT}/bl31.img - diff --git a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S index b47be6dc4..13ca6aaa2 100644 --- a/plat/nvidia/tegra/common/aarch64/tegra_helpers.S +++ b/plat/nvidia/tegra/common/aarch64/tegra_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -218,49 +218,6 @@ func platform_mem_init ret endfunc platform_mem_init - /* --------------------------------------------- - * int plat_crash_console_init(void) - * Function to initialize the crash console - * without a C Runtime to print crash report. - * Clobber list : x0 - x4 - * --------------------------------------------- - */ -func plat_crash_console_init - mov x0, #0 - adr x1, tegra_console_base - ldr x1, [x1] - cbz x1, 1f - mov w0, #1 -1: ret -endfunc plat_crash_console_init - - /* --------------------------------------------- - * int plat_crash_console_putc(void) - * Function to print a character on the crash - * console without a C Runtime. - * Clobber list : x1, x2 - * --------------------------------------------- - */ -func plat_crash_console_putc - adr x1, tegra_console_base - ldr x1, [x1] - b console_core_putc -endfunc plat_crash_console_putc - - /* --------------------------------------------- - * int plat_crash_console_flush() - * Function to force a write of all buffered - * data that hasn't been output. - * Out : return -1 on error else return 0. - * Clobber list : x0, x1 - * --------------------------------------------- - */ -func plat_crash_console_flush - adr x0, tegra_console_base - ldr x0, [x0] - b console_core_flush -endfunc plat_crash_console_flush - /* --------------------------------------------------- * Function to handle a platform reset and store * input parameters passed by BL2. diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c index 68b450e52..ae899c424 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/intf.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 2017-2018, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> #include <bpmp_ipc.h> -#include <debug.h> +#include <common/debug.h> #include <drivers/delay_timer.h> #include <errno.h> #include <lib/mmio.h> diff --git a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c index 4212eca1d..57daf6aeb 100644 --- a/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c +++ b/plat/nvidia/tegra/common/drivers/bpmp_ipc/ivc.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. + * Copyright (c) 2017-2020, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <arch_helpers.h> #include <assert.h> -#include <debug.h> +#include <common/debug.h> #include <errno.h> #include <stddef.h> #include <string.h> diff --git a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c index a3ef5e131..2f31906d8 100644 --- a/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c +++ b/plat/nvidia/tegra/common/drivers/memctrl/memctrl_v2.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -360,17 +361,15 @@ void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) if ((phys_base > vmem_end_old) || (video_mem_base > vmem_end_new)) { tegra_clear_videomem(video_mem_base, - (uint32_t)video_mem_size_mb << 20U); + video_mem_size_mb << 20U); } else { if (video_mem_base < phys_base) { non_overlap_area_size = phys_base - video_mem_base; - tegra_clear_videomem(video_mem_base, - (uint32_t)non_overlap_area_size); + tegra_clear_videomem(video_mem_base, non_overlap_area_size); } if (vmem_end_old > vmem_end_new) { non_overlap_area_size = vmem_end_old - vmem_end_new; - tegra_clear_videomem(vmem_end_new, - (uint32_t)non_overlap_area_size); + tegra_clear_videomem(vmem_end_new, non_overlap_area_size); } } diff --git a/plat/nvidia/tegra/common/drivers/spe/shared_console.S b/plat/nvidia/tegra/common/drivers/spe/shared_console.S index c1fbc842f..a3e110ec9 100644 --- a/plat/nvidia/tegra/common/drivers/spe/shared_console.S +++ b/plat/nvidia/tegra/common/drivers/spe/shared_console.S @@ -1,9 +1,10 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <asm_macros.S> +#include <console_macros.S> #define CONSOLE_NUM_BYTES_SHIFT 24 #define CONSOLE_FLUSH_DATA_TO_PORT (1 << 26) @@ -20,37 +21,43 @@ * finally displays everything on the UART port. */ - .globl console_core_init - .globl console_core_putc - .globl console_core_getc - .globl console_core_flush - - /* ----------------------------------------------- - * int console_core_init(uintptr_t base_addr, - * unsigned int uart_clk, unsigned int baud_rate) - * Function to initialize the console without a - * C Runtime to print debug information. This - * function will be accessed by console_init and - * crash reporting. - * In: x0 - console base address - * w1 - Uart clock in Hz + .globl console_spe_core_init + .globl console_spe_core_putc + .globl console_spe_core_getc + .globl console_spe_core_flush + .globl console_spe_putc + .globl console_spe_getc + .globl console_spe_flush + .globl console_spe_register + + /* ------------------------------------------------- + * int console_spe_register(uintptr_t baseaddr, + * uint32_t clock, uint32_t baud, + * console_spe_t *console); + * Function to initialize and register a new spe + * console. Storage passed in for the console struct + * *must* be persistent (i.e. not from the stack). + * In: x0 - UART register base address + * w1 - UART clock in Hz * w2 - Baud rate - * Out: return 1 on success else 0 on error - * Clobber list : x1, x2 - * ----------------------------------------------- + * x3 - pointer to empty console_spe_t struct + * Out: return 1 on success, 0 on error + * Clobber list : x0, x1, x2, x6, x7, x14 + * ------------------------------------------------- */ -func console_core_init - /* Check the input base address */ - cbz x0, core_init_fail - mov w0, #1 - ret -core_init_fail: +func console_spe_register + cbz x3, register_fail + str x0, [x3, #CONSOLE_T_DRVDATA] + mov x0, x3 + finish_console_register spe putc=1, getc=1, flush=1 + +register_fail: mov w0, wzr ret -endfunc console_core_init +endfunc console_spe_register /* -------------------------------------------------------- - * int console_core_putc(int c, uintptr_t base_addr) + * int console_spe_core_putc(int c, uintptr_t base_addr) * Function to output a character over the console. It * returns the character printed on success or -1 on error. * In : w0 - character to be printed @@ -59,7 +66,7 @@ endfunc console_core_init * Clobber list : x2 * -------------------------------------------------------- */ -func console_core_putc +func console_spe_core_putc /* Check the input parameter */ cbz x1, putc_error @@ -95,32 +102,48 @@ func console_core_putc putc_error: mov w0, #-1 ret -endfunc console_core_putc +endfunc console_spe_core_putc + + /* -------------------------------------------------------- + * int console_spe_putc(int c, console_spe_t *console) + * Function to output a character over the console. It + * returns the character printed on success or -1 on error. + * In : w0 - character to be printed + * x1 - pointer to console_t structure + * Out : return -1 on error else return character. + * Clobber list : x2 + * -------------------------------------------------------- + */ +func console_spe_putc + ldr x1, [x1, #CONSOLE_T_DRVDATA] + b console_spe_core_putc +endfunc console_spe_putc /* --------------------------------------------- - * int console_core_getc(uintptr_t base_addr) + * int console_spe_getc(console_spe_t *console) * Function to get a character from the console. * It returns the character grabbed on success - * or -1 on error. - * In : x0 - console base address + * or -1 if no character is available. + * In : x0 - pointer to console_t structure + * Out: w0 - character if available, else -1 * Clobber list : x0, x1 * --------------------------------------------- */ -func console_core_getc +func console_spe_getc mov w0, #-1 ret -endfunc console_core_getc +endfunc console_spe_getc - /* --------------------------------------------- - * int console_core_flush(uintptr_t base_addr) + /* ------------------------------------------------- + * int console_spe_core_flush(uintptr_t base_addr) * Function to force a write of all buffered * data that hasn't been output. * In : x0 - console base address * Out : return -1 on error else return 0. * Clobber list : x0, x1 - * --------------------------------------------- + * ------------------------------------------------- */ -func console_core_flush +func console_spe_core_flush cbz x0, flush_error /* flush console */ @@ -131,4 +154,18 @@ func console_core_flush flush_error: mov w0, #-1 ret -endfunc console_core_flush +endfunc console_spe_core_flush + + /* --------------------------------------------- + * int console_spe_flush(console_spe_t *console) + * Function to force a write of all buffered + * data that hasn't been output. + * In : x0 - pointer to console_t structure + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func console_spe_flush + ldr x0, [x0, #CONSOLE_T_DRVDATA] + b console_spe_core_flush +endfunc console_spe_flush diff --git a/plat/nvidia/tegra/common/tegra_bl31_setup.c b/plat/nvidia/tegra/common/tegra_bl31_setup.c index a9d037f19..cbe3377b0 100644 --- a/plat/nvidia/tegra/common/tegra_bl31_setup.c +++ b/plat/nvidia/tegra/common/tegra_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -42,21 +42,22 @@ extern void memcpy16(void *dest, const void *src, unsigned int length); ******************************************************************************/ IMPORT_SYM(uint64_t, __RW_START__, BL31_RW_START); -IMPORT_SYM(uint64_t, __RW_END__, BL31_RW_END); -IMPORT_SYM(uint64_t, __RODATA_START__, BL31_RODATA_BASE); -IMPORT_SYM(uint64_t, __RODATA_END__, BL31_RODATA_END); -IMPORT_SYM(uint64_t, __TEXT_START__, TEXT_START); -IMPORT_SYM(uint64_t, __TEXT_END__, TEXT_END); + +static const uint64_t BL31_RW_END = BL_END; +static const uint64_t BL31_RODATA_BASE = BL_RO_DATA_BASE; +static const uint64_t BL31_RODATA_END = BL_RO_DATA_END; +static const uint64_t TEXT_START = BL_CODE_BASE; +static const uint64_t TEXT_END = BL_CODE_END; extern uint64_t tegra_bl31_phys_base; -extern uint64_t tegra_console_base; static entry_point_info_t bl33_image_ep_info, bl32_image_ep_info; static plat_params_from_bl2_t plat_bl31_params_from_bl2 = { .tzdram_size = TZDRAM_SIZE }; -static unsigned long bl32_mem_size; -static unsigned long bl32_boot_params; +#ifdef SPD_trusty +static aapcs64_params_t bl32_args; +#endif /******************************************************************************* * This variable holds the non-secure image entry address @@ -131,7 +132,6 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, plat_params_from_bl2_t *plat_params = (plat_params_from_bl2_t *)arg1; image_info_t bl32_img_info = { {0} }; uint64_t tzdram_start, tzdram_end, bl32_start, bl32_end; - uint32_t console_clock; int32_t ret; /* @@ -157,8 +157,10 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, if (arg_from_bl2->bl32_ep_info != NULL) { bl32_image_ep_info = *arg_from_bl2->bl32_ep_info; - bl32_mem_size = arg_from_bl2->bl32_ep_info->args.arg0; - bl32_boot_params = arg_from_bl2->bl32_ep_info->args.arg2; +#ifdef SPD_trusty + /* save BL32 boot parameters */ + memcpy(&bl32_args, &arg_from_bl2->bl32_ep_info->args, sizeof(bl32_args)); +#endif } /* @@ -182,27 +184,9 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, } /* - * Reference clock used by the FPGAs is a lot slower. + * Enable console for the platform */ - if (tegra_platform_is_fpga()) { - console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; - } else { - console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; - } - - /* - * Get the base address of the UART controller to be used for the - * console - */ - tegra_console_base = plat_get_console_from_id(plat_params->uart_id); - - if (tegra_console_base != 0U) { - /* - * Configure the UART port to be used as the console - */ - (void)console_init(tegra_console_base, console_clock, - TEGRA_CONSOLE_BAUDRATE); - } + plat_enable_console(plat_params->uart_id); /* * The previous bootloader passes the base address of the shared memory @@ -293,17 +277,20 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, #ifdef SPD_trusty void plat_trusty_set_boot_args(aapcs64_params_t *args) { - args->arg0 = bl32_mem_size; - args->arg1 = bl32_boot_params; - args->arg2 = TRUSTY_PARAMS_LEN_BYTES; + /* + * arg0 = TZDRAM aperture available for BL32 + * arg1 = BL32 boot params + * arg2 = EKS Blob Length + * arg3 = Boot Profiler Carveout Base + */ + args->arg0 = bl32_args.arg0; + args->arg1 = bl32_args.arg2; /* update EKS size */ - if (args->arg4 != 0U) { - args->arg2 = args->arg4; - } + args->arg2 = bl32_args.arg4; /* Profiler Carveout Base */ - args->arg3 = args->arg5; + args->arg3 = bl32_args.arg5; } #endif diff --git a/plat/nvidia/tegra/common/tegra_common.mk b/plat/nvidia/tegra/common/tegra_common.mk index 2a2f2782d..34b5638ec 100644 --- a/plat/nvidia/tegra/common/tegra_common.mk +++ b/plat/nvidia/tegra/common/tegra_common.mk @@ -20,9 +20,9 @@ TEGRA_GICv2_SOURCES := drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv2.c \ ${COMMON_DIR}/tegra_gicv2.c -BL31_SOURCES += drivers/console/aarch64/console.S \ - drivers/delay_timer/delay_timer.c \ +BL31_SOURCES += drivers/delay_timer/delay_timer.c \ drivers/io/io_storage.c \ + plat/common/aarch64/crash_console_helpers.S \ ${TEGRA_GICv2_SOURCES} \ ${COMMON_DIR}/aarch64/tegra_helpers.S \ ${COMMON_DIR}/drivers/pmc/pmc.c \ diff --git a/plat/nvidia/tegra/common/tegra_pm.c b/plat/nvidia/tegra/common/tegra_pm.c index e06a116e4..39dc42c5b 100644 --- a/plat/nvidia/tegra/common/tegra_pm.c +++ b/plat/nvidia/tegra/common/tegra_pm.c @@ -26,15 +26,6 @@ extern uint64_t tegra_bl31_phys_base; extern uint64_t tegra_sec_entry_point; -extern uint64_t tegra_console_base; - -/* - * tegra_fake_system_suspend acts as a boolean var controlling whether - * we are going to take fake system suspend code or normal system suspend code - * path. This variable is set inside the sip call handlers,when the kernel - * requests a SIP call to set the suspend debug flags. - */ -uint8_t tegra_fake_system_suspend; /* * The following platform setup functions are weakly defined. They @@ -219,7 +210,8 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) /* Disable console if we are entering deep sleep. */ if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == PSTATE_ID_SOC_POWERDN) { - (void)console_uninit(); + (void)console_flush(); + console_switch_state(0); } /* disable GICC */ @@ -233,31 +225,10 @@ void tegra_pwr_domain_suspend(const psci_power_state_t *target_state) __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) { - uint8_t pwr_state = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; - uint64_t rmr_el3 = 0; - /* call the chip's power down handler */ (void)tegra_soc_pwr_domain_power_down_wfi(target_state); - /* - * If we are in fake system suspend mode, ensure we start doing - * procedures that help in looping back towards system suspend exit - * instead of calling WFI by requesting a warm reset. - * Else, just call WFI to enter low power state. - */ - if ((tegra_fake_system_suspend != 0U) && - (pwr_state == (uint8_t)PSTATE_ID_SOC_POWERDN)) { - - /* warm reboot */ - rmr_el3 = read_rmr_el3(); - write_rmr_el3(rmr_el3 | RMR_WARM_RESET_CPU); - - } else { - /* enter power down state */ - wfi(); - } - - /* we can never reach here */ + wfi(); panic(); } @@ -269,12 +240,11 @@ __dead2 void tegra_pwr_domain_power_down_wfi(const psci_power_state_t void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) { const plat_params_from_bl2_t *plat_params; - uint32_t console_clock; /* * Initialize the GIC cpu and distributor interfaces */ - tegra_gic_init(); + tegra_gic_pcpu_init(); /* * Check if we are exiting from deep sleep. @@ -282,20 +252,8 @@ void tegra_pwr_domain_on_finish(const psci_power_state_t *target_state) if (target_state->pwr_domain_state[PLAT_MAX_PWR_LVL] == PSTATE_ID_SOC_POWERDN) { - /* - * Reference clock used by the FPGAs is a lot slower. - */ - if (tegra_platform_is_fpga()) { - console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; - } else { - console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; - } - - /* Initialize the runtime console */ - if (tegra_console_base != 0ULL) { - (void)console_init(tegra_console_base, console_clock, - TEGRA_CONSOLE_BAUDRATE); - } + /* Restart console output. */ + console_switch_state(CONSOLE_FLAG_RUNTIME); /* * Restore Memory Controller settings as it loses state diff --git a/plat/nvidia/tegra/common/tegra_sip_calls.c b/plat/nvidia/tegra/common/tegra_sip_calls.c index 957300e53..b8ba09562 100644 --- a/plat/nvidia/tegra/common/tegra_sip_calls.c +++ b/plat/nvidia/tegra/common/tegra_sip_calls.c @@ -24,12 +24,6 @@ #define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003 #define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005 #define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006 -#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2000007 - -/******************************************************************************* - * Fake system suspend mode control var - ******************************************************************************/ -extern uint8_t tegra_fake_system_suspend; /******************************************************************************* * SoC specific SiP handler @@ -162,26 +156,6 @@ uintptr_t tegra_sip_handler(uint32_t smc_fid, SMC_RET0(handle); - case TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND: - /* - * System suspend fake mode is set if we are on VDK and we make - * a debug SIP call. This mode ensures that we excercise debug - * path instead of the regular code path to suit the pre-silicon - * platform needs. These include replacing the call to WFI by - * a warm reset request. - */ - if (tegra_platform_is_virt_dev_kit() != false) { - - tegra_fake_system_suspend = 1; - SMC_RET1(handle, 0); - } - - /* - * We return to the external world as if this SIP is not - * implemented in case, we are not running on VDK. - */ - break; - default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); break; diff --git a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h index 0d1e40596..a0d02c949 100644 --- a/plat/nvidia/tegra/include/drivers/bpmp_ipc.h +++ b/plat/nvidia/tegra/include/drivers/bpmp_ipc.h @@ -1,11 +1,12 @@ /* * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __BPMP_IPC_H__ -#define __BPMP_IPC_H__ +#ifndef BPMP_IPC_H +#define BPMP_IPC_H #include <lib/utils_def.h> #include <stdbool.h> @@ -44,4 +45,4 @@ int tegra_bpmp_ipc_enable_clock(uint32_t clk_id); */ int tegra_bpmp_ipc_disable_clock(uint32_t clk_id); -#endif /* __BPMP_IPC_H__ */ +#endif /* BPMP_IPC_H */ diff --git a/plat/nvidia/tegra/include/drivers/gpcdma.h b/plat/nvidia/tegra/include/drivers/gpcdma.h index fb5486a8e..a59df37e3 100644 --- a/plat/nvidia/tegra/include/drivers/gpcdma.h +++ b/plat/nvidia/tegra/include/drivers/gpcdma.h @@ -1,11 +1,12 @@ /* * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __GPCDMA_H__ -#define __GPCDMA_H__ +#ifndef GPCDMA_H +#define GPCDMA_H #include <stdint.h> @@ -13,4 +14,4 @@ void tegra_gpcdma_memcpy(uint64_t dst_addr, uint64_t src_addr, uint32_t num_bytes); void tegra_gpcdma_zeromem(uint64_t dst_addr, uint32_t num_bytes); -#endif /* __GPCDMA_H__ */ +#endif /* GPCDMA_H */ diff --git a/plat/nvidia/tegra/include/drivers/security_engine.h b/plat/nvidia/tegra/include/drivers/security_engine.h index 4ab2f9a23..8a249249b 100644 --- a/plat/nvidia/tegra/include/drivers/security_engine.h +++ b/plat/nvidia/tegra/include/drivers/security_engine.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause diff --git a/plat/nvidia/tegra/include/drivers/spe.h b/plat/nvidia/tegra/include/drivers/spe.h new file mode 100644 index 000000000..0d6d69d10 --- /dev/null +++ b/plat/nvidia/tegra/include/drivers/spe.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SPE_H +#define SPE_H + +#include <stdint.h> + +#include <drivers/console.h> + +typedef struct { + console_t console; + uintptr_t base; +} console_spe_t; + +/* + * Initialize a new spe console instance and register it with the console + * framework. The |console| pointer must point to storage that will be valid + * for the lifetime of the console, such as a global or static local variable. + * Its contents will be reinitialized from scratch. + */ +int console_spe_register(uintptr_t baseaddr, uint32_t clock, uint32_t baud, + console_spe_t *console); + +#endif /* SPE_H */ diff --git a/plat/nvidia/tegra/include/drivers/tegra_gic.h b/plat/nvidia/tegra/include/drivers/tegra_gic.h index 6106b40a7..6661dff76 100644 --- a/plat/nvidia/tegra/include/drivers/tegra_gic.h +++ b/plat/nvidia/tegra/include/drivers/tegra_gic.h @@ -1,11 +1,12 @@ /* * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __TEGRA_GIC_H__ -#define __TEGRA_GIC_H__ +#ifndef TEGRA_GIC_H +#define TEGRA_GIC_H #include <common/interrupt_props.h> @@ -26,4 +27,4 @@ void tegra_gic_pcpu_init(void); void tegra_gic_setup(const interrupt_prop_t *interrupt_props, unsigned int interrupt_props_num); -#endif /* __TEGRA_GIC_H__ */ +#endif /* TEGRA_GIC_H */ diff --git a/plat/nvidia/tegra/include/lib/profiler.h b/plat/nvidia/tegra/include/lib/profiler.h index 60f8d804a..684c872f0 100644 --- a/plat/nvidia/tegra/include/lib/profiler.h +++ b/plat/nvidia/tegra/include/lib/profiler.h @@ -1,11 +1,12 @@ /* * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef __PROFILER_H__ -#define __PROFILER_H__ +#ifndef PROFILER_H +#define PROFILER_H /******************************************************************************* * Number of bytes of memory used by the profiler on Tegra @@ -16,4 +17,4 @@ void boot_profiler_init(uint64_t shmem_base, uint32_t tmr_base); void boot_profiler_add_record(const char *str); void boot_profiler_deinit(void); -#endif /* __PROFILER_H__ */ +#endif /* PROFILER_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra194_private.h b/plat/nvidia/tegra/include/t194/tegra194_private.h new file mode 100644 index 000000000..8f1deb2a3 --- /dev/null +++ b/plat/nvidia/tegra/include/t194/tegra194_private.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA194_PRIVATE_H +#define TEGRA194_PRIVATE_H + +void tegra194_cpu_reset_handler(void); +uint64_t tegra194_get_cpu_reset_handler_base(void); +uint64_t tegra194_get_cpu_reset_handler_size(void); +uint64_t tegra194_get_smmu_ctx_offset(void); +void tegra194_set_system_suspend_entry(void); + +#endif /* TEGRA194_PRIVATE_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_def.h b/plat/nvidia/tegra/include/t194/tegra_def.h new file mode 100644 index 000000000..df1d65630 --- /dev/null +++ b/plat/nvidia/tegra/include/t194/tegra_def.h @@ -0,0 +1,269 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA_DEF_H +#define TEGRA_DEF_H + +#include <lib/utils_def.h> + +/******************************************************************************* + * Chip specific page table and MMU setup constants + ******************************************************************************/ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 40) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 40) + +/******************************************************************************* + * These values are used by the PSCI implementation during the `CPU_SUSPEND` + * and `SYSTEM_SUSPEND` calls as the `state-id` field in the 'power state' + * parameter. + ******************************************************************************/ +#define PSTATE_ID_CORE_IDLE U(6) +#define PSTATE_ID_CORE_POWERDN U(7) +#define PSTATE_ID_SOC_POWERDN U(2) + +/******************************************************************************* + * Platform power states (used by PSCI framework) + * + * - PLAT_MAX_RET_STATE should be less than lowest PSTATE_ID + * - PLAT_MAX_OFF_STATE should be greater than the highest PSTATE_ID + ******************************************************************************/ +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(8) + +/******************************************************************************* + * Secure IRQ definitions + ******************************************************************************/ +#define TEGRA194_MAX_SEC_IRQS U(2) +#define TEGRA194_TOP_WDT_IRQ U(49) +#define TEGRA194_AON_WDT_IRQ U(50) + +#define TEGRA194_SEC_IRQ_TARGET_MASK U(0xFF) /* 8 Carmel */ + +/******************************************************************************* + * Tegra Miscellanous register constants + ******************************************************************************/ +#define TEGRA_MISC_BASE U(0x00100000) + +#define HARDWARE_REVISION_OFFSET U(0x4) +#define MISCREG_EMU_REVID U(0x3160) +#define BOARD_MASK_BITS U(0xFF) +#define BOARD_SHIFT_BITS U(24) +#define MISCREG_PFCFG U(0x200C) + +/******************************************************************************* + * Tegra General Purpose Centralised DMA constants + ******************************************************************************/ +#define TEGRA_GPCDMA_BASE U(0x02610000) + +/******************************************************************************* + * Tegra Memory Controller constants + ******************************************************************************/ +#define TEGRA_MC_STREAMID_BASE U(0x02C00000) +#define TEGRA_MC_BASE U(0x02C10000) + +/* General Security Carveout register macros */ +#define MC_GSC_CONFIG_REGS_SIZE U(0x40) +#define MC_GSC_LOCK_CFG_SETTINGS_BIT (U(1) << 1) +#define MC_GSC_ENABLE_TZ_LOCK_BIT (U(1) << 0) +#define MC_GSC_SIZE_RANGE_4KB_SHIFT U(27) +#define MC_GSC_BASE_LO_SHIFT U(12) +#define MC_GSC_BASE_LO_MASK U(0xFFFFF) +#define MC_GSC_BASE_HI_SHIFT U(0) +#define MC_GSC_BASE_HI_MASK U(3) +#define MC_GSC_ENABLE_CPU_SECURE_BIT (U(1) << 31) + +/* TZDRAM carveout configuration registers */ +#define MC_SECURITY_CFG0_0 U(0x70) +#define MC_SECURITY_CFG1_0 U(0x74) +#define MC_SECURITY_CFG3_0 U(0x9BC) + +#define MC_SECURITY_BOM_MASK (U(0xFFF) << 20) +#define MC_SECURITY_SIZE_MB_MASK (U(0x1FFF) << 0) +#define MC_SECURITY_BOM_HI_MASK (U(0x3) << 0) + +#define MC_SECURITY_CFG_REG_CTRL_0 U(0x154) +#define SECURITY_CFG_WRITE_ACCESS_BIT (U(0x1) << 0) +#define SECURITY_CFG_WRITE_ACCESS_ENABLE U(0x0) +#define SECURITY_CFG_WRITE_ACCESS_DISABLE U(0x1) + +/* Video Memory carveout configuration registers */ +#define MC_VIDEO_PROTECT_BASE_HI U(0x978) +#define MC_VIDEO_PROTECT_BASE_LO U(0x648) +#define MC_VIDEO_PROTECT_SIZE_MB U(0x64c) + +/* + * Carveout (MC_SECURITY_CARVEOUT24) registers used to clear the + * non-overlapping Video memory region + */ +#define MC_VIDEO_PROTECT_CLEAR_CFG U(0x25A0) +#define MC_VIDEO_PROTECT_CLEAR_BASE_LO U(0x25A4) +#define MC_VIDEO_PROTECT_CLEAR_BASE_HI U(0x25A8) +#define MC_VIDEO_PROTECT_CLEAR_SIZE U(0x25AC) +#define MC_VIDEO_PROTECT_CLEAR_ACCESS_CFG0 U(0x25B0) + +/* TZRAM carveout (MC_SECURITY_CARVEOUT11) configuration registers */ +#define MC_TZRAM_CARVEOUT_CFG U(0x2190) +#define MC_TZRAM_BASE_LO U(0x2194) +#define MC_TZRAM_BASE_HI U(0x2198) +#define MC_TZRAM_SIZE U(0x219C) +#define MC_TZRAM_CLIENT_ACCESS0_CFG0 U(0x21A0) +#define MC_TZRAM_CLIENT_ACCESS1_CFG0 U(0x21A4) +#define TZRAM_ALLOW_MPCORER (U(1) << 7) +#define TZRAM_ALLOW_MPCOREW (U(1) << 25) + +/* Memory Controller Reset Control registers */ +#define MC_CLIENT_HOTRESET_CTRL1_DLAA_FLUSH_ENB (U(1) << 28) +#define MC_CLIENT_HOTRESET_CTRL1_DLA1A_FLUSH_ENB (U(1) << 29) +#define MC_CLIENT_HOTRESET_CTRL1_PVA0A_FLUSH_ENB (U(1) << 30) +#define MC_CLIENT_HOTRESET_CTRL1_PVA1A_FLUSH_ENB (U(1) << 31) + +/******************************************************************************* + * Tegra UART Controller constants + ******************************************************************************/ +#define TEGRA_UARTA_BASE U(0x03100000) +#define TEGRA_UARTB_BASE U(0x03110000) +#define TEGRA_UARTC_BASE U(0x0C280000) +#define TEGRA_UARTD_BASE U(0x03130000) +#define TEGRA_UARTE_BASE U(0x03140000) +#define TEGRA_UARTF_BASE U(0x03150000) +#define TEGRA_UARTG_BASE U(0x0C290000) + +/******************************************************************************* + * XUSB PADCTL + ******************************************************************************/ +#define TEGRA_XUSB_PADCTL_BASE U(0x03520000) +#define TEGRA_XUSB_PADCTL_SIZE U(0x10000) +#define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0 U(0x136c) +#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0 U(0x1370) +#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1 U(0x1374) +#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2 U(0x1378) +#define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3 U(0x137c) +#define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0 U(0x139c) + +/******************************************************************************* + * Tegra Fuse Controller related constants + ******************************************************************************/ +#define TEGRA_FUSE_BASE U(0x03820000) +#define OPT_SUBREVISION U(0x248) +#define SUBREVISION_MASK U(0xF) + +/******************************************************************************* + * GICv2 & interrupt handling related constants + ******************************************************************************/ +#define TEGRA_GICD_BASE U(0x03881000) +#define TEGRA_GICC_BASE U(0x03882000) + +/******************************************************************************* + * Security Engine related constants + ******************************************************************************/ +#define TEGRA_SE0_BASE U(0x03AC0000) +#define SE0_MUTEX_WATCHDOG_NS_LIMIT U(0x6C) +#define SE0_AES0_ENTROPY_SRC_AGE_CTRL U(0x2FC) +#define TEGRA_PKA1_BASE U(0x03AD0000) +#define SE_PKA1_CTRL_SE_MUTEX_TMOUT_DFTVAL U(0x144) +#define PKA1_MUTEX_WATCHDOG_NS_LIMIT SE_PKA1_CTRL_SE_MUTEX_TMOUT_DFTVAL +#define TEGRA_RNG1_BASE U(0x03AE0000) +#define RNG1_MUTEX_WATCHDOG_NS_LIMIT U(0xFE0) + +/******************************************************************************* + * Tegra HSP doorbell #0 constants + ******************************************************************************/ +#define TEGRA_HSP_DBELL_BASE U(0x03C90000) +#define HSP_DBELL_1_ENABLE U(0x104) +#define HSP_DBELL_3_TRIGGER U(0x300) +#define HSP_DBELL_3_ENABLE U(0x304) + +/******************************************************************************* + * Tegra hardware synchronization primitives for the SPE engine + ******************************************************************************/ +#define TEGRA_AON_HSP_SM_6_7_BASE U(0x0c190000) +#define TEGRA_CONSOLE_SPE_BASE (TEGRA_AON_HSP_SM_6_7_BASE + U(0x8000)) + +/******************************************************************************* + * Tegra micro-seconds timer constants + ******************************************************************************/ +#define TEGRA_TMRUS_BASE U(0x0C2E0000) +#define TEGRA_TMRUS_SIZE U(0x10000) + +/******************************************************************************* + * Tegra Power Mgmt Controller constants + ******************************************************************************/ +#define TEGRA_PMC_BASE U(0x0C360000) + +/******************************************************************************* + * Tegra scratch registers constants + ******************************************************************************/ +#define TEGRA_SCRATCH_BASE U(0x0C390000) +#define SECURE_SCRATCH_RSV75 U(0x2BC) +#define SECURE_SCRATCH_RSV81_LO U(0x2EC) +#define SECURE_SCRATCH_RSV81_HI U(0x2F0) +#define SECURE_SCRATCH_RSV97 U(0x36C) +#define SECURE_SCRATCH_RSV99_LO U(0x37C) +#define SECURE_SCRATCH_RSV99_HI U(0x380) +#define SECURE_SCRATCH_RSV109_LO U(0x3CC) +#define SECURE_SCRATCH_RSV109_HI U(0x3D0) + +#define SCRATCH_BL31_PARAMS_HI_ADDR SECURE_SCRATCH_RSV75 +#define SCRATCH_BL31_PARAMS_HI_ADDR_MASK U(0xFFFF) +#define SCRATCH_BL31_PARAMS_HI_ADDR_SHIFT U(0) +#define SCRATCH_BL31_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_LO +#define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR SECURE_SCRATCH_RSV75 +#define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_MASK U(0xFFFF0000) +#define SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT U(16) +#define SCRATCH_BL31_PLAT_PARAMS_LO_ADDR SECURE_SCRATCH_RSV81_HI +#define SCRATCH_SECURE_BOOTP_FCFG SECURE_SCRATCH_RSV97 +#define SCRATCH_SMMU_TABLE_ADDR_LO SECURE_SCRATCH_RSV99_LO +#define SCRATCH_SMMU_TABLE_ADDR_HI SECURE_SCRATCH_RSV99_HI +#define SCRATCH_RESET_VECTOR_LO SECURE_SCRATCH_RSV109_LO +#define SCRATCH_RESET_VECTOR_HI SECURE_SCRATCH_RSV109_HI + +/******************************************************************************* + * Tegra Memory Mapped Control Register Access Bus constants + ******************************************************************************/ +#define TEGRA_MMCRAB_BASE U(0x0E000000) + +/******************************************************************************* + * Tegra SMMU Controller constants + ******************************************************************************/ +#define TEGRA_SMMU0_BASE U(0x12000000) +#define TEGRA_SMMU1_BASE U(0x11000000) +#define TEGRA_SMMU2_BASE U(0x10000000) + +/******************************************************************************* + * Tegra TZRAM constants + ******************************************************************************/ +#define TEGRA_TZRAM_BASE U(0x40000000) +#define TEGRA_TZRAM_SIZE U(0x40000) + +/******************************************************************************* + * Tegra CCPLEX-BPMP IPC constants + ******************************************************************************/ +#define TEGRA_BPMP_IPC_TX_PHYS_BASE U(0x4004C000) +#define TEGRA_BPMP_IPC_RX_PHYS_BASE U(0x4004D000) +#define TEGRA_BPMP_IPC_CH_MAP_SIZE U(0x1000) /* 4KB */ + +/******************************************************************************* + * Tegra Clock and Reset Controller constants + ******************************************************************************/ +#define TEGRA_CAR_RESET_BASE U(0x20000000) +#define TEGRA_GPU_RESET_REG_OFFSET U(0x18) +#define TEGRA_GPU_RESET_GPU_SET_OFFSET U(0x1C) +#define GPU_RESET_BIT (U(1) << 0) +#define GPU_SET_BIT (U(1) << 0) +#define TEGRA_GPCDMA_RST_SET_REG_OFFSET U(0x6A0004) +#define TEGRA_GPCDMA_RST_CLR_REG_OFFSET U(0x6A0008) + +/******************************************************************************* + * XUSB STREAMIDs + ******************************************************************************/ +#define TEGRA_SID_XUSB_HOST U(0x1b) +#define TEGRA_SID_XUSB_DEV U(0x1c) +#define TEGRA_SID_XUSB_VF0 U(0x5d) +#define TEGRA_SID_XUSB_VF1 U(0x5e) +#define TEGRA_SID_XUSB_VF2 U(0x5f) +#define TEGRA_SID_XUSB_VF3 U(0x60) + +#endif /* TEGRA_DEF_H */ diff --git a/plat/nvidia/tegra/include/t194/tegra_mc_def.h b/plat/nvidia/tegra/include/t194/tegra_mc_def.h new file mode 100644 index 000000000..34bdd7557 --- /dev/null +++ b/plat/nvidia/tegra/include/t194/tegra_mc_def.h @@ -0,0 +1,685 @@ +/* + * Copyright (c) 2019-2020, NVIDIA Corporation. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef TEGRA_MC_DEF_H +#define TEGRA_MC_DEF_H + +/******************************************************************************* + * Memory Controller Order_id registers + ******************************************************************************/ +#define MC_CLIENT_ORDER_ID_9 U(0x2a24) +#define MC_CLIENT_ORDER_ID_9_RESET_VAL 0x00000000U +#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_MASK (0x3U << 12) +#define MC_CLIENT_ORDER_ID_9_XUSB_HOSTW_ORDER_ID (3U << 12) + +#define MC_CLIENT_ORDER_ID_27 U(0x2a6c) +#define MC_CLIENT_ORDER_ID_27_RESET_VAL 0x00000000U +#define MC_CLIENT_ORDER_ID_27_PCIE0W_MASK (0x3U << 4) +#define MC_CLIENT_ORDER_ID_27_PCIE0W_ORDER_ID (2U << 4) + +#define MC_CLIENT_ORDER_ID_28 U(0x2a70) +#define MC_CLIENT_ORDER_ID_28_RESET_VAL 0x00000000U +#define MC_CLIENT_ORDER_ID_28_PCIE4W_MASK (0x3U << 4) +#define MC_CLIENT_ORDER_ID_28_PCIE4W_ORDER_ID (3U << 4) +#define MC_CLIENT_ORDER_ID_28_PCIE5W_MASK (0x3U << 12) +#define MC_CLIENT_ORDER_ID_28_PCIE5W_ORDER_ID (1U << 12) + +#define mc_client_order_id(val, id, client) \ + ((val & ~MC_CLIENT_ORDER_ID_##id##_##client##_MASK) | \ + MC_CLIENT_ORDER_ID_##id##_##client##_ORDER_ID) + +/******************************************************************************* + * Memory Controller's VC ID configuration registers + ******************************************************************************/ +#define VC_NISO 0U +#define VC_SISO 1U +#define VC_ISO 2U + +#define MC_HUB_PC_VC_ID_0 U(0x2a78) +#define MC_HUB_PC_VC_ID_0_RESET_VAL 0x00020100U +#define MC_HUB_PC_VC_ID_0_APB_VC_ID_MASK (0x3U << 8) +#define MC_HUB_PC_VC_ID_0_APB_VC_ID (VC_NISO << 8) + +#define MC_HUB_PC_VC_ID_2 U(0x2a80) +#define MC_HUB_PC_VC_ID_2_RESET_VAL 0x10001000U +#define MC_HUB_PC_VC_ID_2_SD_VC_ID_MASK (0x3U << 28) +#define MC_HUB_PC_VC_ID_2_SD_VC_ID (VC_NISO << 28) + +#define MC_HUB_PC_VC_ID_4 U(0x2a88) +#define MC_HUB_PC_VC_ID_4_RESET_VAL 0x10020011U +#define MC_HUB_PC_VC_ID_4_NIC_VC_ID_MASK (0x3U << 28) +#define MC_HUB_PC_VC_ID_4_NIC_VC_ID (VC_NISO << 28) + +#define MC_HUB_PC_VC_ID_12 U(0x2aa8) +#define MC_HUB_PC_VC_ID_12_RESET_VAL 0x11001011U +#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID_MASK (0x3U << 12) +#define MC_HUB_PC_VC_ID_12_UFSHCPC2_VC_ID (VC_NISO << 12) + +#define mc_hub_vc_id(val, id, client) \ + ((val & ~MC_HUB_PC_VC_ID_##id##_##client##_VC_ID_MASK) | \ + MC_HUB_PC_VC_ID_##id##_##client##_VC_ID) + +/******************************************************************************* + * Memory Controller's PCFIFO client configuration registers + ******************************************************************************/ +#define MC_PCFIFO_CLIENT_CONFIG0 0xdd0U + +#define MC_PCFIFO_CLIENT_CONFIG1 0xdd4U +#define MC_PCFIFO_CLIENT_CONFIG1_RESET_VAL 0x20200000U +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_UNORDERED (0U << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_AFIW_MASK (1U << 17) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_UNORDERED (0U << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_HDAW_MASK (1U << 21) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_UNORDERED (0U << 29) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_ORDERED (1U << 29) +#define MC_PCFIFO_CLIENT_CONFIG1_PCFIFO_SATAW_MASK (1U << 29) + +#define MC_PCFIFO_CLIENT_CONFIG2 0xdd8U +#define MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL 0x00002800U +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_UNORDERED (0U << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_HOSTW_MASK (1U << 11) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_UNORDERED (0U << 13) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_ORDERED (1U << 13) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_XUSB_DEVW_MASK (1U << 13) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_UNORDERED (0U << 21) +#define MC_PCFIFO_CLIENT_CONFIG2_PCFIFO_TSECSWR_MASK (1U << 21) + +#define MC_PCFIFO_CLIENT_CONFIG3 0xddcU +#define MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL 0x08000080U +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_UNORDERED (0U << 4) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWA_MASK (1U << 4) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_UNORDERED (0U << 6) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCW_MASK (1U << 6) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_UNORDERED (0U << 7) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_SDMMCWAB_MASK (1U << 7) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_UNORDERED (0U << 13) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_VICSWR_MASK (1U << 13) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_UNORDERED (0U << 27) +#define MC_PCFIFO_CLIENT_CONFIG3_PCFIFO_APEW_MASK (1U << 27) + +#define MC_PCFIFO_CLIENT_CONFIG4 0xde0U +#define MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL 0x5552a022U +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_UNORDERED (0U << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SESWR_MASK (1U << 1) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_UNORDERED (0U << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_ETRW_MASK (1U << 5) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_UNORDERED (0U << 7) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_TSECSWRB_MASK (1U << 7) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_UNORDERED (0U << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AXISW_MASK (1U << 13) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_UNORDERED (0U << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_EQOSW_MASK (1U << 15) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_UNORDERED (0U << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_UFSHCW_MASK (1U << 17) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_UNORDERED (0U << 20) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPW_MASK (1U << 20) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_UNORDERED (0U << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_BPMPDMAW_MASK (1U << 22) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_UNORDERED (0U << 24) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONW_MASK (1U << 24) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_UNORDERED (0U << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_AONDMAW_MASK (1U << 26) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_UNORDERED (0U << 28) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEW_MASK (1U << 28) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_UNORDERED (0U << 30) +#define MC_PCFIFO_CLIENT_CONFIG4_PCFIFO_SCEDMAW_MASK (1U << 30) + +#define MC_PCFIFO_CLIENT_CONFIG5 0xbf4U +#define MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL 0x20000001U +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_UNORDERED (0U << 0) +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_APEDMAW_MASK (1U << 0) +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_UNORDERED (0U << 30) +#define MC_PCFIFO_CLIENT_CONFIG5_PCFIFO_VIFALW_MASK (1U << 30) + +#define MC_PCFIFO_CLIENT_CONFIG6 0xb90U +#define MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL 0xaa280000U +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_UNORDERED (0U << 19) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEW_MASK (1U << 19) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_UNORDERED (0U << 21) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_RCEDMAW_MASK (1U << 21) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_UNORDERED (0U << 25) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE0W_MASK (1U << 25) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_ORDERED (1U << 27) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE1W_MASK (1U << 27) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_ORDERED (1U << 29) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE2W_MASK (1U << 29) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_ORDERED (1U << 31) +#define MC_PCFIFO_CLIENT_CONFIG6_PCFIFO_PCIE3W_MASK (1U << 31) + +#define MC_PCFIFO_CLIENT_CONFIG7 0xaccU +#define MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL 0x0000000aU +#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_UNORDERED (0U << 1) +#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE4W_MASK (1U << 1) +#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_UNORDERED (0U << 3) +#define MC_PCFIFO_CLIENT_CONFIG7_PCFIFO_PCIE5W_MASK (1U << 3) + +/******************************************************************************* + * StreamID to indicate no SMMU translations (requests to be steered on the + * SMMU bypass path) + ******************************************************************************/ +#define MC_STREAM_ID_MAX 0x7FU + +/******************************************************************************* + * Stream ID Override Config registers + ******************************************************************************/ +#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA 0x660U +#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD 0xe0U +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSWR 0x3f8U +#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA1 0x758U +#define MC_STREAMID_OVERRIDE_CFG_PVA0RDC 0x640U +#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA 0x5f0U +#define MC_STREAMID_OVERRIDE_CFG_BPMPR 0x498U +#define MC_STREAMID_OVERRIDE_CFG_APEDMAR 0x4f8U +#define MC_STREAMID_OVERRIDE_CFG_AXISR 0x460U +#define MC_STREAMID_OVERRIDE_CFG_TSECSRD 0x2a0U +#define MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB 0x5f8U +#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1 0x788U +#define MC_STREAMID_OVERRIDE_CFG_MPCOREW 0x1c8U +#define MC_STREAMID_OVERRIDE_CFG_NVENCSRD1 0x780U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR 0x250U +#define MC_STREAMID_OVERRIDE_CFG_MIU1R 0x540U +#define MC_STREAMID_OVERRIDE_CFG_MIU0R 0x530U +#define MC_STREAMID_OVERRIDE_CFG_PCIE1W 0x6d8U +#define MC_STREAMID_OVERRIDE_CFG_PVA1WRA 0x678U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW 0x258U +#define MC_STREAMID_OVERRIDE_CFG_AXIAPW 0x418U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWAB 0x338U +#define MC_STREAMID_OVERRIDE_CFG_SATAW 0x1e8U +#define MC_STREAMID_OVERRIDE_CFG_DLA0WRA 0x600U +#define MC_STREAMID_OVERRIDE_CFG_PCIE3R 0x6f0U +#define MC_STREAMID_OVERRIDE_CFG_MIU3W 0x588U +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAR 0x4e8U +#define MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR 0xb0U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCWA 0x320U +#define MC_STREAMID_OVERRIDE_CFG_MIU2R 0x570U +#define MC_STREAMID_OVERRIDE_CFG_APEDMAW 0x500U +#define MC_STREAMID_OVERRIDE_CFG_PCIE2AW 0x6e8U +#define MC_STREAMID_OVERRIDE_CFG_SESWR 0x408U +#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB1 0x770U +#define MC_STREAMID_OVERRIDE_CFG_AXISW 0x468U +#define MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB 0x618U +#define MC_STREAMID_OVERRIDE_CFG_AONDMAW 0x4d0U +#define MC_STREAMID_OVERRIDE_CFG_TSECSWRB 0x438U +#define MC_STREAMID_OVERRIDE_CFG_ISPWB 0x238U +#define MC_STREAMID_OVERRIDE_CFG_HDAR 0xa8U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRA 0x300U +#define MC_STREAMID_OVERRIDE_CFG_ETRW 0x428U +#define MC_STREAMID_OVERRIDE_CFG_RCEDMAW 0x6a8U +#define MC_STREAMID_OVERRIDE_CFG_TSECSWR 0x2a8U +#define MC_STREAMID_OVERRIDE_CFG_ETRR 0x420U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCR 0x310U +#define MC_STREAMID_OVERRIDE_CFG_NVJPGSRD 0x3f0U +#define MC_STREAMID_OVERRIDE_CFG_AONDMAR 0x4c8U +#define MC_STREAMID_OVERRIDE_CFG_SCER 0x4d8U +#define MC_STREAMID_OVERRIDE_CFG_MIU5W 0x7e8U +#define MC_STREAMID_OVERRIDE_CFG_NVENC1SRD 0x6b0U +#define MC_STREAMID_OVERRIDE_CFG_PCIE4R 0x700U +#define MC_STREAMID_OVERRIDE_CFG_ISPWA 0x230U +#define MC_STREAMID_OVERRIDE_CFG_PCIE0W 0x6c8U +#define MC_STREAMID_OVERRIDE_CFG_PCIE5R1 0x778U +#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA 0x610U +#define MC_STREAMID_OVERRIDE_CFG_VICSWR 0x368U +#define MC_STREAMID_OVERRIDE_CFG_SESRD 0x400U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCW 0x330U +#define MC_STREAMID_OVERRIDE_CFG_SDMMCRAB 0x318U +#define MC_STREAMID_OVERRIDE_CFG_ISPFALW 0x720U +#define MC_STREAMID_OVERRIDE_CFG_EQOSW 0x478U +#define MC_STREAMID_OVERRIDE_CFG_RCEDMAR 0x6a0U +#define MC_STREAMID_OVERRIDE_CFG_RCER 0x690U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSWR 0x3c8U +#define MC_STREAMID_OVERRIDE_CFG_UFSHCR 0x480U +#define MC_STREAMID_OVERRIDE_CFG_PCIE4W 0x708U +#define MC_STREAMID_OVERRIDE_CFG_VICSRD 0x360U +#define MC_STREAMID_OVERRIDE_CFG_APER 0x3d0U +#define MC_STREAMID_OVERRIDE_CFG_MIU7R 0x8U +#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD 0x7c8U +#define MC_STREAMID_OVERRIDE_CFG_MIU7W 0x10U +#define MC_STREAMID_OVERRIDE_CFG_PVA1RDA1 0x768U +#define MC_STREAMID_OVERRIDE_CFG_PVA1WRC 0x688U +#define MC_STREAMID_OVERRIDE_CFG_AONW 0x4c0U +#define MC_STREAMID_OVERRIDE_CFG_MIU4W 0x598U +#define MC_STREAMID_OVERRIDE_CFG_HDAW 0x1a8U +#define MC_STREAMID_OVERRIDE_CFG_BPMPW 0x4a0U +#define MC_STREAMID_OVERRIDE_CFG_DLA1WRA 0x620U +#define MC_STREAMID_OVERRIDE_CFG_DLA0RDA1 0x748U +#define MC_STREAMID_OVERRIDE_CFG_MIU1W 0x548U +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1 0x508U +#define MC_STREAMID_OVERRIDE_CFG_VICSRD1 0x510U +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAW 0x4b0U +#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SWR 0x7d8U +#define MC_STREAMID_OVERRIDE_CFG_PVA0WRC 0x658U +#define MC_STREAMID_OVERRIDE_CFG_PCIE5R 0x710U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR 0x260U +#define MC_STREAMID_OVERRIDE_CFG_UFSHCW 0x488U +#define MC_STREAMID_OVERRIDE_CFG_PVA1WRB 0x680U +#define MC_STREAMID_OVERRIDE_CFG_PVA0WRB 0x650U +#define MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB 0x628U +#define MC_STREAMID_OVERRIDE_CFG_NVENC1SWR 0x6b8U +#define MC_STREAMID_OVERRIDE_CFG_PCIE0R 0x6c0U +#define MC_STREAMID_OVERRIDE_CFG_PCIE3W 0x6f8U +#define MC_STREAMID_OVERRIDE_CFG_PVA0RDA 0x630U +#define MC_STREAMID_OVERRIDE_CFG_MIU6W 0x7f8U +#define MC_STREAMID_OVERRIDE_CFG_PCIE1R 0x6d0U +#define MC_STREAMID_OVERRIDE_CFG_NVDEC1SRD1 0x7d0U +#define MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB 0x608U +#define MC_STREAMID_OVERRIDE_CFG_PVA1RDC 0x670U +#define MC_STREAMID_OVERRIDE_CFG_MIU0W 0x538U +#define MC_STREAMID_OVERRIDE_CFG_MIU2W 0x578U +#define MC_STREAMID_OVERRIDE_CFG_MPCORER 0x138U +#define MC_STREAMID_OVERRIDE_CFG_AXIAPR 0x410U +#define MC_STREAMID_OVERRIDE_CFG_AONR 0x4b8U +#define MC_STREAMID_OVERRIDE_CFG_BPMPDMAR 0x4a8U +#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB 0x638U +#define MC_STREAMID_OVERRIDE_CFG_VIFALW 0x5e8U +#define MC_STREAMID_OVERRIDE_CFG_MIU6R 0x7f0U +#define MC_STREAMID_OVERRIDE_CFG_EQOSR 0x470U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD 0x3c0U +#define MC_STREAMID_OVERRIDE_CFG_TSECSRDB 0x430U +#define MC_STREAMID_OVERRIDE_CFG_NVDECSRD1 0x518U +#define MC_STREAMID_OVERRIDE_CFG_PVA0RDB1 0x760U +#define MC_STREAMID_OVERRIDE_CFG_PCIE0R1 0x798U +#define MC_STREAMID_OVERRIDE_CFG_SCEDMAW 0x4f0U +#define MC_STREAMID_OVERRIDE_CFG_APEW 0x3d8U +#define MC_STREAMID_OVERRIDE_CFG_MIU5R 0x7e0U +#define MC_STREAMID_OVERRIDE_CFG_DLA1RDA1 0x750U +#define MC_STREAMID_OVERRIDE_CFG_PVA0WRA 0x648U +#define MC_STREAMID_OVERRIDE_CFG_ISPFALR 0x228U +#define MC_STREAMID_OVERRIDE_CFG_PTCR 0x0U +#define MC_STREAMID_OVERRIDE_CFG_MIU4R 0x590U +#define MC_STREAMID_OVERRIDE_CFG_ISPRA 0x220U +#define MC_STREAMID_OVERRIDE_CFG_VIFALR 0x5e0U +#define MC_STREAMID_OVERRIDE_CFG_PCIE2AR 0x6e0U +#define MC_STREAMID_OVERRIDE_CFG_RCEW 0x698U +#define MC_STREAMID_OVERRIDE_CFG_ISPRA1 0x790U +#define MC_STREAMID_OVERRIDE_CFG_SCEW 0x4e0U +#define MC_STREAMID_OVERRIDE_CFG_MIU3R 0x580U +#define MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW 0x268U +#define MC_STREAMID_OVERRIDE_CFG_SATAR 0xf8U +#define MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR 0x490U +#define MC_STREAMID_OVERRIDE_CFG_PVA1RDB 0x668U +#define MC_STREAMID_OVERRIDE_CFG_VIW 0x390U +#define MC_STREAMID_OVERRIDE_CFG_NVENCSWR 0x158U +#define MC_STREAMID_OVERRIDE_CFG_PCIE5W 0x718U + +/******************************************************************************* + * Macro to calculate Security cfg register addr from StreamID Override register + ******************************************************************************/ +#define MC_STREAMID_OVERRIDE_TO_SECURITY_CFG(addr) ((addr) + (uint32_t)sizeof(uint32_t)) + +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_SO_DEV (0U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_SO_DEV (1U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SO_DEV (2U << 4) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_SO_DEV (3U << 4) + +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_NO_OVERRIDE_NORMAL (0U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_NON_COHERENT_NORMAL (1U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_NORMAL (2U << 8) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_FORCE_COHERENT_SNOOP_NORMAL (3U << 8) + +#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_ZERO (0U << 12) +#define MC_TXN_OVERRIDE_CONFIG_CGID_SO_DEV_CLIENT_AXI_ID (1U << 12) + +/******************************************************************************* + * Memory Controller transaction override config registers + ******************************************************************************/ +#define MC_TXN_OVERRIDE_CONFIG_HDAR 0x10a8U +#define MC_TXN_OVERRIDE_CONFIG_DLA1WRA 0x1624U +#define MC_TXN_OVERRIDE_CONFIG_PCIE1W 0x16dcU +#define MC_TXN_OVERRIDE_CONFIG_PVA0RDC 0x1644U +#define MC_TXN_OVERRIDE_CONFIG_PTCR 0x1000U +#define MC_TXN_OVERRIDE_CONFIG_EQOSW 0x1478U +#define MC_TXN_OVERRIDE_CONFIG_MPCOREW 0x11c8U +#define MC_TXN_OVERRIDE_CONFIG_DLA1FALWRB 0x162cU +#define MC_TXN_OVERRIDE_CONFIG_AXISR 0x1460U +#define MC_TXN_OVERRIDE_CONFIG_PVA0WRB 0x1654U +#define MC_TXN_OVERRIDE_CONFIG_MIU6R 0x17f4U +#define MC_TXN_OVERRIDE_CONFIG_MIU5R 0x17e4U +#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD1 0x1784U +#define MC_TXN_OVERRIDE_CONFIG_PCIE0R 0x16c4U +#define MC_TXN_OVERRIDE_CONFIG_EQOSR 0x1470U +#define MC_TXN_OVERRIDE_CONFIG_NVENCSRD 0x10e0U +#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD1 0x178cU +#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB1 0x1774U +#define MC_TXN_OVERRIDE_CONFIG_NVENC1SWR 0x16bcU +#define MC_TXN_OVERRIDE_CONFIG_VICSRD1 0x1510U +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAR 0x14a8U +#define MC_TXN_OVERRIDE_CONFIG_VIW 0x1390U +#define MC_TXN_OVERRIDE_CONFIG_PCIE5R 0x1714U +#define MC_TXN_OVERRIDE_CONFIG_AXISW 0x1468U +#define MC_TXN_OVERRIDE_CONFIG_MIU6W 0x17fcU +#define MC_TXN_OVERRIDE_CONFIG_UFSHCR 0x1480U +#define MC_TXN_OVERRIDE_CONFIG_PCIE0R1 0x179cU +#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB1 0x1764U +#define MC_TXN_OVERRIDE_CONFIG_TSECSWR 0x12a8U +#define MC_TXN_OVERRIDE_CONFIG_MIU7R 0x1008U +#define MC_TXN_OVERRIDE_CONFIG_SATAR 0x10f8U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTW 0x1258U +#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA 0x15f4U +#define MC_TXN_OVERRIDE_CONFIG_TSECSWRB 0x1438U +#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SWR 0x17dcU +#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA1 0x176cU +#define MC_TXN_OVERRIDE_CONFIG_PVA1RDB 0x166cU +#define MC_TXN_OVERRIDE_CONFIG_AONDMAW 0x14d0U +#define MC_TXN_OVERRIDE_CONFIG_AONW 0x14c0U +#define MC_TXN_OVERRIDE_CONFIG_ETRR 0x1420U +#define MC_TXN_OVERRIDE_CONFIG_PCIE2AW 0x16ecU +#define MC_TXN_OVERRIDE_CONFIG_PCIE1R 0x16d4U +#define MC_TXN_OVERRIDE_CONFIG_PVA1RDC 0x1674U +#define MC_TXN_OVERRIDE_CONFIG_PVA0WRA 0x164cU +#define MC_TXN_OVERRIDE_CONFIG_TSECSRDB 0x1430U +#define MC_TXN_OVERRIDE_CONFIG_MIU1W 0x1548U +#define MC_TXN_OVERRIDE_CONFIG_PCIE0W 0x16ccU +#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD 0x17ccU +#define MC_TXN_OVERRIDE_CONFIG_MIU7W 0x1010U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD1 0x1518U +#define MC_TXN_OVERRIDE_CONFIG_MIU3R 0x1580U +#define MC_TXN_OVERRIDE_CONFIG_MIU3W 0x158cU +#define MC_TXN_OVERRIDE_CONFIG_XUSB_HOSTR 0x1250U +#define MC_TXN_OVERRIDE_CONFIG_SESRD 0x1400U +#define MC_TXN_OVERRIDE_CONFIG_SCER 0x14d8U +#define MC_TXN_OVERRIDE_CONFIG_MPCORER 0x1138U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWA 0x1320U +#define MC_TXN_OVERRIDE_CONFIG_HDAW 0x11a8U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSWR 0x13c8U +#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA 0x1634U +#define MC_TXN_OVERRIDE_CONFIG_AONDMAR 0x14c8U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCWAB 0x1338U +#define MC_TXN_OVERRIDE_CONFIG_ISPFALR 0x1228U +#define MC_TXN_OVERRIDE_CONFIG_PVA0RDA1 0x175cU +#define MC_TXN_OVERRIDE_CONFIG_NVENC1SRD 0x16b4U +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR1 0x1508U +#define MC_TXN_OVERRIDE_CONFIG_PVA1RDA 0x1664U +#define MC_TXN_OVERRIDE_CONFIG_DLA0RDA1 0x174cU +#define MC_TXN_OVERRIDE_CONFIG_ISPWB 0x1238U +#define MC_TXN_OVERRIDE_CONFIG_APEW 0x13d8U +#define MC_TXN_OVERRIDE_CONFIG_AXIAPR 0x1410U +#define MC_TXN_OVERRIDE_CONFIG_PCIE2AR 0x16e4U +#define MC_TXN_OVERRIDE_CONFIG_ISPFALW 0x1724U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCR 0x1310U +#define MC_TXN_OVERRIDE_CONFIG_MIU2W 0x1578U +#define MC_TXN_OVERRIDE_CONFIG_RCER 0x1694U +#define MC_TXN_OVERRIDE_CONFIG_PCIE4W 0x170cU +#define MC_TXN_OVERRIDE_CONFIG_BPMPW 0x14a0U +#define MC_TXN_OVERRIDE_CONFIG_NVDISPLAYR 0x1490U +#define MC_TXN_OVERRIDE_CONFIG_ISPRA 0x1220U +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSWR 0x13f8U +#define MC_TXN_OVERRIDE_CONFIG_VICSRD 0x1360U +#define MC_TXN_OVERRIDE_CONFIG_NVDEC1SRD1 0x17d4U +#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA 0x1614U +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAW 0x14f0U +#define MC_TXN_OVERRIDE_CONFIG_SDMMCW 0x1330U +#define MC_TXN_OVERRIDE_CONFIG_DLA1FALRDB 0x161cU +#define MC_TXN_OVERRIDE_CONFIG_APEDMAR 0x14f8U +#define MC_TXN_OVERRIDE_CONFIG_RCEW 0x169cU +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRAB 0x1318U +#define MC_TXN_OVERRIDE_CONFIG_DLA0WRA 0x1604U +#define MC_TXN_OVERRIDE_CONFIG_VIFALR 0x15e4U +#define MC_TXN_OVERRIDE_CONFIG_PCIE3R 0x16f4U +#define MC_TXN_OVERRIDE_CONFIG_MIU1R 0x1540U +#define MC_TXN_OVERRIDE_CONFIG_PCIE5W 0x171cU +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVR 0x1260U +#define MC_TXN_OVERRIDE_CONFIG_MIU0W 0x1538U +#define MC_TXN_OVERRIDE_CONFIG_DLA0FALWRB 0x160cU +#define MC_TXN_OVERRIDE_CONFIG_VIFALW 0x15ecU +#define MC_TXN_OVERRIDE_CONFIG_DLA0FALRDB 0x15fcU +#define MC_TXN_OVERRIDE_CONFIG_PCIE3W 0x16fcU +#define MC_TXN_OVERRIDE_CONFIG_MIU0R 0x1530U +#define MC_TXN_OVERRIDE_CONFIG_PVA0WRC 0x165cU +#define MC_TXN_OVERRIDE_CONFIG_SCEDMAR 0x14e8U +#define MC_TXN_OVERRIDE_CONFIG_APEDMAW 0x1500U +#define MC_TXN_OVERRIDE_CONFIG_HOST1XDMAR 0x10b0U +#define MC_TXN_OVERRIDE_CONFIG_SESWR 0x1408U +#define MC_TXN_OVERRIDE_CONFIG_AXIAPW 0x1418U +#define MC_TXN_OVERRIDE_CONFIG_MIU4R 0x1594U +#define MC_TXN_OVERRIDE_CONFIG_MIU4W 0x159cU +#define MC_TXN_OVERRIDE_CONFIG_NVJPGSRD 0x13f0U +#define MC_TXN_OVERRIDE_CONFIG_NVDECSRD 0x13c0U +#define MC_TXN_OVERRIDE_CONFIG_BPMPDMAW 0x14b0U +#define MC_TXN_OVERRIDE_CONFIG_APER 0x13d0U +#define MC_TXN_OVERRIDE_CONFIG_DLA1RDA1 0x1754U +#define MC_TXN_OVERRIDE_CONFIG_PVA1WRB 0x1684U +#define MC_TXN_OVERRIDE_CONFIG_ISPWA 0x1230U +#define MC_TXN_OVERRIDE_CONFIG_PVA1WRC 0x168cU +#define MC_TXN_OVERRIDE_CONFIG_RCEDMAR 0x16a4U +#define MC_TXN_OVERRIDE_CONFIG_ISPRA1 0x1794U +#define MC_TXN_OVERRIDE_CONFIG_AONR 0x14b8U +#define MC_TXN_OVERRIDE_CONFIG_RCEDMAW 0x16acU +#define MC_TXN_OVERRIDE_CONFIG_UFSHCW 0x1488U +#define MC_TXN_OVERRIDE_CONFIG_ETRW 0x1428U +#define MC_TXN_OVERRIDE_CONFIG_SATAW 0x11e8U +#define MC_TXN_OVERRIDE_CONFIG_VICSWR 0x1368U +#define MC_TXN_OVERRIDE_CONFIG_NVENCSWR 0x1158U +#define MC_TXN_OVERRIDE_CONFIG_PCIE5R1 0x177cU +#define MC_TXN_OVERRIDE_CONFIG_PVA0RDB 0x163cU +#define MC_TXN_OVERRIDE_CONFIG_SDMMCRA 0x1300U +#define MC_TXN_OVERRIDE_CONFIG_PVA1WRA 0x167cU +#define MC_TXN_OVERRIDE_CONFIG_MIU5W 0x17ecU +#define MC_TXN_OVERRIDE_CONFIG_BPMPR 0x1498U +#define MC_TXN_OVERRIDE_CONFIG_MIU2R 0x1570U +#define MC_TXN_OVERRIDE_CONFIG_XUSB_DEVW 0x1268U +#define MC_TXN_OVERRIDE_CONFIG_TSECSRD 0x12a0U +#define MC_TXN_OVERRIDE_CONFIG_PCIE4R 0x1704U +#define MC_TXN_OVERRIDE_CONFIG_SCEW 0x14e0U + +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_CGID (1U << 0) +#define MC_TXN_OVERRIDE_CONFIG_COH_PATH_OVERRIDE_SO_DEV (2U << 4) +#define MC_TXN_OVERRIDE_CONFIG_AXID_OVERRIDE_SO_DEV_CGID_SO_DEV_CLIENT (1U << 12) + +/******************************************************************************* + * Non-SO_DEV transactions override values for CGID_TAG bitfield for the + * MC_TXN_OVERRIDE_CONFIG_{module} registers + ******************************************************************************/ +#define MC_TXN_OVERRIDE_CGID_TAG_DEFAULT 0U +#define MC_TXN_OVERRIDE_CGID_TAG_CLIENT_AXI_ID 1U +#define MC_TXN_OVERRIDE_CGID_TAG_ZERO 2U +#define MC_TXN_OVERRIDE_CGID_TAG_ADR 3U +#define MC_TXN_OVERRIDE_CGID_TAG_MASK 3ULL + +/******************************************************************************* + * Memory Controller Reset Control registers + ******************************************************************************/ +#define MC_CLIENT_HOTRESET_CTRL0 0x200U +#define MC_CLIENT_HOTRESET_CTRL0_RESET_VAL 0U +#define MC_CLIENT_HOTRESET_CTRL0_AFI_FLUSH_ENB (1U << 0) +#define MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB (1U << 6) +#define MC_CLIENT_HOTRESET_CTRL0_HDA_FLUSH_ENB (1U << 7) +#define MC_CLIENT_HOTRESET_CTRL0_ISP2_FLUSH_ENB (1U << 8) +#define MC_CLIENT_HOTRESET_CTRL0_MPCORE_FLUSH_ENB (1U << 9) +#define MC_CLIENT_HOTRESET_CTRL0_NVENC_FLUSH_ENB (1U << 11) +#define MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB (1U << 15) +#define MC_CLIENT_HOTRESET_CTRL0_VI_FLUSH_ENB (1U << 17) +#define MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB (1U << 18) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB (1U << 19) +#define MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB (1U << 20) +#define MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB (1U << 22) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB (1U << 29) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC2A_FLUSH_ENB (1U << 30) +#define MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB (1U << 31) +#define MC_CLIENT_HOTRESET_STATUS0 0x204U +#define MC_CLIENT_HOTRESET_CTRL1 0x970U +#define MC_CLIENT_HOTRESET_CTRL1_RESET_VAL 0U +#define MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB (1U << 0) +#define MC_CLIENT_HOTRESET_CTRL1_GPU_FLUSH_ENB (1U << 2) +#define MC_CLIENT_HOTRESET_CTRL1_NVDEC_FLUSH_ENB (1U << 5) +#define MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB (1U << 6) +#define MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB (1U << 7) +#define MC_CLIENT_HOTRESET_CTRL1_NVJPG_FLUSH_ENB (1U << 8) +#define MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB (1U << 12) +#define MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB (1U << 13) +#define MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB (1U << 17) +#define MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB (1U << 18) +#define MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB (1U << 19) +#define MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB (1U << 20) +#define MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB (1U << 21) +#define MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB (1U << 22) +#define MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB (1U << 23) +#define MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB (1U << 26) +#define MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB (1U << 31) +#define MC_CLIENT_HOTRESET_STATUS1 0x974U +#define MC_CLIENT_HOTRESET_CTRL2 0x97cU +#define MC_CLIENT_HOTRESET_CTRL2_RESET_VAL 0U +#define MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB (1U << 0) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB (1U << 2) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB (1U << 4) +#define MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB (1U << 9) +#define MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB (1U << 10) +#define MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB (1U << 11) +#define MC_CLIENT_HOTRESET_CTRL2_APEDMA_FLUSH_ENB (1U << 14) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB (1U << 16) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB (1U << 17) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB (1U << 22) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB (1U << 23) +#define MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB (1U << 25) +#define MC_CLIENT_HOTRESET_STATUS2 0x1898U + +#define MC_COALESCE_CTRL 0x2930U +#define MC_COALESCE_CTRL_COALESCER_ENABLE (1U << 31) +#define MC_COALESCE_CONFIG_6_0 0x294cU +#define MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED (1U << 8) +#define MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED (1U << 14) + +/******************************************************************************* + * Tegra TSA Controller constants + ******************************************************************************/ +#define TEGRA_TSA_BASE U(0x02000000) + +#define TSA_CONFIG_STATIC0_CSR_RESET_R 0x20000000U +#define TSA_CONFIG_STATIC0_CSW_RESET_W 0x20001000U +#define TSA_CONFIG_STATIC0_CSW_RESET_SO_DEV 0x20001000U + +#define TSA_CONFIG_STATIC0_CSW_PCIE1W 0x1004U +#define TSA_CONFIG_STATIC0_CSW_PCIE2AW 0x1008U +#define TSA_CONFIG_STATIC0_CSW_PCIE3W 0x100cU +#define TSA_CONFIG_STATIC0_CSW_PCIE4W 0x1028U +#define TSA_CONFIG_STATIC0_CSW_XUSB_DEVW 0x2004U +#define TSA_CONFIG_STATIC0_CSR_SATAR 0x2010U +#define TSA_CONFIG_STATIC0_CSW_SATAW 0x2014U +#define TSA_CONFIG_STATIC0_CSW_PCIE0W 0x2020U +#define TSA_CONFIG_STATIC0_CSW_XUSB_HOSTW 0x202cU +#define TSA_CONFIG_STATIC0_CSW_NVENC1SWR 0x3004U +#define TSA_CONFIG_STATIC0_CSW_NVENCSWR 0x3010U +#define TSA_CONFIG_STATIC0_CSW_NVDEC1SWR 0x4004U +#define TSA_CONFIG_STATIC0_CSR_ISPFALR 0x4010U +#define TSA_CONFIG_STATIC0_CSW_ISPWA 0x4014U +#define TSA_CONFIG_STATIC0_CSW_ISPWB 0x4018U +#define TSA_CONFIG_STATIC0_CSW_ISPFALW 0x401cU +#define TSA_CONFIG_STATIC0_CSW_NVDECSWR 0x5004U +#define TSA_CONFIG_STATIC0_CSR_EQOSR 0x5010U +#define TSA_CONFIG_STATIC0_CSW_EQOSW 0x5014U +#define TSA_CONFIG_STATIC0_CSR_SDMMCRAB 0x5020U +#define TSA_CONFIG_STATIC0_CSW_SDMMCWAB 0x5024U +#define TSA_CONFIG_STATIC0_CSW_UFSHCW 0x6004U +#define TSA_CONFIG_STATIC0_CSR_SDMMCR 0x6010U +#define TSA_CONFIG_STATIC0_CSR_SDMMCRA 0x6014U +#define TSA_CONFIG_STATIC0_CSW_SDMMCW 0x6018U +#define TSA_CONFIG_STATIC0_CSW_SDMMCWA 0x601cU +#define TSA_CONFIG_STATIC0_CSR_RCER 0x6030U +#define TSA_CONFIG_STATIC0_CSR_RCEDMAR 0x6034U +#define TSA_CONFIG_STATIC0_CSW_RCEW 0x6038U +#define TSA_CONFIG_STATIC0_CSW_RCEDMAW 0x603cU +#define TSA_CONFIG_STATIC0_CSR_SCER 0x6050U +#define TSA_CONFIG_STATIC0_CSR_SCEDMAR 0x6054U +#define TSA_CONFIG_STATIC0_CSW_SCEW 0x6058U +#define TSA_CONFIG_STATIC0_CSW_SCEDMAW 0x605cU +#define TSA_CONFIG_STATIC0_CSR_AXIAPR 0x7004U +#define TSA_CONFIG_STATIC0_CSR_ETRR 0x7008U +#define TSA_CONFIG_STATIC0_CSR_HOST1XDMAR 0x700cU +#define TSA_CONFIG_STATIC0_CSW_AXIAPW 0x7010U +#define TSA_CONFIG_STATIC0_CSW_ETRW 0x7014U +#define TSA_CONFIG_STATIC0_CSR_NVJPGSRD 0x8004U +#define TSA_CONFIG_STATIC0_CSW_NVJPGSWR 0x8008U +#define TSA_CONFIG_STATIC0_CSR_AXISR 0x8014U +#define TSA_CONFIG_STATIC0_CSW_AXISW 0x8018U +#define TSA_CONFIG_STATIC0_CSR_BPMPR 0x9004U +#define TSA_CONFIG_STATIC0_CSR_BPMPDMAR 0x9008U +#define TSA_CONFIG_STATIC0_CSW_BPMPW 0x900cU +#define TSA_CONFIG_STATIC0_CSW_BPMPDMAW 0x9010U +#define TSA_CONFIG_STATIC0_CSR_SESRD 0x9024U +#define TSA_CONFIG_STATIC0_CSR_TSECSRD 0x9028U +#define TSA_CONFIG_STATIC0_CSR_TSECSRDB 0x902cU +#define TSA_CONFIG_STATIC0_CSW_SESWR 0x9030U +#define TSA_CONFIG_STATIC0_CSW_TSECSWR 0x9034U +#define TSA_CONFIG_STATIC0_CSW_TSECSWRB 0x9038U +#define TSA_CONFIG_STATIC0_CSW_PCIE5W 0xb004U +#define TSA_CONFIG_STATIC0_CSW_VICSWR 0xc004U +#define TSA_CONFIG_STATIC0_CSR_APER 0xd004U +#define TSA_CONFIG_STATIC0_CSR_APEDMAR 0xd008U +#define TSA_CONFIG_STATIC0_CSW_APEW 0xd00cU +#define TSA_CONFIG_STATIC0_CSW_APEDMAW 0xd010U +#define TSA_CONFIG_STATIC0_CSR_HDAR 0xf004U +#define TSA_CONFIG_STATIC0_CSW_HDAW 0xf008U +#define TSA_CONFIG_STATIC0_CSR_NVDISPLAYR 0xf014U +#define TSA_CONFIG_STATIC0_CSR_VIFALR 0x10004U +#define TSA_CONFIG_STATIC0_CSW_VIW 0x10008U +#define TSA_CONFIG_STATIC0_CSW_VIFALW 0x1000cU +#define TSA_CONFIG_STATIC0_CSR_AONR 0x12004U +#define TSA_CONFIG_STATIC0_CSR_AONDMAR 0x12008U +#define TSA_CONFIG_STATIC0_CSW_AONW 0x1200cU +#define TSA_CONFIG_STATIC0_CSW_AONDMAW 0x12010U +#define TSA_CONFIG_STATIC0_CSR_PCIE1R 0x14004U +#define TSA_CONFIG_STATIC0_CSR_PCIE2AR 0x14008U +#define TSA_CONFIG_STATIC0_CSR_PCIE3R 0x1400cU +#define TSA_CONFIG_STATIC0_CSR_PCIE4R 0x14028U +#define TSA_CONFIG_STATIC0_CSR_XUSB_DEVR 0x15004U +#define TSA_CONFIG_STATIC0_CSR_XUSB_HOSTR 0x15010U +#define TSA_CONFIG_STATIC0_CSR_UFSHCR 0x16004U +#define TSA_CONFIG_STATIC0_CSW_DLA1WRA 0x18004U +#define TSA_CONFIG_STATIC0_CSR_DLA1FALRDB 0x18010U +#define TSA_CONFIG_STATIC0_CSW_DLA1FALWRB 0x18014U +#define TSA_CONFIG_STATIC0_CSW_DLA0WRA 0x19004U +#define TSA_CONFIG_STATIC0_CSR_DLA0FALRDB 0x19010U +#define TSA_CONFIG_STATIC0_CSW_DLA0FALWRB 0x19014U +#define TSA_CONFIG_STATIC0_CSR_PVA1RDC 0x1a004U +#define TSA_CONFIG_STATIC0_CSW_PVA1WRC 0x1a008U +#define TSA_CONFIG_STATIC0_CSW_PVA1WRA 0x1a014U +#define TSA_CONFIG_STATIC0_CSW_PVA1WRB 0x1a020U +#define TSA_CONFIG_STATIC0_CSW_PVA0WRB 0x1b004U +#define TSA_CONFIG_STATIC0_CSR_PVA0RDC 0x1b010U +#define TSA_CONFIG_STATIC0_CSW_PVA0WRC 0x1b014U +#define TSA_CONFIG_STATIC0_CSW_PVA0WRA 0x1b020U +#define TSA_CONFIG_STATIC0_CSR_NVENC1SRD 0x1d004U +#define TSA_CONFIG_STATIC0_CSR_NVENCSRD 0x1d010U +#define TSA_CONFIG_STATIC0_CSR_NVDEC1SRD 0x1e004U +#define TSA_CONFIG_STATIC0_CSR_ISPRA 0x1e010U +#define TSA_CONFIG_STATIC0_CSR_NVDECSRD 0x1f004U +#define TSA_CONFIG_STATIC0_CSR_PCIE0R 0x21004U +#define TSA_CONFIG_STATIC0_CSR_PCIE5R 0x23004U +#define TSA_CONFIG_STATIC0_CSR_VICSRD 0x24004U +#define TSA_CONFIG_STATIC0_CSR_DLA1RDA 0x26004U +#define TSA_CONFIG_STATIC0_CSR_DLA0RDA 0x27004U +#define TSA_CONFIG_STATIC0_CSR_PVA1RDA 0x28004U +#define TSA_CONFIG_STATIC0_CSR_PVA1RDB 0x28010U +#define TSA_CONFIG_STATIC0_CSR_PVA0RDB 0x29004U +#define TSA_CONFIG_STATIC0_CSR_PVA0RDA 0x29010U + +#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_MASK (ULL(0x3) << 11) +#define TSA_CONFIG_CSW_MEMTYPE_OVERRIDE_PASTHRU (ULL(0) << 11) +#define TSA_CONFIG_CSW_SO_DEV_HUBID_MASK (ULL(0x3) << 15) +#define TSA_CONFIG_CSW_SO_DEV_HUB2 (ULL(2) << 15) + +#define REORDER_DEPTH_LIMIT 16 +#define TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK (ULL(0x7FF) << 21) +#define reorder_depth_limit(limit) (ULL(limit) << 21) + +#define tsa_read_32(client) \ + mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client) + +#define mc_set_tsa_hub2(val, client) \ + { \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + ((val & ~TSA_CONFIG_CSW_SO_DEV_HUBID_MASK) | \ + TSA_CONFIG_CSW_SO_DEV_HUB2)); \ + } + +#define mc_set_tsa_depth_limit(limit, client) \ + { \ + uint32_t val = mmio_read_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client); \ + mmio_write_32(TEGRA_TSA_BASE + TSA_CONFIG_STATIC0_CSW_##client, \ + ((val & ~TSA_CONFIG_CSW_REORDER_DEPTH_LIMIT_MASK) | \ + reorder_depth_limit(limit))); \ + } + +#endif /* TEGRA_MC_DEF_H */ diff --git a/plat/nvidia/tegra/include/tegra_private.h b/plat/nvidia/tegra/include/tegra_private.h index cdd9e08c1..761acdea5 100644 --- a/plat/nvidia/tegra/include/tegra_private.h +++ b/plat/nvidia/tegra/include/tegra_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <arch.h> #include <arch_helpers.h> +#include <drivers/ti/uart/uart_16550.h> #include <lib/psci/psci.h> #include <lib/xlat_tables/xlat_tables_v2.h> @@ -75,7 +76,7 @@ int32_t tegra_soc_validate_power_state(uint32_t power_state, /* Declarations for plat_setup.c */ const mmap_region_t *plat_get_mmio_map(void); -uint32_t plat_get_console_from_id(int32_t id); +void plat_enable_console(int32_t id); void plat_gic_setup(void); struct tegra_bl31_params *plat_get_bl31_params(void); plat_params_from_bl2_t *plat_get_bl31_plat_params(void); @@ -96,8 +97,6 @@ void tegra_security_setup(void); void tegra_security_setup_videomem(uintptr_t base, uint64_t size); /* Declarations for tegra_pm.c */ -extern uint8_t tegra_fake_system_suspend; - void tegra_pm_system_suspend_entry(void); void tegra_pm_system_suspend_exit(void); int32_t tegra_system_suspended(void); @@ -138,7 +137,6 @@ int32_t bl31_check_ns_address(uint64_t base, uint64_t size_in_bytes); void tegra_delay_timer_init(void); void tegra_secure_entrypoint(void); -void tegra186_cpu_reset_handler(void); /* Declarations for tegra_sip_calls.c */ uintptr_t tegra_sip_handler(uint32_t smc_fid, diff --git a/plat/nvidia/tegra/scat/bl31.scat b/plat/nvidia/tegra/scat/bl31.scat index 2f5fd9ecb..2d6d2b3d2 100644 --- a/plat/nvidia/tegra/scat/bl31.scat +++ b/plat/nvidia/tegra/scat/bl31.scat @@ -95,7 +95,7 @@ LR_RO_DATA +0 /* cpu_ops must always be defined */ ScatterAssert(ImageLength(__CPU_OPS__) > 0) -#if ENABLE_SPM +#if SPM_MM LR_SPM +0 { /* diff --git a/plat/nvidia/tegra/soc/t132/plat_setup.c b/plat/nvidia/tegra/soc/t132/plat_setup.c index 570acd900..df6267897 100644 --- a/plat/nvidia/tegra/soc/t132/plat_setup.c +++ b/plat/nvidia/tegra/soc/t132/plat_setup.c @@ -6,9 +6,11 @@ #include <arch_helpers.h> #include <common/bl_common.h> +#include <drivers/console.h> #include <lib/xlat_tables/xlat_tables_v2.h> #include <plat/common/platform.h> #include <tegra_def.h> +#include <tegra_platform.h> #include <tegra_private.h> /* sets of MMIO ranges setup */ @@ -85,14 +87,30 @@ static uint32_t tegra132_uart_addresses[TEGRA132_MAX_UART_PORTS + 1] = { }; /******************************************************************************* - * Retrieve the UART controller base to be used as the console + * Enable console corresponding to the console ID ******************************************************************************/ -uint32_t plat_get_console_from_id(int id) +void plat_enable_console(int32_t id) { - if (id > TEGRA132_MAX_UART_PORTS) - return 0; + static console_16550_t uart_console; + uint32_t console_clock; - return tegra132_uart_addresses[id]; + if ((id > 0) && (id < TEGRA132_MAX_UART_PORTS)) { + /* + * Reference clock used by the FPGAs is a lot slower. + */ + if (tegra_platform_is_fpga()) { + console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; + } else { + console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; + } + + (void)console_16550_register(tegra132_uart_addresses[id], + console_clock, + TEGRA_CONSOLE_BAUDRATE, + &uart_console); + console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t186/plat_setup.c b/plat/nvidia/tegra/soc/t186/plat_setup.c index ef0ba4eb1..1018caa94 100644 --- a/plat/nvidia/tegra/soc/t186/plat_setup.c +++ b/plat/nvidia/tegra/soc/t186/plat_setup.c @@ -141,19 +141,30 @@ static uint32_t tegra186_uart_addresses[TEGRA186_MAX_UART_PORTS + 1] = { }; /******************************************************************************* - * Retrieve the UART controller base to be used as the console + * Enable console corresponding to the console ID ******************************************************************************/ -uint32_t plat_get_console_from_id(int32_t id) +void plat_enable_console(int32_t id) { - uint32_t ret; + static console_16550_t uart_console; + uint32_t console_clock; + + if ((id > 0) && (id < TEGRA186_MAX_UART_PORTS)) { + /* + * Reference clock used by the FPGAs is a lot slower. + */ + if (tegra_platform_is_fpga()) { + console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; + } else { + console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; + } - if (id > TEGRA186_MAX_UART_PORTS) { - ret = 0; - } else { - ret = tegra186_uart_addresses[id]; + (void)console_16550_register(tegra186_uart_addresses[id], + console_clock, + TEGRA_CONSOLE_BAUDRATE, + &uart_console); + console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); } - - return ret; } /******************************************************************************* diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h new file mode 100644 index 000000000..1fe3aad39 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/include/mce_private.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef MCE_PRIVATE_H +#define MCE_PRIVATE_H + +#include <stdbool.h> +#include <tegra_def.h> + +/******************************************************************************* + * Macros to prepare CSTATE info request + ******************************************************************************/ +/* Description of the parameters for UPDATE_CSTATE_INFO request */ +#define CLUSTER_CSTATE_MASK 0x7U +#define CLUSTER_CSTATE_SHIFT 0X0U +#define CLUSTER_CSTATE_UPDATE_BIT (1U << 7) +#define CCPLEX_CSTATE_MASK 0x7U +#define CCPLEX_CSTATE_SHIFT 8U +#define CCPLEX_CSTATE_UPDATE_BIT (1U << 15) +#define SYSTEM_CSTATE_MASK 0xFU +#define SYSTEM_CSTATE_SHIFT 16U +#define SYSTEM_CSTATE_UPDATE_BIT (1U << 23) +#define CSTATE_WAKE_MASK_UPDATE_BIT (1U << 31) +#define CSTATE_WAKE_MASK_SHIFT 32U +#define CSTATE_WAKE_MASK_CLEAR 0xFFFFFFFFU + +/******************************************************************************* + * Core ID mask (bits 3:0 in the online request) + ******************************************************************************/ +#define MCE_CORE_ID_MASK 0xFU + +/******************************************************************************* + * C-state statistics macros + ******************************************************************************/ +#define MCE_STAT_ID_SHIFT 16U + +/******************************************************************************* + * Security config macros + ******************************************************************************/ +#define STRICT_CHECKING_ENABLED_SET (1UL << 0) +#define STRICT_CHECKING_LOCKED_SET (1UL << 1) + +/* declarations for NVG handler functions */ +uint64_t nvg_get_version(void); +void nvg_set_wake_time(uint32_t wake_time); +void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex, + uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask); +int32_t nvg_set_cstate_stat_query_value(uint64_t data); +uint64_t nvg_get_cstate_stat_query_value(void); +int32_t nvg_is_sc7_allowed(void); +int32_t nvg_online_core(uint32_t core); +int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx); +int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time); +int32_t nvg_roc_clean_cache_trbits(void); +void nvg_enable_strict_checking_mode(void); +void nvg_system_shutdown(void); +void nvg_system_reboot(void); + +/* declarations for assembly functions */ +void nvg_set_request_data(uint64_t req, uint64_t data); +void nvg_set_request(uint64_t req); +uint64_t nvg_get_result(void); +uint64_t nvg_cache_clean(void); +uint64_t nvg_cache_clean_inval(void); +uint64_t nvg_cache_inval_all(void); + +/* MCE helper functions */ +void mce_enable_strict_checking(void); +void mce_system_shutdown(void); +void mce_system_reboot(void); + +#endif /* MCE_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/se.h b/plat/nvidia/tegra/soc/t194/drivers/include/se.h new file mode 100644 index 000000000..e7cf88d05 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/include/se.h @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SE_H +#define SE_H + +int32_t tegra_se_suspend(void); +void tegra_se_resume(void); + +#endif /* SE_H */ diff --git a/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h new file mode 100644 index 000000000..ccc46655a --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/include/t194_nvg.h @@ -0,0 +1,424 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef T194_NVG_H +#define T194_NVG_H + +/** + * t194_nvg.h - Header for the NVIDIA Generic interface (NVG). + * Official documentation for this interface is included as part + * of the T194 TRM. + */ + +/** + * Current version - Major version increments may break backwards + * compatiblity and binary compatibility. Minor version increments + * occur when there is only new functionality. + */ +enum { + TEGRA_NVG_VERSION_MAJOR = 6, + TEGRA_NVG_VERSION_MINOR = 6 +}; + +typedef enum { + TEGRA_NVG_CHANNEL_VERSION = 0, + TEGRA_NVG_CHANNEL_POWER_PERF = 1, + TEGRA_NVG_CHANNEL_POWER_MODES = 2, + TEGRA_NVG_CHANNEL_WAKE_TIME = 3, + TEGRA_NVG_CHANNEL_CSTATE_INFO = 4, + TEGRA_NVG_CHANNEL_CROSSOVER_C6_LOWER_BOUND = 5, + TEGRA_NVG_CHANNEL_CROSSOVER_CC6_LOWER_BOUND = 6, + TEGRA_NVG_CHANNEL_CROSSOVER_CG7_LOWER_BOUND = 8, + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_REQUEST = 10, + TEGRA_NVG_CHANNEL_CSTATE_STAT_QUERY_VALUE = 11, + TEGRA_NVG_CHANNEL_NUM_CORES = 20, + TEGRA_NVG_CHANNEL_UNIQUE_LOGICAL_ID = 21, + TEGRA_NVG_CHANNEL_LOGICAL_TO_PHYSICAL_MAPPING = 22, + TEGRA_NVG_CHANNEL_LOGICAL_TO_MPIDR = 23, + TEGRA_NVG_CHANNEL_SHUTDOWN = 42, + TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED = 43, + TEGRA_NVG_CHANNEL_ONLINE_CORE = 44, + TEGRA_NVG_CHANNEL_CC3_CTRL = 45, + TEGRA_NVG_CHANNEL_CCPLEX_CACHE_CONTROL = 49, + TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC = 50, + TEGRA_NVG_CHANNEL_HSM_ERROR_CTRL = 53, + TEGRA_NVG_CHANNEL_SECURITY_CONFIG = 54, + TEGRA_NVG_CHANNEL_DEBUG_CONFIG = 55, + TEGRA_NVG_CHANNEL_DDA_SNOC_MCF = 56, + TEGRA_NVG_CHANNEL_DDA_MCF_ORD1 = 57, + TEGRA_NVG_CHANNEL_DDA_MCF_ORD2 = 58, + TEGRA_NVG_CHANNEL_DDA_MCF_ORD3 = 59, + TEGRA_NVG_CHANNEL_DDA_MCF_ISO = 60, + TEGRA_NVG_CHANNEL_DDA_MCF_SISO = 61, + TEGRA_NVG_CHANNEL_DDA_MCF_NISO = 62, + TEGRA_NVG_CHANNEL_DDA_MCF_NISO_REMOTE = 63, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_ISO = 64, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_SISO = 65, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO = 66, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_NISO_REMOTE = 67, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3FILL = 68, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3WR = 69, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_L3RD_DMA = 70, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_RSP_MCFRD_DMA = 71, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_GLOBAL = 72, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_LL = 73, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_L3D = 74, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_RD = 75, + TEGRA_NVG_CHANNEL_DDA_L3CTRL_FCM_WR = 76, + TEGRA_NVG_CHANNEL_DDA_SNOC_GLOBAL_CTRL = 77, + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REQ_CTRL = 78, + TEGRA_NVG_CHANNEL_DDA_SNOC_CLIENT_REPLENTISH_CTRL = 79, + + TEGRA_NVG_CHANNEL_LAST_INDEX +} tegra_nvg_channel_id_t; + +typedef enum { + NVG_STAT_QUERY_SC7_ENTRIES = 1, + NVG_STAT_QUERY_CC6_ENTRIES = 6, + NVG_STAT_QUERY_CG7_ENTRIES = 7, + NVG_STAT_QUERY_C6_ENTRIES = 10, + NVG_STAT_QUERY_C7_ENTRIES = 14, + NVG_STAT_QUERY_SC7_RESIDENCY_SUM = 32, + NVG_STAT_QUERY_CC6_RESIDENCY_SUM = 41, + NVG_STAT_QUERY_CG7_RESIDENCY_SUM = 46, + NVG_STAT_QUERY_C6_RESIDENCY_SUM = 51, + NVG_STAT_QUERY_C7_RESIDENCY_SUM = 56, + NVG_STAT_QUERY_SC7_ENTRY_TIME_SUM = 60, + NVG_STAT_QUERY_CC6_ENTRY_TIME_SUM = 61, + NVG_STAT_QUERY_CG7_ENTRY_TIME_SUM = 62, + NVG_STAT_QUERY_C6_ENTRY_TIME_SUM = 63, + NVG_STAT_QUERY_C7_ENTRY_TIME_SUM = 64, + NVG_STAT_QUERY_SC7_EXIT_TIME_SUM = 70, + NVG_STAT_QUERY_CC6_EXIT_TIME_SUM = 71, + NVG_STAT_QUERY_CG7_EXIT_TIME_SUM = 72, + NVG_STAT_QUERY_C6_EXIT_TIME_SUM = 73, + NVG_STAT_QUERY_C7_EXIT_TIME_SUM = 74, + NVG_STAT_QUERY_SC7_ENTRY_LAST = 80, + NVG_STAT_QUERY_CC6_ENTRY_LAST = 81, + NVG_STAT_QUERY_CG7_ENTRY_LAST = 82, + NVG_STAT_QUERY_C6_ENTRY_LAST = 83, + NVG_STAT_QUERY_C7_ENTRY_LAST = 84, + NVG_STAT_QUERY_SC7_EXIT_LAST = 90, + NVG_STAT_QUERY_CC6_EXIT_LAST = 91, + NVG_STAT_QUERY_CG7_EXIT_LAST = 92, + NVG_STAT_QUERY_C6_EXIT_LAST = 93, + NVG_STAT_QUERY_C7_EXIT_LAST = 94 +} tegra_nvg_stat_query_t; + +typedef enum { + TEGRA_NVG_CORE_C0 = 0, + TEGRA_NVG_CORE_C1 = 1, + TEGRA_NVG_CORE_C6 = 6, + TEGRA_NVG_CORE_C7 = 7, + TEGRA_NVG_CORE_WARMRSTREQ = 8 +} tegra_nvg_core_sleep_state_t; + +typedef enum { + TEGRA_NVG_SHUTDOWN = 0U, + TEGRA_NVG_REBOOT = 1U +} tegra_nvg_shutdown_reboot_state_t; + +typedef enum { + TEGRA_NVG_CLUSTER_CC0 = 0, + TEGRA_NVG_CLUSTER_AUTO_CC1 = 1, + TEGRA_NVG_CLUSTER_CC6 = 6 +} tegra_nvg_cluster_sleep_state_t; + +typedef enum { + TEGRA_NVG_CG_CG0 = 0, + TEGRA_NVG_CG_CG7 = 7 +} tegra_nvg_cluster_group_sleep_state_t; + +typedef enum { + TEGRA_NVG_SYSTEM_SC0 = 0, + TEGRA_NVG_SYSTEM_SC7 = 7, + TEGRA_NVG_SYSTEM_SC8 = 8 +} tegra_nvg_system_sleep_state_t; + +// --------------------------------------------------------------------------- +// NVG Data subformats +// --------------------------------------------------------------------------- + +typedef union { + uint64_t flat; + struct nvg_version_channel_t { + uint32_t minor_version : 32; + uint32_t major_version : 32; + } bits; +} nvg_version_data_t; + +typedef union { + uint64_t flat; + struct nvg_power_perf_channel_t { + uint32_t perf_per_watt : 1; + uint32_t reserved_31_1 : 31; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_power_perf_channel_t; + +typedef union { + uint64_t flat; + struct nvg_power_modes_channel_t { + uint32_t low_battery : 1; + uint32_t reserved_1_1 : 1; + uint32_t battery_save : 1; + uint32_t reserved_31_3 : 29; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_power_modes_channel_t; + +typedef union nvg_channel_1_data_u { + uint64_t flat; + struct nvg_channel_1_data_s { + uint32_t perf_per_watt_mode : 1; + uint32_t reserved_31_1 : 31; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_channel_1_data_t; + +typedef union { + uint64_t flat; + struct nvg_ccplex_cache_control_channel_t { + uint32_t gpu_ways : 5; + uint32_t reserved_7_5 : 3; + uint32_t gpu_only_ways : 5; + uint32_t reserved_31_13 : 19; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_ccplex_cache_control_channel_t; + +typedef union nvg_channel_2_data_u { + uint64_t flat; + struct nvg_channel_2_data_s { + uint32_t reserved_1_0 : 2; + uint32_t battery_saver_mode : 1; + uint32_t reserved_31_3 : 29; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_channel_2_data_t; + +typedef union { + uint64_t flat; + struct nvg_wake_time_channel_t { + uint32_t wake_time : 32; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_wake_time_channel_t; + +typedef union { + uint64_t flat; + struct nvg_cstate_info_channel_t { + uint32_t cluster_state : 3; + uint32_t reserved_6_3 : 4; + uint32_t update_cluster : 1; + uint32_t cg_cstate : 3; + uint32_t reserved_14_11 : 4; + uint32_t update_cg : 1; + uint32_t system_cstate : 4; + uint32_t reserved_22_20 : 3; + uint32_t update_system : 1; + uint32_t reserved_30_24 : 7; + uint32_t update_wake_mask : 1; + union { + uint32_t flat : 32; + struct { + uint32_t vfiq : 1; + uint32_t virq : 1; + uint32_t fiq : 1; + uint32_t irq : 1; + uint32_t serror : 1; + uint32_t reserved_10_5 : 6; + uint32_t fiqout : 1; + uint32_t irqout : 1; + uint32_t reserved_31_13 : 19; + } carmel; + } wake_mask; + } bits; +} nvg_cstate_info_channel_t; + +typedef union { + uint64_t flat; + struct nvg_lower_bound_channel_t { + uint32_t crossover_value : 32; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_lower_bound_channel_t; + +typedef union { + uint64_t flat; + struct nvg_cstate_stat_query_channel_t { + uint32_t unit_id : 4; + uint32_t reserved_15_4 : 12; + uint32_t stat_id : 16; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_cstate_stat_query_channel_t; + +typedef union { + uint64_t flat; + struct nvg_num_cores_channel_t { + uint32_t num_cores : 4; + uint32_t reserved_31_4 : 28; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_num_cores_channel_t; + +typedef union { + uint64_t flat; + struct nvg_unique_logical_id_channel_t { + uint32_t unique_core_id : 3; + uint32_t reserved_31_3 : 29; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_unique_logical_id_channel_t; + +typedef union { + uint64_t flat; + struct nvg_logical_to_physical_mappings_channel_t { + uint32_t lcore0_pcore_id : 4; + uint32_t lcore1_pcore_id : 4; + uint32_t lcore2_pcore_id : 4; + uint32_t lcore3_pcore_id : 4; + uint32_t lcore4_pcore_id : 4; + uint32_t lcore5_pcore_id : 4; + uint32_t lcore6_pcore_id : 4; + uint32_t lcore7_pcore_id : 4; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_logical_to_physical_mappings_channel_t; + +typedef union { + uint64_t flat; + struct nvg_logical_to_mpidr_channel_write_t { + uint32_t lcore_id : 3; + uint32_t reserved_31_3 : 29; + uint32_t reserved_63_32 : 32; + } write; + struct nvg_logical_to_mpidr_channel_read_t { + uint32_t mpidr : 32; + uint32_t reserved_63_32 : 32; + } read; +} nvg_logical_to_mpidr_channel_t; + +typedef union { + uint64_t flat; + struct nvg_is_sc7_allowed_channel_t { + uint32_t is_sc7_allowed : 1; + uint32_t reserved_31_1 : 31; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_is_sc7_allowed_channel_t; + +typedef union { + uint64_t flat; + struct nvg_core_online_channel_t { + uint32_t core_id : 4; + uint32_t reserved_31_4 : 28; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_core_online_channel_t; + +typedef union { + uint64_t flat; + struct nvg_cc3_control_channel_t { + uint32_t freq_req : 9; + uint32_t reserved_30_9 : 22; + uint32_t enable : 1; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_cc3_control_channel_t; + +typedef enum { + TEGRA_NVG_CHANNEL_UPDATE_GSC_ALL = 0, + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVDEC = 1, + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR1 = 2, + TEGRA_NVG_CHANNEL_UPDATE_GSC_WPR2 = 3, + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECA = 4, + TEGRA_NVG_CHANNEL_UPDATE_GSC_TSECB = 5, + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP = 6, + TEGRA_NVG_CHANNEL_UPDATE_GSC_APE = 7, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SPE = 8, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SCE = 9, + TEGRA_NVG_CHANNEL_UPDATE_GSC_APR = 10, + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM = 11, + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_TSEC = 12, + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_RCE = 13, + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_MCE = 14, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SE_SC7 = 15, + TEGRA_NVG_CHANNEL_UPDATE_GSC_BPMP_TO_SPE = 16, + TEGRA_NVG_CHANNEL_UPDATE_GSC_RCE = 17, + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_TZ_TO_BPMP = 18, + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR1 = 19, + TEGRA_NVG_CHANNEL_UPDATE_GSC_CPU_NS_TO_BPMP = 20, + TEGRA_NVG_CHANNEL_UPDATE_GSC_OEM_SC7 = 21, + TEGRA_NVG_CHANNEL_UPDATE_GSC_IPC_SE_SPE_SCE_BPMP = 22, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SC7_RESUME_FW = 23, + TEGRA_NVG_CHANNEL_UPDATE_GSC_CAMERA_TASKLIST = 24, + TEGRA_NVG_CHANNEL_UPDATE_GSC_XUSB = 25, + TEGRA_NVG_CHANNEL_UPDATE_GSC_CV = 26, + TEGRA_NVG_CHANNEL_UPDATE_GSC_VM_ENCR2 = 27, + TEGRA_NVG_CHANNEL_UPDATE_GSC_HYPERVISOR_SW = 28, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SMMU_PAGETABLES = 29, + TEGRA_NVG_CHANNEL_UPDATE_GSC_30 = 30, + TEGRA_NVG_CHANNEL_UPDATE_GSC_31 = 31, + TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM = 32, + TEGRA_NVG_CHANNEL_UPDATE_GSC_NVLINK = 33, + TEGRA_NVG_CHANNEL_UPDATE_GSC_SBS = 34, + TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR = 35, + TEGRA_NVG_CHANNEL_UPDATE_GSC_LAST_INDEX +} tegra_nvg_channel_update_gsc_gsc_enum_t; + +typedef union { + uint64_t flat; + struct nvg_update_ccplex_gsc_channel_t { + uint32_t gsc_enum : 16; + uint32_t reserved_31_16 : 16; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_update_ccplex_gsc_channel_t; + +typedef union { + uint64_t flat; + struct nvg_security_config_channel_t { + uint32_t strict_checking_enabled : 1; + uint32_t strict_checking_locked : 1; + uint32_t reserved_31_2 : 30; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_security_config_t; + +typedef union { + uint64_t flat; + struct nvg_shutdown_channel_t { + uint32_t reboot : 1; + uint32_t reserved_31_1 : 31; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_shutdown_t; + +typedef union { + uint64_t flat; + struct nvg_debug_config_channel_t { + uint32_t enter_debug_state_on_mca : 1; + uint32_t reserved_31_1 : 31; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_debug_config_t; + +typedef union { + uint64_t flat; + struct nvg_hsm_error_ctrl_channel_t { + uint32_t uncorr : 1; + uint32_t corr : 1; + uint32_t reserved_31_2 : 30; + uint32_t reserved_63_32 : 32; + } bits; +} nvg_hsm_error_ctrl_channel_t; + +extern nvg_debug_config_t nvg_debug_config; + +#endif + diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S new file mode 100644 index 000000000..3c47208a1 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/aarch64/nvg_helpers.S @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> + + .globl nvg_set_request_data + .globl nvg_set_request + .globl nvg_get_result + .globl nvg_cache_clean + .globl nvg_cache_clean_inval + .globl nvg_cache_inval_all + +/* void nvg_set_request_data(uint64_t req, uint64_t data) */ +func nvg_set_request_data + msr s3_0_c15_c1_2, x0 + msr s3_0_c15_c1_3, x1 + ret +endfunc nvg_set_request_data + +/* void nvg_set_request(uint64_t req) */ +func nvg_set_request + msr s3_0_c15_c1_2, x0 + ret +endfunc nvg_set_request + +/* uint64_t nvg_get_result(void) */ +func nvg_get_result + mrs x0, s3_0_c15_c1_3 + ret +endfunc nvg_get_result + +/* uint64_t nvg_cache_clean(void) */ +func nvg_cache_clean + mrs x0, s3_0_c15_c3_5 + ret +endfunc nvg_cache_clean + +/* uint64_t nvg_cache_clean_inval(void) */ +func nvg_cache_clean_inval + mrs x0, s3_0_c15_c3_6 + ret +endfunc nvg_cache_clean_inval + +/* uint64_t nvg_cache_inval_all(void) */ +func nvg_cache_inval_all + mrs x0, s3_0_c15_c3_7 + ret +endfunc nvg_cache_inval_all
\ No newline at end of file diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c new file mode 100644 index 000000000..00c671bcc --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/mce.c @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/bl_common.h> +#include <context.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <common/debug.h> +#include <denver.h> +#include <mce.h> +#include <mce_private.h> +#include <platform_def.h> +#include <stdbool.h> +#include <string.h> +#include <errno.h> +#include <t194_nvg.h> +#include <tegra_def.h> +#include <tegra_platform.h> +#include <tegra_private.h> + +/* Handler to check if MCE firmware is supported */ +static bool mce_firmware_not_supported(void) +{ + bool status; + + /* these platforms do not load MCE firmware */ + status = tegra_platform_is_linsim() || tegra_platform_is_qt() || + tegra_platform_is_virt_dev_kit(); + + return status; +} + +/******************************************************************************* + * Common handler for all MCE commands + ******************************************************************************/ +int32_t mce_command_handler(uint64_t cmd, uint64_t arg0, uint64_t arg1, + uint64_t arg2) +{ + int32_t ret = 0; + + switch (cmd) { + case (uint64_t)MCE_CMD_ENTER_CSTATE: + ret = nvg_enter_cstate((uint32_t)arg0, (uint32_t)arg1); + if (ret < 0) { + ERROR("%s: enter_cstate failed(%d)\n", __func__, ret); + } + + break; + + case (uint64_t)MCE_CMD_IS_SC7_ALLOWED: + ret = nvg_is_sc7_allowed(); + if (ret < 0) { + ERROR("%s: is_sc7_allowed failed(%d)\n", __func__, ret); + } + + break; + + case (uint64_t)MCE_CMD_ONLINE_CORE: + ret = nvg_online_core((uint32_t)arg0); + if (ret < 0) { + ERROR("%s: online_core failed(%d)\n", __func__, ret); + } + + break; + + default: + ERROR("unknown MCE command (%llu)\n", cmd); + ret = -EINVAL; + break; + } + + return ret; +} + +/******************************************************************************* + * Handler to update carveout values for Video Memory Carveout region + ******************************************************************************/ +int32_t mce_update_gsc_videomem(void) +{ + int32_t ret; + + /* + * MCE firmware is not running on simulation platforms. + */ + if (mce_firmware_not_supported()) { + ret = -EINVAL; + } else { + ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR); + } + + return ret; +} + +/******************************************************************************* + * Handler to update carveout values for TZDRAM aperture + ******************************************************************************/ +int32_t mce_update_gsc_tzdram(void) +{ + int32_t ret; + + /* + * MCE firmware is not running on simulation platforms. + */ + if (mce_firmware_not_supported()) { + ret = -EINVAL; + } else { + ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZ_DRAM); + } + + return ret; +} + +/******************************************************************************* + * Handler to update carveout values for TZ SysRAM aperture + ******************************************************************************/ +int32_t mce_update_gsc_tzram(void) +{ + int32_t ret; + + /* + * MCE firmware is not running on simulation platforms. + */ + if (mce_firmware_not_supported()) { + ret = -EINVAL; + } else { + ret = nvg_update_ccplex_gsc((uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_TZRAM); + } + + return ret; +} + +/******************************************************************************* + * Handler to issue the UPDATE_CSTATE_INFO request + ******************************************************************************/ +void mce_update_cstate_info(const mce_cstate_info_t *cstate) +{ + /* issue the UPDATE_CSTATE_INFO request */ + nvg_update_cstate_info(cstate->cluster, cstate->ccplex, cstate->system, + cstate->wake_mask, cstate->update_wake_mask); +} + +/******************************************************************************* + * Handler to read the MCE firmware version and check if it is compatible + * with interface header the BL3-1 was compiled against + ******************************************************************************/ +void mce_verify_firmware_version(void) +{ + uint64_t version; + uint32_t major, minor; + + /* + * MCE firmware is not running on simulation platforms. + */ + if (mce_firmware_not_supported()) { + return; + } + + /* + * Read the MCE firmware version and extract the major and minor + * version fields + */ + version = nvg_get_version(); + minor = (uint32_t)version; + major = (uint32_t)(version >> 32); + + INFO("MCE Version - HW=%u:%u, SW=%u:%u\n", major, minor, + TEGRA_NVG_VERSION_MAJOR, TEGRA_NVG_VERSION_MINOR); + + /* + * Verify that the MCE firmware version and the interface header + * match + */ + if (major != (uint32_t)TEGRA_NVG_VERSION_MAJOR) { + ERROR("MCE major version mismatch\n"); + panic(); + } + + if (minor < (uint32_t)TEGRA_NVG_VERSION_MINOR) { + ERROR("MCE minor version mismatch\n"); + panic(); + } +} + +#if ENABLE_STRICT_CHECKING_MODE +/******************************************************************************* + * Handler to enable the strict checking mode + ******************************************************************************/ +void mce_enable_strict_checking(void) +{ + uint64_t sctlr = read_sctlr_el3(); + int32_t ret = 0; + + if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) { + /* + * Step1: TZ-DRAM and TZRAM should be setup before the MMU is + * enabled. + * + * The common code makes sure that TZDRAM/TZRAM are already + * enabled before calling into this handler. If this is not the + * case, the following sequence must be executed before moving + * on to step 2. + * + * tlbialle1is(); + * tlbialle3is(); + * dsbsy(); + * isb(); + * + */ + if ((sctlr & (uint64_t)SCTLR_M_BIT) == (uint64_t)SCTLR_M_BIT) { + tlbialle1is(); + tlbialle3is(); + dsbsy(); + isb(); + } + + /* + * Step2: SCF flush - Clean and invalidate caches and clear the + * TR-bits + */ + ret = nvg_roc_clean_cache_trbits(); + if (ret < 0) { + ERROR("%s: flush cache_trbits failed(%d)\n", __func__, + ret); + return; + } + + /* + * Step3: Issue the SECURITY_CONFIG request to MCE to enable + * strict checking mode. + */ + nvg_enable_strict_checking_mode(); + } +} +#endif + +/******************************************************************************* + * Handler to power down the entire system + ******************************************************************************/ +void mce_system_shutdown(void) +{ + nvg_system_shutdown(); +} + +/******************************************************************************* + * Handler to reboot the entire system + ******************************************************************************/ +void mce_system_reboot(void) +{ + nvg_system_reboot(); +} diff --git a/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c new file mode 100644 index 000000000..1012cdf11 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/mce/nvg.c @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <common/debug.h> +#include <denver.h> +#include <errno.h> +#include <lib/mmio.h> +#include <mce_private.h> +#include <platform_def.h> +#include <t194_nvg.h> +#include <tegra_private.h> + +#define ID_AFR0_EL1_CACHE_OPS_SHIFT 12 +#define ID_AFR0_EL1_CACHE_OPS_MASK 0xFU +/* + * Reports the major and minor version of this interface. + * + * NVGDATA[0:31]: SW(R) Minor Version + * NVGDATA[32:63]: SW(R) Major Version + */ +uint64_t nvg_get_version(void) +{ + nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_VERSION); + + return (uint64_t)nvg_get_result(); +} + +/* + * Set the expected wake time in TSC ticks for the next low-power state the + * core enters. + * + * NVGDATA[0:31]: SW(RW), WAKE_TIME + */ +void nvg_set_wake_time(uint32_t wake_time) +{ + /* time (TSC ticks) until the core is expected to get a wake event */ + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_WAKE_TIME, (uint64_t)wake_time); +} + +/* + * This request allows updating of CLUSTER_CSTATE, CCPLEX_CSTATE and + * SYSTEM_CSTATE values. + * + * NVGDATA[0:2]: SW(RW), CLUSTER_CSTATE + * NVGDATA[7]: SW(W), update cluster flag + * NVGDATA[8:10]: SW(RW), CG_CSTATE + * NVGDATA[15]: SW(W), update ccplex flag + * NVGDATA[16:19]: SW(RW), SYSTEM_CSTATE + * NVGDATA[23]: SW(W), update system flag + * NVGDATA[31]: SW(W), update wake mask flag + * NVGDATA[32:63]: SW(RW), WAKE_MASK + */ +void nvg_update_cstate_info(uint32_t cluster, uint32_t ccplex, + uint32_t system, uint32_t wake_mask, uint8_t update_wake_mask) +{ + uint64_t val = 0; + + /* update CLUSTER_CSTATE? */ + if (cluster != 0U) { + val |= ((uint64_t)cluster & CLUSTER_CSTATE_MASK) | + CLUSTER_CSTATE_UPDATE_BIT; + } + + /* update CCPLEX_CSTATE? */ + if (ccplex != 0U) { + val |= (((uint64_t)ccplex & CCPLEX_CSTATE_MASK) << CCPLEX_CSTATE_SHIFT) | + CCPLEX_CSTATE_UPDATE_BIT; + } + + /* update SYSTEM_CSTATE? */ + if (system != 0U) { + val |= (((uint64_t)system & SYSTEM_CSTATE_MASK) << SYSTEM_CSTATE_SHIFT) | + SYSTEM_CSTATE_UPDATE_BIT; + } + + /* update wake mask value? */ + if (update_wake_mask != 0U) { + val |= CSTATE_WAKE_MASK_UPDATE_BIT; + } + + /* set the wake mask */ + val |= ((uint64_t)wake_mask & CSTATE_WAKE_MASK_CLEAR) << CSTATE_WAKE_MASK_SHIFT; + + /* set the updated cstate info */ + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_CSTATE_INFO, val); +} + +/* + * Return a non-zero value if the CCPLEX is able to enter SC7 + * + * NVGDATA[0]: SW(R), Is allowed result + */ +int32_t nvg_is_sc7_allowed(void) +{ + /* issue command to check if SC7 is allowed */ + nvg_set_request((uint64_t)TEGRA_NVG_CHANNEL_IS_SC7_ALLOWED); + + /* 1 = SC7 allowed, 0 = SC7 not allowed */ + return (int32_t)nvg_get_result(); +} + +/* + * Wake an offlined logical core. Note that a core is offlined by entering + * a C-state where the WAKE_MASK is all 0. + * + * NVGDATA[0:3]: SW(W) logical core to online + */ +int32_t nvg_online_core(uint32_t core) +{ + int32_t ret = 0; + + /* sanity check the core ID value */ + if (core > (uint32_t)PLATFORM_CORE_COUNT) { + ERROR("%s: unknown core id (%d)\n", __func__, core); + ret = -EINVAL; + } else { + /* get a core online */ + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_ONLINE_CORE, + (uint64_t)core & MCE_CORE_ID_MASK); + } + + return ret; +} + +/* + * MC GSC (General Security Carveout) register values are expected to be + * changed by TrustZone ARM code after boot. + * + * NVGDATA[0:15] SW(R) GSC enun + */ +int32_t nvg_update_ccplex_gsc(uint32_t gsc_idx) +{ + int32_t ret = 0; + + /* sanity check GSC ID */ + if (gsc_idx > (uint32_t)TEGRA_NVG_CHANNEL_UPDATE_GSC_VPR) { + ERROR("%s: unknown gsc_idx (%u)\n", __func__, gsc_idx); + ret = -EINVAL; + } else { + nvg_set_request_data((uint64_t)TEGRA_NVG_CHANNEL_UPDATE_CCPLEX_GSC, + (uint64_t)gsc_idx); + } + + return ret; +} + +/* + * Cache clean and invalidate, clear TR-bit operation for all CCPLEX caches. + */ +int32_t nvg_roc_clean_cache_trbits(void) +{ + int32_t ret = 0; + + /* check if cache flush through mts is supported */ + if (((read_id_afr0_el1() >> ID_AFR0_EL1_CACHE_OPS_SHIFT) & + ID_AFR0_EL1_CACHE_OPS_MASK) == 1U) { + if (nvg_cache_inval_all() == 0U) { + ERROR("%s: failed\n", __func__); + ret = -ENODEV; + } + } else { + ret = -ENOTSUP; + } + + return ret; +} + +/* + * Set the power state for a core + */ +int32_t nvg_enter_cstate(uint32_t state, uint32_t wake_time) +{ + int32_t ret = 0; + uint64_t val = 0ULL; + + /* check for allowed power state */ + if ((state != (uint32_t)TEGRA_NVG_CORE_C0) && + (state != (uint32_t)TEGRA_NVG_CORE_C1) && + (state != (uint32_t)TEGRA_NVG_CORE_C6) && + (state != (uint32_t)TEGRA_NVG_CORE_C7)) + { + ERROR("%s: unknown cstate (%u)\n", __func__, state); + ret = -EINVAL; + } else { + /* time (TSC ticks) until the core is expected to get a wake event */ + nvg_set_wake_time(wake_time); + + /* set the core cstate */ + val = read_actlr_el1() & ~ACTLR_EL1_PMSTATE_MASK; + write_actlr_el1(val | (uint64_t)state); + } + + return ret; +} + +#if ENABLE_STRICT_CHECKING_MODE +/* + * Enable strict checking mode + * + * NVGDATA[3] strict_check ON + lock + */ +void nvg_enable_strict_checking_mode(void) +{ + uint64_t params = (uint64_t)(STRICT_CHECKING_ENABLED_SET | + STRICT_CHECKING_LOCKED_SET); + + nvg_set_request_data(TEGRA_NVG_CHANNEL_SECURITY_CONFIG, params); +} +#endif + +/* + * Request a reboot + * + * NVGDATA[0]: reboot command + */ +void nvg_system_reboot(void) +{ + /* issue command for reboot */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_REBOOT); +} + +/* + * Request a shutdown + * + * NVGDATA[0]: shutdown command + */ +void nvg_system_shutdown(void) +{ + /* issue command for shutdown */ + nvg_set_request_data(TEGRA_NVG_CHANNEL_SHUTDOWN, TEGRA_NVG_SHUTDOWN); +} diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se.c b/plat/nvidia/tegra/soc/t194/drivers/se/se.c new file mode 100644 index 000000000..3a2e959d0 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se.c @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <errno.h> +#include <stdbool.h> + +#include <arch_helpers.h> +#include <bpmp_ipc.h> +#include <common/debug.h> +#include <drivers/delay_timer.h> +#include <lib/mmio.h> +#include <lib/psci/psci.h> +#include <tegra_platform.h> + +#include "se_private.h" + +/******************************************************************************* + * Constants and Macros + ******************************************************************************/ +#define ERR_STATUS_SW_CLEAR U(0xFFFFFFFF) +#define INT_STATUS_SW_CLEAR U(0xFFFFFFFF) +#define MAX_TIMEOUT_MS U(100) /* Timeout in 100ms */ +#define NUM_SE_REGS_TO_SAVE U(4) + +/******************************************************************************* + * Data structure and global variables + ******************************************************************************/ +static uint32_t se_regs[NUM_SE_REGS_TO_SAVE]; + +/* + * Check that SE operation has completed after kickoff. + * + * This function is invoked after an SE operation has been started, + * and it checks the following conditions: + * + * 1. SE_STATUS = IDLE + * 2. AHB bus data transfer is complete. + * 3. SE_ERR_STATUS is clean. + */ +static bool tegra_se_is_operation_complete(void) +{ + uint32_t val = 0, timeout = 0, sha_status, aes_status; + int32_t ret = 0; + bool se_is_busy, txn_has_errors, txn_successful; + + /* + * Poll the status register to check if the operation + * completed. + */ + do { + val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); + se_is_busy = !!(val & CTX_SAVE_AUTO_SE_BUSY); + + /* sleep until SE finishes */ + if (se_is_busy) { + mdelay(1); + timeout++; + } + + } while (se_is_busy && (timeout < MAX_TIMEOUT_MS)); + + /* any transaction errors? */ + txn_has_errors = (tegra_se_read_32(SHA_ERR_STATUS) != 0U) || + (tegra_se_read_32(AES0_ERR_STATUS) != 0U); + + /* transaction successful? */ + sha_status = tegra_se_read_32(SHA_INT_STATUS) & SHA_SE_OP_DONE; + aes_status = tegra_se_read_32(AES0_INT_STATUS) & AES0_SE_OP_DONE; + txn_successful = (sha_status == SHA_SE_OP_DONE) && + (aes_status == AES0_SE_OP_DONE); + + if ((timeout == MAX_TIMEOUT_MS) || txn_has_errors || !txn_successful) { + ERROR("%s: Atomic context save operation failed!\n", + __func__); + ret = -ECANCELED; + } + + return (ret == 0); +} + +/* + * Wait for SE engine to be idle and clear any pending interrupts, before + * starting the next SE operation. + */ +static bool tegra_se_is_ready(void) +{ + int32_t ret = 0; + uint32_t val = 0, timeout = 0; + bool se_is_ready; + + /* Wait for previous operation to finish */ + do { + val = tegra_se_read_32(CTX_SAVE_AUTO_STATUS); + se_is_ready = (val == CTX_SAVE_AUTO_SE_READY); + + /* sleep until SE is ready */ + if (!se_is_ready) { + mdelay(1); + timeout++; + } + + } while (!se_is_ready && (timeout < MAX_TIMEOUT_MS)); + + if (timeout == MAX_TIMEOUT_MS) { + ERROR("%s: SE is not ready!\n", __func__); + ret = -ETIMEDOUT; + } + + /* Clear any pending interrupts from previous operation */ + tegra_se_write_32(AES0_INT_STATUS, INT_STATUS_SW_CLEAR); + tegra_se_write_32(AES1_INT_STATUS, INT_STATUS_SW_CLEAR); + tegra_se_write_32(RSA_INT_STATUS, INT_STATUS_SW_CLEAR); + tegra_se_write_32(SHA_INT_STATUS, INT_STATUS_SW_CLEAR); + + /* Clear error status for each engine seen from current port */ + tegra_se_write_32(AES0_ERR_STATUS, ERR_STATUS_SW_CLEAR); + tegra_se_write_32(AES1_ERR_STATUS, ERR_STATUS_SW_CLEAR); + tegra_se_write_32(RSA_ERR_STATUS, ERR_STATUS_SW_CLEAR); + tegra_se_write_32(SHA_ERR_STATUS, ERR_STATUS_SW_CLEAR); + + return (ret == 0); +} + +/* + * During System Suspend, this handler triggers the hardware context + * save operation. + */ +static int32_t tegra_se_save_context(void) +{ + int32_t ret = -ECANCELED; + + /* + * 1. Ensure all SE Driver including RNG1/PKA1 are shut down. + * TSEC/R5s are powergated/idle. All tasks on SE1~SE4, RNG1, + * PKA1 are wrapped up. SE0 is ready for use. + * 2. Clear interrupt/error in SE0 status register. + * 3. Scrub SE0 register to avoid false failure for illegal + * configuration. Probably not needed, dependent on HW + * implementation. + * 4. Check SE is ready for HW CTX_SAVE by polling + * SE_CTX_SAVE_AUTO_STATUS.SE_READY. + * + * Steps 1-4 are executed by tegra_se_is_ready(). + * + * 5. Issue context save command. + * 6. Check SE is busy with CTX_SAVE, the command in step5 was not + * dropped for ongoing traffic in any of SE port/engine. + * 7. Poll SE register or wait for SE APB interrupt for task completion + * a. Polling: Read SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE + * b. Interrupt: After receiving interrupt from SE APB, read + * SE_CTX_SAVE_AUTO_STATUS.BUSY till it reports IDLE. + * 8. Check AES0 and SHA ERR_STATUS to ensure no error case. + * 9. Check AES0 and SHA INT_STATUS to ensure operation has successfully + * completed. + * + * Steps 6-9 are executed by tegra_se_is_operation_complete(). + */ + if (tegra_se_is_ready()) { + + /* Issue context save command */ + tegra_se_write_32(AES0_OPERATION, SE_OP_CTX_SAVE); + + /* Wait for operation to finish */ + if (tegra_se_is_operation_complete()) { + ret = 0; + } + } + + return ret; +} + +/* + * Handler to power down the SE hardware blocks - SE, RNG1 and PKA1. This + * needs to be called only during System Suspend. + */ +int32_t tegra_se_suspend(void) +{ + int32_t ret = 0; + + /* initialise communication channel with BPMP */ + assert(tegra_bpmp_ipc_init() == 0); + + /* Enable SE clock before SE context save */ + tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + + /* save SE registers */ + se_regs[0] = mmio_read_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT); + se_regs[1] = mmio_read_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL); + se_regs[2] = mmio_read_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT); + se_regs[3] = mmio_read_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT); + + /* Save SE context. The BootROM restores it during System Resume */ + ret = tegra_se_save_context(); + if (ret != 0) { + ERROR("%s: context save failed (%d)\n", __func__, ret); + } + + /* Disable SE clock after SE context save */ + tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); + + return ret; +} + +/* + * Handler to power up the SE hardware block(s) during System Resume. + */ +void tegra_se_resume(void) +{ + /* initialise communication channel with BPMP */ + assert(tegra_bpmp_ipc_init() == 0); + + /* Enable SE clock before SE context restore */ + tegra_bpmp_ipc_enable_clock(TEGRA_CLK_SE); + + /* + * When TZ takes over after System Resume, TZ should first reconfigure + * SE_MUTEX_WATCHDOG_NS_LIMIT, PKA1_MUTEX_WATCHDOG_NS_LIMIT, + * RNG1_MUTEX_WATCHDOG_NS_LIMIT and SE_ENTROPY_SRC_AGE_CTRL before + * other operations. + */ + mmio_write_32(TEGRA_SE0_BASE + SE0_MUTEX_WATCHDOG_NS_LIMIT, se_regs[0]); + mmio_write_32(TEGRA_SE0_BASE + SE0_AES0_ENTROPY_SRC_AGE_CTRL, se_regs[1]); + mmio_write_32(TEGRA_RNG1_BASE + RNG1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[2]); + mmio_write_32(TEGRA_PKA1_BASE + PKA1_MUTEX_WATCHDOG_NS_LIMIT, se_regs[3]); + + /* Disable SE clock after SE context restore */ + tegra_bpmp_ipc_disable_clock(TEGRA_CLK_SE); +} diff --git a/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h new file mode 100644 index 000000000..a2c5d1c38 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/drivers/se/se_private.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SE_PRIVATE_H +#define SE_PRIVATE_H + +#include <lib/utils_def.h> + +/* SE0_INT_ENABLE_0 */ +#define SE0_INT_ENABLE U(0x88) +#define SE0_DISABLE_ALL_INT U(0x0) + +/* SE0_INT_STATUS_0 */ +#define SE0_INT_STATUS U(0x8C) +#define SE0_CLEAR_ALL_INT_STATUS U(0x3F) + +/* SE0_SHA_INT_STATUS_0 */ +#define SHA_INT_STATUS U(0x184) +#define SHA_SE_OP_DONE (U(1) << 4) + +/* SE0_SHA_ERR_STATUS_0 */ +#define SHA_ERR_STATUS U(0x18C) + +/* SE0_AES0_INT_STATUS_0 */ +#define AES0_INT_STATUS U(0x2F0) +#define AES0_SE_OP_DONE (U(1) << 4) + +/* SE0_AES0_ERR_STATUS_0 */ +#define AES0_ERR_STATUS U(0x2F8) + +/* SE0_AES1_INT_STATUS_0 */ +#define AES1_INT_STATUS U(0x4F0) + +/* SE0_AES1_ERR_STATUS_0 */ +#define AES1_ERR_STATUS U(0x4F8) + +/* SE0_RSA_INT_STATUS_0 */ +#define RSA_INT_STATUS U(0x758) + +/* SE0_RSA_ERR_STATUS_0 */ +#define RSA_ERR_STATUS U(0x760) + +/* SE0_AES0_OPERATION_0 */ +#define AES0_OPERATION U(0x238) +#define OP_MASK_BITS U(0x7) +#define SE_OP_CTX_SAVE U(0x3) + +/* SE0_AES0_CTX_SAVE_CONFIG_0 */ +#define CTX_SAVE_CONFIG U(0x2D4) + +/* SE0_AES0_CTX_SAVE_AUTO_STATUS_0 */ +#define CTX_SAVE_AUTO_STATUS U(0x300) +#define CTX_SAVE_AUTO_SE_READY U(0xFF) +#define CTX_SAVE_AUTO_SE_BUSY (U(0x1) << 31) + +/* SE0_AES0_CTX_SAVE_AUTO_CTRL_0 */ +#define CTX_SAVE_AUTO_CTRL U(0x304) +#define SE_CTX_SAVE_AUTO_EN (U(0x1) << 0) +#define SE_CTX_SAVE_AUTO_LOCK_EN (U(0x1) << 1) + +/* SE0_AES0_CTX_SAVE_AUTO_START_ADDR_0 */ +#define CTX_SAVE_AUTO_START_ADDR U(0x308) + +/* SE0_AES0_CTX_SAVE_AUTO_START_ADDR_HI_0 */ +#define CTX_SAVE_AUTO_START_ADDR_HI U(0x30C) + +/******************************************************************************* + * Inline functions definition + ******************************************************************************/ + +static inline uint32_t tegra_se_read_32(uint32_t offset) +{ + return mmio_read_32(TEGRA_SE0_BASE + offset); +} + +static inline void tegra_se_write_32(uint32_t offset, uint32_t val) +{ + mmio_write_32(TEGRA_SE0_BASE + offset, val); +} + +#endif /* SE_PRIVATE_H */ diff --git a/plat/nvidia/tegra/soc/t194/plat_memctrl.c b/plat/nvidia/tegra/soc/t194/plat_memctrl.c new file mode 100644 index 000000000..bb1dd6706 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_memctrl.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <common/bl_common.h> +#include <mce.h> +#include <memctrl_v2.h> +#include <tegra_mc_def.h> +#include <tegra_platform.h> + +/******************************************************************************* + * Array to hold stream_id override config register offsets + ******************************************************************************/ +const static uint32_t tegra194_streamid_override_regs[] = { + MC_STREAMID_OVERRIDE_CFG_HDAR, + MC_STREAMID_OVERRIDE_CFG_HOST1XDMAR, + MC_STREAMID_OVERRIDE_CFG_NVENCSRD, + MC_STREAMID_OVERRIDE_CFG_SATAR, + MC_STREAMID_OVERRIDE_CFG_NVENCSWR, + MC_STREAMID_OVERRIDE_CFG_HDAW, + MC_STREAMID_OVERRIDE_CFG_SATAW, + MC_STREAMID_OVERRIDE_CFG_ISPRA, + MC_STREAMID_OVERRIDE_CFG_ISPFALR, + MC_STREAMID_OVERRIDE_CFG_ISPWA, + MC_STREAMID_OVERRIDE_CFG_ISPWB, + MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTR, + MC_STREAMID_OVERRIDE_CFG_XUSB_HOSTW, + MC_STREAMID_OVERRIDE_CFG_XUSB_DEVR, + MC_STREAMID_OVERRIDE_CFG_XUSB_DEVW, + MC_STREAMID_OVERRIDE_CFG_TSECSRD, + MC_STREAMID_OVERRIDE_CFG_TSECSWR, + MC_STREAMID_OVERRIDE_CFG_SDMMCRA, + MC_STREAMID_OVERRIDE_CFG_SDMMCR, + MC_STREAMID_OVERRIDE_CFG_SDMMCRAB, + MC_STREAMID_OVERRIDE_CFG_SDMMCWA, + MC_STREAMID_OVERRIDE_CFG_SDMMCW, + MC_STREAMID_OVERRIDE_CFG_SDMMCWAB, + MC_STREAMID_OVERRIDE_CFG_VICSRD, + MC_STREAMID_OVERRIDE_CFG_VICSWR, + MC_STREAMID_OVERRIDE_CFG_VIW, + MC_STREAMID_OVERRIDE_CFG_NVDECSRD, + MC_STREAMID_OVERRIDE_CFG_NVDECSWR, + MC_STREAMID_OVERRIDE_CFG_APER, + MC_STREAMID_OVERRIDE_CFG_APEW, + MC_STREAMID_OVERRIDE_CFG_NVJPGSRD, + MC_STREAMID_OVERRIDE_CFG_NVJPGSWR, + MC_STREAMID_OVERRIDE_CFG_SESRD, + MC_STREAMID_OVERRIDE_CFG_SESWR, + MC_STREAMID_OVERRIDE_CFG_AXIAPR, + MC_STREAMID_OVERRIDE_CFG_AXIAPW, + MC_STREAMID_OVERRIDE_CFG_ETRR, + MC_STREAMID_OVERRIDE_CFG_ETRW, + MC_STREAMID_OVERRIDE_CFG_TSECSRDB, + MC_STREAMID_OVERRIDE_CFG_TSECSWRB, + MC_STREAMID_OVERRIDE_CFG_AXISR, + MC_STREAMID_OVERRIDE_CFG_AXISW, + MC_STREAMID_OVERRIDE_CFG_EQOSR, + MC_STREAMID_OVERRIDE_CFG_EQOSW, + MC_STREAMID_OVERRIDE_CFG_UFSHCR, + MC_STREAMID_OVERRIDE_CFG_UFSHCW, + MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR, + MC_STREAMID_OVERRIDE_CFG_BPMPR, + MC_STREAMID_OVERRIDE_CFG_BPMPW, + MC_STREAMID_OVERRIDE_CFG_BPMPDMAR, + MC_STREAMID_OVERRIDE_CFG_BPMPDMAW, + MC_STREAMID_OVERRIDE_CFG_AONR, + MC_STREAMID_OVERRIDE_CFG_AONW, + MC_STREAMID_OVERRIDE_CFG_AONDMAR, + MC_STREAMID_OVERRIDE_CFG_AONDMAW, + MC_STREAMID_OVERRIDE_CFG_SCER, + MC_STREAMID_OVERRIDE_CFG_SCEW, + MC_STREAMID_OVERRIDE_CFG_SCEDMAR, + MC_STREAMID_OVERRIDE_CFG_SCEDMAW, + MC_STREAMID_OVERRIDE_CFG_APEDMAR, + MC_STREAMID_OVERRIDE_CFG_APEDMAW, + MC_STREAMID_OVERRIDE_CFG_NVDISPLAYR1, + MC_STREAMID_OVERRIDE_CFG_VICSRD1, + MC_STREAMID_OVERRIDE_CFG_NVDECSRD1, + MC_STREAMID_OVERRIDE_CFG_VIFALR, + MC_STREAMID_OVERRIDE_CFG_VIFALW, + MC_STREAMID_OVERRIDE_CFG_DLA0RDA, + MC_STREAMID_OVERRIDE_CFG_DLA0FALRDB, + MC_STREAMID_OVERRIDE_CFG_DLA0WRA, + MC_STREAMID_OVERRIDE_CFG_DLA0FALWRB, + MC_STREAMID_OVERRIDE_CFG_DLA1RDA, + MC_STREAMID_OVERRIDE_CFG_DLA1FALRDB, + MC_STREAMID_OVERRIDE_CFG_DLA1WRA, + MC_STREAMID_OVERRIDE_CFG_DLA1FALWRB, + MC_STREAMID_OVERRIDE_CFG_PVA0RDA, + MC_STREAMID_OVERRIDE_CFG_PVA0RDB, + MC_STREAMID_OVERRIDE_CFG_PVA0RDC, + MC_STREAMID_OVERRIDE_CFG_PVA0WRA, + MC_STREAMID_OVERRIDE_CFG_PVA0WRB, + MC_STREAMID_OVERRIDE_CFG_PVA0WRC, + MC_STREAMID_OVERRIDE_CFG_PVA1RDA, + MC_STREAMID_OVERRIDE_CFG_PVA1RDB, + MC_STREAMID_OVERRIDE_CFG_PVA1RDC, + MC_STREAMID_OVERRIDE_CFG_PVA1WRA, + MC_STREAMID_OVERRIDE_CFG_PVA1WRB, + MC_STREAMID_OVERRIDE_CFG_PVA1WRC, + MC_STREAMID_OVERRIDE_CFG_RCER, + MC_STREAMID_OVERRIDE_CFG_RCEW, + MC_STREAMID_OVERRIDE_CFG_RCEDMAR, + MC_STREAMID_OVERRIDE_CFG_RCEDMAW, + MC_STREAMID_OVERRIDE_CFG_NVENC1SRD, + MC_STREAMID_OVERRIDE_CFG_NVENC1SWR, + MC_STREAMID_OVERRIDE_CFG_PCIE0R, + MC_STREAMID_OVERRIDE_CFG_PCIE0W, + MC_STREAMID_OVERRIDE_CFG_PCIE1R, + MC_STREAMID_OVERRIDE_CFG_PCIE1W, + MC_STREAMID_OVERRIDE_CFG_PCIE2AR, + MC_STREAMID_OVERRIDE_CFG_PCIE2AW, + MC_STREAMID_OVERRIDE_CFG_PCIE3R, + MC_STREAMID_OVERRIDE_CFG_PCIE3W, + MC_STREAMID_OVERRIDE_CFG_PCIE4R, + MC_STREAMID_OVERRIDE_CFG_PCIE4W, + MC_STREAMID_OVERRIDE_CFG_PCIE5R, + MC_STREAMID_OVERRIDE_CFG_PCIE5W, + MC_STREAMID_OVERRIDE_CFG_ISPFALW, + MC_STREAMID_OVERRIDE_CFG_DLA0RDA1, + MC_STREAMID_OVERRIDE_CFG_DLA1RDA1, + MC_STREAMID_OVERRIDE_CFG_PVA0RDA1, + MC_STREAMID_OVERRIDE_CFG_PVA0RDB1, + MC_STREAMID_OVERRIDE_CFG_PVA1RDA1, + MC_STREAMID_OVERRIDE_CFG_PVA1RDB1, + MC_STREAMID_OVERRIDE_CFG_PCIE5R1, + MC_STREAMID_OVERRIDE_CFG_NVENCSRD1, + MC_STREAMID_OVERRIDE_CFG_NVENC1SRD1, + MC_STREAMID_OVERRIDE_CFG_ISPRA1, + MC_STREAMID_OVERRIDE_CFG_PCIE0R1, + MC_STREAMID_OVERRIDE_CFG_MIU0R, + MC_STREAMID_OVERRIDE_CFG_MIU0W, + MC_STREAMID_OVERRIDE_CFG_MIU1R, + MC_STREAMID_OVERRIDE_CFG_MIU1W, + MC_STREAMID_OVERRIDE_CFG_MIU2R, + MC_STREAMID_OVERRIDE_CFG_MIU2W, + MC_STREAMID_OVERRIDE_CFG_MIU3R, + MC_STREAMID_OVERRIDE_CFG_MIU3W +}; + +/******************************************************************************* + * Array to hold the security configs for stream IDs + ******************************************************************************/ +const static mc_streamid_security_cfg_t tegra194_streamid_sec_cfgs[] = { + mc_make_sec_cfg(HDAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(HOST1XDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENCSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SATAR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENCSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(HDAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SATAW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPRA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPFALR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPWA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPWB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_HOSTR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_HOSTW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_DEVR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(XUSB_DEVW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCRA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCRAB, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWA, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(SDMMCWAB, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VIW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVJPGSWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SESRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SESWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AXIAPR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(AXIAPW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ETRW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(TSECSWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AXISR, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(AXISW, SECURE, NO_OVERRIDE, DISABLE), + mc_make_sec_cfg(EQOSR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(EQOSW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(UFSHCW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDISPLAYR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(BPMPDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AONR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AONW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AONDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(AONDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SCER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SCEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(SCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(APEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDISPLAYR1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(VICSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVDECSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VIFALR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(VIFALW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA1FALRDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA1FALWRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0RDA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0RDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0RDC, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0WRA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0WRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0WRC, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1RDA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1RDB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1RDC, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1WRA, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1WRB, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1WRC, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(RCER, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(RCEW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(RCEDMAR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(RCEDMAW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENC1SRD, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENC1SWR, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE0R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE0W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE1R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE1W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE2AR, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE2AW, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE3R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE3W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE4R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE4W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE5R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE5W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPFALW, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(DLA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA0RDB1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1RDA1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PVA1RDB1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE5R1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENCSRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(NVENC1SRD1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(ISPRA1, NON_SECURE, NO_OVERRIDE, ENABLE), + mc_make_sec_cfg(PCIE0R1, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU0R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU0W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU1R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU1W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU2R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU2W, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU3R, NON_SECURE, OVERRIDE, ENABLE), + mc_make_sec_cfg(MIU3W, NON_SECURE, OVERRIDE, ENABLE), +}; + +/* To be called by common memctrl_v2.c */ +static void tegra194_memctrl_reconfig_mss_clients(void) +{ + uint32_t reg_val, wdata_0, wdata_1, wdata_2; + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_HC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_SATA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_VIC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_HOST_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_XUSB_DEV_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_TSEC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL0_SDMMC3A_FLUSH_ENB; + if (tegra_platform_is_silicon()) { + wdata_0 |= MC_CLIENT_HOTRESET_CTRL0_SDMMC1A_FLUSH_ENB; + } + + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS0); + } while ((reg_val & wdata_0) != wdata_0); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_SDMMC4A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_ETR_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_TSECB_FLUSH_ENB| + MC_CLIENT_HOTRESET_CTRL1_AXIS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_UFSHC_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_NVDISPLAY_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_BPMP_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_AON_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_SCE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_VIFAL_FLUSH_ENB; + if (tegra_platform_is_silicon()) { + wdata_1 |= MC_CLIENT_HOTRESET_CTRL1_APE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_EQOS_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL1_RCE_FLUSH_ENB; + } + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS1); + } while ((reg_val & wdata_1) != wdata_1); + + wdata_2 = MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_AONDMA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_BPMPDMA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_SCEDMA_FLUSH_ENB; + if (tegra_platform_is_silicon()) { + wdata_2 |= MC_CLIENT_HOTRESET_CTRL2_RCEDMA_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE5A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE3A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE3_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE0A_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE0A2_FLUSH_ENB | + MC_CLIENT_HOTRESET_CTRL2_PCIE4A_FLUSH_ENB; + } + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2); + /* Wait for HOTRESET STATUS to indicate FLUSH_DONE */ + do { + reg_val = tegra_mc_read_32(MC_CLIENT_HOTRESET_STATUS2); + } while ((reg_val & wdata_2) != wdata_2); + + /* + * Change MEMTYPE_OVERRIDE from SO_DEV -> PASSTHRU for boot and + * strongly ordered MSS clients. + * + * MC clients with default SO_DEV override still enabled at TSA: + * EQOSW, SATAW, XUSB_DEVW, XUSB_HOSTW, PCIe0w, PCIe1w, PCIe2w, + * PCIe3w, PCIe4w and PCIe5w. + */ + mc_set_tsa_w_passthrough(AONDMAW); + mc_set_tsa_w_passthrough(AONW); + mc_set_tsa_w_passthrough(APEDMAW); + mc_set_tsa_w_passthrough(APEW); + mc_set_tsa_w_passthrough(AXISW); + mc_set_tsa_w_passthrough(BPMPDMAW); + mc_set_tsa_w_passthrough(BPMPW); + mc_set_tsa_w_passthrough(EQOSW); + mc_set_tsa_w_passthrough(ETRW); + mc_set_tsa_w_passthrough(RCEDMAW); + mc_set_tsa_w_passthrough(RCEW); + mc_set_tsa_w_passthrough(SCEDMAW); + mc_set_tsa_w_passthrough(SCEW); + mc_set_tsa_w_passthrough(SDMMCW); + mc_set_tsa_w_passthrough(SDMMCWA); + mc_set_tsa_w_passthrough(SDMMCWAB); + mc_set_tsa_w_passthrough(SESWR); + mc_set_tsa_w_passthrough(TSECSWR); + mc_set_tsa_w_passthrough(TSECSWRB); + mc_set_tsa_w_passthrough(UFSHCW); + mc_set_tsa_w_passthrough(VICSWR); + mc_set_tsa_w_passthrough(VIFALW); + /* + * set HUB2 as SO_DEV_HUBID + */ + reg_val = tsa_read_32(PCIE0W); + mc_set_tsa_hub2(reg_val, PCIE0W); + reg_val = tsa_read_32(PCIE1W); + mc_set_tsa_hub2(reg_val, PCIE1W); + reg_val = tsa_read_32(PCIE2AW); + mc_set_tsa_hub2(reg_val, PCIE2AW); + reg_val = tsa_read_32(PCIE3W); + mc_set_tsa_hub2(reg_val, PCIE3W); + reg_val = tsa_read_32(PCIE4W); + mc_set_tsa_hub2(reg_val, PCIE4W); + reg_val = tsa_read_32(SATAW); + mc_set_tsa_hub2(reg_val, SATAW); + reg_val = tsa_read_32(XUSB_DEVW); + mc_set_tsa_hub2(reg_val, XUSB_DEVW); + reg_val = tsa_read_32(XUSB_HOSTW); + mc_set_tsa_hub2(reg_val, XUSB_HOSTW); + + /* + * Hw Bug: 200385660, 200394107 + * PCIE datapath hangs when there are more than 28 outstanding + * requests on data backbone for x1 controller. This is seen + * on third party PCIE IP, C1 - PCIE1W, C2 - PCIE2AW and C3 - PCIE3W. + * + * Setting Reorder depth limit, 16 which is < 28. + */ + mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE1W); + mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE2AW); + mc_set_tsa_depth_limit(REORDER_DEPTH_LIMIT, PCIE3W); + + /* Ordered MC Clients on Xavier are EQOS, SATA, XUSB, PCIe1 and PCIe3 + * ISO clients(DISP, VI, EQOS) should never snoop caches and + * don't need ROC/PCFIFO ordering. + * ISO clients(EQOS) that need ordering should use PCFIFO ordering + * and bypass ROC ordering by using FORCE_NON_COHERENT path. + * FORCE_NON_COHERENT/FORCE_COHERENT config take precedence + * over SMMU attributes. + * Force all Normal memory transactions from ISO and non-ISO to be + * non-coherent(bypass ROC, avoid cache snoop to avoid perf hit). + * Force the SO_DEV transactions from ordered ISO clients(EQOS) to + * non-coherent path and enable MC PCFIFO interlock for ordering. + * Force the SO_DEV transactions from ordered non-ISO clients (PCIe, + * XUSB, SATA) to coherent so that the transactions are + * ordered by ROC. + * PCFIFO ensure write ordering. + * Read after Write ordering is maintained/enforced by MC clients. + * Clients that need PCIe type write ordering must + * go through ROC ordering. + * Ordering enable for Read clients is not necessary. + * R5's and A9 would get necessary ordering from AXI and + * don't need ROC ordering enable: + * - MMIO ordering is through dev mapping and MMIO + * accesses bypass SMMU. + * - Normal memory is accessed through SMMU and ordering is + * ensured by client and AXI. + * - Ack point for Normal memory is WCAM in MC. + * - MMIO's can be early acked and AXI ensures dev memory ordering, + * Client ensures read/write direction change ordering. + * - See Bug 200312466 for more details. + */ + mc_set_txn_override(AONDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(AONDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(AONR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(AONW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(APEDMAR, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(APEDMAW, CGID_TAG_ADR, SO_DEV_CLIENT_AXI_ID, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(APER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(APEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(AXISR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(AXISW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(BPMPDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(BPMPDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(BPMPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(BPMPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(EQOSR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(EQOSW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ETRR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ETRW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(HOST1XDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(MPCORER, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MPCOREW, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(NVDISPLAYR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(NVDISPLAYR1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(PCIE0R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE0R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE0W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE1R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE1W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + if (tegra_platform_is_silicon()) { + mc_set_txn_override(PCIE2AR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE2AW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE3R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE3W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE4R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE4W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE5R, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE5W, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(PCIE5R1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + } + mc_set_txn_override(PTCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(RCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(RCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(RCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(RCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SATAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(SATAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(SCEDMAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SCEDMAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SCER, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SCEW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCRAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(SDMMCWAB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + /* + * TO DO: make SESRD/WR FORCE_COHERENT once SE+TZ with SMMU is enabled. + */ + mc_set_txn_override(SESRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(SESWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(TSECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(TSECSRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(TSECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(TSECSWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(UFSHCR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(UFSHCW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(VICSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(VICSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(VICSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(VIFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(VIFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(XUSB_DEVR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(XUSB_DEVW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(XUSB_HOSTR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(XUSB_HOSTW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT_SNOOP, FORCE_COHERENT_SNOOP); + mc_set_txn_override(AXIAPR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(AXIAPW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA0FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA0FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA1FALRDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA1FALWRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(DLA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(HDAR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(HDAW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + mc_set_txn_override(ISPFALR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ISPFALW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ISPRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ISPRA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ISPWA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(ISPWB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDEC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDEC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDEC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDECSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDECSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVDECSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENC1SRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENC1SRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENC1SWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENCSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENCSRD1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVENCSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVJPGSRD, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(NVJPGSWR, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA0WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1RDA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1RDA1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1RDB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1RDB1, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1RDC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1WRA, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1WRB, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(PVA1WRC, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_COHERENT, FORCE_COHERENT); + mc_set_txn_override(VIW, CGID_TAG_ADR, SO_DEV_ZERO, FORCE_NON_COHERENT, FORCE_NON_COHERENT); + + if (tegra_platform_is_silicon()) { + mc_set_txn_override(MIU0R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU0W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU1R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU1W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU2R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU2W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU3R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU3W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU4R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU4W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU5R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU5W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU6R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU6W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU7R, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + mc_set_txn_override(MIU7W, CGID_TAG_ADR, SO_DEV_ZERO, NO_OVERRIDE, NO_OVERRIDE); + } + + /* + * At this point, ordering can occur at SCF. So, remove PCFIFO's + * control over ordering requests. + * + * Change PCFIFO_*_ORDERED_CLIENT from ORDERED -> UNORDERED for + * boot and strongly ordered MSS clients + */ + reg_val = MC_PCFIFO_CLIENT_CONFIG2_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(2, XUSB_HOSTW) & + mc_set_pcfifo_unordered_boot_so_mss(2, TSECSWR); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG2, reg_val); + + reg_val = MC_PCFIFO_CLIENT_CONFIG3_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWA) & + mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCW) & + mc_set_pcfifo_unordered_boot_so_mss(3, SDMMCWAB) & + mc_set_pcfifo_unordered_boot_so_mss(3, VICSWR) & + mc_set_pcfifo_unordered_boot_so_mss(3, APEW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG3, reg_val); + + reg_val = MC_PCFIFO_CLIENT_CONFIG4_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(4, SESWR) & + mc_set_pcfifo_unordered_boot_so_mss(4, ETRW) & + mc_set_pcfifo_unordered_boot_so_mss(4, TSECSWRB) & + mc_set_pcfifo_unordered_boot_so_mss(4, AXISW) & + mc_set_pcfifo_unordered_boot_so_mss(4, UFSHCW) & + mc_set_pcfifo_unordered_boot_so_mss(4, BPMPW) & + mc_set_pcfifo_unordered_boot_so_mss(4, BPMPDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AONW) & + mc_set_pcfifo_unordered_boot_so_mss(4, AONDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(4, SCEW) & + mc_set_pcfifo_unordered_boot_so_mss(4, SCEDMAW); + /* EQOSW has PCFIFO order enabled. */ + reg_val |= mc_set_pcfifo_unordered_boot_so_mss(4, EQOSW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG4, reg_val); + + reg_val = MC_PCFIFO_CLIENT_CONFIG5_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(5, APEDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(5, VIFALW); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG5, reg_val); + + reg_val = MC_PCFIFO_CLIENT_CONFIG6_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(6, RCEW) & + mc_set_pcfifo_unordered_boot_so_mss(6, RCEDMAW) & + mc_set_pcfifo_unordered_boot_so_mss(6, PCIE0W); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG6, reg_val); + + reg_val = MC_PCFIFO_CLIENT_CONFIG7_RESET_VAL & + mc_set_pcfifo_unordered_boot_so_mss(7, PCIE4W) & + mc_set_pcfifo_unordered_boot_so_mss(7, PCIE5W); + tegra_mc_write_32(MC_PCFIFO_CLIENT_CONFIG7, reg_val); + + /* Set Order Id only for the clients having non zero order id */ + reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_9_RESET_VAL, 9, XUSB_HOSTW); + tegra_mc_write_32(MC_CLIENT_ORDER_ID_9, reg_val); + + reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_27_RESET_VAL, 27, PCIE0W); + tegra_mc_write_32(MC_CLIENT_ORDER_ID_27, reg_val); + + reg_val = mc_client_order_id(MC_CLIENT_ORDER_ID_28_RESET_VAL, 28, PCIE4W); + reg_val = mc_client_order_id(reg_val, 28, PCIE5W); + tegra_mc_write_32(MC_CLIENT_ORDER_ID_28, reg_val); + + /* + * Set VC Id only for the clients having different reset values like + * SDMMCRAB, SDMMCWAB, SESRD, SESWR, TSECSRD,TSECSRDB, TSECSWR and + * TSECSWRB clients + */ + reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_0_RESET_VAL, 0, APB); + tegra_mc_write_32(MC_HUB_PC_VC_ID_0, reg_val); + + /* SDMMCRAB and SDMMCWAB clients */ + reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_2_RESET_VAL, 2, SD); + tegra_mc_write_32(MC_HUB_PC_VC_ID_2, reg_val); + + reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_4_RESET_VAL, 4, NIC); + tegra_mc_write_32(MC_HUB_PC_VC_ID_4, reg_val); + + reg_val = mc_hub_vc_id(MC_HUB_PC_VC_ID_12_RESET_VAL, 12, UFSHCPC2); + tegra_mc_write_32(MC_HUB_PC_VC_ID_12, reg_val); + + wdata_0 = MC_CLIENT_HOTRESET_CTRL0_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL0, wdata_0); + + wdata_1 = MC_CLIENT_HOTRESET_CTRL1_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL1, wdata_1); + + wdata_2 = MC_CLIENT_HOTRESET_CTRL2_RESET_VAL; + tegra_mc_write_32(MC_CLIENT_HOTRESET_CTRL2, wdata_2); + + reg_val = MC_COALESCE_CTRL_COALESCER_ENABLE; + tegra_mc_write_32(MC_COALESCE_CTRL, reg_val); + + /* + * WAR to hardware bug 1953865: Coalescer must be disabled + * for PVA0RDC and PVA1RDC interfaces. + */ + reg_val = tegra_mc_read_32(MC_COALESCE_CONFIG_6_0); + reg_val &= ~(MC_COALESCE_CONFIG_6_0_PVA0RDC_COALESCER_ENABLED | + MC_COALESCE_CONFIG_6_0_PVA1RDC_COALESCER_ENABLED); + tegra_mc_write_32(MC_COALESCE_CONFIG_6_0, reg_val); +} + +/******************************************************************************* + * Struct to hold the memory controller settings + ******************************************************************************/ +static tegra_mc_settings_t tegra194_mc_settings = { + .streamid_override_cfg = tegra194_streamid_override_regs, + .num_streamid_override_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_override_regs), + .streamid_security_cfg = tegra194_streamid_sec_cfgs, + .num_streamid_security_cfgs = (uint32_t)ARRAY_SIZE(tegra194_streamid_sec_cfgs), + .reconfig_mss_clients = tegra194_memctrl_reconfig_mss_clients +}; + +/******************************************************************************* + * Handler to return the pointer to the memory controller's settings struct + ******************************************************************************/ +tegra_mc_settings_t *tegra_get_mc_settings(void) +{ + return &tegra194_mc_settings; +} + +/******************************************************************************* + * Handler to program the scratch registers with TZDRAM settings for the + * resume firmware + ******************************************************************************/ +void plat_memctrl_tzdram_setup(uint64_t phys_base, uint64_t size_in_bytes) +{ + uint32_t sec_reg_ctrl = tegra_mc_read_32(MC_SECURITY_CFG_REG_CTRL_0); + + /* + * Check TZDRAM carveout register access status. Setup TZDRAM fence + * only if access is enabled. + */ + if ((sec_reg_ctrl & SECURITY_CFG_WRITE_ACCESS_BIT) == + SECURITY_CFG_WRITE_ACCESS_ENABLE) { + + /* + * Setup the Memory controller to allow only secure accesses to + * the TZDRAM carveout + */ + INFO("Configuring TrustZone DRAM Memory Carveout\n"); + + tegra_mc_write_32(MC_SECURITY_CFG0_0, (uint32_t)phys_base); + tegra_mc_write_32(MC_SECURITY_CFG3_0, (uint32_t)(phys_base >> 32)); + tegra_mc_write_32(MC_SECURITY_CFG1_0, (uint32_t)(size_in_bytes >> 20)); + + /* + * MCE propagates the security configuration values across the + * CCPLEX. + */ + (void)mce_update_gsc_tzdram(); + } +} diff --git a/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c new file mode 100644 index 000000000..cc8be128a --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_psci_handlers.c @@ -0,0 +1,499 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <assert.h> +#include <stdbool.h> +#include <string.h> + +#include <arch_helpers.h> +#include <common/bl_common.h> +#include <common/debug.h> +#include <context.h> +#include <denver.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <lib/psci/psci.h> +#include <mce.h> +#include <mce_private.h> +#include <plat/common/platform.h> +#include <se.h> +#include <smmu.h> +#include <t194_nvg.h> +#include <tegra194_private.h> +#include <tegra_platform.h> +#include <tegra_private.h> + +extern uint32_t __tegra194_cpu_reset_handler_data, + __tegra194_cpu_reset_handler_end; + +/* TZDRAM offset for saving SMMU context */ +#define TEGRA194_SMMU_CTX_OFFSET 16U + +/* state id mask */ +#define TEGRA194_STATE_ID_MASK 0xFU +/* constants to get power state's wake time */ +#define TEGRA194_WAKE_TIME_MASK 0x0FFFFFF0U +#define TEGRA194_WAKE_TIME_SHIFT 4U +/* default core wake mask for CPU_SUSPEND */ +#define TEGRA194_CORE_WAKE_MASK 0x180cU + +static struct t19x_psci_percpu_data { + uint32_t wake_time; +} __aligned(CACHE_WRITEBACK_GRANULE) t19x_percpu_data[PLATFORM_CORE_COUNT]; + +/* + * tegra_fake_system_suspend acts as a boolean var controlling whether + * we are going to take fake system suspend code or normal system suspend code + * path. This variable is set inside the sip call handlers, when the kernel + * requests an SIP call to set the suspend debug flags. + */ +bool tegra_fake_system_suspend; + +int32_t tegra_soc_validate_power_state(uint32_t power_state, + psci_power_state_t *req_state) +{ + uint8_t state_id = (uint8_t)psci_get_pstate_id(power_state) & + TEGRA194_STATE_ID_MASK; + uint32_t cpu = plat_my_core_pos(); + int32_t ret = PSCI_E_SUCCESS; + + /* save the core wake time (in TSC ticks)*/ + t19x_percpu_data[cpu].wake_time = (power_state & TEGRA194_WAKE_TIME_MASK) + << TEGRA194_WAKE_TIME_SHIFT; + + /* + * Clean t19x_percpu_data[cpu] to DRAM. This needs to be done to ensure + * that the correct value is read in tegra_soc_pwr_domain_suspend(), + * which is called with caches disabled. It is possible to read a stale + * value from DRAM in that function, because the L2 cache is not flushed + * unless the cluster is entering CC6/CC7. + */ + clean_dcache_range((uint64_t)&t19x_percpu_data[cpu], + sizeof(t19x_percpu_data[cpu])); + + /* Sanity check the requested state id */ + switch (state_id) { + case PSTATE_ID_CORE_IDLE: + + /* Core idle request */ + req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; + req_state->pwr_domain_state[MPIDR_AFFLVL1] = PSCI_LOCAL_STATE_RUN; + break; + + case PSTATE_ID_CORE_POWERDN: + + /* Core powerdown request */ + req_state->pwr_domain_state[MPIDR_AFFLVL0] = state_id; + req_state->pwr_domain_state[MPIDR_AFFLVL1] = state_id; + + break; + + default: + ERROR("%s: unsupported state id (%d)\n", __func__, state_id); + ret = PSCI_E_INVALID_PARAMS; + break; + } + + return ret; +} + +int32_t tegra_soc_cpu_standby(plat_local_state_t cpu_state) +{ + uint32_t cpu = plat_my_core_pos(); + mce_cstate_info_t cstate_info = { 0 }; + + /* Program default wake mask */ + cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); + + /* Enter CPU idle */ + (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C6, + t19x_percpu_data[cpu].wake_time, + 0U); + + return PSCI_E_SUCCESS; +} + +int32_t tegra_soc_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + const plat_local_state_t *pwr_domain_state; + uint8_t stateid_afflvl0, stateid_afflvl2; + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t smmu_ctx_base; + uint32_t val; + mce_cstate_info_t sc7_cstate_info = { + .cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6, + .ccplex = (uint32_t)TEGRA_NVG_CG_CG7, + .system = (uint32_t)TEGRA_NVG_SYSTEM_SC7, + .system_state_force = 1U, + .update_wake_mask = 1U, + }; + uint32_t cpu = plat_my_core_pos(); + int32_t ret = 0; + + /* get the state ID */ + pwr_domain_state = target_state->pwr_domain_state; + stateid_afflvl0 = pwr_domain_state[MPIDR_AFFLVL0] & + TEGRA194_STATE_ID_MASK; + stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & + TEGRA194_STATE_ID_MASK; + + if ((stateid_afflvl0 == PSTATE_ID_CORE_POWERDN)) { + + /* Enter CPU powerdown */ + (void)mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C7, + t19x_percpu_data[cpu].wake_time, + 0U); + + } else if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + + /* save 'Secure Boot' Processor Feature Config Register */ + val = mmio_read_32(TEGRA_MISC_BASE + MISCREG_PFCFG); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_SECURE_BOOTP_FCFG, val); + + /* save SMMU context */ + smmu_ctx_base = params_from_bl2->tzdram_base + + tegra194_get_smmu_ctx_offset(); + tegra_smmu_save_context((uintptr_t)smmu_ctx_base); + + /* + * Suspend SE, RNG1 and PKA1 only on silcon and fpga, + * since VDK does not support atomic se ctx save + */ + if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) { + ret = tegra_se_suspend(); + assert(ret == 0); + } + + if (!tegra_fake_system_suspend) { + + /* Prepare for system suspend */ + mce_update_cstate_info(&sc7_cstate_info); + + do { + val = (uint32_t)mce_command_handler( + (uint32_t)MCE_CMD_IS_SC7_ALLOWED, + (uint32_t)TEGRA_NVG_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0U); + } while (val == 0U); + + /* Instruct the MCE to enter system suspend state */ + ret = mce_command_handler( + (uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C7, + MCE_CORE_SLEEP_TIME_INFINITE, + 0U); + assert(ret == 0); + + /* set system suspend state for house-keeping */ + tegra194_set_system_suspend_entry(); + } + } else { + ; /* do nothing */ + } + + return PSCI_E_SUCCESS; +} + +/******************************************************************************* + * Helper function to check if this is the last ON CPU in the cluster + ******************************************************************************/ +static bool tegra_last_on_cpu_in_cluster(const plat_local_state_t *states, + uint32_t ncpu) +{ + plat_local_state_t target; + bool last_on_cpu = true; + uint32_t num_cpus = ncpu, pos = 0; + + do { + target = states[pos]; + if (target != PLAT_MAX_OFF_STATE) { + last_on_cpu = false; + } + --num_cpus; + pos++; + } while (num_cpus != 0U); + + return last_on_cpu; +} + +/******************************************************************************* + * Helper function to get target power state for the cluster + ******************************************************************************/ +static plat_local_state_t tegra_get_afflvl1_pwr_state(const plat_local_state_t *states, + uint32_t ncpu) +{ + uint32_t core_pos = (uint32_t)read_mpidr() & (uint32_t)MPIDR_CPU_MASK; + plat_local_state_t target = states[core_pos]; + mce_cstate_info_t cstate_info = { 0 }; + + /* CPU suspend */ + if (target == PSTATE_ID_CORE_POWERDN) { + + /* Program default wake mask */ + cstate_info.wake_mask = TEGRA194_CORE_WAKE_MASK; + cstate_info.update_wake_mask = 1; + mce_update_cstate_info(&cstate_info); + } + + /* CPU off */ + if (target == PLAT_MAX_OFF_STATE) { + + /* Enable cluster powerdn from last CPU in the cluster */ + if (tegra_last_on_cpu_in_cluster(states, ncpu)) { + + /* Enable CC6 state and turn off wake mask */ + cstate_info.cluster = (uint32_t)TEGRA_NVG_CLUSTER_CC6; + cstate_info.ccplex = (uint32_t)TEGRA_NVG_CG_CG7; + cstate_info.system_state_force = 1; + cstate_info.update_wake_mask = 1U; + mce_update_cstate_info(&cstate_info); + + } else { + + /* Turn off wake_mask */ + cstate_info.update_wake_mask = 1U; + mce_update_cstate_info(&cstate_info); + target = PSCI_LOCAL_STATE_RUN; + } + } + + return target; +} + +/******************************************************************************* + * Platform handler to calculate the proper target power level at the + * specified affinity level + ******************************************************************************/ +plat_local_state_t tegra_soc_get_target_pwr_state(uint32_t lvl, + const plat_local_state_t *states, + uint32_t ncpu) +{ + plat_local_state_t target = PSCI_LOCAL_STATE_RUN; + uint32_t cpu = plat_my_core_pos(); + + /* System Suspend */ + if ((lvl == (uint32_t)MPIDR_AFFLVL2) && (states[cpu] == PSTATE_ID_SOC_POWERDN)) { + target = PSTATE_ID_SOC_POWERDN; + } + + /* CPU off, CPU suspend */ + if (lvl == (uint32_t)MPIDR_AFFLVL1) { + target = tegra_get_afflvl1_pwr_state(states, ncpu); + } + + /* target cluster/system state */ + return target; +} + +int32_t tegra_soc_pwr_domain_power_down_wfi(const psci_power_state_t *target_state) +{ + const plat_local_state_t *pwr_domain_state = + target_state->pwr_domain_state; + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint8_t stateid_afflvl2 = pwr_domain_state[PLAT_MAX_PWR_LVL] & + TEGRA194_STATE_ID_MASK; + uint64_t val; + u_register_t ns_sctlr_el1; + + if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + /* + * The TZRAM loses power when we enter system suspend. To + * allow graceful exit from system suspend, we need to copy + * BL3-1 over to TZDRAM. + */ + val = params_from_bl2->tzdram_base + + tegra194_get_cpu_reset_handler_size(); + memcpy((void *)(uintptr_t)val, (void *)(uintptr_t)BL31_BASE, + (uintptr_t)&__BL31_END__ - (uintptr_t)BL31_BASE); + + /* + * In fake suspend mode, ensure that the loopback procedure + * towards system suspend exit is started, instead of calling + * WFI. This is done by disabling both MMU's of EL1 & El3 + * and calling tegra_secure_entrypoint(). + */ + if (tegra_fake_system_suspend) { + + /* + * Disable EL1's MMU. + */ + ns_sctlr_el1 = read_sctlr_el1(); + ns_sctlr_el1 &= (~((u_register_t)SCTLR_M_BIT)); + write_sctlr_el1(ns_sctlr_el1); + + /* + * Disable MMU to power up the CPU in a "clean" + * state + */ + disable_mmu_el3(); + tegra_secure_entrypoint(); + panic(); + } + } + + return PSCI_E_SUCCESS; +} + +int32_t tegra_soc_pwr_domain_on(u_register_t mpidr) +{ + uint64_t target_cpu = mpidr & MPIDR_CPU_MASK; + uint64_t target_cluster = (mpidr & MPIDR_CLUSTER_MASK) >> + MPIDR_AFFINITY_BITS; + int32_t ret = 0; + + if (target_cluster > ((uint32_t)PLATFORM_CLUSTER_COUNT - 1U)) { + ERROR("%s: unsupported CPU (0x%lx)\n", __func__ , mpidr); + return PSCI_E_NOT_PRESENT; + } + + /* construct the target CPU # */ + target_cpu += (target_cluster << 1U); + + ret = mce_command_handler((uint64_t)MCE_CMD_ONLINE_CORE, target_cpu, 0U, 0U); + if (ret < 0) { + return PSCI_E_DENIED; + } + + return PSCI_E_SUCCESS; +} + +int32_t tegra_soc_pwr_domain_on_finish(const psci_power_state_t *target_state) +{ + uint8_t stateid_afflvl2 = target_state->pwr_domain_state[PLAT_MAX_PWR_LVL]; + + /* + * Reset power state info for CPUs when onlining, we set + * deepest power when offlining a core but that may not be + * requested by non-secure sw which controls idle states. It + * will re-init this info from non-secure software when the + * core come online. + */ + + /* + * Check if we are exiting from deep sleep and restore SE + * context if we are. + */ + if (stateid_afflvl2 == PSTATE_ID_SOC_POWERDN) { + +#if ENABLE_STRICT_CHECKING_MODE + /* + * Enable strict checking after programming the GSC for + * enabling TZSRAM and TZDRAM + */ + mce_enable_strict_checking(); +#endif + + /* Init SMMU */ + tegra_smmu_init(); + + /* Resume SE, RNG1 and PKA1 */ + tegra_se_resume(); + + /* + * Program XUSB STREAMIDs + * ====================== + * T19x XUSB has support for XUSB virtualization. It will + * have one physical function (PF) and four Virtual functions + * (VF) + * + * There were below two SIDs for XUSB until T186. + * 1) #define TEGRA_SID_XUSB_HOST 0x1bU + * 2) #define TEGRA_SID_XUSB_DEV 0x1cU + * + * We have below four new SIDs added for VF(s) + * 3) #define TEGRA_SID_XUSB_VF0 0x5dU + * 4) #define TEGRA_SID_XUSB_VF1 0x5eU + * 5) #define TEGRA_SID_XUSB_VF2 0x5fU + * 6) #define TEGRA_SID_XUSB_VF3 0x60U + * + * When virtualization is enabled then we have to disable SID + * override and program above SIDs in below newly added SID + * registers in XUSB PADCTL MMIO space. These registers are + * TZ protected and so need to be done in ATF. + * + * a) #define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0 (0x136cU) + * b) #define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0 (0x139cU) + * c) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0 (0x1370U) + * d) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1 (0x1374U) + * e) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2 (0x1378U) + * f) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3 (0x137cU) + * + * This change disables SID override and programs XUSB SIDs + * in above registers to support both virtualization and + * non-virtualization platforms + */ + if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) { + + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); + } + + /* + * Reset power state info for the last core doing SC7 + * entry and exit, we set deepest power state as CC7 + * and SC7 for SC7 entry which may not be requested by + * non-secure SW which controls idle states. + */ + } + + return PSCI_E_SUCCESS; +} + +int32_t tegra_soc_pwr_domain_off(const psci_power_state_t *target_state) +{ + uint64_t impl = (read_midr() >> MIDR_IMPL_SHIFT) & MIDR_IMPL_MASK; + int32_t ret = 0; + + (void)target_state; + + /* Disable Denver's DCO operations */ + if (impl == DENVER_IMPL) { + denver_disable_dco(); + } + + /* Turn off CPU */ + ret = mce_command_handler((uint64_t)MCE_CMD_ENTER_CSTATE, + (uint64_t)TEGRA_NVG_CORE_C7, MCE_CORE_SLEEP_TIME_INFINITE, 0U); + assert(ret == 0); + + return PSCI_E_SUCCESS; +} + +__dead2 void tegra_soc_prepare_system_off(void) +{ + /* System power off */ + mce_system_shutdown(); + + wfi(); + + /* wait for the system to power down */ + for (;;) { + ; + } +} + +int32_t tegra_soc_prepare_system_reset(void) +{ + /* System reboot */ + mce_system_reboot(); + + return PSCI_E_SUCCESS; +} diff --git a/plat/nvidia/tegra/soc/t194/plat_secondary.c b/plat/nvidia/tegra/soc/t194/plat_secondary.c new file mode 100644 index 000000000..c397c91ba --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_secondary.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <common/debug.h> +#include <lib/mmio.h> +#include <mce.h> +#include <string.h> +#include <tegra194_private.h> +#include <tegra_def.h> +#include <tegra_private.h> + +#define MISCREG_AA64_RST_LOW 0x2004U +#define MISCREG_AA64_RST_HIGH 0x2008U + +#define CPU_RESET_MODE_AA64 1U + +/******************************************************************************* + * Setup secondary CPU vectors + ******************************************************************************/ +void plat_secondary_setup(void) +{ + uint32_t addr_low, addr_high; + plat_params_from_bl2_t *params_from_bl2 = bl31_get_plat_params(); + uint64_t cpu_reset_handler_base, cpu_reset_handler_size; + + INFO("Setting up secondary CPU boot\n"); + + /* + * The BL31 code resides in the TZSRAM which loses state + * when we enter System Suspend. Copy the wakeup trampoline + * code to TZDRAM to help us exit from System Suspend. + */ + cpu_reset_handler_base = tegra194_get_cpu_reset_handler_base(); + cpu_reset_handler_size = tegra194_get_cpu_reset_handler_size(); + memcpy((void *)((uintptr_t)params_from_bl2->tzdram_base), + (void *)((uintptr_t)cpu_reset_handler_base), + cpu_reset_handler_size); + + /* TZDRAM base will be used as the "resume" address */ + addr_low = (uint32_t)params_from_bl2->tzdram_base | CPU_RESET_MODE_AA64; + addr_high = (uint32_t)((params_from_bl2->tzdram_base >> 32U) & 0x7ffU); + + /* write lower 32 bits first, then the upper 11 bits */ + mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_LOW, addr_low); + mmio_write_32(TEGRA_MISC_BASE + MISCREG_AA64_RST_HIGH, addr_high); + + /* save reset vector to be used during SYSTEM_SUSPEND exit */ + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_LO, + addr_low); + mmio_write_32(TEGRA_SCRATCH_BASE + SCRATCH_RESET_VECTOR_HI, + addr_high); +} diff --git a/plat/nvidia/tegra/soc/t194/plat_setup.c b/plat/nvidia/tegra/soc/t194/plat_setup.c new file mode 100644 index 000000000..912dcc6f9 --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_setup.c @@ -0,0 +1,316 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch_helpers.h> +#include <assert.h> +#include <bl31/bl31.h> +#include <common/bl_common.h> +#include <common/interrupt_props.h> +#include <drivers/console.h> +#include <context.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <cortex_a57.h> +#include <common/debug.h> +#include <denver.h> +#include <drivers/arm/gic_common.h> +#include <drivers/arm/gicv2.h> +#include <bl31/interrupt_mgmt.h> +#include <mce.h> +#include <mce_private.h> +#include <plat/common/platform.h> +#include <spe.h> +#include <tegra_def.h> +#include <tegra_mc_def.h> +#include <tegra_platform.h> +#include <tegra_private.h> +#include <lib/xlat_tables/xlat_tables_v2.h> + +/* ID for spe-console */ +#define TEGRA_CONSOLE_SPE_ID 0xFE + +/******************************************************************************* + * The Tegra power domain tree has a single system level power domain i.e. a + * single root node. The first entry in the power domain descriptor specifies + * the number of power domains at the highest power level. + ******************************************************************************* + */ +static const uint8_t tegra_power_domain_tree_desc[] = { + /* No of root nodes */ + 1, + /* No of clusters */ + PLATFORM_CLUSTER_COUNT, + /* No of CPU cores - cluster0 */ + PLATFORM_MAX_CPUS_PER_CLUSTER, + /* No of CPU cores - cluster1 */ + PLATFORM_MAX_CPUS_PER_CLUSTER, + /* No of CPU cores - cluster2 */ + PLATFORM_MAX_CPUS_PER_CLUSTER, + /* No of CPU cores - cluster3 */ + PLATFORM_MAX_CPUS_PER_CLUSTER +}; + +/******************************************************************************* + * This function returns the Tegra default topology tree information. + ******************************************************************************/ +const uint8_t *plat_get_power_domain_tree_desc(void) +{ + return tegra_power_domain_tree_desc; +} + +/* + * Table of regions to map using the MMU. + */ +static const mmap_region_t tegra_mmap[] = { + MAP_REGION_FLAT(TEGRA_MISC_BASE, 0x4000U, /* 16KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_TSA_BASE, 0x20000U, /* 128KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_GPCDMA_BASE, 0x10000U, /* 64KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_MC_STREAMID_BASE, 0x8000U, /* 32KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_MC_BASE, 0x8000U, /* 32KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), +#if !ENABLE_CONSOLE_SPE + MAP_REGION_FLAT(TEGRA_UARTA_BASE, 0x20000U, /* 128KB - UART A, B*/ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_UARTC_BASE, 0x20000U, /* 128KB - UART C, G */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_UARTD_BASE, 0x30000U, /* 192KB - UART D, E, F */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), +#endif + MAP_REGION_FLAT(TEGRA_XUSB_PADCTL_BASE, 0x2000U, /* 8KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_GICD_BASE, 0x1000, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_GICC_BASE, 0x1000, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_SE0_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_PKA1_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_RNG1_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_HSP_DBELL_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), +#if ENABLE_CONSOLE_SPE + MAP_REGION_FLAT(TEGRA_CONSOLE_SPE_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), +#endif + MAP_REGION_FLAT(TEGRA_TMRUS_BASE, TEGRA_TMRUS_SIZE, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_SCRATCH_BASE, 0x1000U, /* 4KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_SMMU2_BASE, 0x800000U, /* 8MB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_SMMU1_BASE, 0x800000U, /* 8MB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_SMMU0_BASE, 0x800000U, /* 8MB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_BPMP_IPC_TX_PHYS_BASE, 0x10000U, /* 64KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + MAP_REGION_FLAT(TEGRA_CAR_RESET_BASE, 0x10000U, /* 64KB */ + (uint8_t)MT_DEVICE | (uint8_t)MT_RW | (uint8_t)MT_SECURE), + {0} +}; + +/******************************************************************************* + * Set up the pagetables as per the platform memory map & initialize the MMU + ******************************************************************************/ +const mmap_region_t *plat_get_mmio_map(void) +{ + /* MMIO space */ + return tegra_mmap; +} + +/******************************************************************************* + * Handler to get the System Counter Frequency + ******************************************************************************/ +uint32_t plat_get_syscnt_freq2(void) +{ + return 31250000; +} + +#if !ENABLE_CONSOLE_SPE +/******************************************************************************* + * Maximum supported UART controllers + ******************************************************************************/ +#define TEGRA194_MAX_UART_PORTS 7 + +/******************************************************************************* + * This variable holds the UART port base addresses + ******************************************************************************/ +static uint32_t tegra194_uart_addresses[TEGRA194_MAX_UART_PORTS + 1] = { + 0, /* undefined - treated as an error case */ + TEGRA_UARTA_BASE, + TEGRA_UARTB_BASE, + TEGRA_UARTC_BASE, + TEGRA_UARTD_BASE, + TEGRA_UARTE_BASE, + TEGRA_UARTF_BASE, + TEGRA_UARTG_BASE +}; +#endif + +/******************************************************************************* + * Enable console corresponding to the console ID + ******************************************************************************/ +void plat_enable_console(int32_t id) +{ + uint32_t console_clock = 0U; + +#if ENABLE_CONSOLE_SPE + static console_spe_t spe_console; + + if (id == TEGRA_CONSOLE_SPE_ID) { + (void)console_spe_register(TEGRA_CONSOLE_SPE_BASE, + console_clock, + TEGRA_CONSOLE_BAUDRATE, + &spe_console); + console_set_scope(&spe_console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } +#else + static console_16550_t uart_console; + + if ((id > 0) && (id < TEGRA194_MAX_UART_PORTS)) { + /* + * Reference clock used by the FPGAs is a lot slower. + */ + if (tegra_platform_is_fpga()) { + console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; + } else { + console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; + } + + (void)console_16550_register(tegra194_uart_addresses[id], + console_clock, + TEGRA_CONSOLE_BAUDRATE, + &uart_console); + console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } +#endif +} + +/******************************************************************************* + * Handler for early platform setup + ******************************************************************************/ +void plat_early_platform_setup(void) +{ + /* sanity check MCE firmware compatibility */ + mce_verify_firmware_version(); + + /* + * Program XUSB STREAMIDs + * ====================== + * T19x XUSB has support for XUSB virtualization. It will have one + * physical function (PF) and four Virtual function (VF) + * + * There were below two SIDs for XUSB until T186. + * 1) #define TEGRA_SID_XUSB_HOST 0x1bU + * 2) #define TEGRA_SID_XUSB_DEV 0x1cU + * + * We have below four new SIDs added for VF(s) + * 3) #define TEGRA_SID_XUSB_VF0 0x5dU + * 4) #define TEGRA_SID_XUSB_VF1 0x5eU + * 5) #define TEGRA_SID_XUSB_VF2 0x5fU + * 6) #define TEGRA_SID_XUSB_VF3 0x60U + * + * When virtualization is enabled then we have to disable SID override + * and program above SIDs in below newly added SID registers in XUSB + * PADCTL MMIO space. These registers are TZ protected and so need to + * be done in ATF. + * a) #define XUSB_PADCTL_HOST_AXI_STREAMID_PF_0 (0x136cU) + * b) #define XUSB_PADCTL_DEV_AXI_STREAMID_PF_0 (0x139cU) + * c) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_0 (0x1370U) + * d) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_1 (0x1374U) + * e) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_2 (0x1378U) + * f) #define XUSB_PADCTL_HOST_AXI_STREAMID_VF_3 (0x137cU) + * + * This change disables SID override and programs XUSB SIDs in + * above registers to support both virtualization and + * non-virtualization platforms + */ + if (tegra_platform_is_silicon() || tegra_platform_is_fpga()) { + + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_HOST); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_0, TEGRA_SID_XUSB_VF0); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_1, TEGRA_SID_XUSB_VF1); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_2, TEGRA_SID_XUSB_VF2); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_HOST_AXI_STREAMID_VF_3, TEGRA_SID_XUSB_VF3); + mmio_write_32(TEGRA_XUSB_PADCTL_BASE + + XUSB_PADCTL_DEV_AXI_STREAMID_PF_0, TEGRA_SID_XUSB_DEV); + } +} + +/* Secure IRQs for Tegra194 */ +static const interrupt_prop_t tegra194_interrupt_props[] = { + INTR_PROP_DESC(TEGRA194_TOP_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE), + INTR_PROP_DESC(TEGRA194_AON_WDT_IRQ, GIC_HIGHEST_SEC_PRIORITY, + GICV2_INTR_GROUP0, GIC_INTR_CFG_EDGE) +}; + +/******************************************************************************* + * Initialize the GIC and SGIs + ******************************************************************************/ +void plat_gic_setup(void) +{ + tegra_gic_setup(tegra194_interrupt_props, ARRAY_SIZE(tegra194_interrupt_props)); + tegra_gic_init(); + + /* + * Initialize the FIQ handler + */ + tegra_fiq_handler_setup(); +} + +/******************************************************************************* + * Return pointer to the BL31 params from previous bootloader + ******************************************************************************/ +struct tegra_bl31_params *plat_get_bl31_params(void) +{ + uint64_t val; + + val = (mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_HI_ADDR) & + SCRATCH_BL31_PARAMS_HI_ADDR_MASK) >> SCRATCH_BL31_PARAMS_HI_ADDR_SHIFT; + val <<= 32; + val |= mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PARAMS_LO_ADDR); + + return (struct tegra_bl31_params *)(uintptr_t)val; +} + +/******************************************************************************* + * Return pointer to the BL31 platform params from previous bootloader + ******************************************************************************/ +plat_params_from_bl2_t *plat_get_bl31_plat_params(void) +{ + uint64_t val; + + val = (mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_HI_ADDR) & + SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_MASK) >> SCRATCH_BL31_PLAT_PARAMS_HI_ADDR_SHIFT; + val <<= 32; + val |= mmio_read_32(TEGRA_SCRATCH_BASE + SCRATCH_BL31_PLAT_PARAMS_LO_ADDR); + + return (plat_params_from_bl2_t *)(uintptr_t)val; +} + +void plat_late_platform_setup(void) +{ +#if ENABLE_STRICT_CHECKING_MODE + /* + * Enable strict checking after programming the GSC for + * enabling TZSRAM and TZDRAM + */ + mce_enable_strict_checking(); +#endif +} diff --git a/plat/nvidia/tegra/soc/t194/plat_sip_calls.c b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c new file mode 100644 index 000000000..8873358cd --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_sip_calls.c @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <arch_helpers.h> +#include <assert.h> +#include <common/bl_common.h> +#include <lib/el3_runtime/context_mgmt.h> +#include <common/debug.h> +#include <errno.h> +#include <mce.h> +#include <memctrl.h> +#include <common/runtime_svc.h> +#include <tegra_private.h> +#include <tegra_platform.h> +#include <stdbool.h> + +extern bool tegra_fake_system_suspend; + +/******************************************************************************* + * Tegra194 SiP SMCs + ******************************************************************************/ +#define TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND 0xC2FFFE03U + +/******************************************************************************* + * This function is responsible for handling all T194 SiP calls + ******************************************************************************/ +int32_t plat_sip_handler(uint32_t smc_fid, + uint64_t x1, + uint64_t x2, + uint64_t x3, + uint64_t x4, + const void *cookie, + void *handle, + uint64_t flags) +{ + int32_t ret = -ENOTSUP; + + (void)x1; + (void)x4; + (void)cookie; + (void)flags; + + if (smc_fid == TEGRA_SIP_ENABLE_FAKE_SYSTEM_SUSPEND) { + /* + * System suspend mode is set if the platform ATF is + * running on VDK and there is a debug SIP call. This mode + * ensures that the debug path is exercised, instead of + * regular code path to suit the pre-silicon platform needs. + * This includes replacing the call to WFI, with calls to + * system suspend exit procedures. + */ + if (tegra_platform_is_virt_dev_kit()) { + tegra_fake_system_suspend = true; + ret = 0; + } + } + + return ret; +} diff --git a/plat/nvidia/tegra/soc/t194/plat_smmu.c b/plat/nvidia/tegra/soc/t194/plat_smmu.c new file mode 100644 index 000000000..3b4a3803c --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_smmu.c @@ -0,0 +1,306 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <common/bl_common.h> +#include <common/debug.h> +#include <smmu.h> +#include <tegra_def.h> +#include <tegra_mc_def.h> + +#define BOARD_SYSTEM_FPGA_BASE U(1) +#define BASE_CONFIG_SMMU_DEVICES U(2) +#define MAX_NUM_SMMU_DEVICES U(3) + +static uint32_t tegra_misc_read_32(uint32_t off) +{ + return mmio_read_32((uintptr_t)TEGRA_MISC_BASE + off); +} + +/******************************************************************************* + * Array to hold SMMU context for Tegra194 + ******************************************************************************/ +static __attribute__((aligned(16))) smmu_regs_t tegra194_smmu_context[] = { + _START_OF_TABLE_, + mc_make_sid_security_cfg(HDAR), + mc_make_sid_security_cfg(HOST1XDMAR), + mc_make_sid_security_cfg(NVENCSRD), + mc_make_sid_security_cfg(SATAR), + mc_make_sid_security_cfg(NVENCSWR), + mc_make_sid_security_cfg(HDAW), + mc_make_sid_security_cfg(SATAW), + mc_make_sid_security_cfg(ISPRA), + mc_make_sid_security_cfg(ISPFALR), + mc_make_sid_security_cfg(ISPWA), + mc_make_sid_security_cfg(ISPWB), + mc_make_sid_security_cfg(XUSB_HOSTR), + mc_make_sid_security_cfg(XUSB_HOSTW), + mc_make_sid_security_cfg(XUSB_DEVR), + mc_make_sid_security_cfg(XUSB_DEVW), + mc_make_sid_security_cfg(TSECSRD), + mc_make_sid_security_cfg(TSECSWR), + mc_make_sid_security_cfg(SDMMCRA), + mc_make_sid_security_cfg(SDMMCR), + mc_make_sid_security_cfg(SDMMCRAB), + mc_make_sid_security_cfg(SDMMCWA), + mc_make_sid_security_cfg(SDMMCW), + mc_make_sid_security_cfg(SDMMCWAB), + mc_make_sid_security_cfg(VICSRD), + mc_make_sid_security_cfg(VICSWR), + mc_make_sid_security_cfg(VIW), + mc_make_sid_security_cfg(NVDECSRD), + mc_make_sid_security_cfg(NVDECSWR), + mc_make_sid_security_cfg(APER), + mc_make_sid_security_cfg(APEW), + mc_make_sid_security_cfg(NVJPGSRD), + mc_make_sid_security_cfg(NVJPGSWR), + mc_make_sid_security_cfg(SESRD), + mc_make_sid_security_cfg(SESWR), + mc_make_sid_security_cfg(AXIAPR), + mc_make_sid_security_cfg(AXIAPW), + mc_make_sid_security_cfg(ETRR), + mc_make_sid_security_cfg(ETRW), + mc_make_sid_security_cfg(TSECSRDB), + mc_make_sid_security_cfg(TSECSWRB), + mc_make_sid_security_cfg(AXISR), + mc_make_sid_security_cfg(AXISW), + mc_make_sid_security_cfg(EQOSR), + mc_make_sid_security_cfg(EQOSW), + mc_make_sid_security_cfg(UFSHCR), + mc_make_sid_security_cfg(UFSHCW), + mc_make_sid_security_cfg(NVDISPLAYR), + mc_make_sid_security_cfg(BPMPR), + mc_make_sid_security_cfg(BPMPW), + mc_make_sid_security_cfg(BPMPDMAR), + mc_make_sid_security_cfg(BPMPDMAW), + mc_make_sid_security_cfg(AONR), + mc_make_sid_security_cfg(AONW), + mc_make_sid_security_cfg(AONDMAR), + mc_make_sid_security_cfg(AONDMAW), + mc_make_sid_security_cfg(SCER), + mc_make_sid_security_cfg(SCEW), + mc_make_sid_security_cfg(SCEDMAR), + mc_make_sid_security_cfg(SCEDMAW), + mc_make_sid_security_cfg(APEDMAR), + mc_make_sid_security_cfg(APEDMAW), + mc_make_sid_security_cfg(NVDISPLAYR1), + mc_make_sid_security_cfg(VICSRD1), + mc_make_sid_security_cfg(NVDECSRD1), + mc_make_sid_security_cfg(VIFALR), + mc_make_sid_security_cfg(VIFALW), + mc_make_sid_security_cfg(DLA0RDA), + mc_make_sid_security_cfg(DLA0FALRDB), + mc_make_sid_security_cfg(DLA0WRA), + mc_make_sid_security_cfg(DLA0FALWRB), + mc_make_sid_security_cfg(DLA1RDA), + mc_make_sid_security_cfg(DLA1FALRDB), + mc_make_sid_security_cfg(DLA1WRA), + mc_make_sid_security_cfg(DLA1FALWRB), + mc_make_sid_security_cfg(PVA0RDA), + mc_make_sid_security_cfg(PVA0RDB), + mc_make_sid_security_cfg(PVA0RDC), + mc_make_sid_security_cfg(PVA0WRA), + mc_make_sid_security_cfg(PVA0WRB), + mc_make_sid_security_cfg(PVA0WRC), + mc_make_sid_security_cfg(PVA1RDA), + mc_make_sid_security_cfg(PVA1RDB), + mc_make_sid_security_cfg(PVA1RDC), + mc_make_sid_security_cfg(PVA1WRA), + mc_make_sid_security_cfg(PVA1WRB), + mc_make_sid_security_cfg(PVA1WRC), + mc_make_sid_security_cfg(RCER), + mc_make_sid_security_cfg(RCEW), + mc_make_sid_security_cfg(RCEDMAR), + mc_make_sid_security_cfg(RCEDMAW), + mc_make_sid_security_cfg(NVENC1SRD), + mc_make_sid_security_cfg(NVENC1SWR), + mc_make_sid_security_cfg(PCIE0R), + mc_make_sid_security_cfg(PCIE0W), + mc_make_sid_security_cfg(PCIE1R), + mc_make_sid_security_cfg(PCIE1W), + mc_make_sid_security_cfg(PCIE2AR), + mc_make_sid_security_cfg(PCIE2AW), + mc_make_sid_security_cfg(PCIE3R), + mc_make_sid_security_cfg(PCIE3W), + mc_make_sid_security_cfg(PCIE4R), + mc_make_sid_security_cfg(PCIE4W), + mc_make_sid_security_cfg(PCIE5R), + mc_make_sid_security_cfg(PCIE5W), + mc_make_sid_security_cfg(ISPFALW), + mc_make_sid_security_cfg(DLA0RDA1), + mc_make_sid_security_cfg(DLA1RDA1), + mc_make_sid_security_cfg(PVA0RDA1), + mc_make_sid_security_cfg(PVA0RDB1), + mc_make_sid_security_cfg(PVA1RDA1), + mc_make_sid_security_cfg(PVA1RDB1), + mc_make_sid_security_cfg(PCIE5R1), + mc_make_sid_security_cfg(NVENCSRD1), + mc_make_sid_security_cfg(NVENC1SRD1), + mc_make_sid_security_cfg(ISPRA1), + mc_make_sid_security_cfg(PCIE0R1), + mc_make_sid_security_cfg(MIU0R), + mc_make_sid_security_cfg(MIU0W), + mc_make_sid_security_cfg(MIU1R), + mc_make_sid_security_cfg(MIU1W), + mc_make_sid_security_cfg(MIU2R), + mc_make_sid_security_cfg(MIU2W), + mc_make_sid_security_cfg(MIU3R), + mc_make_sid_security_cfg(MIU3W), + mc_make_sid_override_cfg(HDAR), + mc_make_sid_override_cfg(HOST1XDMAR), + mc_make_sid_override_cfg(NVENCSRD), + mc_make_sid_override_cfg(SATAR), + mc_make_sid_override_cfg(NVENCSWR), + mc_make_sid_override_cfg(HDAW), + mc_make_sid_override_cfg(SATAW), + mc_make_sid_override_cfg(ISPRA), + mc_make_sid_override_cfg(ISPFALR), + mc_make_sid_override_cfg(ISPWA), + mc_make_sid_override_cfg(ISPWB), + mc_make_sid_override_cfg(XUSB_HOSTR), + mc_make_sid_override_cfg(XUSB_HOSTW), + mc_make_sid_override_cfg(XUSB_DEVR), + mc_make_sid_override_cfg(XUSB_DEVW), + mc_make_sid_override_cfg(TSECSRD), + mc_make_sid_override_cfg(TSECSWR), + mc_make_sid_override_cfg(SDMMCRA), + mc_make_sid_override_cfg(SDMMCR), + mc_make_sid_override_cfg(SDMMCRAB), + mc_make_sid_override_cfg(SDMMCWA), + mc_make_sid_override_cfg(SDMMCW), + mc_make_sid_override_cfg(SDMMCWAB), + mc_make_sid_override_cfg(VICSRD), + mc_make_sid_override_cfg(VICSWR), + mc_make_sid_override_cfg(VIW), + mc_make_sid_override_cfg(NVDECSRD), + mc_make_sid_override_cfg(NVDECSWR), + mc_make_sid_override_cfg(APER), + mc_make_sid_override_cfg(APEW), + mc_make_sid_override_cfg(NVJPGSRD), + mc_make_sid_override_cfg(NVJPGSWR), + mc_make_sid_override_cfg(SESRD), + mc_make_sid_override_cfg(SESWR), + mc_make_sid_override_cfg(AXIAPR), + mc_make_sid_override_cfg(AXIAPW), + mc_make_sid_override_cfg(ETRR), + mc_make_sid_override_cfg(ETRW), + mc_make_sid_override_cfg(TSECSRDB), + mc_make_sid_override_cfg(TSECSWRB), + mc_make_sid_override_cfg(AXISR), + mc_make_sid_override_cfg(AXISW), + mc_make_sid_override_cfg(EQOSR), + mc_make_sid_override_cfg(EQOSW), + mc_make_sid_override_cfg(UFSHCR), + mc_make_sid_override_cfg(UFSHCW), + mc_make_sid_override_cfg(NVDISPLAYR), + mc_make_sid_override_cfg(BPMPR), + mc_make_sid_override_cfg(BPMPW), + mc_make_sid_override_cfg(BPMPDMAR), + mc_make_sid_override_cfg(BPMPDMAW), + mc_make_sid_override_cfg(AONR), + mc_make_sid_override_cfg(AONW), + mc_make_sid_override_cfg(AONDMAR), + mc_make_sid_override_cfg(AONDMAW), + mc_make_sid_override_cfg(SCER), + mc_make_sid_override_cfg(SCEW), + mc_make_sid_override_cfg(SCEDMAR), + mc_make_sid_override_cfg(SCEDMAW), + mc_make_sid_override_cfg(APEDMAR), + mc_make_sid_override_cfg(APEDMAW), + mc_make_sid_override_cfg(NVDISPLAYR1), + mc_make_sid_override_cfg(VICSRD1), + mc_make_sid_override_cfg(NVDECSRD1), + mc_make_sid_override_cfg(VIFALR), + mc_make_sid_override_cfg(VIFALW), + mc_make_sid_override_cfg(DLA0RDA), + mc_make_sid_override_cfg(DLA0FALRDB), + mc_make_sid_override_cfg(DLA0WRA), + mc_make_sid_override_cfg(DLA0FALWRB), + mc_make_sid_override_cfg(DLA1RDA), + mc_make_sid_override_cfg(DLA1FALRDB), + mc_make_sid_override_cfg(DLA1WRA), + mc_make_sid_override_cfg(DLA1FALWRB), + mc_make_sid_override_cfg(PVA0RDA), + mc_make_sid_override_cfg(PVA0RDB), + mc_make_sid_override_cfg(PVA0RDC), + mc_make_sid_override_cfg(PVA0WRA), + mc_make_sid_override_cfg(PVA0WRB), + mc_make_sid_override_cfg(PVA0WRC), + mc_make_sid_override_cfg(PVA1RDA), + mc_make_sid_override_cfg(PVA1RDB), + mc_make_sid_override_cfg(PVA1RDC), + mc_make_sid_override_cfg(PVA1WRA), + mc_make_sid_override_cfg(PVA1WRB), + mc_make_sid_override_cfg(PVA1WRC), + mc_make_sid_override_cfg(RCER), + mc_make_sid_override_cfg(RCEW), + mc_make_sid_override_cfg(RCEDMAR), + mc_make_sid_override_cfg(RCEDMAW), + mc_make_sid_override_cfg(NVENC1SRD), + mc_make_sid_override_cfg(NVENC1SWR), + mc_make_sid_override_cfg(PCIE0R), + mc_make_sid_override_cfg(PCIE0W), + mc_make_sid_override_cfg(PCIE1R), + mc_make_sid_override_cfg(PCIE1W), + mc_make_sid_override_cfg(PCIE2AR), + mc_make_sid_override_cfg(PCIE2AW), + mc_make_sid_override_cfg(PCIE3R), + mc_make_sid_override_cfg(PCIE3W), + mc_make_sid_override_cfg(PCIE4R), + mc_make_sid_override_cfg(PCIE4W), + mc_make_sid_override_cfg(PCIE5R), + mc_make_sid_override_cfg(PCIE5W), + mc_make_sid_override_cfg(ISPFALW), + mc_make_sid_override_cfg(DLA0RDA1), + mc_make_sid_override_cfg(DLA1RDA1), + mc_make_sid_override_cfg(PVA0RDA1), + mc_make_sid_override_cfg(PVA0RDB1), + mc_make_sid_override_cfg(PVA1RDA1), + mc_make_sid_override_cfg(PVA1RDB1), + mc_make_sid_override_cfg(PCIE5R1), + mc_make_sid_override_cfg(NVENCSRD1), + mc_make_sid_override_cfg(NVENC1SRD1), + mc_make_sid_override_cfg(ISPRA1), + mc_make_sid_override_cfg(PCIE0R1), + mc_make_sid_override_cfg(MIU0R), + mc_make_sid_override_cfg(MIU0W), + mc_make_sid_override_cfg(MIU1R), + mc_make_sid_override_cfg(MIU1W), + mc_make_sid_override_cfg(MIU2R), + mc_make_sid_override_cfg(MIU2W), + mc_make_sid_override_cfg(MIU3R), + mc_make_sid_override_cfg(MIU3W), + smmu_make_cfg(TEGRA_SMMU0_BASE), + smmu_make_cfg(TEGRA_SMMU2_BASE), + smmu_bypass_cfg, /* TBU settings */ + _END_OF_TABLE_, +}; + +/******************************************************************************* + * Handler to return the pointer to the SMMU's context struct + ******************************************************************************/ +smmu_regs_t *plat_get_smmu_ctx(void) +{ + /* index of _END_OF_TABLE_ */ + tegra194_smmu_context[0].val = (uint32_t)ARRAY_SIZE(tegra194_smmu_context) - 1U; + + return tegra194_smmu_context; +} + +/******************************************************************************* + * Handler to return the support SMMU devices number + ******************************************************************************/ +uint32_t plat_get_num_smmu_devices(void) +{ + uint32_t ret_num = MAX_NUM_SMMU_DEVICES; + uint32_t board_revid = ((tegra_misc_read_32(MISCREG_EMU_REVID) >> \ + BOARD_SHIFT_BITS) & BOARD_MASK_BITS); + + if (board_revid == BOARD_SYSTEM_FPGA_BASE) { + ret_num = BASE_CONFIG_SMMU_DEVICES; + } + + return ret_num; +} diff --git a/plat/nvidia/tegra/soc/t194/plat_trampoline.S b/plat/nvidia/tegra/soc/t194/plat_trampoline.S new file mode 100644 index 000000000..540c2019c --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/plat_trampoline.S @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <plat/common/common_def.h> +#include <memctrl_v2.h> +#include <tegra_def.h> + +#define TEGRA194_STATE_SYSTEM_SUSPEND 0x5C7 +#define TEGRA194_STATE_SYSTEM_RESUME 0x600D +#define TEGRA194_SMMU_CTX_SIZE 0x80D + + .align 4 + .globl tegra194_cpu_reset_handler + +/* CPU reset handler routine */ +func tegra194_cpu_reset_handler + /* check if we are exiting system suspend state */ + adr x0, __tegra194_system_suspend_state + ldr x1, [x0] + mov x2, #TEGRA194_STATE_SYSTEM_SUSPEND + lsl x2, x2, #16 + add x2, x2, #TEGRA194_STATE_SYSTEM_SUSPEND + cmp x1, x2 + bne boot_cpu + + /* set system resume state */ + mov x1, #TEGRA194_STATE_SYSTEM_RESUME + lsl x1, x1, #16 + mov x2, #TEGRA194_STATE_SYSTEM_RESUME + add x1, x1, x2 + str x1, [x0] + dsb sy + + /* prepare to relocate to TZSRAM */ + mov x0, #BL31_BASE + adr x1, __tegra194_cpu_reset_handler_end + adr x2, __tegra194_cpu_reset_handler_data + ldr x2, [x2, #8] + + /* memcpy16 */ +m_loop16: + cmp x2, #16 + b.lt m_loop1 + ldp x3, x4, [x1], #16 + stp x3, x4, [x0], #16 + sub x2, x2, #16 + b m_loop16 + /* copy byte per byte */ +m_loop1: + cbz x2, boot_cpu + ldrb w3, [x1], #1 + strb w3, [x0], #1 + subs x2, x2, #1 + b.ne m_loop1 + +boot_cpu: + adr x0, __tegra194_cpu_reset_handler_data + ldr x0, [x0] + br x0 +endfunc tegra194_cpu_reset_handler + + /* + * Tegra194 reset data (offset 0x0 - 0x2490) + * + * 0x0000: secure world's entrypoint + * 0x0008: BL31 size (RO + RW) + * 0x0010: SMMU context start + * 0x2490: SMMU context end + */ + + .align 4 + .type __tegra194_cpu_reset_handler_data, %object + .globl __tegra194_cpu_reset_handler_data +__tegra194_cpu_reset_handler_data: + .quad tegra_secure_entrypoint + .quad __BL31_END__ - BL31_BASE + + .globl __tegra194_system_suspend_state +__tegra194_system_suspend_state: + .quad 0 + + .align 4 +__tegra194_smmu_context: + .rept TEGRA194_SMMU_CTX_SIZE + .quad 0 + .endr + .size __tegra194_cpu_reset_handler_data, \ + . - __tegra194_cpu_reset_handler_data + + .align 4 + .globl __tegra194_cpu_reset_handler_end +__tegra194_cpu_reset_handler_end: + + .globl tegra194_get_cpu_reset_handler_size + .globl tegra194_get_cpu_reset_handler_base + .globl tegra194_get_smmu_ctx_offset + .globl tegra194_set_system_suspend_entry + +/* return size of the CPU reset handler */ +func tegra194_get_cpu_reset_handler_size + adr x0, __tegra194_cpu_reset_handler_end + adr x1, tegra194_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra194_get_cpu_reset_handler_size + +/* return the start address of the CPU reset handler */ +func tegra194_get_cpu_reset_handler_base + adr x0, tegra194_cpu_reset_handler + ret +endfunc tegra194_get_cpu_reset_handler_base + +/* return the size of the SMMU context */ +func tegra194_get_smmu_ctx_offset + adr x0, __tegra194_smmu_context + adr x1, tegra194_cpu_reset_handler + sub x0, x0, x1 + ret +endfunc tegra194_get_smmu_ctx_offset + +/* set system suspend state before SC7 entry */ +func tegra194_set_system_suspend_entry + mov x0, #TEGRA_MC_BASE + mov x3, #MC_SECURITY_CFG3_0 + ldr w1, [x0, x3] + lsl x1, x1, #32 + mov x3, #MC_SECURITY_CFG0_0 + ldr w2, [x0, x3] + orr x3, x1, x2 /* TZDRAM base */ + adr x0, __tegra194_system_suspend_state + adr x1, tegra194_cpu_reset_handler + sub x2, x0, x1 /* offset in TZDRAM */ + mov x0, #TEGRA194_STATE_SYSTEM_SUSPEND + lsl x0, x0, #16 + add x0, x0, #TEGRA194_STATE_SYSTEM_SUSPEND + str x0, [x3, x2] /* set value in TZDRAM */ + dsb sy + ret +endfunc tegra194_set_system_suspend_entry diff --git a/plat/nvidia/tegra/soc/t194/platform_t194.mk b/plat/nvidia/tegra/soc/t194/platform_t194.mk new file mode 100644 index 000000000..78766fcbe --- /dev/null +++ b/plat/nvidia/tegra/soc/t194/platform_t194.mk @@ -0,0 +1,63 @@ +# +# Copyright (c) 2019-2020, NVIDIA CORPORATION. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +# platform configs +ENABLE_CONSOLE_SPE := 1 +$(eval $(call add_define,ENABLE_CONSOLE_SPE)) + +ENABLE_STRICT_CHECKING_MODE := 1 +$(eval $(call add_define,ENABLE_STRICT_CHECKING_MODE)) + +USE_GPC_DMA := 1 +$(eval $(call add_define,USE_GPC_DMA)) + +RESET_TO_BL31 := 1 + +PROGRAMMABLE_RESET_ADDRESS := 1 + +COLD_BOOT_SINGLE_CPU := 1 + +# platform settings +TZDRAM_BASE := 0x40000000 +$(eval $(call add_define,TZDRAM_BASE)) + +PLATFORM_CLUSTER_COUNT := 4 +$(eval $(call add_define,PLATFORM_CLUSTER_COUNT)) + +PLATFORM_MAX_CPUS_PER_CLUSTER := 2 +$(eval $(call add_define,PLATFORM_MAX_CPUS_PER_CLUSTER)) + +MAX_XLAT_TABLES := 25 +$(eval $(call add_define,MAX_XLAT_TABLES)) + +MAX_MMAP_REGIONS := 30 +$(eval $(call add_define,MAX_MMAP_REGIONS)) + +# platform files +PLAT_INCLUDES += -I${SOC_DIR}/drivers/include + +BL31_SOURCES += drivers/ti/uart/aarch64/16550_console.S \ + lib/cpus/aarch64/denver.S \ + ${COMMON_DIR}/drivers/bpmp_ipc/intf.c \ + ${COMMON_DIR}/drivers/bpmp_ipc/ivc.c \ + ${COMMON_DIR}/drivers/gpcdma/gpcdma.c \ + ${COMMON_DIR}/drivers/memctrl/memctrl_v2.c \ + ${COMMON_DIR}/drivers/smmu/smmu.c \ + ${SOC_DIR}/drivers/mce/mce.c \ + ${SOC_DIR}/drivers/mce/nvg.c \ + ${SOC_DIR}/drivers/mce/aarch64/nvg_helpers.S \ + ${SOC_DIR}/drivers/se/se.c \ + ${SOC_DIR}/plat_memctrl.c \ + ${SOC_DIR}/plat_psci_handlers.c \ + ${SOC_DIR}/plat_setup.c \ + ${SOC_DIR}/plat_secondary.c \ + ${SOC_DIR}/plat_sip_calls.c \ + ${SOC_DIR}/plat_smmu.c \ + ${SOC_DIR}/plat_trampoline.S + +ifeq (${ENABLE_CONSOLE_SPE},1) +BL31_SOURCES += ${COMMON_DIR}/drivers/spe/shared_console.S +endif diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h index be1f9cc39..352107d2c 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h +++ b/plat/nvidia/tegra/soc/t210/drivers/se/se_private.h @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause diff --git a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c index 8d7dbf9e5..d5e049126 100644 --- a/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c +++ b/plat/nvidia/tegra/soc/t210/drivers/se/security_engine.c @@ -1,5 +1,5 @@ -/* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. +/* + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause diff --git a/plat/nvidia/tegra/soc/t210/plat_setup.c b/plat/nvidia/tegra/soc/t210/plat_setup.c index 2a2d102f7..bfa818419 100644 --- a/plat/nvidia/tegra/soc/t210/plat_setup.c +++ b/plat/nvidia/tegra/soc/t210/plat_setup.c @@ -114,14 +114,30 @@ static uint32_t tegra210_uart_addresses[TEGRA210_MAX_UART_PORTS + 1] = { }; /******************************************************************************* - * Retrieve the UART controller base to be used as the console + * Enable console corresponding to the console ID ******************************************************************************/ -uint32_t plat_get_console_from_id(int id) +void plat_enable_console(int32_t id) { - if (id > TEGRA210_MAX_UART_PORTS) - return 0; + static console_16550_t uart_console; + uint32_t console_clock; - return tegra210_uart_addresses[id]; + if ((id > 0) && (id < TEGRA210_MAX_UART_PORTS)) { + /* + * Reference clock used by the FPGAs is a lot slower. + */ + if (tegra_platform_is_fpga()) { + console_clock = TEGRA_BOOT_UART_CLK_13_MHZ; + } else { + console_clock = TEGRA_BOOT_UART_CLK_408_MHZ; + } + + (void)console_16550_register(tegra210_uart_addresses[id], + console_clock, + TEGRA_CONSOLE_BAUDRATE, + &uart_console); + console_set_scope(&uart_console.console, CONSOLE_FLAG_BOOT | + CONSOLE_FLAG_RUNTIME | CONSOLE_FLAG_CRASH); + } } /******************************************************************************* diff --git a/plat/qemu/aarch32/plat_helpers.S b/plat/qemu/common/aarch32/plat_helpers.S index aebcfa78f..15e860b42 100644 --- a/plat/qemu/aarch32/plat_helpers.S +++ b/plat/qemu/common/aarch32/plat_helpers.S @@ -72,8 +72,14 @@ func plat_secondary_cold_boot_setup /* Wait until we have a go */ poll_mailbox: ldr r1, [r2, r0] - cmp r1, #0 + cmp r1, #PLAT_QEMU_HOLD_STATE_WAIT beq 1f + + /* Clear the mailbox again ready for next time. */ + mov r1, #PLAT_QEMU_HOLD_STATE_WAIT + str r1, [r2, r0] + + /* Jump to the provided entrypoint. */ mov_imm r0, PLAT_QEMU_TRUSTED_MAILBOX_BASE ldr r1, [r0] bx r1 diff --git a/plat/qemu/aarch64/plat_helpers.S b/plat/qemu/common/aarch64/plat_helpers.S index 13a5ee461..dbcdc2d39 100644 --- a/plat/qemu/aarch64/plat_helpers.S +++ b/plat/qemu/common/aarch64/plat_helpers.S @@ -70,6 +70,12 @@ func plat_secondary_cold_boot_setup poll_mailbox: ldr x1, [x2, x0] cbz x1, 1f + + /* Clear the mailbox again ready for next time. */ + mov x1, #PLAT_QEMU_HOLD_STATE_WAIT + str x1, [x2, x0] + + /* Jump to the provided entrypoint. */ mov_imm x0, PLAT_QEMU_TRUSTED_MAILBOX_BASE ldr x1, [x0] br x1 diff --git a/plat/qemu/include/plat_macros.S b/plat/qemu/common/include/plat_macros.S index b6cdb0714..b6cdb0714 100644 --- a/plat/qemu/include/plat_macros.S +++ b/plat/qemu/common/include/plat_macros.S diff --git a/plat/qemu/qemu_bl1_setup.c b/plat/qemu/common/qemu_bl1_setup.c index 67f33273f..67f33273f 100644 --- a/plat/qemu/qemu_bl1_setup.c +++ b/plat/qemu/common/qemu_bl1_setup.c diff --git a/plat/qemu/qemu_bl2_mem_params_desc.c b/plat/qemu/common/qemu_bl2_mem_params_desc.c index a01f2dc91..f8b9066df 100644 --- a/plat/qemu/qemu_bl2_mem_params_desc.c +++ b/plat/qemu/common/qemu_bl2_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -139,8 +139,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), .image_info.image_base = NS_IMAGE_OFFSET, - .image_info.image_max_size = NS_DRAM0_BASE + NS_DRAM0_SIZE - - NS_IMAGE_OFFSET, + .image_info.image_max_size = NS_IMAGE_MAX_SIZE, # endif /* !PRELOADED_BL33_BASE */ .next_handoff_image_id = INVALID_IMAGE_ID, diff --git a/plat/qemu/qemu_bl2_setup.c b/plat/qemu/common/qemu_bl2_setup.c index 4c97c8dd6..3e289fc6b 100644 --- a/plat/qemu/qemu_bl2_setup.c +++ b/plat/qemu/common/qemu_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,6 +15,7 @@ #include <common/bl_common.h> #include <common/debug.h> #include <common/desc_image_load.h> +#include <common/fdt_fixup.h> #include <lib/optee_utils.h> #include <lib/utils.h> #include <plat/common/platform.h> @@ -50,7 +51,7 @@ static void security_setup(void) static void update_dt(void) { int ret; - void *fdt = (void *)(uintptr_t)PLAT_QEMU_DT_BASE; + void *fdt = (void *)(uintptr_t)ARM_PRELOADED_DTB_BASE; ret = fdt_open_into(fdt, fdt, PLAT_QEMU_DT_MAX_SIZE); if (ret < 0) { @@ -171,12 +172,12 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id) * OP-TEE expect to receive DTB address in x2. * This will be copied into x2 by dispatcher. */ - bl_mem_params->ep_info.args.arg3 = PLAT_QEMU_DT_BASE; + bl_mem_params->ep_info.args.arg3 = ARM_PRELOADED_DTB_BASE; #else /* case AARCH32_SP_OPTEE */ bl_mem_params->ep_info.args.arg0 = bl_mem_params->ep_info.args.arg1; bl_mem_params->ep_info.args.arg1 = 0; - bl_mem_params->ep_info.args.arg2 = PLAT_QEMU_DT_BASE; + bl_mem_params->ep_info.args.arg2 = ARM_PRELOADED_DTB_BASE; bl_mem_params->ep_info.args.arg3 = 0; #endif #endif @@ -191,8 +192,23 @@ static int qemu_bl2_handle_post_image_load(unsigned int image_id) pager_mem_params->ep_info.lr_svc = bl_mem_params->ep_info.pc; #endif +#if ARM_LINUX_KERNEL_AS_BL33 + /* + * According to the file ``Documentation/arm64/booting.txt`` of + * the Linux kernel tree, Linux expects the physical address of + * the device tree blob (DTB) in x0, while x1-x3 are reserved + * for future use and must be 0. + */ + bl_mem_params->ep_info.args.arg0 = + (u_register_t)ARM_PRELOADED_DTB_BASE; + bl_mem_params->ep_info.args.arg1 = 0U; + bl_mem_params->ep_info.args.arg2 = 0U; + bl_mem_params->ep_info.args.arg3 = 0U; +#else /* BL33 expects to receive the primary CPU MPID (through r0) */ bl_mem_params->ep_info.args.arg0 = 0xffff & read_mpidr(); +#endif + bl_mem_params->ep_info.spsr = qemu_get_spsr_for_bl33_entry(); break; default: diff --git a/plat/qemu/qemu_bl31_setup.c b/plat/qemu/common/qemu_bl31_setup.c index 4d36b0391..4d36b0391 100644 --- a/plat/qemu/qemu_bl31_setup.c +++ b/plat/qemu/common/qemu_bl31_setup.c diff --git a/plat/qemu/qemu_common.c b/plat/qemu/common/qemu_common.c index 56bf9532f..365cfb7f0 100644 --- a/plat/qemu/qemu_common.c +++ b/plat/qemu/common/qemu_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -41,6 +41,9 @@ #define MAP_FLASH0 MAP_REGION_FLAT(QEMU_FLASH0_BASE, QEMU_FLASH0_SIZE, \ MT_MEMORY | MT_RO | MT_SECURE) +#define MAP_FLASH1 MAP_REGION_FLAT(QEMU_FLASH1_BASE, QEMU_FLASH1_SIZE, \ + MT_MEMORY | MT_RO | MT_SECURE) + /* * Table of regions for various BL stages to map using the MMU. * This doesn't include TZRAM as the 'mem_layout' argument passed to @@ -49,6 +52,7 @@ #ifdef IMAGE_BL1 static const mmap_region_t plat_qemu_mmap[] = { MAP_FLASH0, + MAP_FLASH1, MAP_SHARED_RAM, MAP_DEVICE0, #ifdef MAP_DEVICE1 @@ -63,6 +67,7 @@ static const mmap_region_t plat_qemu_mmap[] = { #ifdef IMAGE_BL2 static const mmap_region_t plat_qemu_mmap[] = { MAP_FLASH0, + MAP_FLASH1, MAP_SHARED_RAM, MAP_DEVICE0, #ifdef MAP_DEVICE1 diff --git a/plat/qemu/qemu_console.c b/plat/qemu/common/qemu_console.c index fec182892..fec182892 100644 --- a/plat/qemu/qemu_console.c +++ b/plat/qemu/common/qemu_console.c diff --git a/plat/qemu/qemu_gicv2.c b/plat/qemu/common/qemu_gicv2.c index fb566227a..2c358ea1a 100644 --- a/plat/qemu/qemu_gicv2.c +++ b/plat/qemu/common/qemu_gicv2.c @@ -37,3 +37,8 @@ void qemu_pwr_gic_on_finish(void) /* Enable the gic cpu interface */ gicv2_cpuif_enable(); } + +void qemu_pwr_gic_off(void) +{ + gicv2_cpuif_disable(); +} diff --git a/plat/qemu/qemu_gicv3.c b/plat/qemu/common/qemu_gicv3.c index 28572c5ef..0d35446bd 100644 --- a/plat/qemu/qemu_gicv3.c +++ b/plat/qemu/common/qemu_gicv3.c @@ -44,3 +44,9 @@ void qemu_pwr_gic_on_finish(void) gicv3_rdistif_init(plat_my_core_pos()); gicv3_cpuif_enable(plat_my_core_pos()); } + +void qemu_pwr_gic_off(void) +{ + gicv3_cpuif_disable(plat_my_core_pos()); + gicv3_rdistif_off(plat_my_core_pos()); +} diff --git a/plat/qemu/qemu_image_load.c b/plat/qemu/common/qemu_image_load.c index 9970d1de7..9970d1de7 100644 --- a/plat/qemu/qemu_image_load.c +++ b/plat/qemu/common/qemu_image_load.c diff --git a/plat/qemu/qemu_io_storage.c b/plat/qemu/common/qemu_io_storage.c index 0e81cd199..0e81cd199 100644 --- a/plat/qemu/qemu_io_storage.c +++ b/plat/qemu/common/qemu_io_storage.c diff --git a/plat/qemu/qemu_pm.c b/plat/qemu/common/qemu_pm.c index a199688df..cf800096f 100644 --- a/plat/qemu/qemu_pm.c +++ b/plat/qemu/common/qemu_pm.c @@ -10,10 +10,13 @@ #include <arch_helpers.h> #include <common/debug.h> #include <lib/psci/psci.h> +#include <lib/semihosting.h> #include <plat/common/platform.h> #include "qemu_private.h" +#define ADP_STOPPED_APPLICATION_EXIT 0x20026 + /* * The secure entry point to be used on warm reset. */ @@ -149,9 +152,18 @@ static int qemu_pwr_domain_on(u_register_t mpidr) * Platform handler called when a power domain is about to be turned off. The * target_state encodes the power state that each level should transition to. ******************************************************************************/ -void qemu_pwr_domain_off(const psci_power_state_t *target_state) +static void qemu_pwr_domain_off(const psci_power_state_t *target_state) { - assert(0); + qemu_pwr_gic_off(); +} + +void __dead2 plat_secondary_cold_boot_setup(void); + +static void __dead2 +qemu_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ + disable_mmu_el3(); + plat_secondary_cold_boot_setup(); } /******************************************************************************* @@ -191,7 +203,8 @@ void qemu_pwr_domain_suspend_finish(const psci_power_state_t *target_state) ******************************************************************************/ static void __dead2 qemu_system_off(void) { - ERROR("QEMU System Off: operation not handled.\n"); + semihosting_exit(ADP_STOPPED_APPLICATION_EXIT, 0); + ERROR("QEMU System Off: semihosting call unexpectedly returned.\n"); panic(); } @@ -205,6 +218,7 @@ static const plat_psci_ops_t plat_qemu_psci_pm_ops = { .cpu_standby = qemu_cpu_standby, .pwr_domain_on = qemu_pwr_domain_on, .pwr_domain_off = qemu_pwr_domain_off, + .pwr_domain_pwr_down_wfi = qemu_pwr_domain_pwr_down_wfi, .pwr_domain_suspend = qemu_pwr_domain_suspend, .pwr_domain_on_finish = qemu_pwr_domain_on_finish, .pwr_domain_suspend_finish = qemu_pwr_domain_suspend_finish, diff --git a/plat/qemu/qemu_private.h b/plat/qemu/common/qemu_private.h index 46b1ca1e9..4dc62f539 100644 --- a/plat/qemu/qemu_private.h +++ b/plat/qemu/common/qemu_private.h @@ -28,12 +28,10 @@ void qemu_configure_mmu_el3(unsigned long total_base, unsigned long total_size, void plat_qemu_io_setup(void); unsigned int plat_qemu_calc_core_pos(u_register_t mpidr); -int dt_add_psci_node(void *fdt); -int dt_add_psci_cpu_enable_methods(void *fdt); - void qemu_console_init(void); void plat_qemu_gic_init(void); void qemu_pwr_gic_on_finish(void); +void qemu_pwr_gic_off(void); #endif /* QEMU_PRIVATE_H */ diff --git a/plat/qemu/qemu_rotpk.S b/plat/qemu/common/qemu_rotpk.S index 5d1b83f40..5d1b83f40 100644 --- a/plat/qemu/qemu_rotpk.S +++ b/plat/qemu/common/qemu_rotpk.S diff --git a/plat/qemu/qemu_stack_protector.c b/plat/qemu/common/qemu_stack_protector.c index c226158ad..c226158ad 100644 --- a/plat/qemu/qemu_stack_protector.c +++ b/plat/qemu/common/qemu_stack_protector.c diff --git a/plat/qemu/qemu_trusted_boot.c b/plat/qemu/common/qemu_trusted_boot.c index 1ef7e431b..1ef7e431b 100644 --- a/plat/qemu/qemu_trusted_boot.c +++ b/plat/qemu/common/qemu_trusted_boot.c diff --git a/plat/qemu/sp_min/sp_min-qemu.mk b/plat/qemu/common/sp_min/sp_min-qemu.mk index e93a0c231..e93a0c231 100644 --- a/plat/qemu/sp_min/sp_min-qemu.mk +++ b/plat/qemu/common/sp_min/sp_min-qemu.mk diff --git a/plat/qemu/sp_min/sp_min_setup.c b/plat/qemu/common/sp_min/sp_min_setup.c index 7ec657b79..7ec657b79 100644 --- a/plat/qemu/sp_min/sp_min_setup.c +++ b/plat/qemu/common/sp_min/sp_min_setup.c diff --git a/plat/qemu/topology.c b/plat/qemu/common/topology.c index 6352706e9..6352706e9 100644 --- a/plat/qemu/topology.c +++ b/plat/qemu/common/topology.c diff --git a/plat/qemu/dt.c b/plat/qemu/dt.c deleted file mode 100644 index b1cd368cb..000000000 --- a/plat/qemu/dt.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <string.h> - -#include <libfdt.h> - -#include <common/debug.h> -#include <drivers/console.h> -#include <lib/psci/psci.h> - -#include "qemu_private.h" - -static int append_psci_compatible(void *fdt, int offs, const char *str) -{ - return fdt_appendprop(fdt, offs, "compatible", str, strlen(str) + 1); -} - -int dt_add_psci_node(void *fdt) -{ - int offs; - - if (fdt_path_offset(fdt, "/psci") >= 0) { - WARN("PSCI Device Tree node already exists!\n"); - return 0; - } - - offs = fdt_path_offset(fdt, "/"); - if (offs < 0) - return -1; - offs = fdt_add_subnode(fdt, offs, "psci"); - if (offs < 0) - return -1; - if (append_psci_compatible(fdt, offs, "arm,psci-1.0")) - return -1; - if (append_psci_compatible(fdt, offs, "arm,psci-0.2")) - return -1; - if (append_psci_compatible(fdt, offs, "arm,psci")) - return -1; - if (fdt_setprop_string(fdt, offs, "method", "smc")) - return -1; - if (fdt_setprop_u32(fdt, offs, "cpu_suspend", PSCI_CPU_SUSPEND_AARCH64)) - return -1; - if (fdt_setprop_u32(fdt, offs, "cpu_off", PSCI_CPU_OFF)) - return -1; - if (fdt_setprop_u32(fdt, offs, "cpu_on", PSCI_CPU_ON_AARCH64)) - return -1; - if (fdt_setprop_u32(fdt, offs, "sys_poweroff", PSCI_SYSTEM_OFF)) - return -1; - if (fdt_setprop_u32(fdt, offs, "sys_reset", PSCI_SYSTEM_RESET)) - return -1; - return 0; -} - -static int check_node_compat_prefix(void *fdt, int offs, const char *prefix) -{ - const size_t prefix_len = strlen(prefix); - size_t l; - int plen; - const char *prop; - - prop = fdt_getprop(fdt, offs, "compatible", &plen); - if (!prop) - return -1; - - while (plen > 0) { - if (memcmp(prop, prefix, prefix_len) == 0) - return 0; /* match */ - - l = strlen(prop) + 1; - prop += l; - plen -= l; - } - - return -1; -} - -int dt_add_psci_cpu_enable_methods(void *fdt) -{ - int offs = 0; - - while (1) { - offs = fdt_next_node(fdt, offs, NULL); - if (offs < 0) - break; - if (fdt_getprop(fdt, offs, "enable-method", NULL)) - continue; /* already set */ - if (check_node_compat_prefix(fdt, offs, "arm,cortex-a")) - continue; /* no compatible */ - if (fdt_setprop_string(fdt, offs, "enable-method", "psci")) - return -1; - /* Need to restart scanning as offsets may have changed */ - offs = 0; - } - return 0; -} diff --git a/plat/qemu/include/platform_def.h b/plat/qemu/qemu/include/platform_def.h index d7f77cc78..cce992ff9 100644 --- a/plat/qemu/include/platform_def.h +++ b/plat/qemu/qemu/include/platform_def.h @@ -18,20 +18,20 @@ #define PLATFORM_STACK_SIZE 0x1000 #if ARM_ARCH_MAJOR == 7 -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 1 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #else -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 -#define PLATFORM_CLUSTER_COUNT 2 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(2) #define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER #endif #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ PLATFORM_CLUSTER1_CORE_COUNT) -#define QEMU_PRIMARY_CPU 0 +#define QEMU_PRIMARY_CPU U(0) #define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) @@ -165,11 +165,12 @@ # error "Unsupported BL32_RAM_LOCATION_ID value" #endif -#define NS_IMAGE_OFFSET 0x60000000 +#define NS_IMAGE_OFFSET (NS_DRAM0_BASE + 0x20000000) +#define NS_IMAGE_MAX_SIZE (NS_DRAM0_SIZE - 0x20000000) #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) -#define MAX_MMAP_REGIONS 10 +#define MAX_MMAP_REGIONS 11 #define MAX_XLAT_TABLES 6 #define MAX_IO_DEVICES 3 #define MAX_IO_HANDLES 4 @@ -190,11 +191,13 @@ #define PLAT_QEMU_CONSOLE_BAUDRATE 115200 -#define QEMU_FLASH0_BASE 0x04000000 +#define QEMU_FLASH0_BASE 0x00000000 #define QEMU_FLASH0_SIZE 0x04000000 +#define QEMU_FLASH1_BASE 0x04000000 +#define QEMU_FLASH1_SIZE 0x04000000 -#define PLAT_QEMU_FIP_BASE QEMU_FLASH0_BASE -#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH0_SIZE +#define PLAT_QEMU_FIP_BASE QEMU_FLASH1_BASE +#define PLAT_QEMU_FIP_MAX_SIZE QEMU_FLASH1_SIZE #define DEVICE0_BASE 0x08000000 #define DEVICE0_SIZE 0x01000000 diff --git a/plat/qemu/platform.mk b/plat/qemu/qemu/platform.mk index 6b9749c79..b95bf5a51 100644 --- a/plat/qemu/platform.mk +++ b/plat/qemu/qemu/platform.mk @@ -32,16 +32,20 @@ ifeq ($(NEED_BL32),yes) $(eval $(call add_define,QEMU_LOAD_BL32)) endif -PLAT_PATH := plat/qemu/ -PLAT_INCLUDES := -Iplat/qemu/include +PLAT_QEMU_PATH := plat/qemu/qemu +PLAT_QEMU_COMMON_PATH := plat/qemu/common +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -I${PLAT_QEMU_COMMON_PATH}/include \ + -I${PLAT_QEMU_PATH}/include \ + -Iinclude/common/tbbr ifeq (${ARM_ARCH_MAJOR},8) PLAT_INCLUDES += -Iinclude/plat/arm/common/${ARCH} endif -PLAT_BL_COMMON_SOURCES := plat/qemu/qemu_common.c \ - plat/qemu/qemu_console.c \ - drivers/arm/pl011/${ARCH}/pl011_console.S \ +PLAT_BL_COMMON_SOURCES := ${PLAT_QEMU_COMMON_PATH}/qemu_common.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_console.c \ + drivers/arm/pl011/${ARCH}/pl011_console.S include lib/xlat_tables_v2/xlat_tables.mk PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} @@ -59,13 +63,13 @@ ifneq (${TRUSTED_BOARD_BOOT},0) BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/common/tbbr/plat_tbbr.c \ - plat/qemu/qemu_trusted_boot.c \ - $(PLAT_PATH)/qemu_rotpk.S + ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ - plat/qemu/qemu_trusted_boot.c \ - $(PLAT_PATH)/qemu_rotpk.S + ${PLAT_QEMU_COMMON_PATH}/qemu_trusted_boot.c \ + $(PLAT_QEMU_COMMON_PATH)/qemu_rotpk.S ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin @@ -93,9 +97,9 @@ BL1_SOURCES += drivers/io/io_semihosting.c \ drivers/io/io_memmap.c \ lib/semihosting/semihosting.c \ lib/semihosting/${ARCH}/semihosting_call.S \ - plat/qemu/qemu_io_storage.c \ - plat/qemu/${ARCH}/plat_helpers.S \ - plat/qemu/qemu_bl1_setup.c + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c ifeq (${ARM_ARCH_MAJOR},8) BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \ @@ -110,13 +114,13 @@ BL2_SOURCES += drivers/io/io_semihosting.c \ drivers/io/io_fip.c \ drivers/io/io_memmap.c \ lib/semihosting/semihosting.c \ - lib/semihosting/${ARCH}/semihosting_call.S\ - plat/qemu/qemu_io_storage.c \ - plat/qemu/${ARCH}/plat_helpers.S \ - plat/qemu/qemu_bl2_setup.c \ - plat/qemu/dt.c \ - plat/qemu/qemu_bl2_mem_params_desc.c \ - plat/qemu/qemu_image_load.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \ + common/fdt_fixup.c \ common/desc_image_load.c ifeq ($(add-lib-optee),yes) @@ -127,13 +131,13 @@ QEMU_GICV2_SOURCES := drivers/arm/gic/v2/gicv2_helpers.c \ drivers/arm/gic/v2/gicv2_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv2.c \ - plat/qemu/qemu_gicv2.c + ${PLAT_QEMU_COMMON_PATH}/qemu_gicv2.c QEMU_GICV3_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/common/gic_common.c \ plat/common/plat_gicv3.c \ - plat/qemu/qemu_gicv3.c + ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c ifeq (${QEMU_USE_GIC_DRIVER}, QEMU_GICV2) QEMU_GIC_SOURCES := ${QEMU_GICV2_SOURCES} @@ -147,11 +151,13 @@ ifeq (${ARM_ARCH_MAJOR},8) BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a57.S \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ plat/common/plat_psci_common.c \ - plat/qemu/qemu_pm.c \ - plat/qemu/topology.c \ - plat/qemu/aarch64/plat_helpers.S \ - plat/qemu/qemu_bl31_setup.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ + ${PLAT_QEMU_COMMON_PATH}/topology.c \ + ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ ${QEMU_GIC_SOURCES} endif @@ -167,7 +173,7 @@ endif SEPARATE_CODE_AND_RODATA := 1 ENABLE_STACK_PROTECTOR := 0 ifneq ($(ENABLE_STACK_PROTECTOR), 0) - PLAT_BL_COMMON_SOURCES += plat/qemu/qemu_stack_protector.c + PLAT_BL_COMMON_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c endif BL32_RAM_LOCATION := tdram @@ -182,5 +188,13 @@ endif # Process flags $(eval $(call add_define,BL32_RAM_LOCATION_ID)) +# Don't have the Linux kernel as a BL33 image by default +ARM_LINUX_KERNEL_AS_BL33 := 0 +$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33)) +$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) + +ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE +$(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) + # Do not enable SVE ENABLE_SVE_FOR_NS := 0 diff --git a/plat/qemu/qemu_sbsa/include/platform_def.h b/plat/qemu/qemu_sbsa/include/platform_def.h new file mode 100644 index 000000000..f44b9f6e0 --- /dev/null +++ b/plat/qemu/qemu_sbsa/include/platform_def.h @@ -0,0 +1,243 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * + * Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. + */ + +#ifndef __PLATFORM_DEF_H__ +#define __PLATFORM_DEF_H__ + +#include <arch.h> +#include <plat/common/common_def.h> +#include <tbbr_img_def.h> + +/* Special value used to verify platform parameters from BL2 to BL3-1 */ +#define QEMU_BL31_PLAT_PARAM_VAL 0x0f1e2d3c4b5a6978ULL + +#define PLATFORM_STACK_SIZE 0x1000 + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CLUSTER1_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT + \ + PLATFORM_CLUSTER1_CORE_COUNT) + +#define QEMU_PRIMARY_CPU U(0) + +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 + +#define PLAT_MAX_RET_STATE 1 +#define PLAT_MAX_OFF_STATE 2 + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN 0 +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET 1 +/* + * Local power state for OFF/power-down. Valid for CPU and cluster power + * domains. + */ +#define PLAT_LOCAL_STATE_OFF 2 + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH 4 +#define PLAT_LOCAL_PSTATE_MASK ((1 << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT 6 +#define CACHE_WRITEBACK_GRANULE (1 << CACHE_WRITEBACK_SHIFT) + +/* + * Partition memory into secure ROM, non-secure DRAM, secure "SRAM", + * and secure DRAM. + */ +#define SEC_ROM_BASE 0x00000000 +#define SEC_ROM_SIZE 0x00020000 + +#define NS_DRAM0_BASE 0x10000000000ULL +#define NS_DRAM0_SIZE 0x00020000000 + +#define SEC_SRAM_BASE 0x20000000 +#define SEC_SRAM_SIZE 0x20000000 + +/* + * RAD just placeholders, need to be chosen after finalizing mem map + */ +#define SEC_DRAM_BASE 0x1000 +#define SEC_DRAM_SIZE 0x1000 + +/* Load pageable part of OP-TEE 2MB above secure DRAM base */ +#define QEMU_OPTEE_PAGEABLE_LOAD_BASE (SEC_DRAM_BASE + 0x00200000) +#define QEMU_OPTEE_PAGEABLE_LOAD_SIZE 0x00400000 + +/* + * ARM-TF lives in SRAM, partition it here + */ + +#define SHARED_RAM_BASE SEC_SRAM_BASE +#define SHARED_RAM_SIZE 0x00001000 + +#define PLAT_QEMU_TRUSTED_MAILBOX_BASE SHARED_RAM_BASE +#define PLAT_QEMU_TRUSTED_MAILBOX_SIZE (8 + PLAT_QEMU_HOLD_SIZE) +#define PLAT_QEMU_HOLD_BASE (PLAT_QEMU_TRUSTED_MAILBOX_BASE + 8) +#define PLAT_QEMU_HOLD_SIZE (PLATFORM_CORE_COUNT * \ + PLAT_QEMU_HOLD_ENTRY_SIZE) +#define PLAT_QEMU_HOLD_ENTRY_SHIFT 3 +#define PLAT_QEMU_HOLD_ENTRY_SIZE (1 << PLAT_QEMU_HOLD_ENTRY_SHIFT) +#define PLAT_QEMU_HOLD_STATE_WAIT 0 +#define PLAT_QEMU_HOLD_STATE_GO 1 + +#define BL_RAM_BASE (SHARED_RAM_BASE + SHARED_RAM_SIZE) +#define BL_RAM_SIZE (SEC_SRAM_SIZE - SHARED_RAM_SIZE) + +/* + * BL1 specific defines. + * + * BL1 RW data is relocated from ROM to RAM at runtime so we need 2 sets of + * addresses. + * Put BL1 RW at the top of the Secure SRAM. BL1_RW_BASE is calculated using + * the current BL1 RW debug size plus a little space for growth. + */ +#define BL1_RO_BASE SEC_ROM_BASE +#define BL1_RO_LIMIT (SEC_ROM_BASE + SEC_ROM_SIZE) +#define BL1_RW_BASE (BL1_RW_LIMIT - 0x12000) +#define BL1_RW_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) + +/* + * BL2 specific defines. + * + * Put BL2 just below BL3-1. BL2_BASE is calculated using the current BL2 debug + * size plus a little space for growth. + */ +#define BL2_BASE (BL31_BASE - 0x1D000) +#define BL2_LIMIT BL31_BASE + +/* + * BL3-1 specific defines. + * + * Put BL3-1 at the top of the Trusted SRAM. BL31_BASE is calculated using the + * current BL3-1 debug size plus a little space for growth. + */ +#define BL31_BASE (BL31_LIMIT - 0x20000) +#define BL31_LIMIT (BL_RAM_BASE + BL_RAM_SIZE) +#define BL31_PROGBITS_LIMIT BL1_RW_BASE + + +/* + * BL3-2 specific defines. + * + * BL3-2 can execute from Secure SRAM, or Secure DRAM. + */ +#define BL32_SRAM_BASE BL_RAM_BASE +#define BL32_SRAM_LIMIT BL31_BASE +#define BL32_DRAM_BASE SEC_DRAM_BASE +#define BL32_DRAM_LIMIT (SEC_DRAM_BASE + SEC_DRAM_SIZE) + +#define BL32_MEM_BASE BL_RAM_BASE +#define BL32_MEM_SIZE BL_RAM_SIZE +#define BL32_BASE BL32_SRAM_BASE +#define BL32_LIMIT BL32_SRAM_LIMIT + +#define NS_IMAGE_OFFSET (NS_DRAM0_BASE + 0x20000000) +#define NS_IMAGE_MAX_SIZE (NS_DRAM0_SIZE - 0x20000000) + +#define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 42) +#define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 42) +#define MAX_MMAP_REGIONS 11 +#define MAX_XLAT_TABLES 10 +#define MAX_IO_DEVICES 3 +#define MAX_IO_HANDLES 4 + +/* + * PL011 related constants + */ +#define UART0_BASE 0x60000000 +#define UART1_BASE 0x60030000 +#define UART0_CLK_IN_HZ 1 +#define UART1_CLK_IN_HZ 1 + +#define PLAT_QEMU_BOOT_UART_BASE UART0_BASE +#define PLAT_QEMU_BOOT_UART_CLK_IN_HZ UART0_CLK_IN_HZ + +#define PLAT_QEMU_CRASH_UART_BASE UART1_BASE +#define PLAT_QEMU_CRASH_UART_CLK_IN_HZ UART1_CLK_IN_HZ + +#define PLAT_QEMU_CONSOLE_BAUDRATE 115200 + +#define QEMU_FLASH0_BASE 0x00000000 +#define QEMU_FLASH0_SIZE 0x10000000 +#define QEMU_FLASH1_BASE 0x10000000 +#define QEMU_FLASH1_SIZE 0x10000000 + +#define PLAT_QEMU_FIP_BASE 0x00008000 +#define PLAT_QEMU_FIP_MAX_SIZE 0x00020000 + +/* This is map from GIC_DIST up to last CPU (255) GIC_REDISTR */ +#define DEVICE0_BASE 0x40000000 +#define DEVICE0_SIZE 0x04080000 +/* This is map from NORMAL_UART up to SECURE_UART_MM */ +#define DEVICE1_BASE 0x60000000 +#define DEVICE1_SIZE 0x00041000 + +/* + * GIC related constants + * We use GICv3 where CPU Interface registers are not memory mapped + */ +#define GICD_BASE 0x40060000 +#define GICR_BASE 0x40080000 +#define GICC_BASE 0x0 + +#define QEMU_IRQ_SEC_SGI_0 8 +#define QEMU_IRQ_SEC_SGI_1 9 +#define QEMU_IRQ_SEC_SGI_2 10 +#define QEMU_IRQ_SEC_SGI_3 11 +#define QEMU_IRQ_SEC_SGI_4 12 +#define QEMU_IRQ_SEC_SGI_5 13 +#define QEMU_IRQ_SEC_SGI_6 14 +#define QEMU_IRQ_SEC_SGI_7 15 + +/****************************************************************************** + * On a GICv2 system, the Group 1 secure interrupts are treated as Group 0 + * interrupts. + *****************************************************************************/ +#define PLATFORM_G1S_PROPS(grp) \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_0, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_1, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_2, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_3, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_4, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_5, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_6, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE), \ + INTR_PROP_DESC(QEMU_IRQ_SEC_SGI_7, GIC_HIGHEST_SEC_PRIORITY, \ + grp, GIC_INTR_CFG_EDGE) + +#define PLATFORM_G0_PROPS(grp) + +/* + * DT related constants + */ +#define PLAT_QEMU_DT_BASE NS_DRAM0_BASE +#define PLAT_QEMU_DT_MAX_SIZE 0x10000 + +/* + * System counter + */ +#define SYS_COUNTER_FREQ_IN_TICKS ((1000 * 1000 * 1000) / 16) + +#endif /* __PLATFORM_DEF_H__ */ diff --git a/plat/qemu/qemu_sbsa/platform.mk b/plat/qemu/qemu_sbsa/platform.mk new file mode 100644 index 000000000..51832d0ff --- /dev/null +++ b/plat/qemu/qemu_sbsa/platform.mk @@ -0,0 +1,111 @@ +# +# Copyright (c) 2019, Linaro Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +CRASH_REPORTING := 1 + +include lib/libfdt/libfdt.mk + +# Enable new version of image loading on QEMU platforms +LOAD_IMAGE_V2 := 1 + +ifeq ($(NEED_BL32),yes) +$(eval $(call add_define,QEMU_LOAD_BL32)) +endif + +PLAT_QEMU_PATH := plat/qemu/qemu_sbsa +PLAT_QEMU_COMMON_PATH := plat/qemu/common +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -I${PLAT_QEMU_COMMON_PATH}/include \ + -I${PLAT_QEMU_PATH}/include \ + -Iinclude/common/tbbr + +PLAT_INCLUDES += -Iinclude/plat/arm/common/${ARCH} + +PLAT_BL_COMMON_SOURCES := ${PLAT_QEMU_COMMON_PATH}/qemu_common.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_console.c \ + drivers/arm/pl011/${ARCH}/pl011_console.S + +include lib/xlat_tables_v2/xlat_tables.mk +PLAT_BL_COMMON_SOURCES += ${XLAT_TABLES_LIB_SRCS} + +BL1_SOURCES += drivers/io/io_semihosting.c \ + drivers/io/io_storage.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl1_setup.c + +BL1_SOURCES += lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S + +BL2_SOURCES += drivers/io/io_semihosting.c \ + drivers/io/io_storage.c \ + drivers/io/io_fip.c \ + drivers/io/io_memmap.c \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_io_storage.c \ + ${PLAT_QEMU_COMMON_PATH}/${ARCH}/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_setup.c \ + common/fdt_fixup.c \ + $(LIBFDT_SRCS) +ifeq (${LOAD_IMAGE_V2},1) +BL2_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_bl2_mem_params_desc.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_image_load.c \ + common/desc_image_load.c +endif + +QEMU_GIC_SOURCES := drivers/arm/gic/v3/gicv3_helpers.c \ + drivers/arm/gic/v3/gicv3_main.c \ + drivers/arm/gic/common/gic_common.c \ + plat/common/plat_gicv3.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_gicv3.c + +BL31_SOURCES += lib/cpus/aarch64/aem_generic.S \ + lib/cpus/aarch64/cortex_a53.S \ + lib/cpus/aarch64/cortex_a57.S \ + lib/semihosting/semihosting.c \ + lib/semihosting/${ARCH}/semihosting_call.S \ + plat/common/plat_psci_common.c \ + ${PLAT_QEMU_COMMON_PATH}/qemu_pm.c \ + ${PLAT_QEMU_COMMON_PATH}/topology.c \ + ${PLAT_QEMU_COMMON_PATH}/aarch64/plat_helpers.S \ + ${PLAT_QEMU_COMMON_PATH}/qemu_bl31_setup.c \ + ${QEMU_GIC_SOURCES} + +SEPARATE_CODE_AND_RODATA := 1 +ENABLE_STACK_PROTECTOR := 0 +ifneq ($(ENABLE_STACK_PROTECTOR), 0) + PLAT_BL_COMMON_SOURCES += ${PLAT_QEMU_COMMON_PATH}/qemu_stack_protector.c +endif + +MULTI_CONSOLE_API := 1 + +# Disable the PSCI platform compatibility layer +ENABLE_PLAT_COMPAT := 0 + +# Use known base for UEFI if not given from command line +# By default BL33 is at FLASH1 base +PRELOADED_BL33_BASE ?= 0x10000000 + +# Qemu SBSA plafrom only support SEC_SRAM +BL32_RAM_LOCATION_ID = SEC_SRAM_ID +$(eval $(call add_define,BL32_RAM_LOCATION_ID)) + +# Don't have the Linux kernel as a BL33 image by default +ARM_LINUX_KERNEL_AS_BL33 := 0 +$(eval $(call assert_boolean,ARM_LINUX_KERNEL_AS_BL33)) +$(eval $(call add_define,ARM_LINUX_KERNEL_AS_BL33)) + +ARM_PRELOADED_DTB_BASE := PLAT_QEMU_DT_BASE +$(eval $(call add_define,ARM_PRELOADED_DTB_BASE)) + +# Do not enable SVE +ENABLE_SVE_FOR_NS := 0 diff --git a/plat/renesas/rcar/aarch64/plat_helpers.S b/plat/renesas/rcar/aarch64/plat_helpers.S index 61dd62287..138d98807 100644 --- a/plat/renesas/rcar/aarch64/plat_helpers.S +++ b/plat/renesas/rcar/aarch64/plat_helpers.S @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause @@ -189,7 +189,7 @@ func bl2_enter_bl31 ldp x0, x1, [x20, #ENTRY_POINT_INFO_PC_OFFSET] msr elr_el3, x0 msr spsr_el3, x1 - eret + exception_return endfunc bl2_enter_bl31 /* ----------------------------------------------------- diff --git a/plat/renesas/rcar/bl2_cpg_init.c b/plat/renesas/rcar/bl2_cpg_init.c index ed9b7724d..c3ca9ea16 100644 --- a/plat/renesas/rcar/bl2_cpg_init.c +++ b/plat/renesas/rcar/bl2_cpg_init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -109,12 +109,12 @@ static void bl2_secure_cpg_init(void) #if (RCAR_LSI == RCAR_AUTO) || (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) static void bl2_realtime_cpg_init_h3(void) { - uint32_t cut = mmio_read_32(RCAR_PRR) & RCAR_CUT_MASK; + uint32_t cut = mmio_read_32(RCAR_PRR) & PRR_CUT_MASK; uint32_t cr0, cr8; - cr0 = (cut == RCAR_CUT_VER10 || cut == RCAR_CUT_VER11) ? + cr0 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? 0x00200000U : 0x00210000U; - cr8 = (cut == RCAR_CUT_VER10 || cut == RCAR_CUT_VER11) ? + cr8 = (cut == PRR_PRODUCT_10 || cut == PRR_PRODUCT_11) ? 0x01F1FFF4U : 0x01F1FFF7U; cpg_write(RMSTPCR0, cr0); @@ -329,7 +329,7 @@ void bl2_cpg_init(void) { uint32_t boot_cpu = mmio_read_32(RCAR_MODEMR) & MODEMR_BOOT_CPU_MASK; #if RCAR_LSI == RCAR_AUTO - uint32_t product = mmio_read_32(RCAR_PRR) & RCAR_PRODUCT_MASK; + uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; #endif bl2_secure_cpg_init(); @@ -338,22 +338,22 @@ void bl2_cpg_init(void) #if RCAR_LSI == RCAR_AUTO switch (product) { - case RCAR_PRODUCT_H3: + case PRR_PRODUCT_H3: bl2_realtime_cpg_init_h3(); break; - case RCAR_PRODUCT_M3: + case PRR_PRODUCT_M3: bl2_realtime_cpg_init_m3(); break; - case RCAR_PRODUCT_M3N: + case PRR_PRODUCT_M3N: bl2_realtime_cpg_init_m3n(); break; - case RCAR_PRODUCT_V3M: + case PRR_PRODUCT_V3M: bl2_realtime_cpg_init_v3m(); break; - case RCAR_PRODUCT_E3: + case PRR_PRODUCT_E3: bl2_realtime_cpg_init_e3(); break; - case RCAR_PRODUCT_D3: + case PRR_PRODUCT_D3: bl2_realtime_cpg_init_d3(); break; default: @@ -381,25 +381,25 @@ void bl2_cpg_init(void) void bl2_system_cpg_init(void) { #if RCAR_LSI == RCAR_AUTO - uint32_t product = mmio_read_32(RCAR_PRR) & RCAR_PRODUCT_MASK; + uint32_t product = mmio_read_32(RCAR_PRR) & PRR_PRODUCT_MASK; switch (product) { - case RCAR_PRODUCT_H3: + case PRR_PRODUCT_H3: bl2_system_cpg_init_h3(); break; - case RCAR_PRODUCT_M3: + case PRR_PRODUCT_M3: bl2_system_cpg_init_m3(); break; - case RCAR_PRODUCT_M3N: + case PRR_PRODUCT_M3N: bl2_system_cpg_init_m3n(); break; - case RCAR_PRODUCT_V3M: + case PRR_PRODUCT_V3M: bl2_system_cpg_init_v3m(); break; - case RCAR_PRODUCT_E3: + case PRR_PRODUCT_E3: bl2_system_cpg_init_e3(); break; - case RCAR_PRODUCT_D3: + case PRR_PRODUCT_D3: bl2_system_cpg_init_d3(); break; default: diff --git a/plat/renesas/rcar/bl2_plat_mem_params_desc.c b/plat/renesas/rcar/bl2_plat_mem_params_desc.c index 3b124c789..bf2706d53 100644 --- a/plat/renesas/rcar/bl2_plat_mem_params_desc.c +++ b/plat/renesas/rcar/bl2_plat_mem_params_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016-2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -53,6 +53,7 @@ static bl_mem_params_node_t bl2_mem_params_descs[] = { entry_point_info_t, SECURE | EXECUTABLE), .ep_info.pc = BL32_BASE, .ep_info.spsr = 0, + .ep_info.args.arg3 = (uintptr_t)fdt_blob, SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), diff --git a/plat/renesas/rcar/bl2_plat_setup.c b/plat/renesas/rcar/bl2_plat_setup.c index 3c9b56f4e..578892eb3 100644 --- a/plat/renesas/rcar/bl2_plat_setup.c +++ b/plat/renesas/rcar/bl2_plat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2018-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -39,12 +39,19 @@ #include "rcar_version.h" #include "rom_api.h" -IMPORT_SYM(unsigned long, __RO_START__, BL2_RO_BASE) -IMPORT_SYM(unsigned long, __RO_END__, BL2_RO_LIMIT) +#if RCAR_BL2_DCACHE == 1 +/* + * Following symbols are only used during plat_arch_setup() only + * when RCAR_BL2_DCACHE is enabled. + */ +static const uint64_t BL2_RO_BASE = BL_CODE_BASE; +static const uint64_t BL2_RO_LIMIT = BL_CODE_END; #if USE_COHERENT_MEM -IMPORT_SYM(unsigned long, __COHERENT_RAM_START__, BL2_COHERENT_RAM_BASE) -IMPORT_SYM(unsigned long, __COHERENT_RAM_END__, BL2_COHERENT_RAM_LIMIT) +static const uint64_t BL2_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; +static const uint64_t BL2_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; +#endif + #endif extern void plat_rcar_gic_driver_init(void); @@ -65,22 +72,22 @@ static void bl2_init_generic_timer(void); /* R-Car Gen3 product check */ #if (RCAR_LSI == RCAR_H3) || (RCAR_LSI == RCAR_H3N) -#define TARGET_PRODUCT RCAR_PRODUCT_H3 +#define TARGET_PRODUCT PRR_PRODUCT_H3 #define TARGET_NAME "R-Car H3" #elif RCAR_LSI == RCAR_M3 -#define TARGET_PRODUCT RCAR_PRODUCT_M3 +#define TARGET_PRODUCT PRR_PRODUCT_M3 #define TARGET_NAME "R-Car M3" #elif RCAR_LSI == RCAR_M3N -#define TARGET_PRODUCT RCAR_PRODUCT_M3N +#define TARGET_PRODUCT PRR_PRODUCT_M3N #define TARGET_NAME "R-Car M3N" #elif RCAR_LSI == RCAR_V3M -#define TARGET_PRODUCT RCAR_PRODUCT_V3M +#define TARGET_PRODUCT PRR_PRODUCT_V3M #define TARGET_NAME "R-Car V3M" #elif RCAR_LSI == RCAR_E3 -#define TARGET_PRODUCT RCAR_PRODUCT_E3 +#define TARGET_PRODUCT PRR_PRODUCT_E3 #define TARGET_NAME "R-Car E3" #elif RCAR_LSI == RCAR_D3 -#define TARGET_PRODUCT RCAR_PRODUCT_D3 +#define TARGET_PRODUCT PRR_PRODUCT_D3 #define TARGET_NAME "R-Car D3" #elif RCAR_LSI == RCAR_AUTO #define TARGET_NAME "R-Car H3/M3/M3N/V3M" @@ -238,17 +245,17 @@ void bl2_plat_flush_bl31_params(void) bl2_secure_setting(); reg = mmio_read_32(RCAR_PRR); - product_cut = reg & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK); - product = reg & RCAR_PRODUCT_MASK; - cut = reg & RCAR_CUT_MASK; + product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + product = reg & PRR_PRODUCT_MASK; + cut = reg & PRR_CUT_MASK; - if (product == RCAR_PRODUCT_M3 && RCAR_CUT_VER30 > cut) + if (product == PRR_PRODUCT_M3 && PRR_PRODUCT_30 > cut) goto tlb; - if (product == RCAR_PRODUCT_H3 && RCAR_CUT_VER20 > cut) + if (product == PRR_PRODUCT_H3 && PRR_PRODUCT_20 > cut) goto tlb; - if (product == RCAR_PRODUCT_D3) + if (product == PRR_PRODUCT_D3) goto tlb; /* Disable MFIS write protection */ @@ -261,28 +268,28 @@ tlb: boot_cpu != MODEMR_BOOT_CPU_CA53) goto mmu; - if (product_cut == RCAR_PRODUCT_H3_CUT20) { + if (product_cut == PRR_PRODUCT_H3_CUT20) { mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUVI1_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV1_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV2_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV3_IMSCTLR, IMSCTLR_DISCACHE); - } else if (product_cut == (RCAR_PRODUCT_M3N | RCAR_CUT_VER10) || - product_cut == (RCAR_PRODUCT_M3N | RCAR_CUT_VER11)) { + } else if (product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11)) { mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); - } else if ((product_cut == (RCAR_PRODUCT_E3 | RCAR_CUT_VER10)) || - (product_cut == (RCAR_PRODUCT_E3 | RCAR_CUT_VER11))) { + } else if ((product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) || + (product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_11))) { mmio_write_32(IPMMUVI0_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUVP0_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUPV0_IMSCTLR, IMSCTLR_DISCACHE); } - if (product_cut == (RCAR_PRODUCT_H3_CUT20) || - product_cut == (RCAR_PRODUCT_M3N | RCAR_CUT_VER10) || - product_cut == (RCAR_PRODUCT_M3N | RCAR_CUT_VER11) || - product_cut == (RCAR_PRODUCT_E3 | RCAR_CUT_VER10)) { + if (product_cut == (PRR_PRODUCT_H3_CUT20) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_10) || + product_cut == (PRR_PRODUCT_M3N | PRR_PRODUCT_11) || + product_cut == (PRR_PRODUCT_E3 | PRR_PRODUCT_10)) { mmio_write_32(IPMMUHC_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMURT_IMSCTLR, IMSCTLR_DISCACHE); mmio_write_32(IPMMUMP_IMSCTLR, IMSCTLR_DISCACHE); @@ -408,43 +415,46 @@ struct meminfo *bl2_plat_sec_mem_layout(void) return &bl2_tzram_layout; } -static void bl2_populate_compatible_string(void *fdt) +static void bl2_populate_compatible_string(void *dt) { uint32_t board_type; uint32_t board_rev; uint32_t reg; int ret; + fdt_setprop_u32(dt, 0, "#address-cells", 2); + fdt_setprop_u32(dt, 0, "#size-cells", 2); + /* Populate compatible string */ rcar_get_board_type(&board_type, &board_rev); switch (board_type) { case BOARD_SALVATOR_X: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,salvator-x"); break; case BOARD_SALVATOR_XS: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,salvator-xs"); break; case BOARD_STARTER_KIT: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,m3ulcb"); break; case BOARD_STARTER_KIT_PRE: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,h3ulcb"); break; case BOARD_EAGLE: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,eagle"); break; case BOARD_EBISU: case BOARD_EBISU_4D: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,ebisu"); break; case BOARD_DRAAK: - ret = fdt_setprop_string(fdt, 0, "compatible", + ret = fdt_setprop_string(dt, 0, "compatible", "renesas,draak"); break; default: @@ -458,29 +468,29 @@ static void bl2_populate_compatible_string(void *fdt) } reg = mmio_read_32(RCAR_PRR); - switch (reg & RCAR_PRODUCT_MASK) { - case RCAR_PRODUCT_H3: - ret = fdt_appendprop_string(fdt, 0, "compatible", + switch (reg & PRR_PRODUCT_MASK) { + case PRR_PRODUCT_H3: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a7795"); break; - case RCAR_PRODUCT_M3: - ret = fdt_appendprop_string(fdt, 0, "compatible", + case PRR_PRODUCT_M3: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a7796"); break; - case RCAR_PRODUCT_M3N: - ret = fdt_appendprop_string(fdt, 0, "compatible", + case PRR_PRODUCT_M3N: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a77965"); break; - case RCAR_PRODUCT_V3M: - ret = fdt_appendprop_string(fdt, 0, "compatible", + case PRR_PRODUCT_V3M: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a77970"); break; - case RCAR_PRODUCT_E3: - ret = fdt_appendprop_string(fdt, 0, "compatible", + case PRR_PRODUCT_E3: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a77990"); break; - case RCAR_PRODUCT_D3: - ret = fdt_appendprop_string(fdt, 0, "compatible", + case PRR_PRODUCT_D3: + ret = fdt_appendprop_string(dt, 0, "compatible", "renesas,r8a77995"); break; default: @@ -572,7 +582,7 @@ static void bl2_advertise_dram_size(uint32_t product) }; switch (product) { - case RCAR_PRODUCT_H3: + case PRR_PRODUCT_H3: #if (RCAR_DRAM_LPDDR4_MEMCONF == 0) /* 4GB(1GBx4) */ dram_config[1] = 0x40000000ULL; @@ -594,7 +604,7 @@ static void bl2_advertise_dram_size(uint32_t product) #endif /* RCAR_DRAM_LPDDR4_MEMCONF == 0 */ break; - case RCAR_PRODUCT_M3: + case PRR_PRODUCT_M3: #if (RCAR_GEN3_ULCB == 1) /* 2GB(1GBx2 2ch split) */ dram_config[1] = 0x40000000ULL; @@ -606,17 +616,17 @@ static void bl2_advertise_dram_size(uint32_t product) #endif break; - case RCAR_PRODUCT_M3N: + case PRR_PRODUCT_M3N: /* 2GB(1GBx2) */ dram_config[1] = 0x80000000ULL; break; - case RCAR_PRODUCT_V3M: + case PRR_PRODUCT_V3M: /* 1GB(512MBx2) */ dram_config[1] = 0x40000000ULL; break; - case RCAR_PRODUCT_E3: + case PRR_PRODUCT_E3: #if (RCAR_DRAM_DDR3L_MEMCONF == 0) /* 1GB(512MBx2) */ dram_config[1] = 0x40000000ULL; @@ -629,7 +639,7 @@ static void bl2_advertise_dram_size(uint32_t product) #endif /* RCAR_DRAM_DDR3L_MEMCONF == 0 */ break; - case RCAR_PRODUCT_D3: + case PRR_PRODUCT_D3: /* 512MB */ dram_config[1] = 0x20000000ULL; break; @@ -716,26 +726,26 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, version_of_renesas); reg = mmio_read_32(RCAR_PRR); - product_cut = reg & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK); - product = reg & RCAR_PRODUCT_MASK; + product_cut = reg & (PRR_PRODUCT_MASK | PRR_CUT_MASK); + product = reg & PRR_PRODUCT_MASK; switch (product) { - case RCAR_PRODUCT_H3: + case PRR_PRODUCT_H3: str = product_h3; break; - case RCAR_PRODUCT_M3: + case PRR_PRODUCT_M3: str = product_m3; break; - case RCAR_PRODUCT_M3N: + case PRR_PRODUCT_M3N: str = product_m3n; break; - case RCAR_PRODUCT_V3M: + case PRR_PRODUCT_V3M: str = product_v3m; break; - case RCAR_PRODUCT_E3: + case PRR_PRODUCT_E3: str = product_e3; break; - case RCAR_PRODUCT_D3: + case PRR_PRODUCT_D3: str = product_d3; break; default: @@ -743,9 +753,9 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, break; } - if ((RCAR_PRODUCT_M3 == product) && - (RCAR_CUT_VER20 == (reg & RCAR_MAJOR_MASK))) { - if (RCAR_M3_CUT_VER11 == (reg & RCAR_CUT_MASK)) { + if ((PRR_PRODUCT_M3 == product) && + (PRR_PRODUCT_20 == (reg & RCAR_MAJOR_MASK))) { + if (RCAR_M3_CUT_VER11 == (reg & PRR_CUT_MASK)) { /* M3 Ver.1.1 or Ver.1.2 */ NOTICE("BL2: PRR is R-Car %s Ver.1.1 / Ver.1.2\n", str); @@ -761,7 +771,7 @@ void bl2_el3_early_platform_setup(u_register_t arg1, u_register_t arg2, NOTICE("BL2: PRR is R-Car %s Ver.%d.%d\n", str, major, minor); } - if (product == RCAR_PRODUCT_E3) { + if (product == PRR_PRODUCT_E3) { reg = mmio_read_32(RCAR_MODEMR); sscg = reg & RCAR_SSCG_MASK; str = sscg == RCAR_SSCG_ENABLE ? sscg_on : sscg_off; @@ -930,7 +940,7 @@ lcm_state: mmio_write_32(CPG_CA53DBGRCR, DBGCPUPREN | mmio_read_32(CPG_CA53DBGRCR)); - if (product_cut == RCAR_PRODUCT_H3_CUT10) { + if (product_cut == PRR_PRODUCT_H3_CUT10) { reg = mmio_read_32(CPG_PLL2CR); reg &= ~((uint32_t) 1 << 5); mmio_write_32(CPG_PLL2CR, reg); @@ -1016,7 +1026,7 @@ static void bl2_init_generic_timer(void) /* Set frequency data in CNTFID0 */ reg_cntfid = pll_table[modemr_pll >> MODEMR_BOOT_PLL_SHIFT]; - reg = mmio_read_32(RCAR_PRR) & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK); + reg = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); switch (modemr_pll) { case MD14_MD13_TYPE_0: rcar_get_board_type(&board_type, &board_rev); @@ -1025,7 +1035,7 @@ static void bl2_init_generic_timer(void) } break; case MD14_MD13_TYPE_3: - if (RCAR_PRODUCT_H3_CUT10 == reg) { + if (PRR_PRODUCT_H3_CUT10 == reg) { reg_cntfid = reg_cntfid >> 1U; } break; diff --git a/plat/renesas/rcar/bl31_plat_setup.c b/plat/renesas/rcar/bl31_plat_setup.c index 4fff233e7..7bc0d8e27 100644 --- a/plat/renesas/rcar/bl31_plat_setup.c +++ b/plat/renesas/rcar/bl31_plat_setup.c @@ -1,6 +1,6 @@ /* * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -22,12 +22,12 @@ #include "rcar_private.h" #include "rcar_version.h" -IMPORT_SYM(uint64_t, __RO_START__, BL31_RO_BASE) -IMPORT_SYM(uint64_t, __RO_END__, BL31_RO_LIMIT) +static const uint64_t BL31_RO_BASE = BL_CODE_BASE; +static const uint64_t BL31_RO_LIMIT = BL_CODE_END; #if USE_COHERENT_MEM -IMPORT_SYM(uint64_t, __COHERENT_RAM_START__, BL31_COHERENT_RAM_BASE) -IMPORT_SYM(uint64_t, __COHERENT_RAM_END__, BL31_COHERENT_RAM_LIMIT) +static const uint64_t BL31_COHERENT_RAM_BASE = BL_COHERENT_RAM_BASE; +static const uint64_t BL31_COHERENT_RAM_LIMIT = BL_COHERENT_RAM_END; #endif extern void plat_rcar_gic_driver_init(void); @@ -44,9 +44,9 @@ void plat_cci_init(void) { uint32_t prd; - prd = mmio_read_32(RCAR_PRR) & (RCAR_PRODUCT_MASK | RCAR_CUT_MASK); + prd = mmio_read_32(RCAR_PRR) & (PRR_PRODUCT_MASK | PRR_CUT_MASK); - if (RCAR_PRODUCT_H3_CUT10 == prd || RCAR_PRODUCT_H3_CUT11 == prd) { + if (PRR_PRODUCT_H3_CUT10 == prd || PRR_PRODUCT_H3_CUT11 == prd) { cci_map[0U] = CCI500_CLUSTER0_SL_IFACE_IX; cci_map[1U] = CCI500_CLUSTER1_SL_IFACE_IX; } diff --git a/plat/renesas/rcar/include/rcar_def.h b/plat/renesas/rcar/include/rcar_def.h index ac7dc1767..0ffbfe979 100644 --- a/plat/renesas/rcar/include/rcar_def.h +++ b/plat/renesas/rcar/include/rcar_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -147,31 +147,34 @@ #define RCAR_SYSCISCR U(0xE6180008) /* Interrupt stat clear */ /* Product register */ #define RCAR_PRR U(0xFFF00044) -#define RCAR_PRODUCT_MASK U(0x00007F00) -#define RCAR_CUT_MASK U(0x000000FF) -#define RCAR_PRODUCT_H3 U(0x00004F00) -#define RCAR_PRODUCT_M3 U(0x00005200) -#define RCAR_PRODUCT_V3M U(0x00005400) -#define RCAR_PRODUCT_M3N U(0x00005500) -#define RCAR_PRODUCT_E3 U(0x00005700) -#define RCAR_PRODUCT_D3 U(0x00005800) -#define RCAR_CUT_VER10 U(0x00000000) -#define RCAR_CUT_VER11 U(0x00000001) /* H3/M3N/E3 Ver.1.1 */ #define RCAR_M3_CUT_VER11 U(0x00000010) /* M3 Ver.1.1/Ver.1.2 */ -#define RCAR_CUT_VER20 U(0x00000010) -#define RCAR_CUT_VER30 U(0x00000020) #define RCAR_MAJOR_MASK U(0x000000F0) #define RCAR_MINOR_MASK U(0x0000000F) -#define RCAR_PRODUCT_SHIFT U(8) +#define PRR_PRODUCT_SHIFT U(8) #define RCAR_MAJOR_SHIFT U(4) #define RCAR_MINOR_SHIFT U(0) #define RCAR_MAJOR_OFFSET U(1) #define RCAR_M3_MINOR_OFFSET U(2) -#define RCAR_PRODUCT_H3_CUT10 (RCAR_PRODUCT_H3 | U(0x00)) /* 1.0 */ -#define RCAR_PRODUCT_H3_CUT11 (RCAR_PRODUCT_H3 | U(0x01)) /* 1.1 */ -#define RCAR_PRODUCT_H3_CUT20 (RCAR_PRODUCT_H3 | U(0x10)) /* 2.0 */ -#define RCAR_PRODUCT_M3_CUT10 (RCAR_PRODUCT_M3 | U(0x00)) /* 1.0 */ -#define RCAR_PRODUCT_M3_CUT11 (RCAR_PRODUCT_M3 | U(0x10)) +#define PRR_PRODUCT_H3_CUT10 (PRR_PRODUCT_H3 | U(0x00)) /* 1.0 */ +#define PRR_PRODUCT_H3_CUT11 (PRR_PRODUCT_H3 | U(0x01)) /* 1.1 */ +#define PRR_PRODUCT_H3_CUT20 (PRR_PRODUCT_H3 | U(0x10)) /* 2.0 */ +#define PRR_PRODUCT_M3_CUT10 (PRR_PRODUCT_M3 | U(0x00)) /* 1.0 */ +#define PRR_PRODUCT_M3_CUT11 (PRR_PRODUCT_M3 | U(0x10)) +#define PRR 0xFFF00044U +#define PRR_PRODUCT_MASK 0x00007F00U +#define PRR_CUT_MASK 0x000000FFU +#define PRR_PRODUCT_H3 0x00004F00U /* R-Car H3 */ +#define PRR_PRODUCT_M3 0x00005200U /* R-Car M3-W */ +#define PRR_PRODUCT_V3M 0x00005400U /* R-Car V3M */ +#define PRR_PRODUCT_M3N 0x00005500U /* R-Car M3-N */ +#define PRR_PRODUCT_V3H 0x00005600U /* R-Car V3H */ +#define PRR_PRODUCT_E3 0x00005700U /* R-Car E3 */ +#define PRR_PRODUCT_D3 0x00005800U /* R-Car D3 */ +#define PRR_PRODUCT_10 0x00U /* Ver.1.0 */ +#define PRR_PRODUCT_11 0x01U /* Ver.1.1 */ +#define PRR_PRODUCT_20 0x10U /* Ver.2.0 */ +#define PRR_PRODUCT_21 0x11U /* Ver.2.1 */ +#define PRR_PRODUCT_30 0x20U /* Ver.3.0 */ #define RCAR_CPU_MASK_CA57 U(0x80000000) #define RCAR_CPU_MASK_CA53 U(0x04000000) #define RCAR_CPU_HAVE_CA57 U(0x00000000) @@ -218,9 +221,11 @@ #define CPG_PLL0CR (CPG_BASE + 0x00D8U) #define CPG_PLL2CR (CPG_BASE + 0x002CU) #define CPG_PLL4CR (CPG_BASE + 0x01F4U) +#define CPG_CPGWPCR (CPG_BASE + 0x0904U) /* RST Registers */ #define RST_BASE (0xE6160000U) #define RST_WDTRSTCR (RST_BASE + 0x0054U) +#define RST_MODEMR (RST_BASE + 0x0060U) #define WDTRSTCR_PASSWORD (0xA55A0000U) #define WDTRSTCR_RWDT_RSTMSK ((uint32_t)1U << 0U) /* MFIS Registers */ @@ -264,11 +269,15 @@ #define MIDR_CA57 (0x0D07U << MIDR_PN_SHIFT) #define MIDR_CA53 (0x0D03U << MIDR_PN_SHIFT) /* for SuspendToRAM */ -#define GPIO_BASE (0xE6050000U) -#define GPIO_INDT1 (GPIO_BASE + 0x100CU) +#define GPIO_BASE (0xE6050000U) +#define GPIO_INDT1 (GPIO_BASE + 0x100CU) +#define GPIO_INDT3 (GPIO_BASE + 0x300CU) #define GPIO_INDT6 (GPIO_BASE + 0x540CU) -#define RCAR_COLD_BOOT (0x00U) -#define RCAR_WARM_BOOT (0x01U) +#define GPIO_OUTDT1 (GPIO_BASE + 0x1008U) +#define GPIO_OUTDT3 (GPIO_BASE + 0x3008U) +#define GPIO_OUTDT6 (GPIO_BASE + 0x5408U) +#define RCAR_COLD_BOOT (0x00U) +#define RCAR_WARM_BOOT (0x01U) #if PMIC_ROHM_BD9571 && RCAR_SYSTEM_RESET_KEEPON_DDR #define KEEP10_MAGIC (0x55U) #endif diff --git a/plat/renesas/rcar/plat_pm.c b/plat/renesas/rcar/plat_pm.c index e678da5dc..6fc47b95c 100644 --- a/plat/renesas/rcar/plat_pm.c +++ b/plat/renesas/rcar/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2019, Renesas Electronics Corporation. All rights reserved. + * Copyright (c) 2015-2020, Renesas Electronics Corporation. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -56,7 +56,7 @@ static void rcar_program_mailbox(uint64_t mpidr, uint64_t address) static void rcar_cpu_standby(plat_local_state_t cpu_state) { - uint32_t scr_el3 = read_scr_el3(); + u_register_t scr_el3 = read_scr_el3(); write_scr_el3(scr_el3 | SCR_IRQ_BIT); dsb(); diff --git a/plat/renesas/rcar/platform.mk b/plat/renesas/rcar/platform.mk index dc58e191d..4c41dd341 100644 --- a/plat/renesas/rcar/platform.mk +++ b/plat/renesas/rcar/platform.mk @@ -348,12 +348,12 @@ ERRATA_A53_855873 := 1 ERRATA_A57_859972 := 1 ERRATA_A57_813419 := 1 -include drivers/staging/renesas/rcar/ddr/ddr.mk +include drivers/renesas/rcar/ddr/ddr.mk include drivers/renesas/rcar/qos/qos.mk include drivers/renesas/rcar/pfc/pfc.mk include lib/libfdt/libfdt.mk -PLAT_INCLUDES := -Idrivers/staging/renesas/rcar/ddr \ +PLAT_INCLUDES := -Idrivers/renesas/rcar/ddr \ -Idrivers/renesas/rcar/qos \ -Idrivers/renesas/rcar/iic_dvfs \ -Idrivers/renesas/rcar/board \ diff --git a/plat/rockchip/common/params_setup.c b/plat/rockchip/common/params_setup.c index 8c2e5e911..b2fd2011e 100644 --- a/plat/rockchip/common/params_setup.c +++ b/plat/rockchip/common/params_setup.c @@ -6,6 +6,7 @@ #include <assert.h> #include <errno.h> +#include <limits.h> #include <string.h> #include <lib/bl_aux_params/bl_aux_params.h> @@ -21,8 +22,8 @@ #include <plat_params.h> #include <plat_private.h> -static struct bl_aux_gpio_info rst_gpio; -static struct bl_aux_gpio_info poweroff_gpio; +static struct bl_aux_gpio_info rst_gpio = { .index = UINT_MAX } ; +static struct bl_aux_gpio_info poweroff_gpio = { .index = UINT_MAX }; static struct bl_aux_gpio_info suspend_gpio[10]; uint32_t suspend_gpio_cnt; static struct bl_aux_rk_apio_info suspend_apio; @@ -174,11 +175,17 @@ uint32_t rockchip_get_uart_clock(void) struct bl_aux_gpio_info *plat_get_rockchip_gpio_reset(void) { + if (rst_gpio.index == UINT_MAX) + return NULL; + return &rst_gpio; } struct bl_aux_gpio_info *plat_get_rockchip_gpio_poweroff(void) { + if (poweroff_gpio.index == UINT_MAX) + return NULL; + return &poweroff_gpio; } diff --git a/plat/rockchip/common/plat_pm.c b/plat/rockchip/common/plat_pm.c index c9563c9ed..69268870d 100644 --- a/plat/rockchip/common/plat_pm.c +++ b/plat/rockchip/common/plat_pm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -182,7 +182,7 @@ void rockchip_get_sys_suspend_power_state(psci_power_state_t *req_state) ******************************************************************************/ void rockchip_cpu_standby(plat_local_state_t cpu_state) { - unsigned int scr; + u_register_t scr; assert(cpu_state == PLAT_MAX_RET_STATE); diff --git a/plat/rockchip/px30/drivers/pmu/pmu.c b/plat/rockchip/px30/drivers/pmu/pmu.c index 0a2515d12..5f4e64f7b 100644 --- a/plat/rockchip/px30/drivers/pmu/pmu.c +++ b/plat/rockchip/px30/drivers/pmu/pmu.c @@ -22,6 +22,7 @@ #include <plat_private.h> #include <pmu.h> #include <px30_def.h> +#include <secure.h> #include <soc.h> DEFINE_BAKERY_LOCK(rockchip_pd_lock); diff --git a/plat/rockchip/px30/drivers/secure/secure.c b/plat/rockchip/px30/drivers/secure/secure.c new file mode 100644 index 000000000..144f94537 --- /dev/null +++ b/plat/rockchip/px30/drivers/secure/secure.c @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <ddr_parameter.h> +#include <plat_private.h> +#include <secure.h> +#include <px30_def.h> + +/** + * There are 8 regions for DDR security control + * @rgn - the DDR regions 0 ~ 7 which are can be configured. + * @st - start address to set as secure + * @sz - length of area to set as secure + * The internal unit is megabytes, so memory areas need to be aligned + * to megabyte borders. + */ +static void secure_ddr_region(uint32_t rgn, + uintptr_t st, size_t sz) +{ + uintptr_t ed = st + sz; + uintptr_t st_mb, ed_mb; + uint32_t val; + + assert(rgn <= 7); + assert(st < ed); + + /* check aligned 1MB */ + assert(st % SIZE_M(1) == 0); + assert(ed % SIZE_M(1) == 0); + + st_mb = st / SIZE_M(1); + ed_mb = ed / SIZE_M(1); + + /* map top and base */ + mmio_write_32(FIREWALL_DDR_BASE + + FIREWALL_DDR_FW_DDR_RGN(rgn), + RG_MAP_SECURE(ed_mb, st_mb)); + + /* enable secure */ + val = mmio_read_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_CON_REG); + val |= BIT(rgn); + mmio_write_32(FIREWALL_DDR_BASE + + FIREWALL_DDR_FW_DDR_CON_REG, val); +} + +void secure_timer_init(void) +{ + mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, + TIMER_DIS); + + mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff); + mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff); + + /* auto reload & enable the timer */ + mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, + TIMER_EN | TIMER_FMODE); +} + +void sgrf_init(void) +{ +#ifdef PLAT_RK_SECURE_DDR_MINILOADER + uint32_t i; + struct param_ddr_usage usg; + + /* general secure regions */ + usg = ddr_region_usage_parse(DDR_PARAM_BASE, + PLAT_MAX_DDR_CAPACITY_MB); + + /* region-0 for TF-A, region-1 for optional OP-TEE */ + assert(usg.s_nr < 7); + + for (i = 0; i < usg.s_nr; i++) + secure_ddr_region(7 - i, usg.s_top[i], usg.s_base[i]); +#endif + + /* secure the trustzone ram */ + secure_ddr_region(0, TZRAM_BASE, TZRAM_SIZE); + + /* set all slave ip into no-secure, except stimer */ + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000); + + /* set master crypto to no-secure, dcf to secure */ + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003); + + /* set DMAC into no-secure */ + mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS); + mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0); + mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16); + mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS); + + /* soft reset dma before use */ + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ); + udelay(5); + mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS); +} diff --git a/plat/rockchip/px30/drivers/secure/secure.h b/plat/rockchip/px30/drivers/secure/secure.h new file mode 100644 index 000000000..498027db2 --- /dev/null +++ b/plat/rockchip/px30/drivers/secure/secure.h @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef SECURE_H +#define SECURE_H + +/*************************************************************************** + * SGRF + ***************************************************************************/ +#define SGRF_SOC_CON(i) ((i) * 0x4) +#define SGRF_DMAC_CON(i) (0x30 + (i) * 0x4) + +#define SGRF_MST_S_ALL_NS 0xffffffff +#define SGRF_SLV_S_ALL_NS 0xffff0000 +#define DMA_IRQ_BOOT_NS 0xffffffff +#define DMA_PERI_CH_NS_15_0 0xffffffff +#define DMA_PERI_CH_NS_19_16 0x000f000f +#define DMA_MANAGER_BOOT_NS 0x00010001 +#define DMA_SOFTRST_REQ BITS_WITH_WMASK(1, 0x1, 12) +#define DMA_SOFTRST_RLS BITS_WITH_WMASK(0, 0x1, 12) + +/*************************************************************************** + * DDR FIREWALL + ***************************************************************************/ +#define FIREWALL_DDR_FW_DDR_RGN(i) ((i) * 0x4) +#define FIREWALL_DDR_FW_DDR_MST(i) (0x20 + (i) * 0x4) +#define FIREWALL_DDR_FW_DDR_CON_REG 0x40 +#define FIREWALL_DDR_FW_DDR_RGN_NUM 8 +#define FIREWALL_DDR_FW_DDR_MST_NUM 6 + +#define PLAT_MAX_DDR_CAPACITY_MB 4096 +#define RG_MAP_SECURE(top, base) ((((top) - 1) << 16) | (base)) + +/************************************************** + * secure timer + **************************************************/ + +/* chanal0~5 */ +#define STIMER_CHN_BASE(n) (STIME_BASE + 0x20 * (n)) + +#define TIMER_LOAD_COUNT0 0x0 +#define TIMER_LOAD_COUNT1 0x4 + +#define TIMER_CUR_VALUE0 0x8 +#define TIMER_CUR_VALUE1 0xc + +#define TIMER_CONTROL_REG 0x10 +#define TIMER_INTSTATUS 0x18 + +#define TIMER_DIS 0x0 +#define TIMER_EN 0x1 + +#define TIMER_FMODE (0x0 << 1) +#define TIMER_RMODE (0x1 << 1) + +#define TIMER_LOAD_COUNT0_MSK (0xffffffff) +#define TIMER_LOAD_COUNT1_MSK (0xffffffff00000000) + +void secure_timer_init(void); +void sgrf_init(void); + +#endif /* SECURE_H */ diff --git a/plat/rockchip/px30/drivers/soc/soc.c b/plat/rockchip/px30/drivers/soc/soc.c index e00561d80..200563dee 100644 --- a/plat/rockchip/px30/drivers/soc/soc.c +++ b/plat/rockchip/px30/drivers/soc/soc.c @@ -12,10 +12,10 @@ #include <drivers/delay_timer.h> #include <lib/mmio.h> -#include <ddr_parameter.h> #include <platform_def.h> #include <pmu.h> #include <px30_def.h> +#include <secure.h> #include <soc.h> #include <rockchip_sip_svc.h> @@ -83,65 +83,6 @@ void clk_gate_con_disable(void) 0xffff0000); } -void secure_timer_init(void) -{ - mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, - TIMER_DIS); - - mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT0, 0xffffffff); - mmio_write_32(STIMER_CHN_BASE(1) + TIMER_LOAD_COUNT1, 0xffffffff); - - /* auto reload & enable the timer */ - mmio_write_32(STIMER_CHN_BASE(1) + TIMER_CONTROL_REG, - TIMER_EN | TIMER_FMODE); -} - -static void sgrf_init(void) -{ - uint32_t i, val; - struct param_ddr_usage usg; - - /* general secure regions */ - usg = ddr_region_usage_parse(DDR_PARAM_BASE, - PLAT_MAX_DDR_CAPACITY_MB); - for (i = 0; i < usg.s_nr; i++) { - /* enable secure */ - val = mmio_read_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_CON_REG); - val |= BIT(7 - i); - mmio_write_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_CON_REG, val); - /* map top and base */ - mmio_write_32(FIREWALL_DDR_BASE + - FIREWALL_DDR_FW_DDR_RGN(7 - i), - RG_MAP_SECURE(usg.s_top[i], usg.s_base[i])); - } - - /* set ddr rgn0_top and rga0_top as 0 */ - mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0); - - /* set all slave ip into no-secure, except stimer */ - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(4), SGRF_SLV_S_ALL_NS); - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(5), SGRF_SLV_S_ALL_NS); - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(6), SGRF_SLV_S_ALL_NS); - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(7), SGRF_SLV_S_ALL_NS); - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(8), 0x00030000); - - /* set master crypto to no-secure, dcf to secure */ - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(3), 0x000f0003); - - /* set DMAC into no-secure */ - mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(0), DMA_IRQ_BOOT_NS); - mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(1), DMA_PERI_CH_NS_15_0); - mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(2), DMA_PERI_CH_NS_19_16); - mmio_write_32(SGRF_BASE + SGRF_DMAC_CON(3), DMA_MANAGER_BOOT_NS); - - /* soft reset dma before use */ - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_REQ); - udelay(5); - mmio_write_32(SGRF_BASE + SGRF_SOC_CON(1), DMA_SOFTRST_RLS); -} - static void soc_reset_config_all(void) { uint32_t tmp; diff --git a/plat/rockchip/px30/drivers/soc/soc.h b/plat/rockchip/px30/drivers/soc/soc.h index 69f2de44a..648d18b62 100644 --- a/plat/rockchip/px30/drivers/soc/soc.h +++ b/plat/rockchip/px30/drivers/soc/soc.h @@ -29,21 +29,6 @@ enum pll_mode { }; /*************************************************************************** - * SGRF - ***************************************************************************/ -#define SGRF_SOC_CON(i) ((i) * 0x4) -#define SGRF_DMAC_CON(i) (0x30 + (i) * 0x4) - -#define SGRF_MST_S_ALL_NS 0xffffffff -#define SGRF_SLV_S_ALL_NS 0xffff0000 -#define DMA_IRQ_BOOT_NS 0xffffffff -#define DMA_PERI_CH_NS_15_0 0xffffffff -#define DMA_PERI_CH_NS_19_16 0x000f000f -#define DMA_MANAGER_BOOT_NS 0x00010001 -#define DMA_SOFTRST_REQ BITS_WITH_WMASK(1, 0x1, 12) -#define DMA_SOFTRST_RLS BITS_WITH_WMASK(0, 0x1, 12) - -/*************************************************************************** * GRF ***************************************************************************/ #define GRF_SOC_CON(i) (0x0400 + (i) * 4) @@ -61,18 +46,6 @@ enum pll_mode { #define GRF_SOC_CON2_NSWDT_RST_EN 12 /*************************************************************************** - * DDR FIREWALL - ***************************************************************************/ -#define FIREWALL_DDR_FW_DDR_RGN(i) ((i) * 0x4) -#define FIREWALL_DDR_FW_DDR_MST(i) (0x20 + (i) * 0x4) -#define FIREWALL_DDR_FW_DDR_CON_REG 0x40 -#define FIREWALL_DDR_FW_DDR_RGN_NUM 8 -#define FIREWALL_DDR_FW_DDR_MST_NUM 6 - -#define PLAT_MAX_DDR_CAPACITY_MB 4096 -#define RG_MAP_SECURE(top, base) ((((top) - 1) << 16) | (base)) - -/*************************************************************************** * cru ***************************************************************************/ #define CRU_MODE 0xa0 @@ -136,37 +109,10 @@ enum pll_mode { #define GPIO_INT_STATUS 0x40 #define GPIO_NUMS 4 -/************************************************** - * secure timer - **************************************************/ - -/* chanal0~5 */ -#define STIMER_CHN_BASE(n) (STIME_BASE + 0x20 * (n)) - -#define TIMER_LOAD_COUNT0 0x0 -#define TIMER_LOAD_COUNT1 0x4 - -#define TIMER_CUR_VALUE0 0x8 -#define TIMER_CUR_VALUE1 0xc - -#define TIMER_CONTROL_REG 0x10 -#define TIMER_INTSTATUS 0x18 - -#define TIMER_DIS 0x0 -#define TIMER_EN 0x1 - -#define TIMER_FMODE (0x0 << 1) -#define TIMER_RMODE (0x1 << 1) - -#define TIMER_LOAD_COUNT0_MSK (0xffffffff) -#define TIMER_LOAD_COUNT1_MSK (0xffffffff00000000) - void clk_gate_con_save(uint32_t *clkgt_save); void clk_gate_con_restore(uint32_t *clkgt_save); void clk_gate_con_disable(void); -void secure_timer_init(void); -void secure_timer_disable(void); void px30_soc_reset_config(void); #endif /* __SOC_H__ */ diff --git a/plat/rockchip/px30/include/platform_def.h b/plat/rockchip/px30/include/platform_def.h index c101cdc81..a11f84f42 100644 --- a/plat/rockchip/px30/include/platform_def.h +++ b/plat/rockchip/px30/include/platform_def.h @@ -39,10 +39,10 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) @@ -69,9 +69,9 @@ /******************************************************************************* * Platform memory map related constants ******************************************************************************/ -/* TF txet, ro, rw, Size: 512KB */ +/* TF text, ro, rw, Size: 1MB */ #define TZRAM_BASE (0x0) -#define TZRAM_SIZE (0x80000) +#define TZRAM_SIZE (0x100000) /******************************************************************************* * BL31 specific defines. @@ -79,7 +79,7 @@ /* * Put BL3-1 at the top of the Trusted RAM */ -#define BL31_BASE (TZRAM_BASE + 0x10000) +#define BL31_BASE (TZRAM_BASE + 0x40000) #define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) /******************************************************************************* diff --git a/plat/rockchip/px30/platform.mk b/plat/rockchip/px30/platform.mk index ee85cd311..87cf18704 100644 --- a/plat/rockchip/px30/platform.mk +++ b/plat/rockchip/px30/platform.mk @@ -20,6 +20,7 @@ PLAT_INCLUDES := -Idrivers/arm/gic/common/ \ -I${RK_PLAT_COMMON}/pmusram \ -I${RK_PLAT_SOC}/ \ -I${RK_PLAT_SOC}/drivers/pmu/ \ + -I${RK_PLAT_SOC}/drivers/secure/ \ -I${RK_PLAT_SOC}/drivers/soc/ \ -I${RK_PLAT_SOC}/include/ @@ -45,16 +46,20 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \ ${RK_PLAT_COMMON}/aarch64/platform_common.c \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \ - ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \ ${RK_PLAT_COMMON}/params_setup.c \ ${RK_PLAT_COMMON}/pmusram/cpus_on_fixed_addr.S \ ${RK_PLAT_COMMON}/plat_pm.c \ ${RK_PLAT_COMMON}/plat_topology.c \ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ + ${RK_PLAT_SOC}/drivers/secure/secure.c \ ${RK_PLAT_SOC}/drivers/soc/soc.c \ ${RK_PLAT_SOC}/plat_sip_calls.c +ifdef PLAT_RK_SECURE_DDR_MINILOADER +BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c +endif + ENABLE_PLAT_COMPAT := 0 MULTI_CONSOLE_API := 1 diff --git a/plat/rockchip/px30/px30_def.h b/plat/rockchip/px30/px30_def.h index 9b8ccfca6..efe789e1e 100644 --- a/plat/rockchip/px30/px30_def.h +++ b/plat/rockchip/px30/px30_def.h @@ -11,6 +11,7 @@ #define MINOR_VERSION (0) #define SIZE_K(n) ((n) * 1024) +#define SIZE_M(n) ((n) * 1024 * 1024) #define WITH_16BITS_WMSK(bits) (0xffff0000 | (bits)) @@ -54,6 +55,9 @@ #define UART2_BASE 0xff160000 #define UART2_SIZE SIZE_K(64) +#define UART3_BASE 0xff168000 +#define UART3_SIZE SIZE_K(64) + #define UART5_BASE 0xff178000 #define UART5_SIZE SIZE_K(64) diff --git a/plat/rockchip/rk3288/drivers/secure/secure.c b/plat/rockchip/rk3288/drivers/secure/secure.c index 68994e458..25e1cca48 100644 --- a/plat/rockchip/rk3288/drivers/secure/secure.c +++ b/plat/rockchip/rk3288/drivers/secure/secure.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -38,15 +38,18 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass) * SGRF_SOC_CON21 - end address of the RGN_7 + RGN_X control * * @rgn - the DDR regions 0 ~ 7 which are can be configured. - * The @st and @ed indicate the start and end addresses for which to set - * the security, and the unit is byte. When the st_mb == 0, ed_mb == 0, the + * @st - start address to set as secure + * @sz - length of area to set as secure + * The @st_mb and @ed_mb indicate the start and end addresses for which to set + * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the * address range 0x0 ~ 0xfffff is secure. * * For example, if we would like to set the range [0, 32MB) is security via * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31. */ -static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, uintptr_t ed) +static void sgrf_ddr_rgn_config(uint32_t rgn, uintptr_t st, size_t sz) { + uintptr_t ed = st + sz; uintptr_t st_mb, ed_mb; assert(rgn <= 7); diff --git a/plat/rockchip/rk3288/include/platform_def.h b/plat/rockchip/rk3288/include/platform_def.h index e24aeffac..85ec3fb88 100644 --- a/plat/rockchip/rk3288/include/platform_def.h +++ b/plat/rockchip/rk3288/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -36,11 +36,11 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) diff --git a/plat/rockchip/rk3288/include/shared/bl32_param.h b/plat/rockchip/rk3288/include/shared/bl32_param.h index 743dad41b..ffdb2f38c 100644 --- a/plat/rockchip/rk3288/include/shared/bl32_param.h +++ b/plat/rockchip/rk3288/include/shared/bl32_param.h @@ -10,9 +10,9 @@ /******************************************************************************* * Platform memory map related constants ******************************************************************************/ -/* TF txet, ro, rw, Size: 2MB */ +/* TF text, ro, rw, Size: 1MB */ #define TZRAM_BASE (0x0) -#define TZRAM_SIZE (0x200000) +#define TZRAM_SIZE (0x100000) /******************************************************************************* * BL32 specific defines. @@ -20,7 +20,7 @@ /* * Put BL32 at the top of the Trusted RAM */ -#define BL32_BASE (TZRAM_BASE + 0x100000) +#define BL32_BASE (TZRAM_BASE + 0x40000) #define BL32_LIMIT (TZRAM_BASE + TZRAM_SIZE) #endif /* BL32_PARAM_H */ diff --git a/plat/rockchip/rk3328/drivers/soc/soc.c b/plat/rockchip/rk3328/drivers/soc/soc.c index 59d857244..306308f3f 100644 --- a/plat/rockchip/rk3328/drivers/soc/soc.c +++ b/plat/rockchip/rk3328/drivers/soc/soc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -97,6 +97,7 @@ void secure_timer_init(void) void sgrf_init(void) { +#ifdef PLAT_RK_SECURE_DDR_MINILOADER uint32_t i, val; struct param_ddr_usage usg; @@ -115,6 +116,7 @@ void sgrf_init(void) FIREWALL_DDR_FW_DDR_RGN(7 - i), RG_MAP_SECURE(usg.s_top[i], usg.s_base[i])); } +#endif /* set ddr rgn0_top and rga0_top as 0 */ mmio_write_32(FIREWALL_DDR_BASE + FIREWALL_DDR_FW_DDR_RGN(0), 0x0); diff --git a/plat/rockchip/rk3328/drivers/soc/soc.h b/plat/rockchip/rk3328/drivers/soc/soc.h index a1f35b282..e8cbc09f6 100644 --- a/plat/rockchip/rk3328/drivers/soc/soc.h +++ b/plat/rockchip/rk3328/drivers/soc/soc.h @@ -16,8 +16,6 @@ #define TIMER_INTSTATUS 0x18 #define TIMER_EN 0x1 -extern const unsigned char rockchip_power_domain_tree_desc[]; - /**************************** read/write **************************************/ #ifndef BITS_WMSK #define BITS_WMSK(msk, shift) ((msk) << (shift + REG_MSK_SHIFT)) diff --git a/plat/rockchip/rk3328/include/platform_def.h b/plat/rockchip/rk3328/include/platform_def.h index 3104d9fcb..6579756e0 100644 --- a/plat/rockchip/rk3328/include/platform_def.h +++ b/plat/rockchip/rk3328/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -37,9 +37,9 @@ #define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2 #define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 1 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 0 +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(0) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) @@ -66,9 +66,9 @@ /******************************************************************************* * Platform memory map related constants ******************************************************************************/ -/* TF txet, ro, rw, Size: 512KB */ +/* TF text, ro, rw, Size: 1MB */ #define TZRAM_BASE (0x0) -#define TZRAM_SIZE (0x80000) +#define TZRAM_SIZE (0x100000) /******************************************************************************* * BL31 specific defines. @@ -76,7 +76,7 @@ /* * Put BL3-1 at the top of the Trusted RAM */ -#define BL31_BASE (TZRAM_BASE + 0x10000) +#define BL31_BASE (TZRAM_BASE + 0x40000) #define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) /******************************************************************************* diff --git a/plat/rockchip/rk3328/platform.mk b/plat/rockchip/rk3328/platform.mk index 2be2be3da..fef459855 100644 --- a/plat/rockchip/rk3328/platform.mk +++ b/plat/rockchip/rk3328/platform.mk @@ -41,7 +41,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ drivers/delay_timer/generic_delay_timer.c \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ - ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c \ ${RK_PLAT_COMMON}/aarch64/plat_helpers.S \ ${RK_PLAT_COMMON}/params_setup.c \ ${RK_PLAT_COMMON}/bl31_plat_setup.c \ @@ -52,9 +51,16 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ ${RK_PLAT_SOC}/drivers/soc/soc.c +ifdef PLAT_RK_SECURE_DDR_MINILOADER +BL31_SOURCES += ${RK_PLAT_COMMON}/drivers/parameter/ddr_parameter.c +endif + include lib/coreboot/coreboot.mk include lib/libfdt/libfdt.mk +# Enable workarounds for selected Cortex-A53 errata +ERRATA_A53_855873 := 1 + $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) $(eval $(call add_define,PLAT_SKIP_OPTEE_S_EL1_INT_REGISTER)) diff --git a/plat/rockchip/rk3368/include/platform_def.h b/plat/rockchip/rk3368/include/platform_def.h index 7b3cc6eba..12115b4f0 100644 --- a/plat/rockchip/rk3368/include/platform_def.h +++ b/plat/rockchip/rk3368/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -37,13 +37,13 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 4 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(4) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) @@ -67,9 +67,9 @@ /******************************************************************************* * Platform memory map related constants ******************************************************************************/ -/* TF txet, ro, rw, Size: 512KB */ +/* TF text, ro, rw, Size: 1MB */ #define TZRAM_BASE (0x0) -#define TZRAM_SIZE (0x80000) +#define TZRAM_SIZE (0x100000) /******************************************************************************* * BL31 specific defines. @@ -77,7 +77,7 @@ /* * Put BL3-1 at the top of the Trusted RAM */ -#define BL31_BASE (TZRAM_BASE + 0x10000) +#define BL31_BASE (TZRAM_BASE + 0x40000) #define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) /******************************************************************************* diff --git a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c index aa71fdea6..a8773f4f6 100644 --- a/plat/rockchip/rk3399/drivers/dp/cdn_dp.c +++ b/plat/rockchip/rk3399/drivers/dp/cdn_dp.c @@ -18,7 +18,7 @@ __asm__( ".global hdcp_handler\n" ".balign 4\n" "hdcp_handler:\n" - ".incbin \"" __XSTRING(HDCPFW) "\"\n" + ".incbin \"" HDCPFW "\"\n" ".type hdcp_handler, %function\n" ".size hdcp_handler, .- hdcp_handler\n" ".popsection\n" diff --git a/plat/rockchip/rk3399/drivers/dram/dfs.c b/plat/rockchip/rk3399/drivers/dram/dfs.c index 3b627d287..816372bfc 100644 --- a/plat/rockchip/rk3399/drivers/dram/dfs.c +++ b/plat/rockchip/rk3399/drivers/dram/dfs.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -78,10 +78,10 @@ static struct rk3399_sdram_default_config lpddr4_default_config = { .zqcsi = 0 }; -static uint32_t get_cs_die_capability(struct rk3399_sdram_params *sdram_config, +static uint32_t get_cs_die_capability(struct rk3399_sdram_params *ram_config, uint8_t channel, uint8_t cs) { - struct rk3399_sdram_channel *ch = &sdram_config->ch[channel]; + struct rk3399_sdram_channel *ch = &ram_config->ch[channel]; uint32_t bandwidth; uint32_t die_bandwidth; uint32_t die; diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.c b/plat/rockchip/rk3399/drivers/pmu/pmu.c index 30941fd07..faee6787d 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.c @@ -400,6 +400,25 @@ static void pmu_power_domains_resume(void) clk_gate_con_restore(); } +void pmu_power_domains_on(void) +{ + clk_gate_con_disable(); + pmu_set_power_domain(PD_VDU, pmu_pd_on); + pmu_set_power_domain(PD_VCODEC, pmu_pd_on); + pmu_set_power_domain(PD_RGA, pmu_pd_on); + pmu_set_power_domain(PD_IEP, pmu_pd_on); + pmu_set_power_domain(PD_EDP, pmu_pd_on); + pmu_set_power_domain(PD_GMAC, pmu_pd_on); + pmu_set_power_domain(PD_SDIOAUDIO, pmu_pd_on); + pmu_set_power_domain(PD_HDCP, pmu_pd_on); + pmu_set_power_domain(PD_ISP1, pmu_pd_on); + pmu_set_power_domain(PD_ISP0, pmu_pd_on); + pmu_set_power_domain(PD_VO, pmu_pd_on); + pmu_set_power_domain(PD_TCPD1, pmu_pd_on); + pmu_set_power_domain(PD_TCPD0, pmu_pd_on); + pmu_set_power_domain(PD_GPU, pmu_pd_on); +} + void rk3399_flush_l2_b(void) { uint32_t wait_cnt = 0; diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu.h b/plat/rockchip/rk3399/drivers/pmu/pmu.h index 74db82ff2..bb7de5091 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu.h +++ b/plat/rockchip/rk3399/drivers/pmu/pmu.h @@ -136,5 +136,6 @@ struct pmu_slpdata_s { extern uint32_t clst_warmboot_data[PLATFORM_CLUSTER_COUNT]; extern void sram_func_set_ddrctl_pll(uint32_t pll_src); +void pmu_power_domains_on(void); #endif /* PMU_H */ diff --git a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c index a09ad21e8..25596b188 100644 --- a/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c +++ b/plat/rockchip/rk3399/drivers/pmu/pmu_fw.c @@ -5,20 +5,18 @@ */ /* convoluted way to make sure that the define is pasted just the right way */ -#define _INCBIN(file, sym, sec) \ +#define INCBIN(file, sym, sec) \ __asm__( \ - ".section " #sec "\n" \ - ".global " #sym "\n" \ - ".type " #sym ", %object\n" \ + ".section " sec "\n" \ + ".global " sym "\n" \ + ".type " sym ", %object\n" \ ".align 4\n" \ - #sym ":\n" \ - ".incbin \"" #file "\"\n" \ - ".size " #sym ", .-" #sym "\n" \ - ".global " #sym "_end\n" \ - #sym "_end:\n" \ + sym ":\n" \ + ".incbin \"" file "\"\n" \ + ".size " sym ", .-" sym "\n" \ + ".global " sym "_end\n" \ + sym "_end:\n" \ ) -#define INCBIN(file, sym, sec) _INCBIN(file, sym, sec) - -INCBIN(RK3399M0FW, rk3399m0_bin, ".sram.incbin"); -INCBIN(RK3399M0PMUFW, rk3399m0pmu_bin, ".pmusram.incbin"); +INCBIN(RK3399M0FW, "rk3399m0_bin", ".sram.incbin"); +INCBIN(RK3399M0PMUFW, "rk3399m0pmu_bin", ".pmusram.incbin"); diff --git a/plat/rockchip/rk3399/drivers/secure/secure.c b/plat/rockchip/rk3399/drivers/secure/secure.c index 8286f17c6..13c83ca1f 100644 --- a/plat/rockchip/rk3399/drivers/secure/secure.c +++ b/plat/rockchip/rk3399/drivers/secure/secure.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,6 +45,8 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass) * bypass, 1: enable bypass * * @rgn - the DDR regions 0 ~ 7 which are can be configured. + * @st - start address to set as secure + * @sz - length of area to set as secure * The @st_mb and @ed_mb indicate the start and end addresses for which to set * the security, and the unit is megabyte. When the st_mb == 0, ed_mb == 0, the * address range 0x0 ~ 0xfffff is secure. @@ -53,8 +55,9 @@ static void sgrf_ddr_rgn_global_bypass(uint32_t bypass) * DDR_RGN0, then rgn == 0, st_mb == 0, ed_mb == 31. */ static void sgrf_ddr_rgn_config(uint32_t rgn, - uintptr_t st, uintptr_t ed) + uintptr_t st, size_t sz) { + uintptr_t ed = st + sz; uintptr_t st_mb, ed_mb; assert(rgn <= 7); diff --git a/plat/rockchip/rk3399/drivers/soc/soc.c b/plat/rockchip/rk3399/drivers/soc/soc.c index c877dbde8..98b5ad646 100644 --- a/plat/rockchip/rk3399/drivers/soc/soc.c +++ b/plat/rockchip/rk3399/drivers/soc/soc.c @@ -17,6 +17,7 @@ #include <dram.h> #include <m0_ctl.h> #include <plat_private.h> +#include <pmu.h> #include <rk3399_def.h> #include <secure.h> #include <soc.h> @@ -327,6 +328,7 @@ void soc_global_soft_reset_init(void) void __dead2 soc_global_soft_reset(void) { + pmu_power_domains_on(); set_pll_slow_mode(VPLL_ID); set_pll_slow_mode(NPLL_ID); set_pll_slow_mode(GPLL_ID); diff --git a/plat/rockchip/rk3399/include/platform_def.h b/plat/rockchip/rk3399/include/platform_def.h index 2861a7dd4..78269b632 100644 --- a/plat/rockchip/rk3399/include/platform_def.h +++ b/plat/rockchip/rk3399/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -38,13 +38,13 @@ #define FIRMWARE_WELCOME_STR "Booting Trusted Firmware\n" #define PLATFORM_MAX_AFFLVL MPIDR_AFFLVL2 -#define PLATFORM_SYSTEM_COUNT 1 -#define PLATFORM_CLUSTER_COUNT 2 -#define PLATFORM_CLUSTER0_CORE_COUNT 4 -#define PLATFORM_CLUSTER1_CORE_COUNT 2 +#define PLATFORM_SYSTEM_COUNT U(1) +#define PLATFORM_CLUSTER_COUNT U(2) +#define PLATFORM_CLUSTER0_CORE_COUNT U(4) +#define PLATFORM_CLUSTER1_CORE_COUNT U(2) #define PLATFORM_CORE_COUNT (PLATFORM_CLUSTER1_CORE_COUNT + \ PLATFORM_CLUSTER0_CORE_COUNT) -#define PLATFORM_MAX_CPUS_PER_CLUSTER 4 +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) #define PLATFORM_NUM_AFFS (PLATFORM_SYSTEM_COUNT + \ PLATFORM_CLUSTER_COUNT + \ PLATFORM_CORE_COUNT) diff --git a/plat/rockchip/rk3399/include/shared/bl31_param.h b/plat/rockchip/rk3399/include/shared/bl31_param.h index e7f2226cd..6e7e8ba09 100644 --- a/plat/rockchip/rk3399/include/shared/bl31_param.h +++ b/plat/rockchip/rk3399/include/shared/bl31_param.h @@ -20,7 +20,7 @@ /* * Put BL31 at the top of the Trusted RAM */ -#define BL31_BASE (TZRAM_BASE + 0x1000) +#define BL31_BASE (TZRAM_BASE + 0x40000) #define BL31_LIMIT (TZRAM_BASE + TZRAM_SIZE) #endif /* BL31_PARAM_H */ diff --git a/plat/rockchip/rk3399/plat_sip_calls.c b/plat/rockchip/rk3399/plat_sip_calls.c index c2cc5b11c..ce8476c9a 100644 --- a/plat/rockchip/rk3399/plat_sip_calls.c +++ b/plat/rockchip/rk3399/plat_sip_calls.c @@ -56,17 +56,21 @@ uintptr_t rockchip_plat_sip_handler(uint32_t smc_fid, void *handle, u_register_t flags) { +#ifdef PLAT_RK_DP_HDCP uint64_t x5, x6; +#endif switch (smc_fid) { case RK_SIP_DDR_CFG: SMC_RET1(handle, ddr_smc_handler(x1, x2, x3, x4)); +#ifdef PLAT_RK_DP_HDCP case RK_SIP_HDCP_CONTROL: SMC_RET1(handle, dp_hdcp_ctrl(x1)); case RK_SIP_HDCP_KEY_DATA64: x5 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X5); x6 = read_ctx_reg(get_gpregs_ctx(handle), CTX_GPREG_X6); SMC_RET1(handle, dp_hdcp_store_key(x1, x2, x3, x4, x5, x6)); +#endif default: ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid); SMC_RET1(handle, SMC_UNK); diff --git a/plat/rockchip/rk3399/platform.mk b/plat/rockchip/rk3399/platform.mk index 88fa8e9c0..d58215dcf 100644 --- a/plat/rockchip/rk3399/platform.mk +++ b/plat/rockchip/rk3399/platform.mk @@ -55,7 +55,6 @@ BL31_SOURCES += ${RK_GIC_SOURCES} \ ${RK_PLAT_COMMON}/aarch64/platform_common.c \ ${RK_PLAT_COMMON}/rockchip_sip_svc.c \ ${RK_PLAT_SOC}/plat_sip_calls.c \ - ${RK_PLAT_SOC}/drivers/dp/cdn_dp.c \ ${RK_PLAT_SOC}/drivers/gpio/rk3399_gpio.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu.c \ ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c \ @@ -81,22 +80,26 @@ PLAT_M0 := ${PLAT}m0 BUILD_M0 := ${BUILD_PLAT}/m0 RK3399M0FW=${BUILD_M0}/${PLAT_M0}.bin -$(eval $(call add_define,RK3399M0FW)) +$(eval $(call add_define_val,RK3399M0FW,\"$(RK3399M0FW)\")) RK3399M0PMUFW=${BUILD_M0}/${PLAT_M0}pmu.bin -$(eval $(call add_define,RK3399M0PMUFW)) +$(eval $(call add_define_val,RK3399M0PMUFW,\"$(RK3399M0PMUFW)\")) + +ifdef PLAT_RK_DP_HDCP +BL31_SOURCES += ${RK_PLAT_SOC}/drivers/dp/cdn_dp.c HDCPFW=${RK_PLAT_SOC}/drivers/dp/hdcp.bin -$(eval $(call add_define,HDCPFW)) +$(eval $(call add_define_val,HDCPFW,\"$(HDCPFW)\")) + +${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW) +${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW) +endif # CCACHE_EXTRAFILES is needed because ccache doesn't handle .incbin export CCACHE_EXTRAFILES ${BUILD_PLAT}/bl31/pmu_fw.o: CCACHE_EXTRAFILES=$(RK3399M0FW):$(RK3399M0PMUFW) ${RK_PLAT_SOC}/drivers/pmu/pmu_fw.c: $(RK3399M0FW) -${BUILD_PLAT}/bl31/cdn_dp.o: CCACHE_EXTRAFILES=$(HDCPFW) -${RK_PLAT_SOC}/drivers/dp/cdn_dp.c: $(HDCPFW) - $(eval $(call MAKE_PREREQ_DIR,${BUILD_M0},${BUILD_PLAT})) .PHONY: $(RK3399M0FW) $(RK3399M0FW): | ${BUILD_M0} diff --git a/plat/rpi3/rpi3_private.h b/plat/rpi/common/include/rpi_shared.h index 53078f8e9..de8357162 100644 --- a/plat/rpi3/rpi3_private.h +++ b/plat/rpi/common/include/rpi_shared.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef RPI3_PRIVATE_H -#define RPI3_PRIVATE_H +#ifndef RPI_SHARED_H +#define RPI_SHARED_H #include <stdint.h> @@ -14,7 +14,7 @@ ******************************************************************************/ /* Utility functions */ -void rpi3_console_init(void); +void rpi3_console_init(unsigned int base_clk_rate); void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size, uintptr_t code_start, uintptr_t code_limit, uintptr_t rodata_start, uintptr_t rodata_limit @@ -33,9 +33,6 @@ uint32_t rpi3_get_spsr_for_bl33_entry(void); /* IO storage utility functions */ void plat_rpi3_io_setup(void); -/* Hardware RNG functions */ -void rpi3_rng_read(void *buf, size_t len); - /* VideoCore firmware commands */ int rpi3_vc_hardware_get_board_revision(uint32_t *revision); diff --git a/plat/rpi3/rpi3_common.c b/plat/rpi/common/rpi3_common.c index 9b10974ad..ff3369427 100644 --- a/plat/rpi3/rpi3_common.c +++ b/plat/rpi/common/rpi3_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,16 +16,18 @@ #include <drivers/ti/uart/uart_16550.h> #include <lib/xlat_tables/xlat_tables_v2.h> -#include "rpi3_hw.h" -#include "rpi3_private.h" +#include <rpi_hw.h> +#include <rpi_shared.h> #define MAP_DEVICE0 MAP_REGION_FLAT(DEVICE0_BASE, \ DEVICE0_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +#ifdef SHARED_RAM_BASE #define MAP_SHARED_RAM MAP_REGION_FLAT(SHARED_RAM_BASE, \ SHARED_RAM_SIZE, \ MT_DEVICE | MT_RW | MT_SECURE) +#endif #ifdef RPI3_PRELOADED_DTB_BASE #define MAP_NS_DTB MAP_REGION_FLAT(RPI3_PRELOADED_DTB_BASE, 0x10000, \ @@ -54,7 +56,9 @@ */ #ifdef IMAGE_BL1 static const mmap_region_t plat_rpi3_mmap[] = { +#ifdef MAP_SHARED_RAM MAP_SHARED_RAM, +#endif MAP_DEVICE0, MAP_FIP, #ifdef SPD_opteed @@ -66,7 +70,9 @@ static const mmap_region_t plat_rpi3_mmap[] = { #ifdef IMAGE_BL2 static const mmap_region_t plat_rpi3_mmap[] = { +#ifdef MAP_SHARED_RAM MAP_SHARED_RAM, +#endif MAP_DEVICE0, MAP_FIP, MAP_NS_DRAM0, @@ -79,7 +85,9 @@ static const mmap_region_t plat_rpi3_mmap[] = { #ifdef IMAGE_BL31 static const mmap_region_t plat_rpi3_mmap[] = { +#ifdef MAP_SHARED_RAM MAP_SHARED_RAM, +#endif MAP_DEVICE0, #ifdef RPI3_PRELOADED_DTB_BASE MAP_NS_DTB, @@ -96,14 +104,14 @@ static const mmap_region_t plat_rpi3_mmap[] = { ******************************************************************************/ static console_16550_t rpi3_console; -void rpi3_console_init(void) +void rpi3_console_init(unsigned int base_clk_rate) { int console_scope = CONSOLE_FLAG_BOOT; #if RPI3_RUNTIME_UART != -1 console_scope |= CONSOLE_FLAG_RUNTIME; #endif int rc = console_16550_register(PLAT_RPI3_UART_BASE, - PLAT_RPI3_UART_CLK_IN_HZ, + base_clk_rate, PLAT_RPI3_UART_BAUDRATE, &rpi3_console); if (rc == 0) { @@ -168,18 +176,6 @@ void rpi3_setup_page_tables(uintptr_t total_base, size_t total_size, } /******************************************************************************* - * Return entrypoint of BL33. - ******************************************************************************/ -uintptr_t plat_get_ns_image_entrypoint(void) -{ -#ifdef PRELOADED_BL33_BASE - return PRELOADED_BL33_BASE; -#else - return PLAT_RPI3_NS_IMAGE_OFFSET; -#endif -} - -/******************************************************************************* * Gets SPSR for BL32 entry ******************************************************************************/ uint32_t rpi3_get_spsr_for_bl32_entry(void) diff --git a/plat/rpi3/rpi3_image_load.c b/plat/rpi/common/rpi3_image_load.c index 5394c6f7c..5394c6f7c 100644 --- a/plat/rpi3/rpi3_image_load.c +++ b/plat/rpi/common/rpi3_image_load.c diff --git a/plat/rpi3/rpi3_io_storage.c b/plat/rpi/common/rpi3_io_storage.c index 49c6a760c..49c6a760c 100644 --- a/plat/rpi3/rpi3_io_storage.c +++ b/plat/rpi/common/rpi3_io_storage.c diff --git a/plat/rpi3/rpi3_pm.c b/plat/rpi/common/rpi3_pm.c index 4f586b514..2a6bf076b 100644 --- a/plat/rpi3/rpi3_pm.c +++ b/plat/rpi/common/rpi3_pm.c @@ -15,7 +15,11 @@ #include <lib/psci/psci.h> #include <plat/common/platform.h> -#include "rpi3_hw.h" +#include <rpi_hw.h> + +#ifdef RPI_HAVE_GIC +#include <drivers/arm/gicv2.h> +#endif /* Make composite power state parameter till power level 0 */ #if PSCI_EXTENDED_STATE_ID @@ -112,6 +116,22 @@ static void rpi3_cpu_standby(plat_local_state_t cpu_state) wfi(); } +static void rpi3_pwr_domain_off(const psci_power_state_t *target_state) +{ +#ifdef RPI_HAVE_GIC + gicv2_cpuif_disable(); +#endif +} + +void __dead2 plat_secondary_cold_boot_setup(void); + +static void __dead2 +rpi3_pwr_domain_pwr_down_wfi(const psci_power_state_t *target_state) +{ + disable_mmu_el3(); + plat_secondary_cold_boot_setup(); +} + /******************************************************************************* * Platform handler called when a power domain is about to be turned on. The * mpidr determines the CPU to be turned on. @@ -144,6 +164,11 @@ static void rpi3_pwr_domain_on_finish(const psci_power_state_t *target_state) { assert(target_state->pwr_domain_state[MPIDR_AFFLVL0] == PLAT_LOCAL_STATE_OFF); + +#ifdef RPI_HAVE_GIC + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +#endif } /******************************************************************************* @@ -207,6 +232,8 @@ static void __dead2 rpi3_system_off(void) ******************************************************************************/ static const plat_psci_ops_t plat_rpi3_psci_pm_ops = { .cpu_standby = rpi3_cpu_standby, + .pwr_domain_off = rpi3_pwr_domain_off, + .pwr_domain_pwr_down_wfi = rpi3_pwr_domain_pwr_down_wfi, .pwr_domain_on = rpi3_pwr_domain_on, .pwr_domain_on_finish = rpi3_pwr_domain_on_finish, .system_off = rpi3_system_off, diff --git a/plat/rpi3/rpi3_rotpk.S b/plat/rpi/common/rpi3_rotpk.S index 1c17b2141..1c17b2141 100644 --- a/plat/rpi3/rpi3_rotpk.S +++ b/plat/rpi/common/rpi3_rotpk.S diff --git a/plat/rpi3/rpi3_stack_protector.c b/plat/rpi/common/rpi3_stack_protector.c index 6f49f617b..aae5fac72 100644 --- a/plat/rpi3/rpi3_stack_protector.c +++ b/plat/rpi/common/rpi3_stack_protector.c @@ -9,7 +9,7 @@ #include <lib/utils.h> #include <lib/utils_def.h> -#include "rpi3_private.h" +#include <drivers/rpi3/rng/rpi3_rng.h> /* Get 128 bits of entropy and fuse the values together to form the canary. */ #define TRNG_NBYTES 16U diff --git a/plat/rpi3/rpi3_topology.c b/plat/rpi/common/rpi3_topology.c index 200d41dd1..3747287c2 100644 --- a/plat/rpi3/rpi3_topology.c +++ b/plat/rpi/common/rpi3_topology.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,7 @@ #include <arch.h> -#include "rpi3_private.h" +#include <rpi_shared.h> /* The power domain tree descriptor */ static unsigned char power_domain_tree_desc[] = { diff --git a/plat/rpi3/rpi3_trusted_boot.c b/plat/rpi/common/rpi3_trusted_boot.c index f6c669fad..f6c669fad 100644 --- a/plat/rpi3/rpi3_trusted_boot.c +++ b/plat/rpi/common/rpi3_trusted_boot.c diff --git a/plat/rpi3/aarch64/plat_helpers.S b/plat/rpi/rpi3/aarch64/plat_helpers.S index 7974b602d..24278bdf6 100644 --- a/plat/rpi3/aarch64/plat_helpers.S +++ b/plat/rpi/rpi3/aarch64/plat_helpers.S @@ -9,7 +9,7 @@ #include <assert_macros.S> #include <platform_def.h> -#include "../rpi3_hw.h" +#include "../include/rpi_hw.h" .globl plat_crash_console_flush .globl plat_crash_console_init @@ -18,7 +18,6 @@ .globl plat_get_my_entrypoint .globl plat_is_my_cpu_primary .globl plat_my_core_pos - .globl plat_reset_handler .globl plat_rpi3_calc_core_pos .globl plat_secondary_cold_boot_setup @@ -164,16 +163,3 @@ func plat_crash_console_flush mov_imm x0, PLAT_RPI3_UART_BASE b console_16550_core_flush endfunc plat_crash_console_flush - - /* --------------------------------------------- - * void plat_reset_handler(void); - * --------------------------------------------- - */ -func plat_reset_handler - /* use the 19.2 MHz clock for the architected timer */ - mov x0, #RPI3_INTC_BASE_ADDRESS - mov w1, #0x80000000 - str wzr, [x0, #RPI3_INTC_CONTROL_OFFSET] - str w1, [x0, #RPI3_INTC_PRESCALER_OFFSET] - ret -endfunc plat_reset_handler diff --git a/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c b/plat/rpi/rpi3/aarch64/rpi3_bl2_mem_params_desc.c index 715aec410..715aec410 100644 --- a/plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c +++ b/plat/rpi/rpi3/aarch64/rpi3_bl2_mem_params_desc.c diff --git a/plat/rpi3/include/plat_macros.S b/plat/rpi/rpi3/include/plat_macros.S index c0c396791..c0c396791 100644 --- a/plat/rpi3/include/plat_macros.S +++ b/plat/rpi/rpi3/include/plat_macros.S diff --git a/plat/rpi3/include/platform_def.h b/plat/rpi/rpi3/include/platform_def.h index 4d902225f..e308f70a6 100644 --- a/plat/rpi3/include/platform_def.h +++ b/plat/rpi/rpi3/include/platform_def.h @@ -12,7 +12,7 @@ #include <lib/utils_def.h> #include <plat/common/common_def.h> -#include "../rpi3_hw.h" +#include "rpi_hw.h" /* Special value used to verify platform parameters from BL2 to BL31 */ #define RPI3_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978) @@ -110,8 +110,8 @@ /* * I/O registers. */ -#define DEVICE0_BASE RPI3_IO_BASE -#define DEVICE0_SIZE RPI3_IO_SIZE +#define DEVICE0_BASE RPI_IO_BASE +#define DEVICE0_SIZE RPI_IO_SIZE /* * Arm TF lives in SRAM, partition it here diff --git a/plat/rpi3/rpi3_hw.h b/plat/rpi/rpi3/include/rpi_hw.h index 1a86835b3..01d5b4a0f 100644 --- a/plat/rpi3/rpi3_hw.h +++ b/plat/rpi/rpi3/include/rpi_hw.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef RPI3_HW_H -#define RPI3_HW_H +#ifndef RPI_HW_H +#define RPI_HW_H #include <lib/utils_def.h> @@ -13,14 +13,14 @@ * Peripherals */ -#define RPI3_IO_BASE ULL(0x3F000000) -#define RPI3_IO_SIZE ULL(0x01000000) +#define RPI_IO_BASE ULL(0x3F000000) +#define RPI_IO_SIZE ULL(0x01000000) /* * ARM <-> VideoCore mailboxes */ #define RPI3_MBOX_OFFSET ULL(0x0000B880) -#define RPI3_MBOX_BASE (RPI3_IO_BASE + RPI3_MBOX_OFFSET) +#define RPI3_MBOX_BASE (RPI_IO_BASE + RPI3_MBOX_OFFSET) /* VideoCore -> ARM */ #define RPI3_MBOX0_READ_OFFSET ULL(0x00000000) #define RPI3_MBOX0_PEEK_OFFSET ULL(0x00000010) @@ -41,7 +41,7 @@ * Power management, reset controller, watchdog. */ #define RPI3_IO_PM_OFFSET ULL(0x00100000) -#define RPI3_PM_BASE (RPI3_IO_BASE + RPI3_IO_PM_OFFSET) +#define RPI3_PM_BASE (RPI_IO_BASE + RPI3_IO_PM_OFFSET) /* Registers on top of RPI3_PM_BASE. */ #define RPI3_PM_RSTC_OFFSET ULL(0x0000001C) #define RPI3_PM_RSTS_OFFSET ULL(0x00000020) @@ -62,7 +62,7 @@ * Hardware random number generator. */ #define RPI3_IO_RNG_OFFSET ULL(0x00104000) -#define RPI3_RNG_BASE (RPI3_IO_BASE + RPI3_IO_RNG_OFFSET) +#define RPI3_RNG_BASE (RPI_IO_BASE + RPI3_IO_RNG_OFFSET) #define RPI3_RNG_CTRL_OFFSET ULL(0x00000000) #define RPI3_RNG_STATUS_OFFSET ULL(0x00000004) #define RPI3_RNG_DATA_OFFSET ULL(0x00000008) @@ -80,20 +80,20 @@ * Serial port (called 'Mini UART' in the BCM docucmentation). */ #define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) -#define RPI3_MINI_UART_BASE (RPI3_IO_BASE + RPI3_IO_MINI_UART_OFFSET) +#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) #define RPI3_MINI_UART_CLK_IN_HZ ULL(500000000) /* * GPIO controller */ #define RPI3_IO_GPIO_OFFSET ULL(0x00200000) -#define RPI3_GPIO_BASE (RPI3_IO_BASE + RPI3_IO_GPIO_OFFSET) +#define RPI3_GPIO_BASE (RPI_IO_BASE + RPI3_IO_GPIO_OFFSET) /* * SDHost controller */ #define RPI3_IO_SDHOST_OFFSET ULL(0x00202000) -#define RPI3_SDHOST_BASE (RPI3_IO_BASE + RPI3_IO_SDHOST_OFFSET) +#define RPI3_SDHOST_BASE (RPI_IO_BASE + RPI3_IO_SDHOST_OFFSET) /* * Local interrupt controller @@ -107,4 +107,4 @@ #define RPI3_INTC_PENDING_FIQ_OFFSET ULL(0x00000070) #define RPI3_INTC_PENDING_FIQ_MBOX3 ULL(0x00000080) -#endif /* RPI3_HW_H */ +#endif /* RPI_HW_H */ diff --git a/plat/rpi3/platform.mk b/plat/rpi/rpi3/platform.mk index f238cd61d..a21a7709a 100644 --- a/plat/rpi3/platform.mk +++ b/plat/rpi/rpi3/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -7,10 +7,11 @@ include lib/libfdt/libfdt.mk include lib/xlat_tables_v2/xlat_tables.mk -PLAT_INCLUDES := -Iplat/rpi3/include +PLAT_INCLUDES := -Iplat/rpi/common/include \ + -Iplat/rpi/rpi3/include PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ - plat/rpi3/rpi3_common.c \ + plat/rpi/common/rpi3_common.c \ ${XLAT_TABLES_LIB_SRCS} BL1_SOURCES += drivers/io/io_fip.c \ @@ -18,10 +19,11 @@ BL1_SOURCES += drivers/io/io_fip.c \ drivers/io/io_storage.c \ lib/cpus/aarch64/cortex_a53.S \ plat/common/aarch64/platform_mp_stack.S \ - plat/rpi3/aarch64/plat_helpers.S \ - plat/rpi3/rpi3_bl1_setup.c \ - plat/rpi3/rpi3_io_storage.c \ - plat/rpi3/rpi3_mbox.c + plat/rpi/rpi3/aarch64/plat_helpers.S \ + plat/rpi/rpi3/rpi3_bl1_setup.c \ + plat/rpi/common/rpi3_io_storage.c \ + drivers/rpi3/mailbox/rpi3_mbox.c \ + plat/rpi/rpi3/rpi_mbox_board.c BL2_SOURCES += common/desc_image_load.c \ drivers/io/io_fip.c \ @@ -35,18 +37,18 @@ BL2_SOURCES += common/desc_image_load.c \ drivers/mmc/mmc.c \ drivers/rpi3/sdhost/rpi3_sdhost.c \ plat/common/aarch64/platform_mp_stack.S \ - plat/rpi3/aarch64/plat_helpers.S \ - plat/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \ - plat/rpi3/rpi3_bl2_setup.c \ - plat/rpi3/rpi3_image_load.c \ - plat/rpi3/rpi3_io_storage.c + plat/rpi/rpi3/aarch64/plat_helpers.S \ + plat/rpi/rpi3/aarch64/rpi3_bl2_mem_params_desc.c \ + plat/rpi/rpi3/rpi3_bl2_setup.c \ + plat/rpi/common/rpi3_image_load.c \ + plat/rpi/common/rpi3_io_storage.c BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_psci_common.c \ - plat/rpi3/aarch64/plat_helpers.S \ - plat/rpi3/rpi3_bl31_setup.c \ - plat/rpi3/rpi3_pm.c \ - plat/rpi3/rpi3_topology.c \ + plat/rpi/rpi3/aarch64/plat_helpers.S \ + plat/rpi/rpi3/rpi3_bl31_setup.c \ + plat/rpi/common/rpi3_pm.c \ + plat/rpi/common/rpi3_topology.c \ ${LIBFDT_SRCS} # Tune compiler for Cortex-A53 @@ -158,8 +160,8 @@ ifeq (${ARCH},aarch32) endif ifneq ($(ENABLE_STACK_PROTECTOR), 0) -PLAT_BL_COMMON_SOURCES += plat/rpi3/rpi3_rng.c \ - plat/rpi3/rpi3_stack_protector.c +PLAT_BL_COMMON_SOURCES += drivers/rpi3/rng/rpi3_rng.c \ + plat/rpi/common/rpi3_stack_protector.c endif ifeq (${SPD},opteed) @@ -189,13 +191,13 @@ ifneq (${TRUSTED_BOARD_BOOT},0) BL1_SOURCES += ${AUTH_SOURCES} \ bl1/tbbr/tbbr_img_desc.c \ plat/common/tbbr/plat_tbbr.c \ - plat/rpi3/rpi3_trusted_boot.c \ - plat/rpi3/rpi3_rotpk.S + plat/rpi/common/rpi3_trusted_boot.c \ + plat/rpi/common/rpi3_rotpk.S BL2_SOURCES += ${AUTH_SOURCES} \ plat/common/tbbr/plat_tbbr.c \ - plat/rpi3/rpi3_trusted_boot.c \ - plat/rpi3/rpi3_rotpk.S + plat/rpi/common/rpi3_trusted_boot.c \ + plat/rpi/common/rpi3_rotpk.S ROT_KEY = $(BUILD_PLAT)/rot_key.pem ROTPK_HASH = $(BUILD_PLAT)/rotpk_sha256.bin diff --git a/plat/rpi3/rpi3_bl1_setup.c b/plat/rpi/rpi3/rpi3_bl1_setup.c index b869e9da8..dcce76e47 100644 --- a/plat/rpi3/rpi3_bl1_setup.c +++ b/plat/rpi/rpi3/rpi3_bl1_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,10 +10,11 @@ #include <arch_helpers.h> #include <common/bl_common.h> #include <common/debug.h> +#include <lib/mmio.h> #include <lib/xlat_tables/xlat_mmu_helpers.h> #include <lib/xlat_tables/xlat_tables_defs.h> -#include "rpi3_private.h" +#include <rpi_shared.h> /* Data structure which holds the extents of the trusted SRAM for BL1 */ static meminfo_t bl1_tzram_layout; @@ -28,8 +29,13 @@ meminfo_t *bl1_plat_sec_mem_layout(void) ******************************************************************************/ void bl1_early_platform_setup(void) { + /* use the 19.2 MHz clock for the architected timer */ + mmio_write_32(RPI3_INTC_BASE_ADDRESS + RPI3_INTC_CONTROL_OFFSET, 0); + mmio_write_32(RPI3_INTC_BASE_ADDRESS + RPI3_INTC_PRESCALER_OFFSET, + 0x80000000); + /* Initialize the console to provide early debug support */ - rpi3_console_init(); + rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); /* Allow BL1 to see the whole Trusted RAM */ bl1_tzram_layout.total_base = BL_RAM_BASE; diff --git a/plat/rpi3/rpi3_bl2_setup.c b/plat/rpi/rpi3/rpi3_bl2_setup.c index b5e58352a..44827c63a 100644 --- a/plat/rpi3/rpi3_bl2_setup.c +++ b/plat/rpi/rpi3/rpi3_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,7 +19,7 @@ #include <drivers/rpi3/gpio/rpi3_gpio.h> #include <drivers/rpi3/sdhost/rpi3_sdhost.h> -#include "rpi3_private.h" +#include <rpi_shared.h> /* Data structure which holds the extents of the trusted SRAM for BL2 */ static meminfo_t bl2_tzram_layout __aligned(CACHE_WRITEBACK_GRANULE); @@ -62,7 +62,7 @@ void bl2_early_platform_setup2(u_register_t arg0, u_register_t arg1, meminfo_t *mem_layout = (meminfo_t *) arg1; /* Initialize the console to provide early debug support */ - rpi3_console_init(); + rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); /* Enable arch timer */ generic_delay_timer_init(); diff --git a/plat/rpi3/rpi3_bl31_setup.c b/plat/rpi/rpi3/rpi3_bl31_setup.c index 2f1bc6493..24a56139b 100644 --- a/plat/rpi3/rpi3_bl31_setup.c +++ b/plat/rpi/rpi3/rpi3_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -15,7 +15,7 @@ #include <lib/xlat_tables/xlat_tables_defs.h> #include <plat/common/platform.h> -#include "rpi3_private.h" +#include <rpi_shared.h> /* * Placeholder variables for copying the arguments that have been passed to @@ -48,6 +48,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) } /******************************************************************************* + * Return entrypoint of BL33. + ******************************************************************************/ +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + return PLAT_RPI3_NS_IMAGE_OFFSET; +#endif +} + +/******************************************************************************* * Perform any BL31 early platform setup. Here is an opportunity to copy * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before * they are lost (potentially). This needs to be done before the MMU is @@ -60,7 +72,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, { /* Initialize the console to provide early debug support */ - rpi3_console_init(); + rpi3_console_init(PLAT_RPI3_UART_CLK_IN_HZ); /* * In debug builds, a special value is passed in 'arg1' to verify diff --git a/plat/rpi/rpi3/rpi_mbox_board.c b/plat/rpi/rpi3/rpi_mbox_board.c new file mode 100644 index 000000000..e7c1e2ba3 --- /dev/null +++ b/plat/rpi/rpi3/rpi_mbox_board.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <platform_def.h> + +#include <arch_helpers.h> + +#include <drivers/rpi3/mailbox/rpi3_mbox.h> + +#define RPI3_MBOX_BUFFER_SIZE U(256) +static uint8_t __aligned(16) rpi3_mbox_buffer[RPI3_MBOX_BUFFER_SIZE]; + +/******************************************************************************* + * Request board revision. Returns the revision and 0 on success, -1 on error. + ******************************************************************************/ +int rpi3_vc_hardware_get_board_revision(uint32_t *revision) +{ + uint32_t tag_request_size = sizeof(uint32_t); + rpi3_mbox_request_t *req = (rpi3_mbox_request_t *) rpi3_mbox_buffer; + + assert(revision != NULL); + + VERBOSE("rpi3: mbox: Sending request at %p\n", (void *)req); + + req->size = sizeof(rpi3_mbox_buffer); + req->code = RPI3_MBOX_PROCESS_REQUEST; + + req->tags[0] = RPI3_TAG_HARDWARE_GET_BOARD_REVISION; + req->tags[1] = tag_request_size; /* Space available for the response */ + req->tags[2] = RPI3_TAG_REQUEST; + req->tags[3] = 0; /* Placeholder for the response */ + + req->tags[4] = RPI3_TAG_END; + + rpi3_vc_mailbox_request_send(req, RPI3_MBOX_BUFFER_SIZE); + + if (req->code != RPI3_MBOX_REQUEST_SUCCESSFUL) { + ERROR("rpi3: mbox: Code = 0x%08x\n", req->code); + return -1; + } + + if (req->tags[2] != (RPI3_TAG_IS_RESPONSE | tag_request_size)) { + ERROR("rpi3: mbox: get board revision failed (0x%08x)\n", + req->tags[2]); + return -1; + } + + *revision = req->tags[3]; + + return 0; +} diff --git a/plat/rpi/rpi4/aarch64/armstub8_header.S b/plat/rpi/rpi4/aarch64/armstub8_header.S new file mode 100644 index 000000000..246358d04 --- /dev/null +++ b/plat/rpi/rpi4/aarch64/armstub8_header.S @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * armstub8.bin header to let the GPU firmware recognise this code. + * It will then write the load address of the kernel image and the DT + * after the header magic in RAM, so we can read those addresses at runtime. + */ + +.text + b armstub8_end + +.global stub_magic +.global dtb_ptr32 +.global kernel_entry32 + +.org 0xf0 +armstub8: +stub_magic: + .word 0x5afe570b +stub_version: + .word 0 +dtb_ptr32: + .word 0x0 +kernel_entry32: + .word 0x0 + +/* + * Technically an offset of 0x100 would suffice, but the follow-up code + * (bl31_entrypoint.S at BL31_BASE) needs to be page aligned, so pad here + * till the end of the first 4K page. + */ +.org 0x1000 +armstub8_end: diff --git a/plat/rpi/rpi4/aarch64/plat_helpers.S b/plat/rpi/rpi4/aarch64/plat_helpers.S new file mode 100644 index 000000000..083c30e71 --- /dev/null +++ b/plat/rpi/rpi4/aarch64/plat_helpers.S @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <asm_macros.S> +#include <assert_macros.S> +#include <platform_def.h> +#include <cortex_a72.h> + +#include "../include/rpi_hw.h" + + .globl plat_crash_console_flush + .globl plat_crash_console_init + .globl plat_crash_console_putc + .globl platform_mem_init + .globl plat_get_my_entrypoint + .globl plat_is_my_cpu_primary + .globl plat_my_core_pos + .globl plat_reset_handler + .globl plat_rpi3_calc_core_pos + .globl plat_secondary_cold_boot_setup + + /* ----------------------------------------------------- + * unsigned int plat_my_core_pos(void) + * + * This function uses the plat_rpi3_calc_core_pos() + * definition to get the index of the calling CPU. + * ----------------------------------------------------- + */ +func plat_my_core_pos + mrs x0, mpidr_el1 + b plat_rpi3_calc_core_pos +endfunc plat_my_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_rpi3_calc_core_pos(u_register_t mpidr); + * + * CorePos = (ClusterId * 4) + CoreId + * ----------------------------------------------------- + */ +func plat_rpi3_calc_core_pos + and x1, x0, #MPIDR_CPU_MASK + and x0, x0, #MPIDR_CLUSTER_MASK + add x0, x1, x0, LSR #6 + ret +endfunc plat_rpi3_calc_core_pos + + /* ----------------------------------------------------- + * unsigned int plat_is_my_cpu_primary (void); + * + * Find out whether the current cpu is the primary + * cpu. + * ----------------------------------------------------- + */ +func plat_is_my_cpu_primary + mrs x0, mpidr_el1 + and x0, x0, #(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK) + cmp x0, #RPI4_PRIMARY_CPU + cset w0, eq + ret +endfunc plat_is_my_cpu_primary + + /* ----------------------------------------------------- + * void plat_secondary_cold_boot_setup (void); + * + * This function performs any platform specific actions + * needed for a secondary cpu after a cold reset e.g + * mark the cpu's presence, mechanism to place it in a + * holding pen etc. + * ----------------------------------------------------- + */ +func plat_secondary_cold_boot_setup + /* Calculate address of our hold entry */ + bl plat_my_core_pos + lsl x0, x0, #3 + mov_imm x2, PLAT_RPI3_TM_HOLD_BASE + add x0, x0, x2 + + /* + * This code runs way before requesting the warmboot of this core, + * so it is possible to clear the mailbox before getting a request + * to boot. + */ + mov x1, PLAT_RPI3_TM_HOLD_STATE_WAIT + str x1,[x0] + + /* Wait until we have a go */ +poll_mailbox: + wfe + ldr x1, [x0] + cmp x1, PLAT_RPI3_TM_HOLD_STATE_GO + bne poll_mailbox + + /* Jump to the provided entrypoint */ + mov_imm x0, PLAT_RPI3_TM_ENTRYPOINT + ldr x1, [x0] + br x1 +endfunc plat_secondary_cold_boot_setup + + /* --------------------------------------------------------------------- + * uintptr_t plat_get_my_entrypoint (void); + * + * Main job of this routine is to distinguish between a cold and a warm + * boot. + * + * This functions returns: + * - 0 for a cold boot. + * - Any other value for a warm boot. + * --------------------------------------------------------------------- + */ +func plat_get_my_entrypoint + /* TODO: support warm boot */ + mov x0, #0 + ret +endfunc plat_get_my_entrypoint + + /* --------------------------------------------- + * void platform_mem_init (void); + * + * No need to carry out any memory initialization. + * --------------------------------------------- + */ +func platform_mem_init + ret +endfunc platform_mem_init + + /* --------------------------------------------- + * int plat_crash_console_init(void) + * Function to initialize the crash console + * without a C Runtime to print crash report. + * Clobber list : x0 - x3 + * --------------------------------------------- + */ +func plat_crash_console_init + mov_imm x0, PLAT_RPI3_UART_BASE + mov x1, xzr + mov x2, xzr + b console_16550_core_init +endfunc plat_crash_console_init + + /* --------------------------------------------- + * int plat_crash_console_putc(int c) + * Function to print a character on the crash + * console without a C Runtime. + * Clobber list : x1, x2 + * --------------------------------------------- + */ +func plat_crash_console_putc + mov_imm x1, PLAT_RPI3_UART_BASE + b console_16550_core_putc +endfunc plat_crash_console_putc + + /* --------------------------------------------- + * int plat_crash_console_flush() + * Function to force a write of all buffered + * data that hasn't been output. + * Out : return -1 on error else return 0. + * Clobber list : x0, x1 + * --------------------------------------------- + */ +func plat_crash_console_flush + mov_imm x0, PLAT_RPI3_UART_BASE + b console_16550_core_flush +endfunc plat_crash_console_flush + + /* --------------------------------------------- + * void plat_reset_handler(void); + * --------------------------------------------- + */ +func plat_reset_handler + /* ------------------------------------------------ + * Set L2 read/write cache latency: + * - L2 Data RAM latency: 3 cycles (0b010) + * - L2 Data RAM setup: 1 cycle (bit 5) + * ------------------------------------------------ + */ + mrs x0, CORTEX_A72_L2CTLR_EL1 + mov x1, #0x22 + orr x0, x0, x1 + msr CORTEX_A72_L2CTLR_EL1, x0 + isb + + ret +endfunc plat_reset_handler diff --git a/plat/rpi/rpi4/include/plat.ld.S b/plat/rpi/rpi4/include/plat.ld.S new file mode 100644 index 000000000..9262fad8a --- /dev/null +++ b/plat/rpi/rpi4/include/plat.ld.S @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + * + * Stub linker script to provide the armstub8.bin header before the actual + * code. If the GPU firmware finds a magic value at offset 240 in + * armstub8.bin, it will put the DTB and kernel load address in subsequent + * words. We can then read those values to find the proper NS entry point + * and find our DTB more flexibly. + */ + +MEMORY { + PRERAM (rwx): ORIGIN = 0, LENGTH = 4096 +} + +SECTIONS +{ + .armstub8 . : { + *armstub8_header.o(.text*) + KEEP(*(.armstub8)) + } >PRERAM +} diff --git a/plat/rpi/rpi4/include/plat_macros.S b/plat/rpi/rpi4/include/plat_macros.S new file mode 100644 index 000000000..6007d031e --- /dev/null +++ b/plat/rpi/rpi4/include/plat_macros.S @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef PLAT_MACROS_S +#define PLAT_MACROS_S + + /* --------------------------------------------- + * The below required platform porting macro + * prints out relevant platform registers + * whenever an unhandled exception is taken in + * BL31. + * Clobbers: x0 - x10, x16, x17, sp + * --------------------------------------------- + */ + .macro plat_crash_print_regs + .endm + +#endif /* PLAT_MACROS_S */ diff --git a/plat/rpi/rpi4/include/platform_def.h b/plat/rpi/rpi4/include/platform_def.h new file mode 100644 index 000000000..a9ecdba20 --- /dev/null +++ b/plat/rpi/rpi4/include/platform_def.h @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLATFORM_DEF_H +#define PLATFORM_DEF_H + +#include <arch.h> +#include <common/tbbr/tbbr_img_def.h> +#include <lib/utils_def.h> +#include <plat/common/common_def.h> + +#include "rpi_hw.h" + +/* Special value used to verify platform parameters from BL2 to BL31 */ +#define RPI3_BL31_PLAT_PARAM_VAL ULL(0x0F1E2D3C4B5A6978) + +#define PLATFORM_STACK_SIZE ULL(0x1000) + +#define PLATFORM_MAX_CPUS_PER_CLUSTER U(4) +#define PLATFORM_CLUSTER_COUNT U(1) +#define PLATFORM_CLUSTER0_CORE_COUNT PLATFORM_MAX_CPUS_PER_CLUSTER +#define PLATFORM_CORE_COUNT PLATFORM_CLUSTER0_CORE_COUNT + +#define RPI4_PRIMARY_CPU U(0) + +#define PLAT_MAX_PWR_LVL MPIDR_AFFLVL1 +#define PLAT_NUM_PWR_DOMAINS (PLATFORM_CLUSTER_COUNT + \ + PLATFORM_CORE_COUNT) + +#define PLAT_MAX_RET_STATE U(1) +#define PLAT_MAX_OFF_STATE U(2) + +/* Local power state for power domains in Run state. */ +#define PLAT_LOCAL_STATE_RUN U(0) +/* Local power state for retention. Valid only for CPU power domains */ +#define PLAT_LOCAL_STATE_RET U(1) +/* + * Local power state for OFF/power-down. Valid for CPU and cluster power + * domains. + */ +#define PLAT_LOCAL_STATE_OFF U(2) + +/* + * Macros used to parse state information from State-ID if it is using the + * recommended encoding for State-ID. + */ +#define PLAT_LOCAL_PSTATE_WIDTH U(4) +#define PLAT_LOCAL_PSTATE_MASK ((U(1) << PLAT_LOCAL_PSTATE_WIDTH) - 1) + +/* + * Some data must be aligned on the biggest cache line size in the platform. + * This is known only to the platform as it might have a combination of + * integrated and external caches. + */ +#define CACHE_WRITEBACK_SHIFT U(6) +#define CACHE_WRITEBACK_GRANULE (U(1) << CACHE_WRITEBACK_SHIFT) + +/* + * I/O registers. + */ +#define DEVICE0_BASE RPI_IO_BASE +#define DEVICE0_SIZE RPI_IO_SIZE + +/* + * Mailbox to control the secondary cores. All secondary cores are held in a + * wait loop in cold boot. To release them perform the following steps (plus + * any additional barriers that may be needed): + * + * uint64_t *entrypoint = (uint64_t *)PLAT_RPI3_TM_ENTRYPOINT; + * *entrypoint = ADDRESS_TO_JUMP_TO; + * + * uint64_t *mbox_entry = (uint64_t *)PLAT_RPI3_TM_HOLD_BASE; + * mbox_entry[cpu_id] = PLAT_RPI3_TM_HOLD_STATE_GO; + * + * sev(); + */ +/* The secure entry point to be used on warm reset by all CPUs. */ +#define PLAT_RPI3_TM_ENTRYPOINT 0x100 +#define PLAT_RPI3_TM_ENTRYPOINT_SIZE ULL(8) + +/* Hold entries for each CPU. */ +#define PLAT_RPI3_TM_HOLD_BASE (PLAT_RPI3_TM_ENTRYPOINT + \ + PLAT_RPI3_TM_ENTRYPOINT_SIZE) +#define PLAT_RPI3_TM_HOLD_ENTRY_SIZE ULL(8) +#define PLAT_RPI3_TM_HOLD_SIZE (PLAT_RPI3_TM_HOLD_ENTRY_SIZE * \ + PLATFORM_CORE_COUNT) + +#define PLAT_RPI3_TRUSTED_MAILBOX_SIZE (PLAT_RPI3_TM_ENTRYPOINT_SIZE + \ + PLAT_RPI3_TM_HOLD_SIZE) + +#define PLAT_RPI3_TM_HOLD_STATE_WAIT ULL(0) +#define PLAT_RPI3_TM_HOLD_STATE_GO ULL(1) + +/* + * BL31 specific defines. + * + * Put BL31 at the top of the Trusted SRAM. BL31_BASE is calculated using the + * current BL31 debug size plus a little space for growth. + */ +#define PLAT_MAX_BL31_SIZE ULL(0x80000) + +#define BL31_BASE ULL(0x1000) +#define BL31_LIMIT ULL(0x80000) +#define BL31_PROGBITS_LIMIT ULL(0x80000) + +#define SEC_SRAM_ID 0 +#define SEC_DRAM_ID 1 + +/* + * Other memory-related defines. + */ +#define PLAT_PHY_ADDR_SPACE_SIZE (ULL(1) << 32) +#define PLAT_VIRT_ADDR_SPACE_SIZE (ULL(1) << 32) + +#define MAX_MMAP_REGIONS 8 +#define MAX_XLAT_TABLES 4 + +#define MAX_IO_DEVICES U(3) +#define MAX_IO_HANDLES U(4) + +#define MAX_IO_BLOCK_DEVICES U(1) + +/* + * Serial-related constants. + */ +#define PLAT_RPI3_UART_BASE RPI3_MINI_UART_BASE +#define PLAT_RPI3_UART_BAUDRATE ULL(115200) + +/* + * System counter + */ +#define SYS_COUNTER_FREQ_IN_TICKS ULL(54000000) + +#endif /* PLATFORM_DEF_H */ diff --git a/plat/rpi/rpi4/include/rpi_hw.h b/plat/rpi/rpi4/include/rpi_hw.h new file mode 100644 index 000000000..b1dd4e92e --- /dev/null +++ b/plat/rpi/rpi4/include/rpi_hw.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef RPI_HW_H +#define RPI_HW_H + +#include <lib/utils_def.h> + +/* + * Peripherals + */ + +#define RPI_IO_BASE ULL(0xFE000000) +#define RPI_IO_SIZE ULL(0x02000000) + +/* + * ARM <-> VideoCore mailboxes + */ +#define RPI3_MBOX_OFFSET ULL(0x0000B880) +#define RPI3_MBOX_BASE (RPI_IO_BASE + RPI3_MBOX_OFFSET) +/* VideoCore -> ARM */ +#define RPI3_MBOX0_READ_OFFSET ULL(0x00000000) +#define RPI3_MBOX0_PEEK_OFFSET ULL(0x00000010) +#define RPI3_MBOX0_SENDER_OFFSET ULL(0x00000014) +#define RPI3_MBOX0_STATUS_OFFSET ULL(0x00000018) +#define RPI3_MBOX0_CONFIG_OFFSET ULL(0x0000001C) +/* ARM -> VideoCore */ +#define RPI3_MBOX1_WRITE_OFFSET ULL(0x00000020) +#define RPI3_MBOX1_PEEK_OFFSET ULL(0x00000030) +#define RPI3_MBOX1_SENDER_OFFSET ULL(0x00000034) +#define RPI3_MBOX1_STATUS_OFFSET ULL(0x00000038) +#define RPI3_MBOX1_CONFIG_OFFSET ULL(0x0000003C) +/* Mailbox status constants */ +#define RPI3_MBOX_STATUS_FULL_MASK U(0x80000000) /* Set if full */ +#define RPI3_MBOX_STATUS_EMPTY_MASK U(0x40000000) /* Set if empty */ + +/* + * Power management, reset controller, watchdog. + */ +#define RPI3_IO_PM_OFFSET ULL(0x00100000) +#define RPI3_PM_BASE (RPI_IO_BASE + RPI3_IO_PM_OFFSET) +/* Registers on top of RPI3_PM_BASE. */ +#define RPI3_PM_RSTC_OFFSET ULL(0x0000001C) +#define RPI3_PM_RSTS_OFFSET ULL(0x00000020) +#define RPI3_PM_WDOG_OFFSET ULL(0x00000024) +/* Watchdog constants */ +#define RPI3_PM_PASSWORD U(0x5A000000) +#define RPI3_PM_RSTC_WRCFG_MASK U(0x00000030) +#define RPI3_PM_RSTC_WRCFG_FULL_RESET U(0x00000020) +/* + * The RSTS register is used by the VideoCore firmware when booting the + * Raspberry Pi to know which partition to boot from. The partition value is + * formed by bits 0, 2, 4, 6, 8 and 10. Partition 63 is used by said firmware + * to indicate halt. + */ +#define RPI3_PM_RSTS_WRCFG_HALT U(0x00000555) + +/* + * Hardware random number generator. + */ +#define RPI3_IO_RNG_OFFSET ULL(0x00104000) +#define RPI3_RNG_BASE (RPI_IO_BASE + RPI3_IO_RNG_OFFSET) +#define RPI3_RNG_CTRL_OFFSET ULL(0x00000000) +#define RPI3_RNG_STATUS_OFFSET ULL(0x00000004) +#define RPI3_RNG_DATA_OFFSET ULL(0x00000008) +#define RPI3_RNG_INT_MASK_OFFSET ULL(0x00000010) +/* Enable/disable RNG */ +#define RPI3_RNG_CTRL_ENABLE U(0x1) +#define RPI3_RNG_CTRL_DISABLE U(0x0) +/* Number of currently available words */ +#define RPI3_RNG_STATUS_NUM_WORDS_SHIFT U(24) +#define RPI3_RNG_STATUS_NUM_WORDS_MASK U(0xFF) +/* Value to mask interrupts caused by the RNG */ +#define RPI3_RNG_INT_MASK_DISABLE U(0x1) + +/* + * Serial port (called 'Mini UART' in the Broadcom documentation). + */ +#define RPI3_IO_MINI_UART_OFFSET ULL(0x00215040) +#define RPI3_MINI_UART_BASE (RPI_IO_BASE + RPI3_IO_MINI_UART_OFFSET) + +/* + * GPIO controller + */ +#define RPI3_IO_GPIO_OFFSET ULL(0x00200000) +#define RPI3_GPIO_BASE (RPI_IO_BASE + RPI3_IO_GPIO_OFFSET) + +/* + * SDHost controller + */ +#define RPI3_IO_SDHOST_OFFSET ULL(0x00202000) +#define RPI3_SDHOST_BASE (RPI_IO_BASE + RPI3_IO_SDHOST_OFFSET) + +/* + * GIC interrupt controller + */ +#define RPI_HAVE_GIC +#define RPI4_GIC_GICD_BASE ULL(0xff841000) +#define RPI4_GIC_GICC_BASE ULL(0xff842000) + +#define RPI4_LOCAL_CONTROL_BASE_ADDRESS ULL(0xff800000) +#define RPI4_LOCAL_CONTROL_PRESCALER ULL(0xff800008) + +#endif /* RPI_HW_H */ diff --git a/plat/rpi/rpi4/platform.mk b/plat/rpi/rpi4/platform.mk new file mode 100644 index 000000000..2038021a0 --- /dev/null +++ b/plat/rpi/rpi4/platform.mk @@ -0,0 +1,103 @@ +# +# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# +# SPDX-License-Identifier: BSD-3-Clause +# + +include lib/libfdt/libfdt.mk +include lib/xlat_tables_v2/xlat_tables.mk + +PLAT_INCLUDES := -Iplat/rpi/common/include \ + -Iplat/rpi/rpi4/include + +PLAT_BL_COMMON_SOURCES := drivers/ti/uart/aarch64/16550_console.S \ + plat/rpi/common/rpi3_common.c \ + ${XLAT_TABLES_LIB_SRCS} + +BL31_SOURCES += lib/cpus/aarch64/cortex_a72.S \ + plat/rpi/rpi4/aarch64/plat_helpers.S \ + plat/rpi/rpi4/aarch64/armstub8_header.S \ + drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v2/gicv2_helpers.c \ + drivers/arm/gic/v2/gicv2_main.c \ + plat/common/plat_gicv2.c \ + plat/rpi/rpi4/rpi4_bl31_setup.c \ + plat/rpi/common/rpi3_pm.c \ + plat/common/plat_psci_common.c \ + plat/rpi/common/rpi3_topology.c \ + common/fdt_fixup.c \ + ${LIBFDT_SRCS} + +# For now we only support BL31, using the kernel loaded by the GPU firmware. +RESET_TO_BL31 := 1 + +# All CPUs enter armstub8.bin. +COLD_BOOT_SINGLE_CPU := 0 + +# Tune compiler for Cortex-A72 +ifeq ($(notdir $(CC)),armclang) + TF_CFLAGS_aarch64 += -mcpu=cortex-a72 +else ifneq ($(findstring clang,$(notdir $(CC))),) + TF_CFLAGS_aarch64 += -mcpu=cortex-a72 +else + TF_CFLAGS_aarch64 += -mtune=cortex-a72 +endif + +# Add support for platform supplied linker script for BL31 build +$(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) + +# Enable all errata workarounds for Cortex-A72 +ERRATA_A72_859971 := 1 + +WORKAROUND_CVE_2017_5715 := 1 + +# Add new default target when compiling this platform +all: bl31 + +# Build config flags +# ------------------ + +# Disable stack protector by default +ENABLE_STACK_PROTECTOR := 0 + +# Have different sections for code and rodata +SEPARATE_CODE_AND_RODATA := 1 + +# Use Coherent memory +USE_COHERENT_MEM := 1 + +# Platform build flags +# -------------------- + +# There is not much else than a Linux kernel to load at the moment. +RPI3_DIRECT_LINUX_BOOT := 1 + +# BL33 images are in AArch64 by default +RPI3_BL33_IN_AARCH32 := 0 + +# UART to use at runtime. -1 means the runtime UART is disabled. +# Any other value means the default UART will be used. +RPI3_RUNTIME_UART := 0 + +# Use normal memory mapping for ROM, FIP, SRAM and DRAM +RPI3_USE_UEFI_MAP := 0 + +# Process platform flags +# ---------------------- + +$(eval $(call add_define,RPI3_BL33_IN_AARCH32)) +$(eval $(call add_define,RPI3_DIRECT_LINUX_BOOT)) +ifdef RPI3_PRELOADED_DTB_BASE +$(eval $(call add_define,RPI3_PRELOADED_DTB_BASE)) +endif +$(eval $(call add_define,RPI3_RUNTIME_UART)) +$(eval $(call add_define,RPI3_USE_UEFI_MAP)) + +ifeq (${ARCH},aarch32) + $(error Error: AArch32 not supported on rpi4) +endif + +ifneq ($(ENABLE_STACK_PROTECTOR), 0) +PLAT_BL_COMMON_SOURCES += drivers/rpi3/rng/rpi3_rng.c \ + plat/rpi/common/rpi3_stack_protector.c +endif diff --git a/plat/rpi/rpi4/rpi4_bl31_setup.c b/plat/rpi/rpi4/rpi4_bl31_setup.c new file mode 100644 index 000000000..9e3b53979 --- /dev/null +++ b/plat/rpi/rpi4/rpi4_bl31_setup.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> + +#include <libfdt.h> + +#include <platform_def.h> +#include <arch_helpers.h> +#include <common/bl_common.h> +#include <lib/mmio.h> +#include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <lib/xlat_tables/xlat_tables_defs.h> +#include <lib/xlat_tables/xlat_tables_v2.h> +#include <plat/common/platform.h> +#include <common/fdt_fixup.h> +#include <libfdt.h> + +#include <drivers/arm/gicv2.h> + +#include <rpi_shared.h> + +/* + * Fields at the beginning of armstub8.bin. + * While building the BL31 image, we put the stub magic into the binary. + * The GPU firmware detects this at boot time, clears that field as a + * confirmation and puts the kernel and DT address in the following words. + */ +extern uint32_t stub_magic; +extern uint32_t dtb_ptr32; +extern uint32_t kernel_entry32; + +static const gicv2_driver_data_t rpi4_gic_data = { + .gicd_base = RPI4_GIC_GICD_BASE, + .gicc_base = RPI4_GIC_GICC_BASE, +}; + +/* + * To be filled by the code below. At the moment BL32 is not supported. + * In the future these might be passed down from BL2. + */ +static entry_point_info_t bl32_image_ep_info; +static entry_point_info_t bl33_image_ep_info; + +/******************************************************************************* + * Return a pointer to the 'entry_point_info' structure of the next image for + * the security state specified. BL33 corresponds to the non-secure image type + * while BL32 corresponds to the secure image type. A NULL pointer is returned + * if the image does not exist. + ******************************************************************************/ +entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) +{ + entry_point_info_t *next_image_info; + + assert(sec_state_is_valid(type) != 0); + + next_image_info = (type == NON_SECURE) + ? &bl33_image_ep_info : &bl32_image_ep_info; + + /* None of the images can have 0x0 as the entrypoint. */ + if (next_image_info->pc) { + return next_image_info; + } else { + return NULL; + } +} + +uintptr_t plat_get_ns_image_entrypoint(void) +{ +#ifdef PRELOADED_BL33_BASE + return PRELOADED_BL33_BASE; +#else + /* Cleared by the GPU if kernel address is valid. */ + if (stub_magic == 0) + return kernel_entry32; + + WARN("Stub magic failure, using default kernel address 0x80000\n"); + return 0x80000; +#endif +} + +static uintptr_t rpi4_get_dtb_address(void) +{ +#ifdef RPI3_PRELOADED_DTB_BASE + return RPI3_PRELOADED_DTB_BASE; +#else + /* Cleared by the GPU if DTB address is valid. */ + if (stub_magic == 0) + return dtb_ptr32; + + WARN("Stub magic failure, DTB address unknown\n"); + return 0; +#endif +} + +static void ldelay(register_t delay) +{ + __asm__ volatile ( + "1:\tcbz %0, 2f\n\t" + "sub %0, %0, #1\n\t" + "b 1b\n" + "2:" + : "=&r" (delay) : "0" (delay) + ); +} + +/******************************************************************************* + * Perform any BL31 early platform setup. Here is an opportunity to copy + * parameters passed by the calling EL (S-EL1 in BL2 & EL3 in BL1) before + * they are lost (potentially). This needs to be done before the MMU is + * initialized so that the memory layout can be used while creating page + * tables. BL2 has flushed this information to memory, so we are guaranteed + * to pick up good data. + ******************************************************************************/ +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) + +{ + /* + * LOCAL_CONTROL: + * Bit 9 clear: Increment by 1 (vs. 2). + * Bit 8 clear: Timer source is 19.2MHz crystal (vs. APB). + */ + mmio_write_32(RPI4_LOCAL_CONTROL_BASE_ADDRESS, 0); + + /* LOCAL_PRESCALER; divide-by (0x80000000 / register_val) == 1 */ + mmio_write_32(RPI4_LOCAL_CONTROL_PRESCALER, 0x80000000); + + /* Early GPU firmware revisions need a little break here. */ + ldelay(100000); + + /* + * Initialize the console to provide early debug support. + * We rely on the GPU firmware to have initialised the UART correctly, + * as the baud base clock rate differs across GPU firmware revisions. + * Providing a base clock of 0 lets the 16550 UART init routine skip + * the initial enablement and baud rate setup. + */ + rpi3_console_init(0); + + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = rpi3_get_spsr_for_bl33_entry(); + SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + +#if RPI3_DIRECT_LINUX_BOOT +# if RPI3_BL33_IN_AARCH32 + /* + * According to the file ``Documentation/arm/Booting`` of the Linux + * kernel tree, Linux expects: + * r0 = 0 + * r1 = machine type number, optional in DT-only platforms (~0 if so) + * r2 = Physical address of the device tree blob + */ + VERBOSE("rpi4: Preparing to boot 32-bit Linux kernel\n"); + bl33_image_ep_info.args.arg0 = 0U; + bl33_image_ep_info.args.arg1 = ~0U; + bl33_image_ep_info.args.arg2 = rpi4_get_dtb_address(); +# else + /* + * According to the file ``Documentation/arm64/booting.txt`` of the + * Linux kernel tree, Linux expects the physical address of the device + * tree blob (DTB) in x0, while x1-x3 are reserved for future use and + * must be 0. + */ + VERBOSE("rpi4: Preparing to boot 64-bit Linux kernel\n"); + bl33_image_ep_info.args.arg0 = rpi4_get_dtb_address(); + bl33_image_ep_info.args.arg1 = 0ULL; + bl33_image_ep_info.args.arg2 = 0ULL; + bl33_image_ep_info.args.arg3 = 0ULL; +# endif /* RPI3_BL33_IN_AARCH32 */ +#endif /* RPI3_DIRECT_LINUX_BOOT */ +} + +void bl31_plat_arch_setup(void) +{ + /* + * Is the dtb_ptr32 pointer valid? If yes, map the DTB region. + * We map the 2MB region the DTB start address lives in, plus + * the next 2MB, to have enough room for expansion. + */ + if (stub_magic == 0) { + unsigned long long dtb_region = dtb_ptr32; + + dtb_region &= ~0x1fffff; /* Align to 2 MB. */ + mmap_add_region(dtb_region, dtb_region, 4U << 20, + MT_MEMORY | MT_RW | MT_NS); + } + /* + * Add the first page of memory, which holds the stub magic, + * the kernel and the DT address. + * This also holds the secondary CPU's entrypoints and mailboxes. + */ + mmap_add_region(0, 0, 4096, MT_NON_CACHEABLE | MT_RW | MT_SECURE); + + rpi3_setup_page_tables(BL31_BASE, BL31_END - BL31_BASE, + BL_CODE_BASE, BL_CODE_END, + BL_RO_DATA_BASE, BL_RO_DATA_END +#if USE_COHERENT_MEM + , BL_COHERENT_RAM_BASE, BL_COHERENT_RAM_END +#endif + ); + + enable_mmu_el3(0); +} + +static uint32_t dtb_size(const void *dtb) +{ + const uint32_t *dtb_header = dtb; + + return fdt32_to_cpu(dtb_header[1]); +} + +static void rpi4_prepare_dtb(void) +{ + void *dtb = (void *)rpi4_get_dtb_address(); + uint32_t gic_int_prop[3]; + int ret, offs; + + /* Return if no device tree is detected */ + if (fdt_check_header(dtb) != 0) + return; + + ret = fdt_open_into(dtb, dtb, 0x100000); + if (ret < 0) { + ERROR("Invalid Device Tree at %p: error %d\n", dtb, ret); + return; + } + + if (dt_add_psci_node(dtb)) { + ERROR("Failed to add PSCI Device Tree node\n"); + return; + } + + if (dt_add_psci_cpu_enable_methods(dtb)) { + ERROR("Failed to add PSCI cpu enable methods in Device Tree\n"); + return; + } + + /* Reserve memory used by Trusted Firmware. */ + if (fdt_add_reserved_memory(dtb, "atf@0", 0, 0x80000)) + WARN("Failed to add reserved memory nodes to DT.\n"); + + offs = fdt_node_offset_by_compatible(dtb, 0, "arm,gic-400"); + gic_int_prop[0] = cpu_to_fdt32(1); // PPI + gic_int_prop[1] = cpu_to_fdt32(9); // PPI #9 + gic_int_prop[2] = cpu_to_fdt32(0x0f04); // all cores, level high + fdt_setprop(dtb, offs, "interrupts", gic_int_prop, 12); + + offs = fdt_path_offset(dtb, "/chosen"); + fdt_setprop_string(dtb, offs, "stdout-path", "serial0"); + + ret = fdt_pack(dtb); + if (ret < 0) + ERROR("Failed to pack Device Tree at %p: error %d\n", dtb, ret); + + clean_dcache_range((uintptr_t)dtb, dtb_size(dtb)); + INFO("Changed device tree to advertise PSCI.\n"); +} + +void bl31_platform_setup(void) +{ + rpi4_prepare_dtb(); + + /* Configure the interrupt controller */ + gicv2_driver_init(&rpi4_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} diff --git a/plat/rpi3/rpi3_mbox.c b/plat/rpi3/rpi3_mbox.c deleted file mode 100644 index 2db605edf..000000000 --- a/plat/rpi3/rpi3_mbox.c +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> - -#include <platform_def.h> - -#include <arch_helpers.h> -#include <common/debug.h> -#include <lib/mmio.h> - -#include "rpi3_hw.h" - -/* This struct must be aligned to 16 bytes */ -typedef struct __packed __aligned(16) rpi3_mbox_request { - uint32_t size; /* Buffer size in bytes */ - uint32_t code; /* Request/response code */ - uint32_t tags[0]; -} rpi3_mbox_request_t; - -#define RPI3_MBOX_BUFFER_SIZE U(256) -static uint8_t __aligned(16) rpi3_mbox_buffer[RPI3_MBOX_BUFFER_SIZE]; - -/* Constants to perform a request/check the status of a request. */ -#define RPI3_MBOX_PROCESS_REQUEST U(0x00000000) -#define RPI3_MBOX_REQUEST_SUCCESSFUL U(0x80000000) -#define RPI3_MBOX_REQUEST_ERROR U(0x80000001) - -/* Command constants */ -#define RPI3_TAG_HARDWARE_GET_BOARD_REVISION U(0x00010002) -#define RPI3_TAG_END U(0x00000000) - -#define RPI3_TAG_REQUEST U(0x00000000) -#define RPI3_TAG_IS_RESPONSE U(0x80000000) /* Set if response */ -#define RPI3_TAG_RESPONSE_LENGTH_MASK U(0x7FFFFFFF) - -#define RPI3_CHANNEL_ARM_TO_VC U(0x8) -#define RPI3_CHANNEL_MASK U(0xF) - -#define RPI3_MAILBOX_MAX_RETRIES U(1000000) - -/******************************************************************************* - * Helpers to send requests to the VideoCore using the mailboxes. - ******************************************************************************/ -static void rpi3_vc_mailbox_request_send(void) -{ - uint32_t st, data; - uintptr_t resp_addr, addr; - unsigned int retries; - - /* This is the location of the request buffer */ - addr = (uintptr_t) &rpi3_mbox_buffer; - - /* Make sure that the changes are seen by the VideoCore */ - flush_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE); - - /* Wait until the outbound mailbox is empty */ - retries = 0U; - - do { - st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX1_STATUS_OFFSET); - - retries++; - if (retries == RPI3_MAILBOX_MAX_RETRIES) { - ERROR("rpi3: mbox: Send request timeout\n"); - return; - } - - } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) == 0U); - - /* Send base address of this message to start request */ - mmio_write_32(RPI3_MBOX_BASE + RPI3_MBOX1_WRITE_OFFSET, - RPI3_CHANNEL_ARM_TO_VC | (uint32_t) addr); - - /* Wait until the inbound mailbox isn't empty */ - retries = 0U; - - do { - st = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_STATUS_OFFSET); - - retries++; - if (retries == RPI3_MAILBOX_MAX_RETRIES) { - ERROR("rpi3: mbox: Receive response timeout\n"); - return; - } - - } while ((st & RPI3_MBOX_STATUS_EMPTY_MASK) != 0U); - - /* Get location and channel */ - data = mmio_read_32(RPI3_MBOX_BASE + RPI3_MBOX0_READ_OFFSET); - - if ((data & RPI3_CHANNEL_MASK) != RPI3_CHANNEL_ARM_TO_VC) { - ERROR("rpi3: mbox: Wrong channel: 0x%08x\n", data); - panic(); - } - - resp_addr = (uintptr_t)(data & ~RPI3_CHANNEL_MASK); - if (addr != resp_addr) { - ERROR("rpi3: mbox: Unexpected address: 0x%08x\n", data); - panic(); - } - - /* Make sure that the data seen by the CPU is up to date */ - inv_dcache_range(addr, RPI3_MBOX_BUFFER_SIZE); -} - -/******************************************************************************* - * Request board revision. Returns the revision and 0 on success, -1 on error. - ******************************************************************************/ -int rpi3_vc_hardware_get_board_revision(uint32_t *revision) -{ - uint32_t tag_request_size = sizeof(uint32_t); - rpi3_mbox_request_t *req = (rpi3_mbox_request_t *) rpi3_mbox_buffer; - - assert(revision != NULL); - - VERBOSE("rpi3: mbox: Sending request at %p\n", (void *)req); - - req->size = sizeof(rpi3_mbox_buffer); - req->code = RPI3_MBOX_PROCESS_REQUEST; - - req->tags[0] = RPI3_TAG_HARDWARE_GET_BOARD_REVISION; - req->tags[1] = tag_request_size; /* Space available for the response */ - req->tags[2] = RPI3_TAG_REQUEST; - req->tags[3] = 0; /* Placeholder for the response */ - - req->tags[4] = RPI3_TAG_END; - - rpi3_vc_mailbox_request_send(); - - if (req->code != RPI3_MBOX_REQUEST_SUCCESSFUL) { - ERROR("rpi3: mbox: Code = 0x%08x\n", req->code); - return -1; - } - - if (req->tags[2] != (RPI3_TAG_IS_RESPONSE | tag_request_size)) { - ERROR("rpi3: mbox: get board revision failed (0x%08x)\n", - req->tags[2]); - return -1; - } - - *revision = req->tags[3]; - - return 0; -} diff --git a/plat/rpi3/rpi3_rng.c b/plat/rpi3/rpi3_rng.c deleted file mode 100644 index fd69adbf3..000000000 --- a/plat/rpi3/rpi3_rng.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <assert.h> -#include <string.h> - -#include <lib/mmio.h> - -#include "rpi3_hw.h" - -/* Initial amount of values to discard */ -#define RNG_WARMUP_COUNT U(0x40000) - -static void rpi3_rng_initialize(void) -{ - uint32_t int_mask, ctrl; - - /* Return if it is already enabled */ - ctrl = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET); - if ((ctrl & RPI3_RNG_CTRL_ENABLE) != 0U) { - return; - } - - /* Mask interrupts */ - int_mask = mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET); - int_mask |= RPI3_RNG_INT_MASK_DISABLE; - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_INT_MASK_OFFSET, int_mask); - - /* Discard several values when initializing to give it time to warmup */ - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET, RNG_WARMUP_COUNT); - - mmio_write_32(RPI3_RNG_BASE + RPI3_RNG_CTRL_OFFSET, - RPI3_RNG_CTRL_ENABLE); -} - -static uint32_t rpi3_rng_get_word(void) -{ - size_t nwords; - - do { - /* Get number of available words to read */ - nwords = (mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_STATUS_OFFSET) - >> RPI3_RNG_STATUS_NUM_WORDS_SHIFT) - & RPI3_RNG_STATUS_NUM_WORDS_MASK; - } while (nwords == 0U); - - return mmio_read_32(RPI3_RNG_BASE + RPI3_RNG_DATA_OFFSET); -} - -void rpi3_rng_read(void *buf, size_t len) -{ - uint32_t data; - size_t left = len; - uint32_t *dst = buf; - - assert(buf != NULL); - assert(len != 0U); - assert(check_uptr_overflow((uintptr_t) buf, (uintptr_t) len) == 0); - - rpi3_rng_initialize(); - - while (left >= sizeof(uint32_t)) { - data = rpi3_rng_get_word(); - *dst++ = data; - left -= sizeof(uint32_t); - } - - if (left > 0U) { - data = rpi3_rng_get_word(); - memcpy(dst, &data, left); - } -} diff --git a/plat/socionext/synquacer/include/platform_def.h b/plat/socionext/synquacer/include/platform_def.h index 7e54b39d8..7158bfaf3 100644 --- a/plat/socionext/synquacer/include/platform_def.h +++ b/plat/socionext/synquacer/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,8 +11,8 @@ #include <plat/common/common_def.h> /* CPU topology */ -#define PLAT_MAX_CORES_PER_CLUSTER 2 -#define PLAT_CLUSTER_COUNT 12 +#define PLAT_MAX_CORES_PER_CLUSTER U(2) +#define PLAT_CLUSTER_COUNT U(12) #define PLATFORM_CORE_COUNT (PLAT_CLUSTER_COUNT * \ PLAT_MAX_CORES_PER_CLUSTER) diff --git a/plat/socionext/synquacer/platform.mk b/plat/socionext/synquacer/platform.mk index fe1448ff1..ab1f69e68 100644 --- a/plat/socionext/synquacer/platform.mk +++ b/plat/socionext/synquacer/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -57,7 +57,7 @@ BL31_SOURCES += $(PLAT_PATH)/drivers/scp/sq_scmi.c \ drivers/arm/css/mhu/css_mhu_doorbell.c endif -ifeq (${ENABLE_SPM},1) +ifeq (${SPM_MM},1) $(eval $(call add_define,PLAT_EXTRA_LD_SCRIPT)) BL31_SOURCES += $(PLAT_PATH)/sq_spm.c diff --git a/plat/socionext/synquacer/sq_bl31_setup.c b/plat/socionext/synquacer/sq_bl31_setup.c index c78fe9188..b86402179 100644 --- a/plat/socionext/synquacer/sq_bl31_setup.c +++ b/plat/socionext/synquacer/sq_bl31_setup.c @@ -159,7 +159,7 @@ void bl31_plat_runtime_setup(void) void bl31_plat_arch_setup(void) { static const mmap_region_t secure_partition_mmap[] = { -#if ENABLE_SPM && SPM_MM +#if SPM_MM MAP_REGION_FLAT(PLAT_SPM_BUF_BASE, PLAT_SPM_BUF_SIZE, MT_RW_DATA | MT_SECURE), @@ -173,7 +173,7 @@ void bl31_plat_arch_setup(void) sq_mmap_setup(BL31_BASE, BL31_SIZE, secure_partition_mmap); enable_mmu_el3(XLAT_TABLE_NC); -#if ENABLE_SPM && SPM_MM +#if SPM_MM memcpy((void *)SPM_SHIM_EXCEPTIONS_START, (void *)SPM_SHIM_EXCEPTIONS_LMA, (uintptr_t)SPM_SHIM_EXCEPTIONS_END - diff --git a/plat/socionext/synquacer/sq_psci.c b/plat/socionext/synquacer/sq_psci.c index 731b19a32..0c97fcf79 100644 --- a/plat/socionext/synquacer/sq_psci.c +++ b/plat/socionext/synquacer/sq_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -155,7 +155,7 @@ void __dead2 sq_system_reset(void) void sq_cpu_standby(plat_local_state_t cpu_state) { - unsigned int scr; + u_register_t scr; assert(cpu_state == SQ_LOCAL_STATE_RET); diff --git a/plat/socionext/synquacer/sq_spm.c b/plat/socionext/synquacer/sq_spm.c index 01cce1739..7bea1114e 100644 --- a/plat/socionext/synquacer/sq_spm.c +++ b/plat/socionext/synquacer/sq_spm.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,7 +10,7 @@ #include <bl31/ehf.h> #include <lib/xlat_tables/xlat_tables_v2.h> -#include <services/secure_partition.h> +#include <services/spm_mm_partition.h> static const mmap_region_t plat_arm_secure_partition_mmap[] = { PLAT_SQ_FLASH_MMAP, @@ -27,7 +27,7 @@ static const mmap_region_t plat_arm_secure_partition_mmap[] = { * Boot information passed to a secure partition during initialisation. Linear * indices in MP information will be filled at runtime. */ -static secure_partition_mp_info_t sp_mp_info[] = { +static spm_mm_mp_info_t sp_mp_info[] = { {0x80000000, 0}, {0x80000001, 0}, {0x80000100, 0}, {0x80000101, 0}, {0x80000200, 0}, {0x80000201, 0}, {0x80000300, 0}, {0x80000301, 0}, {0x80000400, 0}, {0x80000401, 0}, {0x80000500, 0}, {0x80000501, 0}, @@ -36,10 +36,10 @@ static secure_partition_mp_info_t sp_mp_info[] = { {0x80000a00, 0}, {0x80000a01, 0}, {0x80000b00, 0}, {0x80000b01, 0}, }; -const secure_partition_boot_info_t plat_arm_secure_partition_boot_info = { +const spm_mm_boot_info_t plat_arm_secure_partition_boot_info = { .h.type = PARAM_SP_IMAGE_BOOT_INFO, .h.version = VERSION_1, - .h.size = sizeof(secure_partition_boot_info_t), + .h.size = sizeof(spm_mm_boot_info_t), .h.attr = 0, .sp_mem_base = BL32_BASE, .sp_mem_limit = BL32_LIMIT, @@ -63,7 +63,7 @@ const struct mmap_region *plat_get_secure_partition_mmap(void *cookie) return plat_arm_secure_partition_mmap; } -const struct secure_partition_boot_info *plat_get_secure_partition_boot_info( +const struct spm_mm_boot_info *plat_get_secure_partition_boot_info( void *cookie) { return &plat_arm_secure_partition_boot_info; diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h index d4db3f5b0..7c6341d14 100644 --- a/plat/socionext/uniphier/include/platform_def.h +++ b/plat/socionext/uniphier/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,8 +17,8 @@ #define CACHE_WRITEBACK_GRANULE (1 << (CACHE_WRITEBACK_SHIFT)) /* topology */ -#define UNIPHIER_MAX_CPUS_PER_CLUSTER 4 -#define UNIPHIER_CLUSTER_COUNT 2 +#define UNIPHIER_MAX_CPUS_PER_CLUSTER U(4) +#define UNIPHIER_CLUSTER_COUNT U(2) #define PLATFORM_CORE_COUNT \ ((UNIPHIER_MAX_CPUS_PER_CLUSTER) * (UNIPHIER_CLUSTER_COUNT)) @@ -28,28 +28,43 @@ #define PLAT_MAX_OFF_STATE U(2) #define PLAT_MAX_RET_STATE U(1) -#define BL2_BASE ULL(0x80000000) -#define BL2_LIMIT ULL(0x80080000) +#define UNIPHIER_BL2_OFFSET UL(0x00000000) +#define UNIPHIER_BL2_MAX_SIZE UL(0x00080000) -/* 0x80080000-0x81000000: reserved for DSP */ +/* 0x00080000-0x01000000: reserved for DSP */ -#define UNIPHIER_SEC_DRAM_BASE 0x81000000ULL -#define UNIPHIER_SEC_DRAM_LIMIT 0x82000000ULL -#define UNIPHIER_SEC_DRAM_SIZE ((UNIPHIER_SEC_DRAM_LIMIT) - \ - (UNIPHIER_SEC_DRAM_BASE)) +#define UNIPHIER_BL31_OFFSET UL(0x01000000) +#define UNIPHIER_BL31_MAX_SIZE UL(0x00080000) -#define BL31_BASE ULL(0x81000000) -#define BL31_LIMIT ULL(0x81080000) +#define UNIPHIER_BL32_OFFSET UL(0x01080000) +#define UNIPHIER_BL32_MAX_SIZE UL(0x00100000) -#define BL32_BASE ULL(0x81080000) -#define BL32_LIMIT ULL(0x81180000) +/* + * The link addresses are determined by UNIPHIER_MEM_BASE + offset. + * When ENABLE_PIE is set, all the TF images can be loaded anywhere, so + * UNIPHIER_MEM_BASE is arbitrary. + * + * When ENABLE_PIE is unset, UNIPHIER_MEM_BASE should be chosen so that + * BL2_BASE matches to the physical address where BL2 is loaded, that is, + * UNIPHIER_MEM_BASE should be the base address of the DRAM region. + */ +#define UNIPHIER_MEM_BASE UL(0x00000000) + +#define BL2_BASE (UNIPHIER_MEM_BASE + UNIPHIER_BL2_OFFSET) +#define BL2_LIMIT (BL2_BASE + UNIPHIER_BL2_MAX_SIZE) + +#define BL31_BASE (UNIPHIER_MEM_BASE + UNIPHIER_BL31_OFFSET) +#define BL31_LIMIT (BL31_BASE + UNIPHIER_BL31_MAX_SIZE) + +#define BL32_BASE (UNIPHIER_MEM_BASE + UNIPHIER_BL32_OFFSET) +#define BL32_LIMIT (BL32_BASE + UNIPHIER_BL32_MAX_SIZE) #define PLAT_PHY_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ULL << 32) #define PLAT_XLAT_TABLES_DYNAMIC 1 -#define MAX_XLAT_TABLES 7 -#define MAX_MMAP_REGIONS 7 +#define MAX_XLAT_TABLES 9 +#define MAX_MMAP_REGIONS 13 #define MAX_IO_HANDLES 2 #define MAX_IO_DEVICES 2 diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index d97458490..8e96b68bb 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause # @@ -10,6 +10,10 @@ override PROGRAMMABLE_RESET_ADDRESS := 1 override USE_COHERENT_MEM := 1 override ENABLE_SVE_FOR_NS := 0 +# Disabling ENABLE_PIE saves memory footprint a lot, but you need to adjust +# UNIPHIER_MEM_BASE so that all TF images are loaded at their link addresses. +override ENABLE_PIE := 1 + # Cortex-A53 revision r0p4-51rel0 # needed for LD20, unneeded for LD11, PXs3 (no ACE) ERRATA_A53_855873 := 1 @@ -60,6 +64,7 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ plat/common/plat_gicv3.c \ plat/common/plat_psci_common.c \ $(PLAT_PATH)/uniphier_bl31_setup.c \ + $(PLAT_PATH)/uniphier_boot_device.c \ $(PLAT_PATH)/uniphier_cci.c \ $(PLAT_PATH)/uniphier_gicv3.c \ $(PLAT_PATH)/uniphier_psci.c \ diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c index 0b232e067..4f58b683c 100644 --- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c +++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,8 +11,6 @@ #include "../uniphier.h" -#define BL32_SIZE ((BL32_END) - (BL32_BASE)) - void tsp_early_platform_setup(void) { uniphier_console_setup(); @@ -24,6 +22,6 @@ void tsp_platform_setup(void) void tsp_plat_arch_setup(void) { - uniphier_mmap_setup(BL32_BASE, BL32_SIZE, NULL); + uniphier_mmap_setup(); enable_mmu_el1(0); } diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 648c2b94c..729dc5caa 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -36,24 +36,25 @@ unsigned int uniphier_get_boot_master(unsigned int soc); void uniphier_console_setup(void); -int uniphier_emmc_init(uintptr_t *block_dev_spec); -int uniphier_nand_init(uintptr_t *block_dev_spec); -int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec); +struct io_block_dev_spec; +int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec); +int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec); +int uniphier_usb_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec); -int uniphier_io_setup(unsigned int soc); +int uniphier_io_setup(unsigned int soc, uintptr_t mem_base); +void uniphier_init_image_descs(uintptr_t mem_base); struct image_info; struct image_info *uniphier_get_image_info(unsigned int image_id); int uniphier_scp_is_running(void); -void uniphier_scp_start(void); +void uniphier_scp_start(uint32_t scp_base); void uniphier_scp_open_com(void); void uniphier_scp_system_off(void); void uniphier_scp_system_reset(void); -struct mmap_region; -void uniphier_mmap_setup(uintptr_t total_base, size_t total_size, - const struct mmap_region *mmap); +void uniphier_mmap_setup(void); void uniphier_cci_init(unsigned int soc); void uniphier_cci_enable(void); @@ -67,25 +68,4 @@ void uniphier_gic_pcpu_init(void); unsigned int uniphier_calc_core_pos(u_register_t mpidr); -#define UNIPHIER_NS_DRAM_BASE 0x84000000 -#define UNIPHIER_NS_DRAM_LIMIT 0x85000000 -#define UNIPHIER_NS_DRAM_SIZE ((UNIPHIER_NS_DRAM_LIMIT) - \ - (UNIPHIER_NS_DRAM_BASE)) - -#define UNIPHIER_BL33_BASE (UNIPHIER_NS_DRAM_BASE) -#define UNIPHIER_BL33_MAX_SIZE 0x00100000 - -#define UNIPHIER_SCP_BASE ((UNIPHIER_BL33_BASE) + \ - (UNIPHIER_BL33_MAX_SIZE)) -#define UNIPHIER_SCP_MAX_SIZE 0x00020000 - -#define UNIPHIER_BLOCK_BUF_BASE ((UNIPHIER_SCP_BASE) + \ - (UNIPHIER_SCP_MAX_SIZE)) -#define UNIPHIER_BLOCK_BUF_SIZE 0x00100000 - -#define UNIPHIER_IMAGE_BUF_BASE ((UNIPHIER_BLOCK_BUF_BASE) + \ - (UNIPHIER_BLOCK_BUF_SIZE)) -#define UNIPHIER_IMAGE_BUF_SIZE ((UNIPHIER_NS_DRAM_LIMIT) - \ - (UNIPHIER_IMAGE_BUF_BASE)) - #endif /* UNIPHIER_H */ diff --git a/plat/socionext/uniphier/uniphier_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 787b3ac3d..11d837cf4 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,8 +21,10 @@ #include "uniphier.h" -#define BL2_SIZE ((BL2_END) - (BL2_BASE)) +#define UNIPHIER_IMAGE_BUF_OFFSET 0x04300000UL +#define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL +static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE; static int uniphier_bl2_kick_scp; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, @@ -31,32 +33,25 @@ void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, uniphier_console_setup(); } -static const struct mmap_region uniphier_bl2_mmap[] = { - /* for BL31, BL32 */ - MAP_REGION_FLAT(UNIPHIER_SEC_DRAM_BASE, UNIPHIER_SEC_DRAM_SIZE, - MT_MEMORY | MT_RW | MT_SECURE), - /* for SCP, BL33 */ - MAP_REGION_FLAT(UNIPHIER_NS_DRAM_BASE, UNIPHIER_NS_DRAM_SIZE, - MT_MEMORY | MT_RW | MT_NS), - { .size = 0 }, -}; - void bl2_el3_plat_arch_setup(void) { unsigned int soc; int skip_scp = 0; int ret; - uniphier_mmap_setup(BL2_BASE, BL2_SIZE, uniphier_bl2_mmap); + uniphier_mmap_setup(); enable_mmu_el3(0); + /* add relocation offset (run-time-address - link-address) */ + uniphier_mem_base += BL_CODE_BASE - BL2_BASE; + soc = uniphier_get_soc_id(); if (soc == UNIPHIER_SOC_UNKNOWN) { ERROR("unsupported SoC\n"); plat_error_handler(-ENOTSUP); } - ret = uniphier_io_setup(soc); + ret = uniphier_io_setup(soc, uniphier_mem_base); if (ret) { ERROR("failed to setup io devices\n"); plat_error_handler(ret); @@ -119,28 +114,47 @@ bl_params_t *plat_get_next_bl_params(void) void bl2_plat_preload_setup(void) { #ifdef UNIPHIER_DECOMPRESS_GZIP - image_decompress_init(UNIPHIER_IMAGE_BUF_BASE, - UNIPHIER_IMAGE_BUF_SIZE, - gunzip); + uintptr_t buf_base = uniphier_mem_base + UNIPHIER_IMAGE_BUF_OFFSET; + int ret; + + ret = mmap_add_dynamic_region(buf_base, buf_base, + UNIPHIER_IMAGE_BUF_SIZE, + MT_MEMORY | MT_RW | MT_NS); + if (ret) + plat_error_handler(ret); + + image_decompress_init(buf_base, UNIPHIER_IMAGE_BUF_SIZE, gunzip); #endif + + uniphier_init_image_descs(uniphier_mem_base); } int bl2_plat_handle_pre_image_load(unsigned int image_id) { + struct image_info *image_info; + int ret; + + image_info = uniphier_get_image_info(image_id); + + ret = mmap_add_dynamic_region(image_info->image_base, + image_info->image_base, + image_info->image_max_size, + MT_MEMORY | MT_RW | MT_NS); + if (ret) + return ret; + #ifdef UNIPHIER_DECOMPRESS_GZIP - image_decompress_prepare(uniphier_get_image_info(image_id)); + image_decompress_prepare(image_info); #endif return 0; } int bl2_plat_handle_post_image_load(unsigned int image_id) { + struct image_info *image_info = uniphier_get_image_info(image_id); #ifdef UNIPHIER_DECOMPRESS_GZIP - struct image_info *image_info; int ret; - image_info = uniphier_get_image_info(image_id); - if (!(image_info->h.attr & IMAGE_ATTRIB_SKIP_LOADING)) { ret = image_decompress(uniphier_get_image_info(image_id)); if (ret) @@ -149,7 +163,7 @@ int bl2_plat_handle_post_image_load(unsigned int image_id) #endif if (image_id == SCP_BL2_IMAGE_ID && uniphier_bl2_kick_scp) - uniphier_scp_start(); + uniphier_scp_start(image_info->image_base); return 0; } diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index 440e6aa11..47f2378bc 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,8 +19,6 @@ #include "uniphier.h" -#define BL31_SIZE ((BL31_END) - (BL31_BASE)) - static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -81,6 +79,6 @@ void bl31_platform_setup(void) void bl31_plat_arch_setup(void) { - uniphier_mmap_setup(BL31_BASE, BL31_SIZE, NULL); + uniphier_mmap_setup(); enable_mmu_el3(0); } diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S index 2c8dc8f84..1113c6e81 100644 --- a/plat/socionext/uniphier/uniphier_console.S +++ b/plat/socionext/uniphier/uniphier_console.S @@ -23,15 +23,9 @@ func uniphier_console_putc 0: ldr w2, [x1, #UNIPHIER_UART_LSR] tbz w2, #UNIPHIER_UART_LSR_THRE_BIT, 0b - mov w2, w0 + str w0, [x1, #UNIPHIER_UART_TX] -1: str w2, [x1, #UNIPHIER_UART_TX] - - cmp w2, #'\n' - b.ne 2f - mov w2, #'\r' /* Append '\r' to '\n' */ - b 1b -2: ret + ret endfunc uniphier_console_putc /* diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c index 8185ec5a1..64ee79714 100644 --- a/plat/socionext/uniphier/uniphier_console_setup.c +++ b/plat/socionext/uniphier/uniphier_console_setup.c @@ -32,7 +32,8 @@ static struct uniphier_console uniphier_console = { #if DEBUG CONSOLE_FLAG_RUNTIME | #endif - CONSOLE_FLAG_CRASH, + CONSOLE_FLAG_CRASH | + CONSOLE_FLAG_TRANSLATE_CRLF, .putc = uniphier_console_putc, .getc = uniphier_console_getc, .flush = uniphier_console_flush, diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c index 4ac1f5108..d666ba781 100644 --- a/plat/socionext/uniphier/uniphier_emmc.c +++ b/plat/socionext/uniphier/uniphier_emmc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -225,11 +225,7 @@ static size_t uniphier_emmc_read(int lba, uintptr_t buf, size_t size) return ret ? 0 : size; } -static const struct io_block_dev_spec uniphier_emmc_dev_spec = { - .buffer = { - .offset = UNIPHIER_BLOCK_BUF_BASE, - .length = UNIPHIER_BLOCK_BUF_SIZE, - }, +static struct io_block_dev_spec uniphier_emmc_dev_spec = { .ops = { .read = uniphier_emmc_read, }, @@ -278,7 +274,7 @@ static int uniphier_emmc_hw_init(void) return 0; } -int uniphier_emmc_init(uintptr_t *block_dev_spec) +int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec) { int ret; @@ -286,7 +282,7 @@ int uniphier_emmc_init(uintptr_t *block_dev_spec) if (ret) return ret; - *block_dev_spec = (uintptr_t)&uniphier_emmc_dev_spec; + *block_dev_spec = &uniphier_emmc_dev_spec; return 0; } diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c index 9e171e073..8c232ba31 100644 --- a/plat/socionext/uniphier/uniphier_image_desc.c +++ b/plat/socionext/uniphier/uniphier_image_desc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,13 +13,19 @@ #include "uniphier.h" +#define UNIPHIER_BL33_OFFSET 0x04000000UL +#define UNIPHIER_BL33_MAX_SIZE 0x00100000UL + +#define UNIPHIER_SCP_OFFSET 0x04100000UL +#define UNIPHIER_SCP_MAX_SIZE 0x00020000UL + static struct bl_mem_params_node uniphier_image_descs[] = { { .image_id = SCP_BL2_IMAGE_ID, SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), - .image_info.image_base = UNIPHIER_SCP_BASE, + .image_info.image_base = UNIPHIER_SCP_OFFSET, .image_info.image_max_size = UNIPHIER_SCP_MAX_SIZE, SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, @@ -33,13 +39,13 @@ static struct bl_mem_params_node uniphier_image_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), - .image_info.image_base = BL31_BASE, - .image_info.image_max_size = BL31_LIMIT - BL31_BASE, + .image_info.image_base = UNIPHIER_BL31_OFFSET, + .image_info.image_max_size = UNIPHIER_BL31_MAX_SIZE, SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, entry_point_info_t, SECURE | EXECUTABLE | EP_FIRST_EXE), - .ep_info.pc = BL31_BASE, + .ep_info.pc = UNIPHIER_BL31_OFFSET, .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), @@ -55,13 +61,13 @@ static struct bl_mem_params_node uniphier_image_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), - .image_info.image_base = BL32_BASE, - .image_info.image_max_size = BL32_LIMIT - BL32_BASE, + .image_info.image_base = UNIPHIER_BL32_OFFSET, + .image_info.image_max_size = UNIPHIER_BL32_MAX_SIZE, SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, entry_point_info_t, SECURE | EXECUTABLE), - .ep_info.pc = BL32_BASE, + .ep_info.pc = UNIPHIER_BL32_OFFSET, .ep_info.spsr = SPSR_64(MODE_EL3, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), @@ -73,14 +79,14 @@ static struct bl_mem_params_node uniphier_image_descs[] = { SET_STATIC_PARAM_HEAD(image_info, PARAM_EP, VERSION_2, image_info_t, 0), - .image_info.image_base = UNIPHIER_BL33_BASE, + .image_info.image_base = UNIPHIER_BL33_OFFSET, .image_info.image_max_size = UNIPHIER_BL33_MAX_SIZE, SET_STATIC_PARAM_HEAD(ep_info, PARAM_EP, VERSION_2, entry_point_info_t, NON_SECURE | EXECUTABLE), - .ep_info.pc = UNIPHIER_BL33_BASE, - .ep_info.spsr = SPSR_64(MODE_EL1, MODE_SP_ELX, + .ep_info.pc = UNIPHIER_BL33_OFFSET, + .ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, DISABLE_ALL_EXCEPTIONS), .next_handoff_image_id = INVALID_IMAGE_ID, @@ -88,6 +94,21 @@ static struct bl_mem_params_node uniphier_image_descs[] = { }; REGISTER_BL_IMAGE_DESCS(uniphier_image_descs) +/* + * image_info.image_base and ep_info.pc are the offset from the memory base. + * When ENABLE_PIE is set, we never know the real memory base at link-time. + * Fix-up the addresses by adding the run-time detected base. + */ +void uniphier_init_image_descs(uintptr_t mem_base) +{ + int i; + + for (i = 0; i < ARRAY_SIZE(uniphier_image_descs); i++) { + uniphier_image_descs[i].image_info.image_base += mem_base; + uniphier_image_descs[i].ep_info.pc += mem_base; + } +} + struct image_info *uniphier_get_image_info(unsigned int image_id) { struct bl_mem_params_node *desc; diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index b456bc538..89c8718b4 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,6 +26,9 @@ #define UNIPHIER_OCM_REGION_BASE 0x30000000ULL #define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL +#define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL +#define UNIPHIER_BLOCK_BUF_SIZE 0x00100000UL + static const io_dev_connector_t *uniphier_fip_dev_con; static uintptr_t uniphier_fip_dev_handle; @@ -189,17 +192,29 @@ static const struct uniphier_io_policy uniphier_io_policies[] = { #endif }; -static int uniphier_io_block_setup(size_t fip_offset, uintptr_t block_dev_spec) +static int uniphier_io_block_setup(size_t fip_offset, + struct io_block_dev_spec *block_dev_spec, + size_t buffer_offset) { int ret; uniphier_fip_spec.offset = fip_offset; + block_dev_spec->buffer.offset = buffer_offset; + block_dev_spec->buffer.length = UNIPHIER_BLOCK_BUF_SIZE; + + ret = mmap_add_dynamic_region(block_dev_spec->buffer.offset, + block_dev_spec->buffer.offset, + block_dev_spec->buffer.length, + MT_MEMORY | MT_RW | MT_NS); + if (ret) + return ret; + ret = register_io_dev_block(&uniphier_backend_dev_con); if (ret) return ret; - return io_dev_open(uniphier_backend_dev_con, block_dev_spec, + return io_dev_open(uniphier_backend_dev_con, (uintptr_t)block_dev_spec, &uniphier_backend_dev_handle); } @@ -234,38 +249,38 @@ static int uniphier_io_fip_setup(void) return io_dev_open(uniphier_fip_dev_con, 0, &uniphier_fip_dev_handle); } -static int uniphier_io_emmc_setup(unsigned int soc_id) +static int uniphier_io_emmc_setup(unsigned int soc_id, size_t buffer_offset) { - uintptr_t block_dev_spec; + struct io_block_dev_spec *block_dev_spec; int ret; ret = uniphier_emmc_init(&block_dev_spec); if (ret) return ret; - return uniphier_io_block_setup(0x20000, block_dev_spec); + return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset); } -static int uniphier_io_nand_setup(unsigned int soc_id) +static int uniphier_io_nand_setup(unsigned int soc_id, size_t buffer_offset) { - uintptr_t block_dev_spec; + struct io_block_dev_spec *block_dev_spec; int ret; ret = uniphier_nand_init(&block_dev_spec); if (ret) return ret; - return uniphier_io_block_setup(0x20000, block_dev_spec); + return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset); } -static int uniphier_io_nor_setup(unsigned int soc_id) +static int uniphier_io_nor_setup(unsigned int soc_id, size_t buffer_offset) { return uniphier_io_memmap_setup(0x70000); } -static int uniphier_io_usb_setup(unsigned int soc_id) +static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset) { - uintptr_t block_dev_spec; + struct io_block_dev_spec *block_dev_spec; int ret; /* use ROM API for loading images from USB storage */ @@ -292,19 +307,19 @@ static int uniphier_io_usb_setup(unsigned int soc_id) if (ret) return ret; - return uniphier_io_block_setup(0x20000, block_dev_spec); + return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset); } -static int (* const uniphier_io_setup_table[])(unsigned int) = { +static int (* const uniphier_io_setup_table[])(unsigned int, size_t) = { [UNIPHIER_BOOT_DEVICE_EMMC] = uniphier_io_emmc_setup, [UNIPHIER_BOOT_DEVICE_NAND] = uniphier_io_nand_setup, [UNIPHIER_BOOT_DEVICE_NOR] = uniphier_io_nor_setup, [UNIPHIER_BOOT_DEVICE_USB] = uniphier_io_usb_setup, }; -int uniphier_io_setup(unsigned int soc_id) +int uniphier_io_setup(unsigned int soc_id, uintptr_t mem_base) { - int (*io_setup)(unsigned int soc_id); + int (*io_setup)(unsigned int soc_id, size_t buffer_offset); unsigned int boot_dev; int ret; @@ -313,7 +328,7 @@ int uniphier_io_setup(unsigned int soc_id) return -EINVAL; io_setup = uniphier_io_setup_table[boot_dev]; - ret = io_setup(soc_id); + ret = io_setup(soc_id, mem_base + UNIPHIER_BLOCK_BUF_OFFSET); if (ret) return ret; diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c index 27e10e4b7..3925177ed 100644 --- a/plat/socionext/uniphier/uniphier_nand.c +++ b/plat/socionext/uniphier/uniphier_nand.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -224,10 +224,6 @@ static size_t uniphier_nand_read(int lba, uintptr_t buf, size_t size) } static struct io_block_dev_spec uniphier_nand_dev_spec = { - .buffer = { - .offset = UNIPHIER_BLOCK_BUF_BASE, - .length = UNIPHIER_BLOCK_BUF_SIZE, - }, .ops = { .read = uniphier_nand_read, }, @@ -259,7 +255,7 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand) return 0; } -int uniphier_nand_init(uintptr_t *block_dev_spec) +int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec) { int ret; @@ -269,7 +265,7 @@ int uniphier_nand_init(uintptr_t *block_dev_spec) uniphier_nand_dev_spec.block_size = uniphier_nand.page_size; - *block_dev_spec = (uintptr_t)&uniphier_nand_dev_spec; + *block_dev_spec = &uniphier_nand_dev_spec; return 0; } diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c index 464252ddd..2acc87440 100644 --- a/plat/socionext/uniphier/uniphier_psci.c +++ b/plat/socionext/uniphier/uniphier_psci.c @@ -6,6 +6,7 @@ #include <arch_helpers.h> #include <common/debug.h> +#include <errno.h> #include <lib/mmio.h> #include <lib/psci/psci.h> @@ -113,17 +114,27 @@ static const struct plat_psci_ops uniphier_psci_ops = { int plat_setup_psci_ops(uintptr_t sec_entrypoint, const struct plat_psci_ops **psci_ops) { + unsigned int soc; + + soc = uniphier_get_soc_id(); + if (soc == UNIPHIER_SOC_UNKNOWN) { + ERROR("unsupported SoC\n"); + return -ENOTSUP; + } + + if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) { + uniphier_psci_scp_mode = uniphier_scp_is_running(); + flush_dcache_range((uint64_t)&uniphier_psci_scp_mode, + sizeof(uniphier_psci_scp_mode)); + + if (uniphier_psci_scp_mode) + uniphier_scp_open_com(); + } + uniphier_sec_entrypoint = sec_entrypoint; flush_dcache_range((uint64_t)&uniphier_sec_entrypoint, sizeof(uniphier_sec_entrypoint)); - uniphier_psci_scp_mode = uniphier_scp_is_running(); - flush_dcache_range((uint64_t)&uniphier_psci_scp_mode, - sizeof(uniphier_psci_scp_mode)); - - if (uniphier_psci_scp_mode) - uniphier_scp_open_com(); - *psci_ops = &uniphier_psci_ops; return 0; diff --git a/plat/socionext/uniphier/uniphier_scp.c b/plat/socionext/uniphier/uniphier_scp.c index c608a255a..8a12d5d8d 100644 --- a/plat/socionext/uniphier/uniphier_scp.c +++ b/plat/socionext/uniphier/uniphier_scp.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -28,11 +28,11 @@ int uniphier_scp_is_running(void) return mmio_read_32(UNIPHIER_STMBE2COM) == UNIPHIER_SCP_READY_MAGIC; } -void uniphier_scp_start(void) +void uniphier_scp_start(uint32_t scp_base) { uint32_t tmp; - mmio_write_32(UNIPHIER_STMBE2COM + 4, UNIPHIER_SCP_BASE); + mmio_write_32(UNIPHIER_STMBE2COM + 4, scp_base); mmio_write_32(UNIPHIER_STMBE2COM, UNIPHIER_SCP_READY_MAGIC); do { diff --git a/plat/socionext/uniphier/uniphier_usb.c b/plat/socionext/uniphier/uniphier_usb.c index ef7079a5f..7469ad1cc 100644 --- a/plat/socionext/uniphier/uniphier_usb.c +++ b/plat/socionext/uniphier/uniphier_usb.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -158,17 +158,14 @@ static size_t uniphier_usb_read(int lba, uintptr_t buf, size_t size) } static struct io_block_dev_spec uniphier_usb_dev_spec = { - .buffer = { - .offset = UNIPHIER_BLOCK_BUF_BASE, - .length = UNIPHIER_BLOCK_BUF_SIZE, - }, .ops = { .read = uniphier_usb_read, }, .block_size = 512, }; -int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec) +int uniphier_usb_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec) { const struct uniphier_usb_rom_param *param; @@ -180,7 +177,7 @@ int uniphier_usb_init(unsigned int soc, uintptr_t *block_dev_spec) __uniphier_usb_read = param->read; - *block_dev_spec = (uintptr_t)&uniphier_usb_dev_spec; + *block_dev_spec = &uniphier_usb_dev_spec; return 0; } diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c index 0faebc993..18d2f9e93 100644 --- a/plat/socionext/uniphier/uniphier_xlat_setup.c +++ b/plat/socionext/uniphier/uniphier_xlat_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -12,13 +12,12 @@ #define UNIPHIER_REG_REGION_BASE 0x50000000ULL #define UNIPHIER_REG_REGION_SIZE 0x20000000ULL -void uniphier_mmap_setup(uintptr_t total_base, size_t total_size, - const struct mmap_region *mmap) +void uniphier_mmap_setup(void) { VERBOSE("Trusted RAM seen by this BL image: %p - %p\n", - (void *)total_base, (void *)(total_base + total_size)); - mmap_add_region(total_base, total_base, - total_size, + (void *)BL_CODE_BASE, (void *)BL_END); + mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, + round_up(BL_END, PAGE_SIZE) - BL_CODE_BASE, MT_MEMORY | MT_RW | MT_SECURE); /* remap the code section */ @@ -40,9 +39,5 @@ void uniphier_mmap_setup(uintptr_t total_base, size_t total_size, UNIPHIER_REG_REGION_SIZE, MT_DEVICE | MT_RW | MT_SECURE); - /* additional regions if needed */ - if (mmap) - mmap_add(mmap); - init_xlat_tables(); } diff --git a/plat/ti/k3/board/generic/include/board_def.h b/plat/ti/k3/board/generic/include/board_def.h index 490b975f4..0d451167e 100644 --- a/plat/ti/k3/board/generic/include/board_def.h +++ b/plat/ti/k3/board/generic/include/board_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,10 +10,10 @@ #include <lib/utils_def.h> /* The ports must be in order and contiguous */ -#define K3_CLUSTER0_CORE_COUNT 2 -#define K3_CLUSTER1_CORE_COUNT 2 -#define K3_CLUSTER2_CORE_COUNT 2 -#define K3_CLUSTER3_CORE_COUNT 2 +#define K3_CLUSTER0_CORE_COUNT U(2) +#define K3_CLUSTER1_CORE_COUNT U(2) +#define K3_CLUSTER2_CORE_COUNT U(2) +#define K3_CLUSTER3_CORE_COUNT U(2) /* * This RAM will be used for the bootloader including code, bss, and stacks. @@ -27,5 +27,6 @@ #define PLAT_PROC_START_ID 32 #define PLAT_PROC_DEVICE_START_ID 202 +#define PLAT_CLUSTER_DEVICE_START_ID 198 #endif /* BOARD_DEF_H */ diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c index ac33278a9..e390efee6 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci.c +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci.c @@ -20,32 +20,10 @@ #include "ti_sci_protocol.h" #include "ti_sci.h" -/** - * struct ti_sci_desc - Description of SoC integration - * @host_id: Host identifier representing the compute entity - * @max_msg_size: Maximum size of data per message that can be handled - */ -struct ti_sci_desc { - uint8_t host_id; - int max_msg_size; -}; - -/** - * struct ti_sci_info - Structure representing a TI SCI instance - * @desc: SoC description for this instance - * @seq: Seq id used for verification for tx and rx message - */ -struct ti_sci_info { - const struct ti_sci_desc desc; - uint8_t seq; -}; - -static struct ti_sci_info info = { - .desc = { - .host_id = TI_SCI_HOST_ID, - .max_msg_size = TI_SCI_MAX_MESSAGE_SIZE, - }, -}; +#if USE_COHERENT_MEM +__section("tzfw_coherent_mem") +#endif +static uint8_t message_sequence; /** * struct ti_sci_xfer - Structure representing a message flow @@ -82,16 +60,16 @@ static int ti_sci_setup_one_xfer(uint16_t msg_type, uint32_t msg_flags, struct ti_sci_msg_hdr *hdr; /* Ensure we have sane transfer sizes */ - if (rx_message_size > info.desc.max_msg_size || - tx_message_size > info.desc.max_msg_size || + if (rx_message_size > TI_SCI_MAX_MESSAGE_SIZE || + tx_message_size > TI_SCI_MAX_MESSAGE_SIZE || rx_message_size < sizeof(*hdr) || tx_message_size < sizeof(*hdr)) return -ERANGE; hdr = (struct ti_sci_msg_hdr *)tx_buf; - hdr->seq = ++info.seq; + hdr->seq = ++message_sequence; hdr->type = msg_type; - hdr->host = info.desc.host_id; + hdr->host = TI_SCI_HOST_ID; hdr->flags = msg_flags | TI_SCI_FLAG_REQ_ACK_ON_PROCESSED; xfer->tx_message.buf = tx_buf; @@ -131,7 +109,7 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer, hdr = (struct ti_sci_msg_hdr *)msg->buf; /* Sanity check for message response */ - if (hdr->seq == info.seq) + if (hdr->seq == message_sequence) break; else WARN("Message with sequence ID %u is not expected\n", hdr->seq); @@ -141,9 +119,9 @@ static inline int ti_sci_get_response(struct ti_sci_xfer *xfer, return -EINVAL; } - if (msg->len > info.desc.max_msg_size) { + if (msg->len > TI_SCI_MAX_MESSAGE_SIZE) { ERROR("Unable to handle %lu xfer (max %d)\n", - msg->len, info.desc.max_msg_size); + msg->len, TI_SCI_MAX_MESSAGE_SIZE); return -EINVAL; } @@ -425,13 +403,13 @@ int ti_sci_device_put_no_wait(uint32_t id) int ret; /* Ensure we have sane transfer size */ - if (sizeof(req) > info.desc.max_msg_size) + if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) return -ERANGE; hdr = (struct ti_sci_msg_hdr *)&req; - hdr->seq = ++info.seq; + hdr->seq = ++message_sequence; hdr->type = TI_SCI_MSG_SET_DEVICE_STATE; - hdr->host = info.desc.host_id; + hdr->host = TI_SCI_HOST_ID; /* Setup with NORESPONSE flag to keep response queue clean */ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE; @@ -1408,13 +1386,13 @@ int ti_sci_proc_set_boot_ctrl_no_wait(uint8_t proc_id, int ret; /* Ensure we have sane transfer size */ - if (sizeof(req) > info.desc.max_msg_size) + if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) return -ERANGE; hdr = (struct ti_sci_msg_hdr *)&req; - hdr->seq = ++info.seq; + hdr->seq = ++message_sequence; hdr->type = TISCI_MSG_SET_PROC_BOOT_CTRL; - hdr->host = info.desc.host_id; + hdr->host = TI_SCI_HOST_ID; /* Setup with NORESPONSE flag to keep response queue clean */ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE; @@ -1650,13 +1628,13 @@ int ti_sci_proc_wait_boot_status_no_wait(uint8_t proc_id, int ret; /* Ensure we have sane transfer size */ - if (sizeof(req) > info.desc.max_msg_size) + if (sizeof(req) > TI_SCI_MAX_MESSAGE_SIZE) return -ERANGE; hdr = (struct ti_sci_msg_hdr *)&req; - hdr->seq = ++info.seq; + hdr->seq = ++message_sequence; hdr->type = TISCI_MSG_WAIT_PROC_BOOT_STATUS; - hdr->host = info.desc.host_id; + hdr->host = TI_SCI_HOST_ID; /* Setup with NORESPONSE flag to keep response queue clean */ hdr->flags = TI_SCI_FLAG_REQ_GENERIC_NORESPONSE; diff --git a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h index a921e512a..2d23f9a9c 100644 --- a/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h +++ b/plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h @@ -563,8 +563,13 @@ struct ti_sci_msg_req_set_proc_boot_config { uint32_t config_flags_clear; } __packed; +/* ARMV8 Control Flags */ +#define PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM 0x00000001 +#define PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS 0x00000002 +#define PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ 0x00000100 + /* R5 Control Flags */ -#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 +#define PROC_BOOT_CTRL_FLAG_R5_CORE_HALT 0x00000001 /** * struct ti_sci_msg_req_set_proc_boot_ctrl - Set Processor boot control flags @@ -618,6 +623,8 @@ struct ti_sci_msg_req_get_proc_boot_status { /* ARMv8 Status Flags */ #define PROC_BOOT_STATUS_FLAG_ARMV8_WFE 0x00000001 #define PROC_BOOT_STATUS_FLAG_ARMV8_WFI 0x00000002 +#define PROC_BOOT_STATUS_FLAG_ARMV8_L2F_DONE 0x00000010 +#define PROC_BOOT_STATUS_FLAG_ARMV8_STANDBYWFIL2 0x00000020 /* R5 Status Flags */ #define PROC_BOOT_STATUS_FLAG_R5_WFE 0x00000001 diff --git a/plat/ti/k3/common/k3_psci.c b/plat/ti/k3/common/k3_psci.c index de9cefe5b..d6ed7667e 100644 --- a/plat/ti/k3/common/k3_psci.c +++ b/plat/ti/k3/common/k3_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -17,11 +17,15 @@ #include <k3_gicv3.h> #include <ti_sci.h> +#define CORE_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL0]) +#define CLUSTER_PWR_STATE(state) ((state)->pwr_domain_state[MPIDR_AFFLVL1]) +#define SYSTEM_PWR_STATE(state) ((state)->pwr_domain_state[PLAT_MAX_PWR_LVL]) + uintptr_t k3_sec_entrypoint; static void k3_cpu_standby(plat_local_state_t cpu_state) { - unsigned int scr; + u_register_t scr; scr = read_scr_el3(); /* Enable the Non secure interrupt to wake the CPU */ @@ -37,30 +41,40 @@ static void k3_cpu_standby(plat_local_state_t cpu_state) static int k3_pwr_domain_on(u_register_t mpidr) { - int core_id, proc, device, ret; + int core, proc_id, device_id, ret; - core_id = plat_core_pos_by_mpidr(mpidr); - if (core_id < 0) { - ERROR("Could not get target core id: %d\n", core_id); + core = plat_core_pos_by_mpidr(mpidr); + if (core < 0) { + ERROR("Could not get target core id: %d\n", core); return PSCI_E_INTERN_FAIL; } - proc = PLAT_PROC_START_ID + core_id; - device = PLAT_PROC_DEVICE_START_ID + core_id; + proc_id = PLAT_PROC_START_ID + core; + device_id = PLAT_PROC_DEVICE_START_ID + core; - ret = ti_sci_proc_request(proc); + ret = ti_sci_proc_request(proc_id); if (ret) { ERROR("Request for processor failed: %d\n", ret); return PSCI_E_INTERN_FAIL; } - ret = ti_sci_proc_set_boot_cfg(proc, k3_sec_entrypoint, 0, 0); + ret = ti_sci_proc_set_boot_cfg(proc_id, k3_sec_entrypoint, 0, 0); if (ret) { ERROR("Request to set core boot address failed: %d\n", ret); return PSCI_E_INTERN_FAIL; } - ret = ti_sci_device_get(device); + /* sanity check these are off before starting a core */ + ret = ti_sci_proc_set_boot_ctrl(proc_id, + 0, PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ | + PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS | + PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM); + if (ret) { + ERROR("Request to clear boot configuration failed: %d\n", ret); + return PSCI_E_INTERN_FAIL; + } + + ret = ti_sci_device_get(device_id); if (ret) { ERROR("Request to start core failed: %d\n", ret); return PSCI_E_INTERN_FAIL; @@ -71,17 +85,35 @@ static int k3_pwr_domain_on(u_register_t mpidr) void k3_pwr_domain_off(const psci_power_state_t *target_state) { - int core_id, proc, device, ret; + int core, cluster, proc_id, device_id, cluster_id, ret; + + /* At very least the local core should be powering down */ + assert(CORE_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE); /* Prevent interrupts from spuriously waking up this cpu */ k3_gic_cpuif_disable(); - core_id = plat_my_core_pos(); - proc = PLAT_PROC_START_ID + core_id; - device = PLAT_PROC_DEVICE_START_ID + core_id; + core = plat_my_core_pos(); + cluster = MPIDR_AFFLVL1_VAL(read_mpidr_el1()); + proc_id = PLAT_PROC_START_ID + core; + device_id = PLAT_PROC_DEVICE_START_ID + core; + cluster_id = PLAT_CLUSTER_DEVICE_START_ID + (cluster * 2); + + /* + * If we are the last core in the cluster then we take a reference to + * the cluster device so that it does not get shutdown before we + * execute the entire cluster L2 cleaning sequence below. + */ + if (CLUSTER_PWR_STATE(target_state) == PLAT_MAX_OFF_STATE) { + ret = ti_sci_device_get(cluster_id); + if (ret) { + ERROR("Request to get cluster failed: %d\n", ret); + return; + } + } /* Start by sending wait for WFI command */ - ret = ti_sci_proc_wait_boot_status_no_wait(proc, + ret = ti_sci_proc_wait_boot_status_no_wait(proc_id, /* * Wait maximum time to give us the best chance to get * to WFI before this command timeouts @@ -95,11 +127,72 @@ void k3_pwr_domain_off(const psci_power_state_t *target_state) } /* Now queue up the core shutdown request */ - ret = ti_sci_device_put_no_wait(device); + ret = ti_sci_device_put_no_wait(device_id); if (ret) { ERROR("Sending core shutdown message failed (%d)\n", ret); return; } + + /* If our cluster is not going down we stop here */ + if (CLUSTER_PWR_STATE(target_state) != PLAT_MAX_OFF_STATE) + return; + + /* set AINACTS */ + ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id, + PROC_BOOT_CTRL_FLAG_ARMV8_AINACTS, 0); + if (ret) { + ERROR("Sending set control message failed (%d)\n", ret); + return; + } + + /* set L2FLUSHREQ */ + ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id, + PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ, 0); + if (ret) { + ERROR("Sending set control message failed (%d)\n", ret); + return; + } + + /* wait for L2FLUSHDONE*/ + ret = ti_sci_proc_wait_boot_status_no_wait(proc_id, + UINT8_MAX, 2, UINT8_MAX, UINT8_MAX, + PROC_BOOT_STATUS_FLAG_ARMV8_L2F_DONE, 0, 0, 0); + if (ret) { + ERROR("Sending wait message failed (%d)\n", ret); + return; + } + + /* clear L2FLUSHREQ */ + ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id, + 0, PROC_BOOT_CTRL_FLAG_ARMV8_L2FLUSHREQ); + if (ret) { + ERROR("Sending set control message failed (%d)\n", ret); + return; + } + + /* set ACINACTM */ + ret = ti_sci_proc_set_boot_ctrl_no_wait(proc_id, + PROC_BOOT_CTRL_FLAG_ARMV8_ACINACTM, 0); + if (ret) { + ERROR("Sending set control message failed (%d)\n", ret); + return; + } + + /* wait for STANDBYWFIL2 */ + ret = ti_sci_proc_wait_boot_status_no_wait(proc_id, + UINT8_MAX, 2, UINT8_MAX, UINT8_MAX, + PROC_BOOT_STATUS_FLAG_ARMV8_STANDBYWFIL2, 0, 0, 0); + if (ret) { + ERROR("Sending wait message failed (%d)\n", ret); + return; + } + + /* Now queue up the cluster shutdown request */ + ret = ti_sci_device_put_no_wait(cluster_id); + if (ret) { + ERROR("Sending cluster shutdown message failed (%d)\n", ret); + return; + } } void k3_pwr_domain_on_finish(const psci_power_state_t *target_state) diff --git a/plat/ti/k3/common/plat_common.mk b/plat/ti/k3/common/plat_common.mk index 20a94ef9e..7956497ae 100644 --- a/plat/ti/k3/common/plat_common.mk +++ b/plat/ti/k3/common/plat_common.mk @@ -31,6 +31,9 @@ HANDLE_EA_EL3_FIRST := 1 # Split out RO data into a non-executable section SEPARATE_CODE_AND_RODATA := 1 +# Generate a Position Independent Executable +ENABLE_PIE := 1 + TI_16550_MDR_QUIRK := 1 $(eval $(call add_define,TI_16550_MDR_QUIRK)) diff --git a/plat/xilinx/common/include/plat_startup.h b/plat/xilinx/common/include/plat_startup.h new file mode 100644 index 000000000..66e793373 --- /dev/null +++ b/plat/xilinx/common/include/plat_startup.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2020, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PLAT_STARTUP_H +#define PLAT_STARTUP_H + +/* For FSBL handover */ +enum fsbl_handoff { + FSBL_HANDOFF_SUCCESS = 0, + FSBL_HANDOFF_NO_STRUCT, + FSBL_HANDOFF_INVAL_STRUCT, + FSBL_HANDOFF_TOO_MANY_PARTS +}; + +enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info, + entry_point_info_t *bl33_image_ep_info, + uint64_t atf_handoff_addr); + +#endif /* PLAT_STARTUP_H */ diff --git a/plat/xilinx/zynqmp/pm_service/pm_client.h b/plat/xilinx/common/include/pm_client.h index adbb76f9b..e91bb8f6c 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_client.h +++ b/plat/xilinx/common/include/pm_client.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2015, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,11 +19,14 @@ void pm_client_suspend(const struct pm_proc *proc, unsigned int state); void pm_client_abort_suspend(void); void pm_client_wakeup(const struct pm_proc *proc); -enum pm_ret_status set_ocm_retention(void); -enum pm_ret_status pm_set_suspend_mode(uint32_t mode); -const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid); /* Global variables to be set in pm_client.c */ extern const struct pm_proc *primary_proc; +#ifndef VERSAL_PLATFORM +enum pm_ret_status set_ocm_retention(void); +enum pm_ret_status pm_set_suspend_mode(uint32_t mode); +const struct pm_proc *pm_get_proc_by_node(enum pm_node_id nid); +#endif + #endif /* PM_CLIENT_H */ diff --git a/plat/xilinx/common/include/pm_ipi.h b/plat/xilinx/common/include/pm_ipi.h index 16db5c548..7bcf59626 100644 --- a/plat/xilinx/common/include/pm_ipi.h +++ b/plat/xilinx/common/include/pm_ipi.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -26,5 +26,8 @@ void pm_ipi_buff_read_callb(unsigned int *value, size_t count); void pm_ipi_irq_enable(const struct pm_proc *proc); void pm_ipi_irq_clear(const struct pm_proc *proc); uint32_t pm_ipi_irq_status(const struct pm_proc *proc); +#if ZYNQMP_IPI_CRC_CHECK +uint32_t calculate_crc(uint32_t payload[PAYLOAD_ARG_CNT], uint32_t buffersize); +#endif #endif /* PM_IPI_H */ diff --git a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c index c499d78e9..f53115885 100644 --- a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c +++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h index 197c78819..10682d835 100644 --- a/plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.h +++ b/plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ diff --git a/plat/xilinx/zynqmp/plat_startup.c b/plat/xilinx/common/plat_startup.c index cd2c3bac6..8c9a049dd 100644 --- a/plat/xilinx/zynqmp/plat_startup.c +++ b/plat/xilinx/common/plat_startup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,10 +8,8 @@ #include <arch_helpers.h> #include <common/debug.h> -#include <lib/mmio.h> -#include <plat_private.h> +#include <plat_startup.h> -#include "zynqmp_def.h" /* * ATFHandoffParams @@ -147,6 +145,7 @@ static int get_fsbl_estate(const struct xfsbl_partition *partition) * Populates the bl32 and bl33 image info structures * @bl32: BL32 image info structure * @bl33: BL33 image info structure + * atf_handoff_addr: ATF handoff address * * Process the handoff paramters from the FSBL and populate the BL32 and BL33 * image info structures accordingly. @@ -154,12 +153,11 @@ static int get_fsbl_estate(const struct xfsbl_partition *partition) * Return: Return the status of the handoff. The value will be from the * fsbl_handoff enum. */ -enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32, entry_point_info_t *bl33) +enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32, + entry_point_info_t *bl33, + uint64_t atf_handoff_addr) { - uint64_t atf_handoff_addr; const struct xfsbl_atf_handoff_params *ATFHandoffParams; - - atf_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6); assert((atf_handoff_addr < BL31_BASE) || (atf_handoff_addr > (uint64_t)&__BL31_END__)); if (!atf_handoff_addr) { diff --git a/plat/xilinx/common/pm_service/pm_ipi.c b/plat/xilinx/common/pm_service/pm_ipi.c index 034cd5bc8..c83d25b0d 100644 --- a/plat/xilinx/common/pm_service/pm_ipi.c +++ b/plat/xilinx/common/pm_service/pm_ipi.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -57,6 +57,9 @@ static enum pm_ret_status pm_ipi_send_common(const struct pm_proc *proc, uintptr_t buffer_base = proc->ipi->buffer_base + IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_REQ_OFFSET; +#if ZYNQMP_IPI_CRC_CHECK + payload[PAYLOAD_CRC_POS] = calculate_crc(payload, IPI_W0_TO_W6_SIZE); +#endif /* Write payload into IPI buffer */ for (size_t i = 0; i < PAYLOAD_ARG_CNT; i++) { @@ -132,6 +135,10 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, unsigned int *value, size_t count) { size_t i; +#if ZYNQMP_IPI_CRC_CHECK + size_t j; + unsigned int response_payload[PAYLOAD_ARG_CNT]; +#endif uintptr_t buffer_base = proc->ipi->buffer_base + IPI_BUFFER_TARGET_REMOTE_OFFSET + IPI_BUFFER_RESP_OFFSET; @@ -147,6 +154,16 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } +#if ZYNQMP_IPI_CRC_CHECK + for (j = 0; j < PAYLOAD_ARG_CNT; j++) + response_payload[j] = mmio_read_32(buffer_base + + (j * PAYLOAD_ARG_SIZE)); + + if (response_payload[PAYLOAD_CRC_POS] != + calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) + NOTICE("ERROR in CRC response payload value:0x%x\n", + response_payload[PAYLOAD_CRC_POS]); +#endif return mmio_read_32(buffer_base); } @@ -162,6 +179,10 @@ static enum pm_ret_status pm_ipi_buff_read(const struct pm_proc *proc, void pm_ipi_buff_read_callb(unsigned int *value, size_t count) { size_t i; +#if ZYNQMP_IPI_CRC_CHECK + size_t j; + unsigned int response_payload[PAYLOAD_ARG_CNT]; +#endif uintptr_t buffer_base = IPI_BUFFER_REMOTE_BASE + IPI_BUFFER_TARGET_LOCAL_OFFSET + IPI_BUFFER_REQ_OFFSET; @@ -173,6 +194,16 @@ void pm_ipi_buff_read_callb(unsigned int *value, size_t count) *value = mmio_read_32(buffer_base + (i * PAYLOAD_ARG_SIZE)); value++; } +#if ZYNQMP_IPI_CRC_CHECK + for (j = 0; j < PAYLOAD_ARG_CNT; j++) + response_payload[j] = mmio_read_32(buffer_base + + (j * PAYLOAD_ARG_SIZE)); + + if (response_payload[PAYLOAD_CRC_POS] != + calculate_crc(response_payload, IPI_W0_TO_W6_SIZE)) + NOTICE("ERROR in CRC response payload value:0x%x\n", + response_payload[PAYLOAD_CRC_POS]); +#endif } /** @@ -228,3 +259,34 @@ uint32_t pm_ipi_irq_status(const struct pm_proc *proc) else return 0; } + +#if ZYNQMP_IPI_CRC_CHECK +uint32_t calculate_crc(uint32_t *payload, uint32_t bufsize) +{ + uint32_t crcinit = CRC_INIT_VALUE; + uint32_t order = CRC_ORDER; + uint32_t polynom = CRC_POLYNOM; + uint32_t i, j, c, bit, datain, crcmask, crchighbit; + uint32_t crc = crcinit; + + crcmask = ((uint32_t)((1U << (order - 1U)) - 1U) << 1U) | 1U; + crchighbit = (uint32_t)(1U << (order - 1U)); + + for (i = 0U; i < bufsize; i++) { + datain = mmio_read_8((unsigned long)payload + i); + c = datain; + j = 0x80U; + while (j != 0U) { + bit = crc & crchighbit; + crc <<= 1U; + if (0U != (c & j)) + bit ^= crchighbit; + if (bit != 0U) + crc ^= polynom; + j >>= 1U; + } + crc &= crcmask; + } + return crc; +} +#endif diff --git a/plat/xilinx/versal/aarch64/versal_common.c b/plat/xilinx/versal/aarch64/versal_common.c index 587b797d7..2fa847658 100644 --- a/plat/xilinx/versal/aarch64/versal_common.c +++ b/plat/xilinx/versal/aarch64/versal_common.c @@ -1,18 +1,18 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <plat_ipi.h> +#include <versal_def.h> +#include <plat_private.h> #include <common/debug.h> #include <drivers/generic_delay_timer.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> #include <plat/common/platform.h> -#include "../versal_def.h" -#include "../versal_private.h" - /* * Table of regions to map using the MMU. * This doesn't include TZRAM as the 'mem_layout' argument passed to @@ -22,6 +22,8 @@ const mmap_region_t plat_versal_mmap[] = { MAP_REGION_FLAT(DEVICE0_BASE, DEVICE0_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_SECURE), MAP_REGION_FLAT(CRF_BASE, CRF_SIZE, MT_DEVICE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(FPD_MAINCCI_BASE, FPD_MAINCCI_SIZE, MT_DEVICE | MT_RW | + MT_SECURE), { 0 } }; @@ -39,11 +41,10 @@ void versal_config_setup(void) { uint32_t val; - versal_print_platform_name(); + /* Configure IPI data for versal */ + versal_ipi_config_table_init(); - mmio_write_32(VERSAL_CRL_IOU_SWITCH_CTRL, - VERSAL_IOU_SWITCH_CTRL_CLKACT_BIT | - (0x20 << VERSAL_IOU_SWITCH_CTRL_DIVISOR0_SHIFT)); + versal_print_platform_name(); /* Global timer init - Program time stamp reference clk */ val = mmio_read_32(VERSAL_CRL_TIMESTAMP_REF_CTRL); @@ -66,11 +67,3 @@ unsigned int plat_get_syscnt_freq2(void) return VERSAL_CPU_CLOCK; } -uintptr_t plat_get_ns_image_entrypoint(void) -{ -#ifdef PRELOADED_BL33_BASE - return PRELOADED_BL33_BASE; -#else - return PLAT_VERSAL_NS_IMAGE_OFFSET; -#endif -} diff --git a/plat/xilinx/versal/bl31_versal_setup.c b/plat/xilinx/versal/bl31_versal_setup.c index d7e07e036..a5cf05e9a 100644 --- a/plat/xilinx/versal/bl31_versal_setup.c +++ b/plat/xilinx/versal/bl31_versal_setup.c @@ -1,21 +1,24 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ #include <assert.h> #include <errno.h> - +#include <plat_arm.h> +#include <plat_private.h> #include <bl31/bl31.h> #include <common/bl_common.h> #include <common/debug.h> #include <drivers/arm/pl011.h> #include <drivers/console.h> +#include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> #include <plat/common/platform.h> - -#include "versal_private.h" +#include <versal_def.h> +#include <plat_private.h> +#include <plat_startup.h> static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -38,6 +41,18 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) } /* + * Set the build time defaults,if we can't find any config data. + */ +static inline void bl31_set_default_config(void) +{ + bl32_image_ep_info.pc = BL32_BASE; + bl32_image_ep_info.spsr = arm_get_spsr_for_bl32_entry(); + bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); + bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, + DISABLE_ALL_EXCEPTIONS); +} + +/* * Perform any BL31 specific platform actions. Here is an opportunity to copy * parameters passed by the calling EL (S-EL1 in BL2 & S-EL3 in BL1) before they * are lost (potentially). This needs to be done before the MMU is initialized @@ -46,6 +61,7 @@ entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + uint64_t atf_handoff_addr; /* Initialize the console to provide early debug support */ int rc = console_pl011_register(VERSAL_UART_BASE, @@ -77,12 +93,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); - /* use build time defaults in JTAG boot mode */ - bl32_image_ep_info.pc = BL32_BASE; - bl32_image_ep_info.spsr = 0; - bl33_image_ep_info.pc = plat_get_ns_image_entrypoint(); - bl33_image_ep_info.spsr = SPSR_64(MODE_EL2, MODE_SP_ELX, - DISABLE_ALL_EXCEPTIONS); + atf_handoff_addr = mmio_read_32(PMC_GLOBAL_GLOB_GEN_STORAGE4); + enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info, + &bl33_image_ep_info, + atf_handoff_addr); + if (ret == FSBL_HANDOFF_NO_STRUCT) { + bl31_set_default_config(); + } else if (ret != FSBL_HANDOFF_SUCCESS) { + panic(); + } NOTICE("BL31: Secure code at 0x%lx\n", bl32_image_ep_info.pc); NOTICE("BL31: Non secure code at 0x%lx\n", bl33_image_ep_info.pc); @@ -104,6 +123,9 @@ void bl31_plat_runtime_setup(void) */ void bl31_plat_arch_setup(void) { + plat_arm_interconnect_init(); + plat_arm_interconnect_enter_coherency(); + const mmap_region_t bl_regions[] = { MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE, MT_MEMORY | MT_RW | MT_SECURE), diff --git a/plat/xilinx/versal/include/plat_ipi.h b/plat/xilinx/versal/include/plat_ipi.h new file mode 100644 index 000000000..6b08f322d --- /dev/null +++ b/plat/xilinx/versal/include/plat_ipi.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Versal IPI management enums and defines */ + +#ifndef PLAT_IPI_H +#define PLAT_IPI_H + +#include <ipi.h> +#include <stdint.h> + +/********************************************************************* + * IPI agent IDs macros + ********************************************************************/ +#define IPI_ID_PMC 1U +#define IPI_ID_APU 2U +#define IPI_ID_RPU0 3U +#define IPI_ID_RPU1 4U +#define IPI_ID_3 5U +#define IPI_ID_4 6U +#define IPI_ID_5 7U + +/********************************************************************* + * IPI message buffers + ********************************************************************/ +#define IPI_BUFFER_BASEADDR 0xFF3F0000U + +#define IPI_BUFFER_APU_BASE (IPI_BUFFER_BASEADDR + 0x400U) +#define IPI_BUFFER_PMC_BASE (IPI_BUFFER_BASEADDR + 0x200U) + +#define IPI_BUFFER_TARGET_APU_OFFSET 0x0U +#define IPI_BUFFER_TARGET_PMC_OFFSET 0x40U + +#define IPI_BUFFER_LOCAL_BASE IPI_BUFFER_APU_BASE +#define IPI_BUFFER_REMOTE_BASE IPI_BUFFER_PMC_BASE + +#define IPI_BUFFER_TARGET_LOCAL_OFFSET IPI_BUFFER_TARGET_APU_OFFSET +#define IPI_BUFFER_TARGET_REMOTE_OFFSET IPI_BUFFER_TARGET_PMC_OFFSET + +#define IPI_BUFFER_MAX_WORDS 8 + +#define IPI_BUFFER_REQ_OFFSET 0x0U +#define IPI_BUFFER_RESP_OFFSET 0x20U + +/********************************************************************* + * Platform specific IPI API declarations + ********************************************************************/ + +/* Configure IPI table for versal */ +void versal_ipi_config_table_init(void); + +#endif /* PLAT_IPI_H */ diff --git a/plat/xilinx/versal/include/plat_pm_common.h b/plat/xilinx/versal/include/plat_pm_common.h new file mode 100644 index 000000000..2d0080168 --- /dev/null +++ b/plat/xilinx/versal/include/plat_pm_common.h @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Contains platform specific definitions of commonly used macros data types + * for PU Power Management. This file should be common for all PU's. + */ + +#ifndef PLAT_PM_COMMON_H +#define PLAT_PM_COMMON_H + +#include <common/debug.h> +#include <stdint.h> +#include "pm_defs.h" + +#define PAYLOAD_ARG_CNT 6U +#define PAYLOAD_ARG_SIZE 4U /* size in bytes */ + +#define VERSAL_TZ_VERSION_MAJOR 1 +#define VERSAL_TZ_VERSION_MINOR 0 +#define VERSAL_TZ_VERSION ((VERSAL_TZ_VERSION_MAJOR << 16) | \ + VERSAL_TZ_VERSION_MINOR) +#endif /* PLAT_PM_COMMON_H */ diff --git a/plat/xilinx/versal/versal_private.h b/plat/xilinx/versal/include/plat_private.h index 5d98d080c..e302096eb 100644 --- a/plat/xilinx/versal/versal_private.h +++ b/plat/xilinx/versal/include/plat_private.h @@ -1,11 +1,11 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ -#ifndef VERSAL_PRIVATE_H -#define VERSAL_PRIVATE_H +#ifndef PLAT_PRIVATE_H +#define PLAT_PRIVATE_H #include <lib/xlat_tables/xlat_tables.h> @@ -18,7 +18,9 @@ void plat_versal_gic_init(void); void plat_versal_gic_cpuif_enable(void); void plat_versal_gic_cpuif_disable(void); void plat_versal_gic_pcpu_init(void); +void plat_versal_gic_save(void); +void plat_versal_gic_resume(void); unsigned int versal_calc_core_pos(u_register_t mpidr); -#endif /* VERSAL_PRIVATE_H */ +#endif /* PLAT_PRIVATE_H */ diff --git a/plat/xilinx/versal/include/platform_def.h b/plat/xilinx/versal/include/platform_def.h index 0c4b9544f..4cdaea219 100644 --- a/plat/xilinx/versal/include/platform_def.h +++ b/plat/xilinx/versal/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -8,8 +8,7 @@ #define PLATFORM_DEF_H #include <arch.h> - -#include "../versal_def.h" +#include "versal_def.h" /******************************************************************************* * Generic platform constants @@ -18,7 +17,7 @@ /* Size of cacheable stacks */ #define PLATFORM_STACK_SIZE 0x440 -#define PLATFORM_CORE_COUNT 2 +#define PLATFORM_CORE_COUNT U(2) #define PLAT_MAX_PWR_LVL 1 #define PLAT_MAX_RET_STATE 1 #define PLAT_MAX_OFF_STATE 2 @@ -32,7 +31,7 @@ * little space for growth. */ #ifndef VERSAL_ATF_MEM_BASE -# define BL31_BASE 0xfffea000 +# define BL31_BASE 0xfffe0000 # define BL31_LIMIT 0xffffffff #else # define BL31_BASE (VERSAL_ATF_MEM_BASE) @@ -57,9 +56,9 @@ * BL33 specific defines. ******************************************************************************/ #ifndef PRELOADED_BL33_BASE -# define PLAT_VERSAL_NS_IMAGE_OFFSET 0x8000000 +# define PLAT_ARM_NS_IMAGE_BASE 0x8000000 #else -# define PLAT_VERSAL_NS_IMAGE_OFFSET PRELOADED_BL33_BASE +# define PLAT_ARM_NS_IMAGE_BASE PRELOADED_BL33_BASE #endif /******************************************************************************* @@ -76,7 +75,7 @@ ******************************************************************************/ #define PLAT_PHY_ADDR_SPACE_SIZE (1ull << 32) #define PLAT_VIRT_ADDR_SPACE_SIZE (1ull << 32) -#define MAX_MMAP_REGIONS 7 +#define MAX_MMAP_REGIONS 8 #define MAX_XLAT_TABLES 5 #define CACHE_WRITEBACK_SHIFT 6 diff --git a/plat/xilinx/versal/versal_def.h b/plat/xilinx/versal/include/versal_def.h index 41c65b94d..9a9b7c017 100644 --- a/plat/xilinx/versal/versal_def.h +++ b/plat/xilinx/versal/include/versal_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -19,6 +19,7 @@ /* List all supported platforms */ #define VERSAL_PLATFORM_ID_versal_virt 1 +#define VERSAL_PLATFORM_ID_silicon 4 #define VERSAL_PLATFORM_IS(con) (VERSAL_PLATFORM_ID_ ## con == VERSAL_PLATFORM) @@ -35,13 +36,10 @@ /* CRL */ #define VERSAL_CRL 0xFF5E0000 -#define VERSAL_CRL_IOU_SWITCH_CTRL (VERSAL_CRL + 0x114) #define VERSAL_CRL_TIMESTAMP_REF_CTRL (VERSAL_CRL + 0x14C) #define VERSAL_CRL_RST_TIMESTAMP_OFFSET (VERSAL_CRL + 0x348) #define VERSAL_CRL_APB_TIMESTAMP_REF_CTRL_CLKACT_BIT (1 << 25) -#define VERSAL_IOU_SWITCH_CTRL_CLKACT_BIT (1 << 25) -#define VERSAL_IOU_SWITCH_CTRL_DIVISOR0_SHIFT 8 /* IOU SCNTRS */ #define VERSAL_IOU_SCNTRS 0xFF140000 @@ -56,6 +54,13 @@ #define VERSAL_IRQ_SEC_PHY_TIMER 29 /******************************************************************************* + * CCI-400 related constants + ******************************************************************************/ +#define PLAT_ARM_CCI_BASE 0xFD000000 +#define PLAT_ARM_CCI_CLUSTER0_SL_IFACE_IX 4 +#define PLAT_ARM_CCI_CLUSTER1_SL_IFACE_IX 5 + +/******************************************************************************* * UART related constants ******************************************************************************/ #define VERSAL_UART0_BASE 0xFF000000 @@ -80,7 +85,12 @@ # define PLATFORM_NAME "Versal Virt" # define VERSAL_UART_CLOCK 25000000 # define VERSAL_UART_BAUDRATE 115200 -# define VERSAL_CPU_CLOCK 62500000 +# define VERSAL_CPU_CLOCK 2720000 +#elif VERSAL_PLATFORM_IS(silicon) +# define PLATFORM_NAME "Versal Silicon" +# define VERSAL_UART_CLOCK 100000000 +# define VERSAL_UART_BAUDRATE 115200 +# define VERSAL_CPU_CLOCK 100000000 #endif /* Access control register defines */ @@ -97,6 +107,9 @@ #define CRF_RST_APU_ACPU_RESET (1 << 0) #define CRF_RST_APU_ACPU_PWRON_RESET (1 << 10) +#define FPD_MAINCCI_BASE 0xFD000000 +#define FPD_MAINCCI_SIZE 0x00100000 + /* APU registers and bitfields */ #define FPD_APU_BASE 0xFD5C0000 #define FPD_APU_CONFIG_0 (FPD_APU_BASE + 0x20) @@ -105,5 +118,26 @@ #define FPD_APU_PWRCTL (FPD_APU_BASE + 0x90) #define FPD_APU_CONFIG_0_VINITHI_SHIFT 8 +#define APU_0_PWRCTL_CPUPWRDWNREQ_MASK 1 +#define APU_1_PWRCTL_CPUPWRDWNREQ_MASK 2 + +/* PMC registers and bitfields */ +#define PMC_GLOBAL_BASE 0xF1110000 +#define PMC_GLOBAL_GLOB_GEN_STORAGE4 (PMC_GLOBAL_BASE + 0x40) + +/* IPI registers and bitfields */ +#define IPI0_REG_BASE 0xFF330000 +#define IPI0_TRIG_BIT (1 << 2) +#define PMC_IPI_TRIG_BIT (1 << 1) +#define IPI1_REG_BASE 0xFF340000 +#define IPI1_TRIG_BIT (1 << 3) +#define IPI2_REG_BASE 0xFF350000 +#define IPI2_TRIG_BIT (1 << 4) +#define IPI3_REG_BASE 0xFF360000 +#define IPI3_TRIG_BIT (1 << 5) +#define IPI4_REG_BASE 0xFF370000 +#define IPI4_TRIG_BIT (1 << 5) +#define IPI5_REG_BASE 0xFF380000 +#define IPI5_TRIG_BIT (1 << 6) #endif /* VERSAL_DEF_H */ diff --git a/plat/xilinx/versal/plat_psci.c b/plat/xilinx/versal/plat_psci.c index 4a443697f..39550858a 100644 --- a/plat/xilinx/versal/plat_psci.c +++ b/plat/xilinx/versal/plat_psci.c @@ -1,63 +1,109 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> +#include <plat_arm.h> +#include <plat_private.h> +#include <pm_common.h> #include <common/debug.h> #include <lib/mmio.h> #include <lib/psci/psci.h> #include <plat/common/platform.h> +#include <plat/arm/common/plat_arm.h> -#include "versal_private.h" +#include "pm_api_sys.h" +#include "pm_client.h" static uintptr_t versal_sec_entry; -static int versal_nopmc_pwr_domain_on(u_register_t mpidr) +static int versal_pwr_domain_on(u_register_t mpidr) { - uint32_t r; unsigned int cpu_id = plat_core_pos_by_mpidr(mpidr); + const struct pm_proc *proc; VERBOSE("%s: mpidr: 0x%lx\n", __func__, mpidr); if (cpu_id == -1) return PSCI_E_INTERN_FAIL; - /* - * program RVBAR - */ - mmio_write_32(FPD_APU_RVBAR_L_0 + (cpu_id << 3), versal_sec_entry); - mmio_write_32(FPD_APU_RVBAR_H_0 + (cpu_id << 3), versal_sec_entry >> 32); + proc = pm_get_proc(cpu_id); - /* - * clear VINITHI - */ - r = mmio_read_32(FPD_APU_CONFIG_0); - r &= ~(1 << FPD_APU_CONFIG_0_VINITHI_SHIFT << cpu_id); - mmio_write_32(FPD_APU_CONFIG_0, r); + /* Send request to PMC to wake up selected ACPU core */ + pm_req_wakeup(proc->node_id, (versal_sec_entry & 0xFFFFFFFF) | 0x1, + versal_sec_entry >> 32, 0); - /* - * FIXME: Add power up sequence, By default it works - * now without the need of it as it was powered up by - * default. - */ + /* Clear power down request */ + pm_client_wakeup(proc); - /* - * clear power down request - */ - r = mmio_read_32(FPD_APU_PWRCTL); - r &= ~(1 << cpu_id); - mmio_write_32(FPD_APU_PWRCTL, r); + return PSCI_E_SUCCESS; +} - /* - * release core reset - */ - r = mmio_read_32(CRF_RST_APU); - r &= ~((CRF_RST_APU_ACPU_PWRON_RESET | - CRF_RST_APU_ACPU_RESET) << cpu_id); - mmio_write_32(CRF_RST_APU, r); +/** + * versal_pwr_domain_suspend() - This function sends request to PMC to suspend + * core. + * + * @target_state Targated state + */ +static void versal_pwr_domain_suspend(const psci_power_state_t *target_state) +{ + unsigned int state; + unsigned int cpu_id = plat_my_core_pos(); + const struct pm_proc *proc = pm_get_proc(cpu_id); - return PSCI_E_SUCCESS; + for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) + VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", + __func__, i, target_state->pwr_domain_state[i]); + + plat_versal_gic_cpuif_disable(); + + plat_versal_gic_save(); + + state = target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE ? + PM_STATE_SUSPEND_TO_RAM : PM_STATE_CPU_IDLE; + + /* Send request to PMC to suspend this core */ + pm_self_suspend(proc->node_id, MAX_LATENCY, state, versal_sec_entry); + + /* APU is to be turned off */ + if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { + /* disable coherency */ + plat_arm_interconnect_exit_coherency(); + } +} + +/** + * versal_pwr_domain_suspend_finish() - This function performs actions to finish + * suspend procedure. + * + * @target_state Targated state + */ +static void versal_pwr_domain_suspend_finish( + const psci_power_state_t *target_state) +{ + unsigned int cpu_id = plat_my_core_pos(); + const struct pm_proc *proc = pm_get_proc(cpu_id); + + for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) + VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", + __func__, i, target_state->pwr_domain_state[i]); + + /* Clear the APU power control register for this cpu */ + pm_client_wakeup(proc); + + /* enable coherency */ + plat_arm_interconnect_enter_coherency(); + + /* APU was turned off, so restore GIC context */ + if (target_state->pwr_domain_state[1] > PLAT_MAX_RET_STATE) { + plat_versal_gic_resume(); + plat_versal_gic_cpuif_enable(); + } else { + plat_versal_gic_cpuif_enable(); + plat_versal_gic_pcpu_init(); + } } void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) @@ -69,9 +115,114 @@ void versal_pwr_domain_on_finish(const psci_power_state_t *target_state) plat_versal_gic_cpuif_enable(); } +/** + * versal_system_off() - This function sends the system off request + * to firmware. This function does not return. + */ +static void __dead2 versal_system_off(void) +{ + /* Send the power down request to the PMC */ + pm_system_shutdown(XPM_SHUTDOWN_TYPE_SHUTDOWN, + pm_get_shutdown_scope()); + + while (1) + wfi(); +} + +/** + * versal_system_reset() - This function sends the reset request + * to firmware for the system to reset. This function does not return. + */ +static void __dead2 versal_system_reset(void) +{ + /* Send the system reset request to the PMC */ + pm_system_shutdown(XPM_SHUTDOWN_TYPE_RESET, + pm_get_shutdown_scope()); + + while (1) + wfi(); +} + +/** + * versal_pwr_domain_off() - This function performs actions to turn off core + * + * @target_state Targated state + */ +static void versal_pwr_domain_off(const psci_power_state_t *target_state) +{ + unsigned int cpu_id = plat_my_core_pos(); + const struct pm_proc *proc = pm_get_proc(cpu_id); + + for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) + VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", + __func__, i, target_state->pwr_domain_state[i]); + + /* Prevent interrupts from spuriously waking up this cpu */ + plat_versal_gic_cpuif_disable(); + + /* + * Send request to PMC to power down the appropriate APU CPU + * core. + * According to PSCI specification, CPU_off function does not + * have resume address and CPU core can only be woken up + * invoking CPU_on function, during which resume address will + * be set. + */ + pm_self_suspend(proc->node_id, MAX_LATENCY, PM_STATE_CPU_IDLE, 0); +} + +/** + * versal_validate_power_state() - This function ensures that the power state + * parameter in request is valid. + * + * @power_state Power state of core + * @req_state Requested state + * + * @return Returns status, either success or reason + */ +static int versal_validate_power_state(unsigned int power_state, + psci_power_state_t *req_state) +{ + VERBOSE("%s: power_state: 0x%x\n", __func__, power_state); + + int pstate = psci_get_pstate_type(power_state); + + assert(req_state); + + /* Sanity check the requested state */ + if (pstate == PSTATE_TYPE_STANDBY) + req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_RET_STATE; + else + req_state->pwr_domain_state[MPIDR_AFFLVL0] = PLAT_MAX_OFF_STATE; + + /* We expect the 'state id' to be zero */ + if (psci_get_pstate_id(power_state)) + return PSCI_E_INVALID_PARAMS; + + return PSCI_E_SUCCESS; +} + +/** + * versal_get_sys_suspend_power_state() - Get power state for system suspend + * + * @req_state Requested state + */ +static void versal_get_sys_suspend_power_state(psci_power_state_t *req_state) +{ + req_state->pwr_domain_state[PSCI_CPU_PWR_LVL] = PLAT_MAX_OFF_STATE; + req_state->pwr_domain_state[1] = PLAT_MAX_OFF_STATE; +} + static const struct plat_psci_ops versal_nopmc_psci_ops = { - .pwr_domain_on = versal_nopmc_pwr_domain_on, + .pwr_domain_on = versal_pwr_domain_on, + .pwr_domain_off = versal_pwr_domain_off, .pwr_domain_on_finish = versal_pwr_domain_on_finish, + .pwr_domain_suspend = versal_pwr_domain_suspend, + .pwr_domain_suspend_finish = versal_pwr_domain_suspend_finish, + .system_off = versal_system_off, + .system_reset = versal_system_reset, + .validate_power_state = versal_validate_power_state, + .get_sys_suspend_power_state = versal_get_sys_suspend_power_state, }; /******************************************************************************* diff --git a/plat/xilinx/versal/plat_versal.c b/plat/xilinx/versal/plat_versal.c index 642867da2..a080a76a9 100644 --- a/plat/xilinx/versal/plat_versal.c +++ b/plat/xilinx/versal/plat_versal.c @@ -1,13 +1,12 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <plat_private.h> #include <plat/common/platform.h> -#include "versal_private.h" - int plat_core_pos_by_mpidr(u_register_t mpidr) { if (mpidr & MPIDR_CLUSTER_MASK) diff --git a/plat/xilinx/versal/platform.mk b/plat/xilinx/versal/platform.mk index 1c56364c8..1e231cce8 100644 --- a/plat/xilinx/versal/platform.mk +++ b/plat/xilinx/versal/platform.mk @@ -1,4 +1,4 @@ -# Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -31,33 +31,50 @@ ifdef VERSAL_BL32_MEM_BASE $(eval $(call add_define,VERSAL_BL32_MEM_SIZE)) endif -VERSAL_PLATFORM ?= versal_virt +VERSAL_PLATFORM ?= silicon $(eval $(call add_define_val,VERSAL_PLATFORM,VERSAL_PLATFORM_ID_${VERSAL_PLATFORM})) VERSAL_CONSOLE ?= pl011 $(eval $(call add_define_val,VERSAL_CONSOLE,VERSAL_CONSOLE_ID_${VERSAL_CONSOLE})) -PLAT_INCLUDES := -Iplat/xilinx/versal/include/ +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -Iplat/xilinx/common/include/ \ + -Iplat/xilinx/common/ipi_mailbox_service/ \ + -Iplat/xilinx/versal/include/ \ + -Iplat/xilinx/versal/pm_service/ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ drivers/delay_timer/delay_timer.c \ drivers/delay_timer/generic_delay_timer.c \ drivers/arm/gic/common/gic_common.c \ + drivers/arm/gic/v3/arm_gicv3_common.c \ + drivers/arm/gic/v3/gic500.c \ drivers/arm/gic/v3/gicv3_main.c \ drivers/arm/gic/v3/gicv3_helpers.c \ drivers/arm/pl011/aarch64/pl011_console.S \ plat/common/aarch64/crash_console_helpers.S \ + plat/arm/common/arm_cci.c \ + plat/arm/common/arm_common.c \ plat/common/plat_gicv3.c \ plat/xilinx/versal/aarch64/versal_helpers.S \ plat/xilinx/versal/aarch64/versal_common.c -BL31_SOURCES += lib/cpus/aarch64/cortex_a53.S \ +BL31_SOURCES += drivers/arm/cci/cci.c \ + lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ plat/common/plat_psci_common.c \ + plat/xilinx/common/ipi.c \ + plat/xilinx/common/plat_startup.c \ + plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \ + plat/xilinx/common/pm_service/pm_ipi.c \ plat/xilinx/versal/bl31_versal_setup.c \ plat/xilinx/versal/plat_psci.c \ plat/xilinx/versal/plat_versal.c \ plat/xilinx/versal/plat_topology.c \ plat/xilinx/versal/sip_svc_setup.c \ - plat/xilinx/versal/versal_gicv3.c + plat/xilinx/versal/versal_gicv3.c \ + plat/xilinx/versal/versal_ipi.c \ + plat/xilinx/versal/pm_service/pm_svc_main.c \ + plat/xilinx/versal/pm_service/pm_api_sys.c \ + plat/xilinx/versal/pm_service/pm_client.c diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.c b/plat/xilinx/versal/pm_service/pm_api_sys.c new file mode 100644 index 000000000..dbe94e624 --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_api_sys.c @@ -0,0 +1,885 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Versal system level PM-API functions and communication with PMC via + * IPI interrupts + */ + +#include <pm_common.h> +#include <pm_ipi.h> +#include <plat/common/platform.h> +#include "pm_api_sys.h" +#include "pm_client.h" + +/********************************************************************* + * Target module IDs macros + ********************************************************************/ +#define LIBPM_MODULE_ID 0x2 +#define LOADER_MODULE_ID 0x7 + +/* default shutdown/reboot scope is system(2) */ +static unsigned int pm_shutdown_scope = XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM; + +/** + * pm_get_shutdown_scope() - Get the currently set shutdown scope + * + * @return Shutdown scope value + */ +unsigned int pm_get_shutdown_scope(void) +{ + return pm_shutdown_scope; +} + +/** + * Assigning of argument values into array elements. + */ +#define PM_PACK_PAYLOAD1(pl, mid, arg0) { \ + pl[0] = (uint32_t)((uint32_t)((arg0) & 0xFF) | (mid << 8)); \ +} + +#define PM_PACK_PAYLOAD2(pl, mid, arg0, arg1) { \ + pl[1] = (uint32_t)(arg1); \ + PM_PACK_PAYLOAD1(pl, mid, arg0); \ +} + +#define PM_PACK_PAYLOAD3(pl, mid, arg0, arg1, arg2) { \ + pl[2] = (uint32_t)(arg2); \ + PM_PACK_PAYLOAD2(pl, mid, arg0, arg1); \ +} + +#define PM_PACK_PAYLOAD4(pl, mid, arg0, arg1, arg2, arg3) { \ + pl[3] = (uint32_t)(arg3); \ + PM_PACK_PAYLOAD3(pl, mid, arg0, arg1, arg2); \ +} + +#define PM_PACK_PAYLOAD5(pl, mid, arg0, arg1, arg2, arg3, arg4) { \ + pl[4] = (uint32_t)(arg4); \ + PM_PACK_PAYLOAD4(pl, mid, arg0, arg1, arg2, arg3); \ +} + +#define PM_PACK_PAYLOAD6(pl, mid, arg0, arg1, arg2, arg3, arg4, arg5) { \ + pl[5] = (uint32_t)(arg5); \ + PM_PACK_PAYLOAD5(pl, mid, arg0, arg1, arg2, arg3, arg4); \ +} + +/* PM API functions */ + +/** + * pm_get_api_version() - Get version number of PMC PM firmware + * @version Returns 32-bit version number of PMC Power Management Firmware + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_get_api_version(unsigned int *version) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, PM_GET_API_VERSION); + return pm_ipi_send_sync(primary_proc, payload, version, 1); +} + +/** + * pm_self_suspend() - PM call for processor to suspend itself + * @nid Node id of the processor or subsystem + * @latency Requested maximum wakeup latency (not supported) + * @state Requested state + * @address Resume address + * + * This is a blocking call, it will return only once PMU has responded. + * On a wakeup, resume address will be automatically set by PMU. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_self_suspend(uint32_t nid, + unsigned int latency, + unsigned int state, + uintptr_t address) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + unsigned int cpuid = plat_my_core_pos(); + const struct pm_proc *proc = pm_get_proc(cpuid); + + if (!proc) { + WARN("Failed to get proc %d\n", cpuid); + return PM_RET_ERROR_INTERNAL; + } + + /* + * Do client specific suspend operations + * (e.g. set powerdown request bit) + */ + pm_client_suspend(proc, state); + + /* Send request to the PLM */ + PM_PACK_PAYLOAD6(payload, LIBPM_MODULE_ID, PM_SELF_SUSPEND, + proc->node_id, latency, state, address, + (address >> 32)); + return pm_ipi_send_sync(proc, payload, NULL, 0); +} + +/** + * pm_abort_suspend() - PM call to announce that a prior suspend request + * is to be aborted. + * @reason Reason for the abort + * + * Calling PU expects the PMU to abort the initiated suspend procedure. + * This is a non-blocking call without any acknowledge. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* + * Do client specific abort suspend operations + * (e.g. enable interrupts and clear powerdown request bit) + */ + pm_client_abort_suspend(); + + /* Send request to the PLM */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_ABORT_SUSPEND, reason, + primary_proc->node_id); + return pm_ipi_send(primary_proc, payload); +} + +/** + * pm_req_suspend() - PM call to request for another PU or subsystem to + * be suspended gracefully. + * @target Node id of the targeted PU or subsystem + * @ack Flag to specify whether acknowledge is requested + * @latency Requested wakeup latency (not supported) + * @state Requested state (not supported) + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_req_suspend(uint32_t target, uint8_t ack, + unsigned int latency, unsigned int state) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_REQ_SUSPEND, target, + latency, state); + if (ack == IPI_BLOCKING) + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); + else + return pm_ipi_send(primary_proc, payload); +} + +/** + * pm_req_wakeup() - PM call for processor to wake up selected processor + * or subsystem + * @target Device ID of the processor or subsystem to wake up + * @set_address Resume address presence indicator + * 1 - resume address specified, 0 - otherwise + * @address Resume address + * @ack Flag to specify whether acknowledge requested + * + * This API function is either used to power up another APU core for SMP + * (by PSCI) or to power up an entirely different PU or subsystem, such + * as RPU0, RPU, or PL_CORE_xx. Resume address for the target PU will be + * automatically set by PMC. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address, + uintptr_t address, uint8_t ack) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC to perform the wake of the PU */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REQ_WAKEUP, target, + set_address, address, ack); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_request_device() - Request a device + * @device_id Device ID + * @capabilities Requested capabilities for the device + * @qos Required Quality of Service + * @ack Flag to specify whether acknowledge requested + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities, + uint32_t qos, uint32_t ack) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_REQUEST_DEVICE, + device_id, capabilities, qos, ack); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_release_device() - Release a device + * @device_id Device ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_release_device(uint32_t device_id) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_RELEASE_DEVICE, + device_id); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_set_requirement() - Set requirement for the device + * @device_id Device ID + * @capabilities Requested capabilities for the device + * @latency Requested maximum latency + * @qos Required Quality of Service + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities, + uint32_t latency, uint32_t qos) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_SET_REQUIREMENT, + device_id, capabilities, latency, qos); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_get_device_status() - Get device's status + * @device_id Device ID + * @response Buffer to store device status response + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_GET_DEVICE_STATUS, + device_id); + + return pm_ipi_send_sync(primary_proc, payload, response, 3); +} + +/** + * pm_reset_assert() - Assert/De-assert reset + * @reset Reset ID + * @assert Assert (1) or de-assert (0) + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_RESET_ASSERT, reset, + assert); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_reset_get_status() - Get current status of a reset line + * @reset Reset ID + * @status Returns current status of selected reset ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_RESET_ASSERT, reset); + + return pm_ipi_send_sync(primary_proc, payload, status, 1); +} + +/** + * pm_get_callbackdata() - Read from IPI response buffer + * @data - array of PAYLOAD_ARG_CNT elements + * + * Read value from ipi buffer response buffer. + */ +void pm_get_callbackdata(uint32_t *data, size_t count) +{ + /* Return if interrupt is not from PMU */ + if (!pm_ipi_irq_status(primary_proc)) + return; + + pm_ipi_buff_read_callb(data, count); + pm_ipi_irq_clear(primary_proc); +} + +/** + * pm_pinctrl_request() - Request a pin + * @pin Pin ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_request(uint32_t pin) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_REQUEST, pin); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pinctrl_release() - Release a pin + * @pin Pin ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_release(uint32_t pin) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_RELEASE, pin); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pinctrl_set_function() - Set pin function + * @pin Pin ID + * @function Function ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PINCTRL_SET_FUNCTION, pin, + function) + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pinctrl_get_function() - Get function set on the pin + * @pin Pin ID + * @function Function set on the pin + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PINCTRL_SET_FUNCTION, + pin); + + return pm_ipi_send_sync(primary_proc, payload, function, 1); +} + +/** + * pm_pinctrl_set_pin_param() - Set configuration parameter for the pin + * @pin Pin ID + * @param Parameter ID + * @value Parameter value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param, + uint32_t value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_PINCTRL_CONFIG_PARAM_SET, + pin, param, value); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pinctrl_get_pin_param() - Get configuration parameter value for the pin + * @pin Pin ID + * @param Parameter ID + * @value Buffer to store parameter value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param, + uint32_t *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PINCTRL_CONFIG_PARAM_GET, + pin, param); + + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +/** + * pm_clock_enable() - Enable the clock + * @clk_id Clock ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_enable(uint32_t clk_id) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_ENABLE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_clock_disable() - Disable the clock + * @clk_id Clock ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_disable(uint32_t clk_id) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_DISABLE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_clock_get_state() - Get clock status + * @clk_id Clock ID + * @state: Buffer to store clock status (1: Enabled, 0:Disabled) + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETSTATE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, state, 1); +} + +/** + * pm_clock_set_divider() - Set divider for the clock + * @clk_id Clock ID + * @divider Divider value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_CLOCK_SETDIVIDER, clk_id, + divider); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_clock_get_divider() - Get divider value for the clock + * @clk_id Clock ID + * @divider: Buffer to store clock divider value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETDIVIDER, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, divider, 1); +} + +/** + * pm_clock_set_parent() - Set parent for the clock + * @clk_id Clock ID + * @parent Parent ID + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_CLOCK_SETPARENT, clk_id, + parent); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_clock_get_parent() - Get parent value for the clock + * @clk_id Clock ID + * @parent: Buffer to store clock parent value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_CLOCK_GETPARENT, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, parent, 1); +} + +/** + * pm_pll_set_param() - Set PLL parameter + * @clk_id PLL clock ID + * @param PLL parameter ID + * @value Value to set for PLL parameter + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, + uint32_t value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_PLL_SET_PARAMETER, clk_id, + param, value); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pll_get_param() - Get PLL parameter value + * @clk_id PLL clock ID + * @param PLL parameter ID + * @value: Buffer to store PLL parameter value + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, + uint32_t *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PLL_GET_PARAMETER, clk_id, + param); + + return pm_ipi_send_sync(primary_proc, payload, value, 1); +} + +/** + * pm_pll_set_mode() - Set PLL mode + * @clk_id PLL clock ID + * @mode PLL mode + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_PLL_SET_MODE, clk_id, + mode); + + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_pll_get_mode() - Get PLL mode + * @clk_id PLL clock ID + * @mode: Buffer to store PLL mode + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_PLL_GET_MODE, clk_id); + + return pm_ipi_send_sync(primary_proc, payload, mode, 1); +} + +/** + * pm_force_powerdown() - PM call to request for another PU or subsystem to + * be powered down forcefully + * @target Device ID of the PU node to be forced powered down. + * @ack Flag to specify whether acknowledge is requested + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_FORCE_POWERDOWN, target, + ack); + + if (ack == IPI_BLOCKING) + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); + else + return pm_ipi_send(primary_proc, payload); +} + +/** + * pm_system_shutdown() - PM call to request a system shutdown or restart + * @type Shutdown or restart? 0=shutdown, 1=restart, 2=setscope + * @subtype Scope: 0=APU-subsystem, 1=PS, 2=system + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + if (type == XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY) { + /* Setting scope for subsequent PSCI reboot or shutdown */ + pm_shutdown_scope = subtype; + return PM_RET_SUCCESS; + } + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_SYSTEM_SHUTDOWN, type, + subtype); + + return pm_ipi_send_non_blocking(primary_proc, payload); +} + +/** +* pm_query_data() - PM API for querying firmware data +* @qid The type of data to query +* @arg1 Argument 1 to requested query data call +* @arg2 Argument 2 to requested query data call +* @arg3 Argument 3 to requested query data call +* @data Returned output data +* +* This function returns requested data. +*/ +enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, + uint32_t arg3, uint32_t *data) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_QUERY_DATA, qid, arg1, + arg2, arg3); + return pm_ipi_send_sync(primary_proc, payload, data, 4); +} +/** + * pm_api_ioctl() - PM IOCTL API for device control and configs + * @device_id Device ID + * @ioctl_id ID of the requested IOCTL + * @arg1 Argument 1 to requested IOCTL call + * @arg2 Argument 2 to requested IOCTL call + * @value Returned output value + * + * This function calls IOCTL to firmware for device control and configuration. + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id, + uint32_t arg1, uint32_t arg2, uint32_t *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + switch (ioctl_id) { + case IOCTL_SET_PLL_FRAC_MODE: + return pm_pll_set_mode(arg1, arg2); + case IOCTL_GET_PLL_FRAC_MODE: + return pm_pll_get_mode(arg1, value); + case IOCTL_SET_PLL_FRAC_DATA: + return pm_pll_set_param(arg1, PM_PLL_PARAM_DATA, arg2); + case IOCTL_GET_PLL_FRAC_DATA: + return pm_pll_get_param(arg1, PM_PLL_PARAM_DATA, value); + default: + /* Send request to the PMC */ + PM_PACK_PAYLOAD5(payload, LIBPM_MODULE_ID, PM_IOCTL, device_id, + ioctl_id, arg1, arg2); + return pm_ipi_send_sync(primary_proc, payload, value, 1); + } +} + +/** + * pm_set_wakeup_source() - PM call to specify the wakeup source while suspended + * @target Device id of the targeted PU or subsystem + * @wkup_node Device id of the wakeup peripheral + * @enable Enable or disable the specified peripheral as wake source + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t wkup_device, + uint8_t enable) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + PM_PACK_PAYLOAD4(payload, LIBPM_MODULE_ID, PM_SET_WAKEUP_SOURCE, target, + wkup_device, enable); + return pm_ipi_send(primary_proc, payload); +} + +/** + * pm_get_chipid() - Read silicon ID registers + * @value Buffer for return values. Must be large enough + * to hold 8 bytes. + * + * @return Returns silicon ID registers + */ +enum pm_ret_status pm_get_chipid(uint32_t *value) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD1(payload, LIBPM_MODULE_ID, PM_GET_CHIPID); + + return pm_ipi_send_sync(primary_proc, payload, value, 2); +} + +/** + * pm_feature_check() - Returns the supported API version if supported + * @api_id API ID to check + * @value Returned supported API version + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version) +{ + uint32_t payload[PAYLOAD_ARG_CNT], fw_api_version; + uint32_t status; + + switch (api_id) { + case PM_GET_CALLBACK_DATA: + case PM_GET_TRUSTZONE_VERSION: + case PM_INIT_FINALIZE: + *version = (PM_API_BASE_VERSION << 16); + return PM_RET_SUCCESS; + case PM_GET_API_VERSION: + case PM_GET_DEVICE_STATUS: + case PM_GET_OP_CHARACTERISTIC: + case PM_REQ_SUSPEND: + case PM_SELF_SUSPEND: + case PM_FORCE_POWERDOWN: + case PM_ABORT_SUSPEND: + case PM_REQ_WAKEUP: + case PM_SET_WAKEUP_SOURCE: + case PM_SYSTEM_SHUTDOWN: + case PM_REQUEST_DEVICE: + case PM_RELEASE_DEVICE: + case PM_SET_REQUIREMENT: + case PM_RESET_ASSERT: + case PM_RESET_GET_STATUS: + case PM_PINCTRL_REQUEST: + case PM_PINCTRL_RELEASE: + case PM_PINCTRL_GET_FUNCTION: + case PM_PINCTRL_SET_FUNCTION: + case PM_PINCTRL_CONFIG_PARAM_GET: + case PM_PINCTRL_CONFIG_PARAM_SET: + case PM_IOCTL: + case PM_QUERY_DATA: + case PM_CLOCK_ENABLE: + case PM_CLOCK_DISABLE: + case PM_CLOCK_GETSTATE: + case PM_CLOCK_SETDIVIDER: + case PM_CLOCK_GETDIVIDER: + case PM_CLOCK_SETPARENT: + case PM_CLOCK_GETPARENT: + case PM_PLL_SET_PARAMETER: + case PM_PLL_GET_PARAMETER: + case PM_PLL_SET_MODE: + case PM_PLL_GET_MODE: + case PM_FEATURE_CHECK: + *version = (PM_API_BASE_VERSION << 16); + break; + case PM_LOAD_PDI: + *version = (PM_API_BASE_VERSION << 16); + return PM_RET_SUCCESS; + default: + *version = 0U; + return PM_RET_ERROR_NOFEATURE; + } + + PM_PACK_PAYLOAD2(payload, LIBPM_MODULE_ID, PM_FEATURE_CHECK, api_id); + + status = pm_ipi_send_sync(primary_proc, payload, &fw_api_version, 1); + if (status != PM_RET_SUCCESS) + return status; + + *version |= fw_api_version; + + return PM_RET_SUCCESS; +} + +/** + * pm_load_pdi() - Load the PDI + * + * This function provides support to load PDI from linux + * + * src: Source device of pdi(DDR, OCM, SD etc) + * address_low: lower 32-bit Linear memory space address + * address_high: higher 32-bit Linear memory space address + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_load_pdi(uint32_t src, + uint32_t address_low, uint32_t address_high) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMU */ + PM_PACK_PAYLOAD4(payload, LOADER_MODULE_ID, PM_LOAD_PDI, src, + address_high, address_low); + return pm_ipi_send_sync(primary_proc, payload, NULL, 0); +} + +/** + * pm_get_op_characteristic() - PM call to request operating characteristics + * of a device + * @device_id Device id + * @type Type of the operating characteristic + * (power, temperature and latency) + * @result Returns the operating characteristic for the requested device, + * specified by the type + * + * @return Returns status, either success or error+reason + */ +enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, + enum pm_opchar_type type, + uint32_t *result) +{ + uint32_t payload[PAYLOAD_ARG_CNT]; + + /* Send request to the PMC */ + PM_PACK_PAYLOAD3(payload, LIBPM_MODULE_ID, PM_GET_OP_CHARACTERISTIC, + device_id, type); + return pm_ipi_send_sync(primary_proc, payload, result, 1); +} diff --git a/plat/xilinx/versal/pm_service/pm_api_sys.h b/plat/xilinx/versal/pm_service/pm_api_sys.h new file mode 100644 index 000000000..4de592a2f --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_api_sys.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PM_API_SYS_H +#define PM_API_SYS_H + +#include <stdint.h> +#include "pm_defs.h" + +/********************************************************** + * PM API function declarations + **********************************************************/ + +enum pm_ret_status pm_get_api_version(unsigned int *version); +enum pm_ret_status pm_self_suspend(uint32_t nid, + unsigned int latency, + unsigned int state, + uintptr_t address); +enum pm_ret_status pm_abort_suspend(enum pm_abort_reason reason); +enum pm_ret_status pm_req_suspend(uint32_t target, + uint8_t ack, + unsigned int latency, + unsigned int state); +enum pm_ret_status pm_req_wakeup(uint32_t target, uint32_t set_address, + uintptr_t address, uint8_t ack); +enum pm_ret_status pm_set_wakeup_source(uint32_t target, uint32_t device_id, + uint8_t enable); +enum pm_ret_status pm_request_device(uint32_t device_id, uint32_t capabilities, + uint32_t qos, uint32_t ack); +enum pm_ret_status pm_release_device(uint32_t device_id); +enum pm_ret_status pm_set_requirement(uint32_t device_id, uint32_t capabilities, + uint32_t latency, uint32_t qos); +enum pm_ret_status pm_get_device_status(uint32_t device_id, uint32_t *response); +enum pm_ret_status pm_reset_assert(uint32_t reset, bool assert); +enum pm_ret_status pm_reset_get_status(uint32_t reset, uint32_t *status); +void pm_get_callbackdata(uint32_t *data, size_t count); +enum pm_ret_status pm_pinctrl_request(uint32_t pin); +enum pm_ret_status pm_pinctrl_release(uint32_t pin); +enum pm_ret_status pm_pinctrl_set_function(uint32_t pin, uint32_t function); +enum pm_ret_status pm_pinctrl_get_function(uint32_t pin, uint32_t *function); +enum pm_ret_status pm_pinctrl_set_pin_param(uint32_t pin, uint32_t param, + uint32_t value); +enum pm_ret_status pm_pinctrl_get_pin_param(uint32_t pin, uint32_t param, + uint32_t *value); +enum pm_ret_status pm_clock_enable(uint32_t clk_id); +enum pm_ret_status pm_clock_disable(uint32_t clk_id); +enum pm_ret_status pm_clock_get_state(uint32_t clk_id, uint32_t *state); +enum pm_ret_status pm_clock_set_divider(uint32_t clk_id, uint32_t divider); +enum pm_ret_status pm_clock_get_divider(uint32_t clk_id, uint32_t *divider); +enum pm_ret_status pm_clock_set_parent(uint32_t clk_id, uint32_t parent); +enum pm_ret_status pm_clock_get_parent(uint32_t clk_id, uint32_t *parent); +enum pm_ret_status pm_pll_set_param(uint32_t clk_id, uint32_t param, + uint32_t value); +enum pm_ret_status pm_pll_get_param(uint32_t clk_id, uint32_t param, + uint32_t *value); +enum pm_ret_status pm_pll_set_mode(uint32_t clk_id, uint32_t mode); +enum pm_ret_status pm_pll_get_mode(uint32_t clk_id, uint32_t *mode); +enum pm_ret_status pm_force_powerdown(uint32_t target, uint8_t ack); +enum pm_ret_status pm_system_shutdown(uint32_t type, uint32_t subtype); +enum pm_ret_status pm_api_ioctl(uint32_t device_id, uint32_t ioctl_id, + uint32_t arg1, uint32_t arg2, uint32_t *value); +enum pm_ret_status pm_query_data(uint32_t qid, uint32_t arg1, uint32_t arg2, + uint32_t arg3, uint32_t *data); +unsigned int pm_get_shutdown_scope(void); +enum pm_ret_status pm_get_chipid(uint32_t *value); +enum pm_ret_status pm_feature_check(uint32_t api_id, unsigned int *version); +enum pm_ret_status pm_load_pdi(uint32_t src, uint32_t address_low, + uint32_t address_high); +enum pm_ret_status pm_get_op_characteristic(uint32_t device_id, + enum pm_opchar_type type, + uint32_t *result); +#endif /* PM_API_SYS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_client.c b/plat/xilinx/versal/pm_service/pm_client.c new file mode 100644 index 000000000..5b47838e9 --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_client.c @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * APU specific definition of processors in the subsystem as well as functions + * for getting information about and changing state of the APU. + */ + +#include <assert.h> +#include <plat_ipi.h> +#include <platform_def.h> +#include <versal_def.h> +#include <lib/bakery_lock.h> +#include <lib/mmio.h> +#include <lib/utils.h> +#include <drivers/arm/gicv3.h> +#include <drivers/arm/gic_common.h> +#include <plat/common/platform.h> +#include "pm_api_sys.h" +#include "pm_client.h" + +#define UNDEFINED_CPUID (~0) +#define IRQ_MAX 142 +#define NUM_GICD_ISENABLER ((IRQ_MAX >> 5) + 1) + +DEFINE_BAKERY_LOCK(pm_client_secure_lock); + +static const struct pm_ipi apu_ipi = { + .local_ipi_id = IPI_ID_APU, + .remote_ipi_id = IPI_ID_PMC, + .buffer_base = IPI_BUFFER_APU_BASE, +}; + +/* Order in pm_procs_all array must match cpu ids */ +static const struct pm_proc pm_procs_all[] = { + { + .node_id = XPM_DEVID_ACPU_0, + .ipi = &apu_ipi, + .pwrdn_mask = APU_0_PWRCTL_CPUPWRDWNREQ_MASK, + }, + { + .node_id = XPM_DEVID_ACPU_1, + .ipi = &apu_ipi, + .pwrdn_mask = APU_1_PWRCTL_CPUPWRDWNREQ_MASK, + } +}; + +const struct pm_proc *primary_proc = &pm_procs_all[0]; + +/* Interrupt to PM node index map */ +static enum pm_device_node_idx irq_node_map[IRQ_MAX + 1] = { + [13] = XPM_NODEIDX_DEV_GPIO, + [14] = XPM_NODEIDX_DEV_I2C_0, + [15] = XPM_NODEIDX_DEV_I2C_1, + [16] = XPM_NODEIDX_DEV_SPI_0, + [17] = XPM_NODEIDX_DEV_SPI_1, + [18] = XPM_NODEIDX_DEV_UART_0, + [19] = XPM_NODEIDX_DEV_UART_1, + [20] = XPM_NODEIDX_DEV_CAN_FD_0, + [21] = XPM_NODEIDX_DEV_CAN_FD_1, + [22] = XPM_NODEIDX_DEV_USB_0, + [23] = XPM_NODEIDX_DEV_USB_0, + [24] = XPM_NODEIDX_DEV_USB_0, + [25] = XPM_NODEIDX_DEV_USB_0, + [26] = XPM_NODEIDX_DEV_USB_0, + [37] = XPM_NODEIDX_DEV_TTC_0, + [38] = XPM_NODEIDX_DEV_TTC_0, + [39] = XPM_NODEIDX_DEV_TTC_0, + [40] = XPM_NODEIDX_DEV_TTC_1, + [41] = XPM_NODEIDX_DEV_TTC_1, + [42] = XPM_NODEIDX_DEV_TTC_1, + [43] = XPM_NODEIDX_DEV_TTC_2, + [44] = XPM_NODEIDX_DEV_TTC_2, + [45] = XPM_NODEIDX_DEV_TTC_2, + [46] = XPM_NODEIDX_DEV_TTC_3, + [47] = XPM_NODEIDX_DEV_TTC_3, + [48] = XPM_NODEIDX_DEV_TTC_3, + [56] = XPM_NODEIDX_DEV_GEM_0, + [57] = XPM_NODEIDX_DEV_GEM_0, + [58] = XPM_NODEIDX_DEV_GEM_1, + [59] = XPM_NODEIDX_DEV_GEM_1, + [60] = XPM_NODEIDX_DEV_ADMA_0, + [61] = XPM_NODEIDX_DEV_ADMA_1, + [62] = XPM_NODEIDX_DEV_ADMA_2, + [63] = XPM_NODEIDX_DEV_ADMA_3, + [64] = XPM_NODEIDX_DEV_ADMA_4, + [65] = XPM_NODEIDX_DEV_ADMA_5, + [66] = XPM_NODEIDX_DEV_ADMA_6, + [67] = XPM_NODEIDX_DEV_ADMA_7, + [74] = XPM_NODEIDX_DEV_USB_0, + [126] = XPM_NODEIDX_DEV_SDIO_0, + [127] = XPM_NODEIDX_DEV_SDIO_0, + [128] = XPM_NODEIDX_DEV_SDIO_1, + [129] = XPM_NODEIDX_DEV_SDIO_1, + [142] = XPM_NODEIDX_DEV_RTC, +}; + +/** + * irq_to_pm_node_idx - Get PM node index corresponding to the interrupt number + * @irq: Interrupt number + * + * Return: PM node index corresponding to the specified interrupt + */ +static enum pm_device_node_idx irq_to_pm_node_idx(unsigned int irq) +{ + assert(irq <= IRQ_MAX); + return irq_node_map[irq]; +} + +/** + * pm_client_set_wakeup_sources - Set all devices with enabled interrupts as + * wake sources in the LibPM. + */ +static void pm_client_set_wakeup_sources(void) +{ + uint32_t reg_num; + uint32_t device_id; + uint8_t pm_wakeup_nodes_set[XPM_NODEIDX_DEV_MAX]; + uintptr_t isenabler1 = PLAT_VERSAL_GICD_BASE + GICD_ISENABLER + 4; + + zeromem(&pm_wakeup_nodes_set, sizeof(pm_wakeup_nodes_set)); + + for (reg_num = 0; reg_num < NUM_GICD_ISENABLER; reg_num++) { + uint32_t base_irq = reg_num << ISENABLER_SHIFT; + uint32_t reg = mmio_read_32(isenabler1 + (reg_num << 2)); + + if (!reg) + continue; + + while (reg) { + enum pm_device_node_idx node_idx; + uint32_t idx, ret, irq, lowest_set = reg & (-reg); + + idx = __builtin_ctz(lowest_set); + irq = base_irq + idx; + + if (irq > IRQ_MAX) + break; + + node_idx = irq_to_pm_node_idx(irq); + reg &= ~lowest_set; + + if ((node_idx != XPM_NODEIDX_DEV_MIN) && + (!pm_wakeup_nodes_set[node_idx])) { + /* Get device ID from node index */ + device_id = PERIPH_DEVID(node_idx); + ret = pm_set_wakeup_source(XPM_DEVID_ACPU_0, + device_id, 1); + pm_wakeup_nodes_set[node_idx] = !ret; + } + } + } +} + +/** + * pm_client_suspend() - Client-specific suspend actions + * + * This function should contain any PU-specific actions + * required prior to sending suspend request to PMU + * Actions taken depend on the state system is suspending to. + */ +void pm_client_suspend(const struct pm_proc *proc, unsigned int state) +{ + bakery_lock_get(&pm_client_secure_lock); + + if (state == PM_STATE_SUSPEND_TO_RAM) + pm_client_set_wakeup_sources(); + + /* Set powerdown request */ + mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) | + proc->pwrdn_mask); + + bakery_lock_release(&pm_client_secure_lock); +} + +/** + * pm_client_abort_suspend() - Client-specific abort-suspend actions + * + * This function should contain any PU-specific actions + * required for aborting a prior suspend request + */ +void pm_client_abort_suspend(void) +{ + /* Enable interrupts at processor level (for current cpu) */ + gicv3_cpuif_enable(plat_my_core_pos()); + + bakery_lock_get(&pm_client_secure_lock); + + /* Clear powerdown request */ + mmio_write_32(FPD_APU_PWRCTL, mmio_read_32(FPD_APU_PWRCTL) & + ~primary_proc->pwrdn_mask); + + bakery_lock_release(&pm_client_secure_lock); +} + +/** + * pm_get_cpuid() - get the local cpu ID for a global node ID + * @nid: node id of the processor + * + * Return: the cpu ID (starting from 0) for the subsystem + */ +static unsigned int pm_get_cpuid(uint32_t nid) +{ + for (size_t i = 0; i < ARRAY_SIZE(pm_procs_all); i++) { + if (pm_procs_all[i].node_id == nid) + return i; + } + return UNDEFINED_CPUID; +} + +/** + * pm_client_wakeup() - Client-specific wakeup actions + * + * This function should contain any PU-specific actions + * required for waking up another APU core + */ +void pm_client_wakeup(const struct pm_proc *proc) +{ + unsigned int cpuid = pm_get_cpuid(proc->node_id); + + if (cpuid == UNDEFINED_CPUID) + return; + + bakery_lock_get(&pm_client_secure_lock); + + /* clear powerdown bit for affected cpu */ + uint32_t val = mmio_read_32(FPD_APU_PWRCTL); + val &= ~(proc->pwrdn_mask); + mmio_write_32(FPD_APU_PWRCTL, val); + + bakery_lock_release(&pm_client_secure_lock); +} + +/** + * pm_get_proc() - returns pointer to the proc structure + * @cpuid: id of the cpu whose proc struct pointer should be returned + * + * Return: pointer to a proc structure if proc is found, otherwise NULL + */ +const struct pm_proc *pm_get_proc(unsigned int cpuid) +{ + if (cpuid < ARRAY_SIZE(pm_procs_all)) + return &pm_procs_all[cpuid]; + + return NULL; +} diff --git a/plat/xilinx/versal/pm_service/pm_defs.h b/plat/xilinx/versal/pm_service/pm_defs.h new file mode 100644 index 000000000..966b00bb5 --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_defs.h @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Versal power management enums and defines */ + +#ifndef PM_DEFS_H +#define PM_DEFS_H + +#include "pm_node.h" + +/********************************************************************* + * Macro definitions + ********************************************************************/ + +/* State arguments of the self suspend */ +#define PM_STATE_CPU_IDLE 0x0U +#define PM_STATE_SUSPEND_TO_RAM 0xFU + +#define MAX_LATENCY (~0U) +#define MAX_QOS 100U + +/* Processor core device IDs */ +#define APU_DEVID(IDX) NODEID(XPM_NODECLASS_DEVICE, XPM_NODESUBCL_DEV_CORE, \ + XPM_NODETYPE_DEV_CORE_APU, (IDX)) + +#define XPM_DEVID_ACPU_0 APU_DEVID(XPM_NODEIDX_DEV_ACPU_0) +#define XPM_DEVID_ACPU_1 APU_DEVID(XPM_NODEIDX_DEV_ACPU_1) + +#define PERIPH_DEVID(IDX) NODEID(XPM_NODECLASS_DEVICE, \ + XPM_NODESUBCL_DEV_PERIPH, \ + XPM_NODETYPE_DEV_PERIPH, (IDX)) + +#define PM_GET_CALLBACK_DATA 0xa01 +#define PM_GET_TRUSTZONE_VERSION 0xa03 + +/* PM API Versions */ +#define PM_API_BASE_VERSION 1U + +/* PM API ids */ +#define PM_GET_API_VERSION 1U +#define PM_GET_DEVICE_STATUS 3U +#define PM_GET_OP_CHARACTERISTIC 4U +#define PM_REQ_SUSPEND 6U +#define PM_SELF_SUSPEND 7U +#define PM_FORCE_POWERDOWN 8U +#define PM_ABORT_SUSPEND 9U +#define PM_REQ_WAKEUP 10U +#define PM_SET_WAKEUP_SOURCE 11U +#define PM_SYSTEM_SHUTDOWN 12U +#define PM_REQUEST_DEVICE 13U +#define PM_RELEASE_DEVICE 14U +#define PM_SET_REQUIREMENT 15U +#define PM_RESET_ASSERT 17U +#define PM_RESET_GET_STATUS 18U +#define PM_INIT_FINALIZE 21U +#define PM_GET_CHIPID 24U +#define PM_PINCTRL_REQUEST 28U +#define PM_PINCTRL_RELEASE 29U +#define PM_PINCTRL_GET_FUNCTION 30U +#define PM_PINCTRL_SET_FUNCTION 31U +#define PM_PINCTRL_CONFIG_PARAM_GET 32U +#define PM_PINCTRL_CONFIG_PARAM_SET 33U +#define PM_IOCTL 34U +#define PM_QUERY_DATA 35U +#define PM_CLOCK_ENABLE 36U +#define PM_CLOCK_DISABLE 37U +#define PM_CLOCK_GETSTATE 38U +#define PM_CLOCK_SETDIVIDER 39U +#define PM_CLOCK_GETDIVIDER 40U +#define PM_CLOCK_SETRATE 41U +#define PM_CLOCK_GETRATE 42U +#define PM_CLOCK_SETPARENT 43U +#define PM_CLOCK_GETPARENT 44U +#define PM_PLL_SET_PARAMETER 48U +#define PM_PLL_GET_PARAMETER 49U +#define PM_PLL_SET_MODE 50U +#define PM_PLL_GET_MODE 51U +#define PM_FEATURE_CHECK 63U + +/* Loader API ids */ +#define PM_LOAD_PDI 0x701U + +/* IOCTL IDs for clock driver */ +#define IOCTL_SET_PLL_FRAC_MODE 8 +#define IOCTL_GET_PLL_FRAC_MODE 9 +#define IOCTL_SET_PLL_FRAC_DATA 10 +#define IOCTL_GET_PLL_FRAC_DATA 11 + +/* Parameter ID for PLL IOCTLs */ +/* Fractional data portion for PLL */ +#define PM_PLL_PARAM_DATA 2 + +/* System shutdown macros */ +#define XPM_SHUTDOWN_TYPE_SHUTDOWN 0U +#define XPM_SHUTDOWN_TYPE_RESET 1U +#define XPM_SHUTDOWN_TYPE_SETSCOPE_ONLY 2U + +#define XPM_SHUTDOWN_SUBTYPE_RST_SUBSYSTEM 0U +#define XPM_SHUTDOWN_SUBTYPE_RST_PS_ONLY 1U +#define XPM_SHUTDOWN_SUBTYPE_RST_SYSTEM 2U + +/********************************************************************* + * Enum definitions + ********************************************************************/ + +enum pm_abort_reason { + ABORT_REASON_WKUP_EVENT = 100, + ABORT_REASON_PU_BUSY, + ABORT_REASON_NO_PWRDN, + ABORT_REASON_UNKNOWN, +}; + +enum pm_opchar_type { + PM_OPCHAR_TYPE_POWER = 1, + PM_OPCHAR_TYPE_TEMP, + PM_OPCHAR_TYPE_LATENCY, +}; + +/** + * Subsystem IDs + */ +typedef enum { + XPM_SUBSYSID_PMC, + XPM_SUBSYSID_PSM, + XPM_SUBSYSID_APU, + XPM_SUBSYSID_RPU0_LOCK, + XPM_SUBSYSID_RPU0_0, + XPM_SUBSYSID_RPU0_1, + XPM_SUBSYSID_DDR0, + XPM_SUBSYSID_ME, + XPM_SUBSYSID_PL, + XPM_SUBSYSID_MAX, +} XPm_SubsystemId; + +/** + * @PM_RET_SUCCESS: success + * @PM_RET_ERROR_ARGS: illegal arguments provided (deprecated) + * @PM_RET_ERROR_NOTSUPPORTED: feature not supported (deprecated) + * @PM_RET_ERROR_NOFEATURE: feature is not available + * @PM_RET_ERROR_INTERNAL: internal error + * @PM_RET_ERROR_CONFLICT: conflict + * @PM_RET_ERROR_ACCESS: access rights violation + * @PM_RET_ERROR_INVALID_NODE: invalid node + * @PM_RET_ERROR_DOUBLE_REQ: duplicate request for same node + * @PM_RET_ERROR_ABORT_SUSPEND: suspend procedure has been aborted + * @PM_RET_ERROR_TIMEOUT: timeout in communication with PMU + * @PM_RET_ERROR_NODE_USED: node is already in use + */ +enum pm_ret_status { + PM_RET_SUCCESS, + PM_RET_ERROR_ARGS = 1, + PM_RET_ERROR_NOTSUPPORTED = 4, + PM_RET_ERROR_NOFEATURE = 19, + PM_RET_ERROR_INTERNAL = 2000, + PM_RET_ERROR_CONFLICT = 2001, + PM_RET_ERROR_ACCESS = 2002, + PM_RET_ERROR_INVALID_NODE = 2003, + PM_RET_ERROR_DOUBLE_REQ = 2004, + PM_RET_ERROR_ABORT_SUSPEND = 2005, + PM_RET_ERROR_TIMEOUT = 2006, + PM_RET_ERROR_NODE_USED = 2007 +}; +#endif /* PM_DEFS_H */ diff --git a/plat/xilinx/versal/pm_service/pm_node.h b/plat/xilinx/versal/pm_service/pm_node.h new file mode 100644 index 000000000..1b82ec70d --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_node.h @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* Versal PM nodes enums and defines */ + +#ifndef PM_NODE_H +#define PM_NODE_H + +/********************************************************************* + * Macro definitions + ********************************************************************/ + +#define NODE_CLASS_SHIFT 26U +#define NODE_SUBCLASS_SHIFT 20U +#define NODE_TYPE_SHIFT 14U +#define NODE_INDEX_SHIFT 0U +#define NODE_CLASS_MASK_BITS 0x3F +#define NODE_SUBCLASS_MASK_BITS 0x3F +#define NODE_TYPE_MASK_BITS 0x3F +#define NODE_INDEX_MASK_BITS 0x3FFF +#define NODE_CLASS_MASK (NODE_CLASS_MASK_BITS << NODE_CLASS_SHIFT) +#define NODE_SUBCLASS_MASK (NODE_SUBCLASS_MASK_BITS << NODE_SUBCLASS_SHIFT) +#define NODE_TYPE_MASK (NODE_TYPE_MASK_BITS << NODE_TYPE_SHIFT) +#define NODE_INDEX_MASK (NODE_INDEX_MASK_BITS << NODE_INDEX_SHIFT) + +#define NODEID(CLASS, SUBCLASS, TYPE, INDEX) \ + ((((CLASS) & NODE_CLASS_MASK_BITS) << NODE_CLASS_SHIFT) | \ + (((SUBCLASS) & NODE_SUBCLASS_MASK_BITS) << NODE_SUBCLASS_SHIFT) | \ + (((TYPE) & NODE_TYPE_MASK_BITS) << NODE_TYPE_SHIFT) | \ + (((INDEX) & NODE_INDEX_MASK_BITS) << NODE_INDEX_SHIFT)) + +#define NODECLASS(ID) (((ID) & NODE_CLASS_MASK) >> NODE_CLASS_SHIFT) +#define NODESUBCLASS(ID) (((ID) & NODE_SUBCLASS_MASK) >> \ + NODE_SUBCLASS_SHIFT) +#define NODETYPE(ID) (((ID) & NODE_TYPE_MASK) >> NODE_TYPE_SHIFT) +#define NODEINDEX(ID) (((ID) & NODE_INDEX_MASK) >> NODE_INDEX_SHIFT) + +/********************************************************************* + * Enum definitions + ********************************************************************/ + +/* Node class types */ +enum pm_node_class { + XPM_NODECLASS_MIN, + + XPM_NODECLASS_POWER, + XPM_NODECLASS_CLOCK, + XPM_NODECLASS_RESET, + XPM_NODECLASS_MEMIC, + XPM_NODECLASS_STMIC, + XPM_NODECLASS_DEVICE, + + XPM_NODECLASS_MAX +}; + +enum pm_device_node_subclass { + /* Device types */ + XPM_NODESUBCL_DEV_CORE = 1, + XPM_NODESUBCL_DEV_PERIPH, + XPM_NODESUBCL_DEV_MEM, + XPM_NODESUBCL_DEV_SOC, + XPM_NODESUBCL_DEV_MEM_CTRLR, + XPM_NODESUBCL_DEV_PHY, +}; + +enum pm_device_node_type { + /* Device types */ + XPM_NODETYPE_DEV_CORE_PMC = 1, + XPM_NODETYPE_DEV_CORE_PSM, + XPM_NODETYPE_DEV_CORE_APU, + XPM_NODETYPE_DEV_CORE_RPU, + XPM_NODETYPE_DEV_OCM, + XPM_NODETYPE_DEV_TCM, + XPM_NODETYPE_DEV_L2CACHE, + XPM_NODETYPE_DEV_DDR, + XPM_NODETYPE_DEV_PERIPH, + XPM_NODETYPE_DEV_SOC, + XPM_NODETYPE_DEV_GT, +}; + +/* Device node Indexes */ +enum pm_device_node_idx { + /* Device nodes */ + XPM_NODEIDX_DEV_MIN, + + /* Processor devices */ + XPM_NODEIDX_DEV_PMC_PROC, + XPM_NODEIDX_DEV_PSM_PROC, + XPM_NODEIDX_DEV_ACPU_0, + XPM_NODEIDX_DEV_ACPU_1, + XPM_NODEIDX_DEV_RPU0_0, + XPM_NODEIDX_DEV_RPU0_1, + + /* Memory devices */ + XPM_NODEIDX_DEV_OCM_0, + XPM_NODEIDX_DEV_OCM_1, + XPM_NODEIDX_DEV_OCM_2, + XPM_NODEIDX_DEV_OCM_3, + XPM_NODEIDX_DEV_TCM_0_A, + XPM_NODEIDX_DEV_TCM_0_B, + XPM_NODEIDX_DEV_TCM_1_A, + XPM_NODEIDX_DEV_TCM_1_B, + XPM_NODEIDX_DEV_L2_BANK_0, + XPM_NODEIDX_DEV_DDR_0, + XPM_NODEIDX_DEV_DDR_1, + XPM_NODEIDX_DEV_DDR_2, + XPM_NODEIDX_DEV_DDR_3, + XPM_NODEIDX_DEV_DDR_4, + XPM_NODEIDX_DEV_DDR_5, + XPM_NODEIDX_DEV_DDR_6, + XPM_NODEIDX_DEV_DDR_7, + + /* LPD Peripheral devices */ + XPM_NODEIDX_DEV_USB_0, + XPM_NODEIDX_DEV_GEM_0, + XPM_NODEIDX_DEV_GEM_1, + XPM_NODEIDX_DEV_SPI_0, + XPM_NODEIDX_DEV_SPI_1, + XPM_NODEIDX_DEV_I2C_0, + XPM_NODEIDX_DEV_I2C_1, + XPM_NODEIDX_DEV_CAN_FD_0, + XPM_NODEIDX_DEV_CAN_FD_1, + XPM_NODEIDX_DEV_UART_0, + XPM_NODEIDX_DEV_UART_1, + XPM_NODEIDX_DEV_GPIO, + XPM_NODEIDX_DEV_TTC_0, + XPM_NODEIDX_DEV_TTC_1, + XPM_NODEIDX_DEV_TTC_2, + XPM_NODEIDX_DEV_TTC_3, + XPM_NODEIDX_DEV_SWDT_LPD, + + /* FPD Peripheral devices */ + XPM_NODEIDX_DEV_SWDT_FPD, + + /* PMC Peripheral devices */ + XPM_NODEIDX_DEV_OSPI, + XPM_NODEIDX_DEV_QSPI, + XPM_NODEIDX_DEV_GPIO_PMC, + XPM_NODEIDX_DEV_I2C_PMC, + XPM_NODEIDX_DEV_SDIO_0, + XPM_NODEIDX_DEV_SDIO_1, + + XPM_NODEIDX_DEV_PL_0, + XPM_NODEIDX_DEV_PL_1, + XPM_NODEIDX_DEV_PL_2, + XPM_NODEIDX_DEV_PL_3, + XPM_NODEIDX_DEV_RTC, + XPM_NODEIDX_DEV_ADMA_0, + XPM_NODEIDX_DEV_ADMA_1, + XPM_NODEIDX_DEV_ADMA_2, + XPM_NODEIDX_DEV_ADMA_3, + XPM_NODEIDX_DEV_ADMA_4, + XPM_NODEIDX_DEV_ADMA_5, + XPM_NODEIDX_DEV_ADMA_6, + XPM_NODEIDX_DEV_ADMA_7, + XPM_NODEIDX_DEV_IPI_0, + XPM_NODEIDX_DEV_IPI_1, + XPM_NODEIDX_DEV_IPI_2, + XPM_NODEIDX_DEV_IPI_3, + XPM_NODEIDX_DEV_IPI_4, + XPM_NODEIDX_DEV_IPI_5, + XPM_NODEIDX_DEV_IPI_6, + + /* Entire SoC */ + XPM_NODEIDX_DEV_SOC, + + /* DDR memory controllers */ + XPM_NODEIDX_DEV_DDRMC_0, + XPM_NODEIDX_DEV_DDRMC_1, + XPM_NODEIDX_DEV_DDRMC_2, + XPM_NODEIDX_DEV_DDRMC_3, + + /* GT devices */ + XPM_NODEIDX_DEV_GT_0, + XPM_NODEIDX_DEV_GT_1, + XPM_NODEIDX_DEV_GT_2, + XPM_NODEIDX_DEV_GT_3, + XPM_NODEIDX_DEV_GT_4, + XPM_NODEIDX_DEV_GT_5, + XPM_NODEIDX_DEV_GT_6, + XPM_NODEIDX_DEV_GT_7, + XPM_NODEIDX_DEV_GT_8, + XPM_NODEIDX_DEV_GT_9, + XPM_NODEIDX_DEV_GT_10, + + XPM_NODEIDX_DEV_MAX +}; + +#endif /* PM_NODE_H */ diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.c b/plat/xilinx/versal/pm_service/pm_svc_main.c new file mode 100644 index 000000000..a3a9f4316 --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_svc_main.c @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Top-level SMC handler for Versal power management calls and + * IPI setup functions for communication with PMC. + */ + +#include <errno.h> +#include <plat_private.h> +#include <stdbool.h> +#include <common/runtime_svc.h> +#include "pm_api_sys.h" +#include "pm_client.h" +#include "pm_ipi.h" + +/* pm_up = true - UP, pm_up = false - DOWN */ +static bool pm_up; + +/** + * pm_setup() - PM service setup + * + * @return On success, the initialization function must return 0. + * Any other return value will cause the framework to ignore + * the service + * + * Initialization functions for Versal power management for + * communicaton with PMC. + * + * Called from sip_svc_setup initialization function with the + * rt_svc_init signature. + */ +int pm_setup(void) +{ + int status, ret = 0; + + status = pm_ipi_init(primary_proc); + + if (status < 0) { + INFO("BL31: PM Service Init Failed, Error Code %d!\n", status); + ret = status; + } else { + pm_up = true; + } + + return ret; +} + +/** + * pm_smc_handler() - SMC handler for PM-API calls coming from EL1/EL2. + * @smc_fid - Function Identifier + * @x1 - x4 - Arguments + * @cookie - Unused + * @handler - Pointer to caller's context structure + * + * @return - Unused + * + * Determines that smc_fid is valid and supported PM SMC Function ID from the + * list of pm_api_ids, otherwise completes the request with + * the unknown SMC Function ID + * + * The SMC calls for PM service are forwarded from SIP Service SMC handler + * function with rt_svc_handle signature + */ +uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, uint64_t flags) +{ + enum pm_ret_status ret; + + uint32_t pm_arg[4]; + + /* Handle case where PM wasn't initialized properly */ + if (!pm_up) + SMC_RET1(handle, SMC_UNK); + + pm_arg[0] = (uint32_t)x1; + pm_arg[1] = (uint32_t)(x1 >> 32); + pm_arg[2] = (uint32_t)x2; + pm_arg[3] = (uint32_t)(x2 >> 32); + + switch (smc_fid & FUNCID_NUM_MASK) { + /* PM API Functions */ + case PM_SELF_SUSPEND: + ret = pm_self_suspend(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_FORCE_POWERDOWN: + ret = pm_force_powerdown(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_REQ_SUSPEND: + ret = pm_req_suspend(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_ABORT_SUSPEND: + ret = pm_abort_suspend(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_SYSTEM_SHUTDOWN: + ret = pm_system_shutdown(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_REQ_WAKEUP: + ret = pm_req_wakeup(pm_arg[0], pm_arg[1], pm_arg[2], pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_SET_WAKEUP_SOURCE: + ret = pm_set_wakeup_source(pm_arg[0], pm_arg[1], pm_arg[2]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_REQUEST_DEVICE: + ret = pm_request_device(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_RELEASE_DEVICE: + ret = pm_release_device(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_SET_REQUIREMENT: + ret = pm_set_requirement(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_GET_API_VERSION: + { + uint32_t api_version; + + ret = pm_get_api_version(&api_version); + SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS | + ((uint64_t)api_version << 32)); + } + + case PM_GET_DEVICE_STATUS: + { + uint32_t buff[3]; + + ret = pm_get_device_status(pm_arg[0], buff); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)buff[0] << 32), + (uint64_t)buff[1] | ((uint64_t)buff[2] << 32)); + } + + case PM_RESET_ASSERT: + ret = pm_reset_assert(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_RESET_GET_STATUS: + { + uint32_t reset_status; + + ret = pm_reset_get_status(pm_arg[0], &reset_status); + SMC_RET1(handle, (uint64_t)ret | + ((uint64_t)reset_status << 32)); + } + + case PM_INIT_FINALIZE: + SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS); + + case PM_GET_CALLBACK_DATA: + { + uint32_t result[4] = {0}; + + pm_get_callbackdata(result, sizeof(result)); + SMC_RET2(handle, + (uint64_t)result[0] | ((uint64_t)result[1] << 32), + (uint64_t)result[2] | ((uint64_t)result[3] << 32)); + } + + case PM_PINCTRL_REQUEST: + ret = pm_pinctrl_request(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_PINCTRL_RELEASE: + ret = pm_pinctrl_release(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_PINCTRL_GET_FUNCTION: + { + uint32_t value = 0; + + ret = pm_pinctrl_get_function(pm_arg[0], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_PINCTRL_SET_FUNCTION: + ret = pm_pinctrl_set_function(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_PINCTRL_CONFIG_PARAM_GET: + { + uint32_t value; + + ret = pm_pinctrl_get_pin_param(pm_arg[0], pm_arg[1], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_PINCTRL_CONFIG_PARAM_SET: + ret = pm_pinctrl_set_pin_param(pm_arg[0], pm_arg[1], pm_arg[2]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_IOCTL: + { + uint32_t value; + + ret = pm_api_ioctl(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_QUERY_DATA: + { + uint32_t data[4] = { 0 }; + + ret = pm_query_data(pm_arg[0], pm_arg[1], pm_arg[2], + pm_arg[3], data); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)data[0] << 32), + (uint64_t)data[1] | ((uint64_t)data[2] << 32)); + } + + case PM_CLOCK_ENABLE: + ret = pm_clock_enable(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_CLOCK_DISABLE: + ret = pm_clock_disable(pm_arg[0]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_CLOCK_GETSTATE: + { + uint32_t value; + + ret = pm_clock_get_state(pm_arg[0], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_CLOCK_SETDIVIDER: + ret = pm_clock_set_divider(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_CLOCK_GETDIVIDER: + { + uint32_t value; + + ret = pm_clock_get_divider(pm_arg[0], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_CLOCK_SETPARENT: + ret = pm_clock_set_parent(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_CLOCK_GETPARENT: + { + uint32_t value; + + ret = pm_clock_get_parent(pm_arg[0], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value) << 32); + } + + case PM_PLL_SET_PARAMETER: + ret = pm_pll_set_param(pm_arg[0], pm_arg[1], pm_arg[2]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_PLL_GET_PARAMETER: + { + uint32_t value; + + ret = pm_pll_get_param(pm_arg[0], pm_arg[1], &value); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)value << 32)); + } + + case PM_PLL_SET_MODE: + ret = pm_pll_set_mode(pm_arg[0], pm_arg[1]); + SMC_RET1(handle, (uint64_t)ret); + + case PM_PLL_GET_MODE: + { + uint32_t mode; + + ret = pm_pll_get_mode(pm_arg[0], &mode); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)mode << 32)); + } + + case PM_GET_TRUSTZONE_VERSION: + SMC_RET1(handle, (uint64_t)PM_RET_SUCCESS | + ((uint64_t)VERSAL_TZ_VERSION << 32)); + + case PM_GET_CHIPID: + { + uint32_t result[2]; + + ret = pm_get_chipid(result); + SMC_RET2(handle, (uint64_t)ret | ((uint64_t)result[0] << 32), + result[1]); + } + + case PM_FEATURE_CHECK: + { + uint32_t version; + + ret = pm_feature_check(pm_arg[0], &version); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)version << 32)); + } + + case PM_LOAD_PDI: + { + ret = pm_load_pdi(pm_arg[0], pm_arg[1], pm_arg[2]); + SMC_RET1(handle, (uint64_t)ret); + } + + case PM_GET_OP_CHARACTERISTIC: + { + uint32_t result; + + ret = pm_get_op_characteristic(pm_arg[0], pm_arg[1], &result); + SMC_RET1(handle, (uint64_t)ret | ((uint64_t)result << 32)); + } + + default: + WARN("Unimplemented PM Service Call: 0x%x\n", smc_fid); + SMC_RET1(handle, SMC_UNK); + } +} diff --git a/plat/xilinx/versal/pm_service/pm_svc_main.h b/plat/xilinx/versal/pm_service/pm_svc_main.h new file mode 100644 index 000000000..71329ca93 --- /dev/null +++ b/plat/xilinx/versal/pm_service/pm_svc_main.h @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#ifndef PM_SVC_MAIN_H +#define PM_SVC_MAIN_H + +#include <pm_common.h> + +int pm_setup(void); +uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, + uint64_t x4, void *cookie, void *handle, + uint64_t flags); + +#endif /* PM_SVC_MAIN_H */ diff --git a/plat/xilinx/versal/sip_svc_setup.c b/plat/xilinx/versal/sip_svc_setup.c index 8f2180b21..bc7d8b7af 100644 --- a/plat/xilinx/versal/sip_svc_setup.c +++ b/plat/xilinx/versal/sip_svc_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -10,6 +10,9 @@ #include <common/runtime_svc.h> #include <tools_share/uuid.h> +#include "ipi_mailbox_svc.h" +#include "pm_svc_main.h" + /* SMC function IDs for SiP Service queries */ #define VERSAL_SIP_SVC_CALL_COUNT 0x8200ff00 #define VERSAL_SIP_SVC_UID 0x8200ff01 @@ -22,7 +25,9 @@ /* These macros are used to identify PM calls from the SMC function ID */ #define PM_FID_MASK 0xf000u #define PM_FID_VALUE 0u +#define IPI_FID_VALUE 0x1000u #define is_pm_fid(_fid) (((_fid) & PM_FID_MASK) == PM_FID_VALUE) +#define is_ipi_fid(_fid) (((_fid) & PM_FID_MASK) == IPI_FID_VALUE) /* SiP Service UUID */ DEFINE_SVC_UUID2(versal_sip_uuid, @@ -36,6 +41,9 @@ DEFINE_SVC_UUID2(versal_sip_uuid, */ static int32_t sip_svc_setup(void) { + /* PM implementation as SiP Service */ + pm_setup(); + return 0; } @@ -55,6 +63,18 @@ uintptr_t sip_svc_smc_handler(uint32_t smc_fid, u_register_t flags) { /* Let PM SMC handler deal with PM-related requests */ + if (is_pm_fid(smc_fid)) { + return pm_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, + flags); + } + + /* Let IPI SMC handler deal with IPI-related requests */ + if (is_ipi_fid(smc_fid)) { + return ipi_smc_handler(smc_fid, x1, x2, x3, x4, cookie, handle, + flags); + } + + /* Let PM SMC handler deal with PM-related requests */ switch (smc_fid) { case VERSAL_SIP_SVC_CALL_COUNT: /* PM functions + default functions */ diff --git a/plat/xilinx/versal/versal_gicv3.c b/plat/xilinx/versal/versal_gicv3.c index dcf23b425..08e7cf95a 100644 --- a/plat/xilinx/versal/versal_gicv3.c +++ b/plat/xilinx/versal/versal_gicv3.c @@ -1,9 +1,10 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <plat_private.h> #include <platform_def.h> #include <common/interrupt_props.h> @@ -11,8 +12,6 @@ #include <lib/utils.h> #include <plat/common/platform.h> -#include "versal_private.h" - /****************************************************************************** * The following functions are defined as weak to allow a platform to override * the way the GICv3 driver is initialised and used. diff --git a/plat/xilinx/versal/versal_ipi.c b/plat/xilinx/versal/versal_ipi.c new file mode 100644 index 000000000..27541ff4b --- /dev/null +++ b/plat/xilinx/versal/versal_ipi.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2019, Xilinx, Inc. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/* + * Versal IPI agent registers access management + */ + +#include <errno.h> +#include <ipi.h> +#include <plat_ipi.h> +#include <plat_private.h> +#include <string.h> +#include <common/debug.h> +#include <common/runtime_svc.h> +#include <lib/bakery_lock.h> +#include <lib/mmio.h> + +/* versal ipi configuration table */ +const static struct ipi_config versal_ipi_table[] = { + /* A72 IPI */ + [IPI_ID_APU] = { + .ipi_bit_mask = IPI0_TRIG_BIT, + .ipi_reg_base = IPI0_REG_BASE, + .secure_only = 0, + }, + + /* PMC IPI */ + [IPI_ID_PMC] = { + .ipi_bit_mask = PMC_IPI_TRIG_BIT, + .ipi_reg_base = IPI0_REG_BASE, + .secure_only = 0, + }, + + /* RPU0 IPI */ + [IPI_ID_RPU0] = { + .ipi_bit_mask = IPI1_TRIG_BIT, + .ipi_reg_base = IPI1_REG_BASE, + .secure_only = 0, + }, + + /* RPU1 IPI */ + [IPI_ID_RPU1] = { + .ipi_bit_mask = IPI2_TRIG_BIT, + .ipi_reg_base = IPI2_REG_BASE, + .secure_only = 0, + }, + + /* IPI3 IPI */ + [IPI_ID_3] = { + .ipi_bit_mask = IPI3_TRIG_BIT, + .ipi_reg_base = IPI3_REG_BASE, + .secure_only = 0, + }, + + /* IPI4 IPI */ + [IPI_ID_4] = { + .ipi_bit_mask = IPI4_TRIG_BIT, + .ipi_reg_base = IPI4_REG_BASE, + .secure_only = 0, + }, + + /* IPI5 IPI */ + [IPI_ID_5] = { + .ipi_bit_mask = IPI5_TRIG_BIT, + .ipi_reg_base = IPI5_REG_BASE, + .secure_only = 0, + }, +}; + +/* versal_ipi_config_table_init() - Initialize versal IPI configuration data + * + * @ipi_config_table - IPI configuration table + * @ipi_total - Total number of IPI available + * + */ +void versal_ipi_config_table_init(void) +{ + ipi_config_table_init(versal_ipi_table, ARRAY_SIZE(versal_ipi_table)); +} diff --git a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c index 8ff6c4360..d6313a68f 100644 --- a/plat/xilinx/zynqmp/aarch64/zynqmp_common.c +++ b/plat/xilinx/zynqmp/aarch64/zynqmp_common.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -11,6 +11,7 @@ #include <drivers/generic_delay_timer.h> #include <lib/mmio.h> #include <lib/xlat_tables/xlat_tables.h> +#include <plat_ipi.h> #include <plat_private.h> #include <plat/common/platform.h> @@ -188,6 +189,18 @@ static const struct { .id = 0x65, .name = "25DR", }, + { + .id = 0x66, + .name = "39DR", + }, + { + .id = 0x7b, + .name = "48DR", + }, + { + .id = 0x7e, + .name = "49DR", + }, }; #define ZYNQMP_PL_STATUS_BIT 9 @@ -325,6 +338,9 @@ unsigned int zynqmp_get_bootmode(void) void zynqmp_config_setup(void) { + /* Configure IPI data for ZynqMP */ + zynqmp_ipi_config_table_init(); + zynqmp_print_platform_name(); generic_delay_timer_init(); } @@ -334,7 +350,7 @@ unsigned int plat_get_syscnt_freq2(void) unsigned int ver = zynqmp_get_silicon_ver(); if (ver == ZYNQMP_CSU_VERSION_QEMU) - return 50000000; + return 65000000; else return mmio_read_32(IOU_SCNTRS_BASEFREQ); } diff --git a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c index 285a4eb8b..6e0e811d4 100644 --- a/plat/xilinx/zynqmp/bl31_zynqmp_setup.c +++ b/plat/xilinx/zynqmp/bl31_zynqmp_setup.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -13,8 +13,11 @@ #include <drivers/console.h> #include <plat/arm/common/plat_arm.h> #include <plat/common/platform.h> +#include <lib/mmio.h> +#include <plat_startup.h> #include <plat_private.h> +#include <zynqmp_def.h> static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; @@ -57,6 +60,7 @@ static inline void bl31_set_default_config(void) void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, u_register_t arg2, u_register_t arg3) { + uint64_t atf_handoff_addr; /* Register the console to provide early debug support */ static console_cdns_t bl31_boot_console; (void)console_cdns_register(ZYNQMP_UART_BASE, @@ -86,12 +90,15 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, SET_PARAM_HEAD(&bl33_image_ep_info, PARAM_EP, VERSION_1, 0); SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); + atf_handoff_addr = mmio_read_32(PMU_GLOBAL_GEN_STORAGE6); + if (zynqmp_get_bootmode() == ZYNQMP_BOOTMODE_JTAG) { bl31_set_default_config(); } else { /* use parameters from FSBL */ enum fsbl_handoff ret = fsbl_atf_handover(&bl32_image_ep_info, - &bl33_image_ep_info); + &bl33_image_ep_info, + atf_handoff_addr); if (ret == FSBL_HANDOFF_NO_STRUCT) bl31_set_default_config(); else if (ret != FSBL_HANDOFF_SUCCESS) diff --git a/plat/xilinx/zynqmp/include/plat_pm_common.h b/plat/xilinx/zynqmp/include/plat_pm_common.h index 1b371cc36..56a747a4f 100644 --- a/plat/xilinx/zynqmp/include/plat_pm_common.h +++ b/plat/xilinx/zynqmp/include/plat_pm_common.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -16,7 +16,16 @@ #include <common/debug.h> #include "pm_defs.h" -#define PAYLOAD_ARG_CNT 6U +#if ZYNQMP_IPI_CRC_CHECK +#define PAYLOAD_ARG_CNT 8U +#define IPI_W0_TO_W6_SIZE 28U +#define PAYLOAD_CRC_POS 7U +#define CRC_INIT_VALUE 0x4F4EU +#define CRC_ORDER 16U +#define CRC_POLYNOM 0x8005U +#else +#define PAYLOAD_ARG_CNT 6U +#endif #define PAYLOAD_ARG_SIZE 4U /* size in bytes */ #define ZYNQMP_TZ_VERSION_MAJOR 1 diff --git a/plat/xilinx/zynqmp/include/plat_private.h b/plat/xilinx/zynqmp/include/plat_private.h index 8bdf42967..288cc5301 100644 --- a/plat/xilinx/zynqmp/include/plat_private.h +++ b/plat/xilinx/zynqmp/include/plat_private.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,13 +21,6 @@ unsigned int zynqmp_calc_core_pos(u_register_t mpidr); unsigned int zynqmp_get_uart_clk(void); unsigned int zynqmp_get_bootmode(void); -/* For FSBL handover */ -enum fsbl_handoff { - FSBL_HANDOFF_SUCCESS = 0, - FSBL_HANDOFF_NO_STRUCT, - FSBL_HANDOFF_INVAL_STRUCT, - FSBL_HANDOFF_TOO_MANY_PARTS, -}; #if ZYNQMP_WDT_RESTART /* @@ -37,7 +30,4 @@ enum fsbl_handoff { int request_intr_type_el3(uint32_t, interrupt_type_handler_t); #endif -enum fsbl_handoff fsbl_atf_handover(entry_point_info_t *bl32_image_ep_info, - entry_point_info_t *bl33_image_ep_info); - #endif /* PLAT_PRIVATE_H */ diff --git a/plat/xilinx/zynqmp/include/platform_def.h b/plat/xilinx/zynqmp/include/platform_def.h index 7b062fcaa..27968409e 100644 --- a/plat/xilinx/zynqmp/include/platform_def.h +++ b/plat/xilinx/zynqmp/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -21,8 +21,8 @@ /* Size of cacheable stacks */ #define PLATFORM_STACK_SIZE 0x440 -#define PLATFORM_CORE_COUNT 4 -#define PLAT_NUM_POWER_DOMAINS 5 +#define PLATFORM_CORE_COUNT U(4) +#define PLAT_NUM_POWER_DOMAINS U(5) #define PLAT_MAX_PWR_LVL U(1) #define PLAT_MAX_RET_STATE U(1) #define PLAT_MAX_OFF_STATE U(2) diff --git a/plat/xilinx/zynqmp/include/zynqmp_def.h b/plat/xilinx/zynqmp/include/zynqmp_def.h index 8648b9ab2..5d335d945 100644 --- a/plat/xilinx/zynqmp/include/zynqmp_def.h +++ b/plat/xilinx/zynqmp/include/zynqmp_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2014-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -330,6 +330,7 @@ #define IOU_SLCR_GEM_CLK_CTRL (IOU_SLCR_BASEADDR + 0x308) #define IOU_SLCR_CAN_MIO_CTRL (IOU_SLCR_BASEADDR + 0x304) #define FPD_SLCR_WDT_CLK_SEL (FPD_SLCR_BASEADDR + 0x100) +#define IOU_SLCR_WDT_CLK_SEL (IOU_SLCR_BASEADDR + 0x300) /* Global general storage register base address */ #define GGS_BASEADDR (0xFFD80030U) diff --git a/plat/xilinx/zynqmp/plat_psci.c b/plat/xilinx/zynqmp/plat_psci.c index a32e08988..f579f795f 100644 --- a/plat/xilinx/zynqmp/plat_psci.c +++ b/plat/xilinx/zynqmp/plat_psci.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2016, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -100,9 +100,8 @@ static void zynqmp_pwr_domain_on_finish(const psci_power_state_t *target_state) for (size_t i = 0; i <= PLAT_MAX_PWR_LVL; i++) VERBOSE("%s: target_state->pwr_domain_state[%lu]=%x\n", __func__, i, target_state->pwr_domain_state[i]); - + plat_arm_gic_pcpu_init(); gicv2_cpuif_enable(); - gicv2_pcpu_distif_init(); } static void zynqmp_pwr_domain_suspend_finish(const psci_power_state_t *target_state) diff --git a/plat/xilinx/zynqmp/platform.mk b/plat/xilinx/zynqmp/platform.mk index bd7bc08da..44f20f69f 100644 --- a/plat/xilinx/zynqmp/platform.mk +++ b/plat/xilinx/zynqmp/platform.mk @@ -1,5 +1,5 @@ # -# Copyright (c) 2013-2019, ARM Limited and Contributors. All rights reserved. +# Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. # # SPDX-License-Identifier: BSD-3-Clause @@ -9,7 +9,10 @@ PSCI_EXTENDED_STATE_ID := 1 A53_DISABLE_NON_TEMPORAL_HINT := 0 SEPARATE_CODE_AND_RODATA := 1 ZYNQMP_WDT_RESTART := 0 +ZYNQMP_IPI_CRC_CHECK := 0 override RESET_TO_BL31 := 1 +override GICV2_G0_FOR_EL3 := 1 +override WARMBOOT_ENABLE_DCACHE_EARLY := 1 # Do not enable SVE ENABLE_SVE_FOR_NS := 0 @@ -45,11 +48,16 @@ ifdef ZYNQMP_WDT_RESTART $(eval $(call add_define,ZYNQMP_WDT_RESTART)) endif -PLAT_INCLUDES := -Iinclude/plat/arm/common/aarch64/ \ +ifdef ZYNQMP_IPI_CRC_CHECK + $(eval $(call add_define,ZYNQMP_IPI_CRC_CHECK)) +endif + +PLAT_INCLUDES := -Iinclude/plat/arm/common/ \ + -Iinclude/plat/arm/common/aarch64/ \ -Iplat/xilinx/common/include/ \ + -Iplat/xilinx/common/ipi_mailbox_service/ \ -Iplat/xilinx/zynqmp/include/ \ -Iplat/xilinx/zynqmp/pm_service/ \ - -Iplat/xilinx/zynqmp/ipi_mailbox_service/ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ lib/xlat_tables/aarch64/xlat_tables.c \ @@ -64,6 +72,7 @@ PLAT_BL_COMMON_SOURCES := lib/xlat_tables/xlat_tables_common.c \ plat/arm/common/arm_gicv2.c \ plat/common/plat_gicv2.c \ plat/xilinx/common/ipi.c \ + plat/xilinx/zynqmp/zynqmp_ipi.c \ plat/xilinx/zynqmp/aarch64/zynqmp_helpers.S \ plat/xilinx/zynqmp/aarch64/zynqmp_common.c @@ -71,18 +80,21 @@ BL31_SOURCES += drivers/arm/cci/cci.c \ lib/cpus/aarch64/aem_generic.S \ lib/cpus/aarch64/cortex_a53.S \ plat/common/plat_psci_common.c \ + plat/xilinx/common/ipi_mailbox_service/ipi_mailbox_svc.c \ plat/xilinx/common/pm_service/pm_ipi.c \ + plat/xilinx/common/plat_startup.c \ plat/xilinx/zynqmp/bl31_zynqmp_setup.c \ plat/xilinx/zynqmp/plat_psci.c \ plat/xilinx/zynqmp/plat_zynqmp.c \ - plat/xilinx/zynqmp/plat_startup.c \ plat/xilinx/zynqmp/plat_topology.c \ plat/xilinx/zynqmp/sip_svc_setup.c \ - plat/xilinx/zynqmp/zynqmp_ipi.c \ plat/xilinx/zynqmp/pm_service/pm_svc_main.c \ plat/xilinx/zynqmp/pm_service/pm_api_sys.c \ plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c \ plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c \ plat/xilinx/zynqmp/pm_service/pm_api_clock.c \ - plat/xilinx/zynqmp/pm_service/pm_client.c \ - plat/xilinx/zynqmp/ipi_mailbox_service/ipi_mailbox_svc.c + plat/xilinx/zynqmp/pm_service/pm_client.c + +ifneq (${RESET_TO_BL31},1) + $(error "Using BL31 as the reset vector is only one option supported on ZynqMP. Please set RESET_TO_BL31 to 1.") +endif diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c index 85cffcb13..852f92763 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -30,6 +30,10 @@ #define CLK_TYPE_SHIFT U(2) #define CLK_CLKFLAGS_SHIFT U(8) #define CLK_TYPEFLAGS_SHIFT U(24) +#define CLK_TYPEFLAGS2_SHIFT U(4) +#define CLK_TYPEFLAGS_BITS_MASK U(0xFF) +#define CLK_TYPEFLAGS2_BITS_MASK U(0x0F00) +#define CLK_TYPEFLAGS_BITS U(8) #define CLK_EXTERNAL_PARENT (PARENT_CLK_EXTERNAL << CLK_PARENTS_ID_LEN) @@ -364,9 +368,8 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = { .offset = PERIPH_MUX_SHIFT, .width = PERIPH_MUX_WIDTH, .clkflags = CLK_SET_RATE_NO_REPARENT | - CLK_SET_RATE_PARENT | - CLK_FRAC | CLK_IS_BASIC, - .typeflags = NA_TYPE_FLAGS, + CLK_SET_RATE_PARENT | CLK_IS_BASIC, + .typeflags = CLK_FRAC, .mult = NA_MULT, .div = NA_DIV, }, @@ -375,8 +378,9 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = { .offset = PERIPH_DIV1_SHIFT, .width = PERIPH_DIV1_WIDTH, .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | - CLK_FRAC | CLK_IS_BASIC, - .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + CLK_IS_BASIC, + .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO | + CLK_FRAC, .mult = NA_MULT, .div = NA_DIV, }, @@ -385,8 +389,9 @@ static struct pm_clock_node dp_audio_video_ref_nodes[] = { .offset = PERIPH_DIV2_SHIFT, .width = PERIPH_DIV2_WIDTH, .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_SET_RATE_PARENT | - CLK_FRAC | CLK_IS_BASIC, - .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, + CLK_IS_BASIC, + .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO | + CLK_FRAC, .mult = NA_MULT, .div = NA_DIV, }, @@ -562,13 +567,13 @@ static struct pm_clock_node gpu_pp1_nodes[] = { }, }; -static struct pm_clock_node gem_nodes[] = { +static struct pm_clock_node gem_ref_ungated_nodes[] = { GENERIC_MUX, { .type = TYPE_DIV1, .offset = 8, .width = 6, - .clkflags = CLK_IS_BASIC, + .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, .mult = NA_MULT, .div = NA_DIV, @@ -577,77 +582,74 @@ static struct pm_clock_node gem_nodes[] = { .type = TYPE_DIV2, .offset = 16, .width = 6, - .clkflags = CLK_IS_BASIC, + .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC | + CLK_SET_RATE_PARENT, .typeflags = CLK_DIVIDER_ONE_BASED | CLK_DIVIDER_ALLOW_ZERO, .mult = NA_MULT, .div = NA_DIV, }, - { - .type = TYPE_GATE, - .offset = 25, - .width = PERIPH_GATE_WIDTH, - .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, - .typeflags = NA_TYPE_FLAGS, - .mult = NA_MULT, - .div = NA_DIV, - }, }; -static struct pm_clock_node gem0_tx_nodes[] = { +static struct pm_clock_node gem0_ref_nodes[] = { { .type = TYPE_MUX, .offset = 1, .width = 1, - .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, - .typeflags = NA_TYPE_FLAGS, - .mult = NA_MULT, - .div = NA_DIV, - }, - { - .type = TYPE_GATE, - .offset = 26, - .width = PERIPH_GATE_WIDTH, - .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, + .clkflags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT | + CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, .mult = NA_MULT, .div = NA_DIV, }, }; -static struct pm_clock_node gem1_tx_nodes[] = { +static struct pm_clock_node gem1_ref_nodes[] = { { .type = TYPE_MUX, .offset = 6, .width = 1, - .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, + .clkflags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT | + CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, .mult = NA_MULT, .div = NA_DIV, }, +}; + +static struct pm_clock_node gem2_ref_nodes[] = { { - .type = TYPE_GATE, - .offset = 26, - .width = PERIPH_GATE_WIDTH, - .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, + .type = TYPE_MUX, + .offset = 11, + .width = 1, + .clkflags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT | + CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, .mult = NA_MULT, .div = NA_DIV, }, }; -static struct pm_clock_node gem2_tx_nodes[] = { +static struct pm_clock_node gem3_ref_nodes[] = { { .type = TYPE_MUX, - .offset = 11, + .offset = 16, .width = 1, - .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, + .clkflags = CLK_SET_RATE_PARENT | + CLK_SET_RATE_NO_REPARENT | + CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, .mult = NA_MULT, .div = NA_DIV, }, +}; + +static struct pm_clock_node gem_tx_nodes[] = { { .type = TYPE_GATE, - .offset = 26, + .offset = 25, .width = PERIPH_GATE_WIDTH, .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, @@ -656,21 +658,12 @@ static struct pm_clock_node gem2_tx_nodes[] = { }, }; -static struct pm_clock_node gem3_tx_nodes[] = { - { - .type = TYPE_MUX, - .offset = 16, - .width = 1, - .clkflags = CLK_SET_RATE_NO_REPARENT | CLK_IS_BASIC, - .typeflags = NA_TYPE_FLAGS, - .mult = NA_MULT, - .div = NA_DIV, - }, +static struct pm_clock_node gem_rx_nodes[] = { { .type = TYPE_GATE, .offset = 26, .width = PERIPH_GATE_WIDTH, - .clkflags = CLK_SET_RATE_PARENT | CLK_IS_BASIC, + .clkflags = CLK_IS_BASIC, .typeflags = NA_TYPE_FLAGS, .mult = NA_MULT, .div = NA_DIV, @@ -1442,8 +1435,8 @@ static struct pm_clock clocks[] = { .nodes = &generic_mux_div_unused_gate_nodes, .num_nodes = ARRAY_SIZE(generic_mux_div_unused_gate_nodes), }, - [CLK_GEM0_REF] = { - .name = "gem0_ref", + [CLK_GEM0_REF_UNGATED] = { + .name = "gem0_ref_ung", .control_reg = CRL_APB_GEM0_REF_CTRL, .status_reg = 0, .parents = &((int32_t []) { @@ -1453,11 +1446,11 @@ static struct pm_clock clocks[] = { CLK_DPLL_TO_LPD, CLK_NA_PARENT }), - .nodes = &gem_nodes, - .num_nodes = ARRAY_SIZE(gem_nodes), + .nodes = &gem_ref_ungated_nodes, + .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), }, - [CLK_GEM1_REF] = { - .name = "gem1_ref", + [CLK_GEM1_REF_UNGATED] = { + .name = "gem1_ref_ung", .control_reg = CRL_APB_GEM1_REF_CTRL, .status_reg = 0, .parents = &((int32_t []) { @@ -1467,11 +1460,11 @@ static struct pm_clock clocks[] = { CLK_DPLL_TO_LPD, CLK_NA_PARENT }), - .nodes = &gem_nodes, - .num_nodes = ARRAY_SIZE(gem_nodes), + .nodes = &gem_ref_ungated_nodes, + .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), }, - [CLK_GEM2_REF] = { - .name = "gem2_ref", + [CLK_GEM2_REF_UNGATED] = { + .name = "gem2_ref_ung", .control_reg = CRL_APB_GEM2_REF_CTRL, .status_reg = 0, .parents = &((int32_t []) { @@ -1481,11 +1474,11 @@ static struct pm_clock clocks[] = { CLK_DPLL_TO_LPD, CLK_NA_PARENT }), - .nodes = &gem_nodes, - .num_nodes = ARRAY_SIZE(gem_nodes), + .nodes = &gem_ref_ungated_nodes, + .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), }, - [CLK_GEM3_REF] = { - .name = "gem3_ref", + [CLK_GEM3_REF_UNGATED] = { + .name = "gem3_ref_ung", .control_reg = CRL_APB_GEM3_REF_CTRL, .status_reg = 0, .parents = &((int32_t []) { @@ -1495,8 +1488,60 @@ static struct pm_clock clocks[] = { CLK_DPLL_TO_LPD, CLK_NA_PARENT }), - .nodes = &gem_nodes, - .num_nodes = ARRAY_SIZE(gem_nodes), + .nodes = &gem_ref_ungated_nodes, + .num_nodes = ARRAY_SIZE(gem_ref_ungated_nodes), + }, + [CLK_GEM0_REF] = { + .name = "gem0_ref", + .control_reg = IOU_SLCR_GEM_CLK_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_GEM0_REF_UNGATED | + (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), + EXT_CLK_GEM0_TX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem0_ref_nodes, + .num_nodes = ARRAY_SIZE(gem0_ref_nodes), + }, + [CLK_GEM1_REF] = { + .name = "gem1_ref", + .control_reg = IOU_SLCR_GEM_CLK_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_GEM1_REF_UNGATED | + (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), + EXT_CLK_GEM1_TX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem1_ref_nodes, + .num_nodes = ARRAY_SIZE(gem1_ref_nodes), + }, + [CLK_GEM2_REF] = { + .name = "gem2_ref", + .control_reg = IOU_SLCR_GEM_CLK_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_GEM2_REF_UNGATED | + (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), + EXT_CLK_GEM2_TX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem2_ref_nodes, + .num_nodes = ARRAY_SIZE(gem2_ref_nodes), + }, + [CLK_GEM3_REF] = { + .name = "gem3_ref", + .control_reg = IOU_SLCR_GEM_CLK_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_GEM3_REF_UNGATED | + (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), + EXT_CLK_GEM3_TX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem3_ref_nodes, + .num_nodes = ARRAY_SIZE(gem3_ref_nodes), }, [CLK_USB0_BUS_REF] = { .name = "usb0_bus_ref", @@ -1960,69 +2005,93 @@ static struct pm_clock clocks[] = { .nodes = &generic_domain_crossing_nodes, .num_nodes = ARRAY_SIZE(generic_domain_crossing_nodes), }, - /* - * This clock control requires different registers for mux and gate. - * Use control and status registers for the same. - */ [CLK_GEM0_TX] = { .name = "gem0_tx", - .control_reg = IOU_SLCR_GEM_CLK_CTRL, - .status_reg = CRL_APB_GEM0_REF_CTRL, + .control_reg = CRL_APB_GEM0_REF_CTRL, + .status_reg = 0, .parents = &((int32_t []) { - CLK_GEM0_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), - EXT_CLK_GEM0_EMIO | CLK_EXTERNAL_PARENT, + CLK_GEM0_REF, CLK_NA_PARENT }), - .nodes = &gem0_tx_nodes, - .num_nodes = ARRAY_SIZE(gem0_tx_nodes), + .nodes = &gem_tx_nodes, + .num_nodes = ARRAY_SIZE(gem_tx_nodes), }, - /* - * This clock control requires different registers for mux and gate. - * Use control and status registers for the same. - */ [CLK_GEM1_TX] = { .name = "gem1_tx", - .control_reg = IOU_SLCR_GEM_CLK_CTRL, - .status_reg = CRL_APB_GEM1_REF_CTRL, + .control_reg = CRL_APB_GEM1_REF_CTRL, + .status_reg = 0, .parents = &((int32_t []) { - CLK_GEM1_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), - EXT_CLK_GEM1_EMIO | CLK_EXTERNAL_PARENT, + CLK_GEM1_REF, CLK_NA_PARENT }), - .nodes = &gem1_tx_nodes, - .num_nodes = ARRAY_SIZE(gem1_tx_nodes), + .nodes = &gem_tx_nodes, + .num_nodes = ARRAY_SIZE(gem_tx_nodes), }, - /* - * This clock control requires different registers for mux and gate. - * Use control and status registers for the same. - */ [CLK_GEM2_TX] = { .name = "gem2_tx", - .control_reg = IOU_SLCR_GEM_CLK_CTRL, - .status_reg = CRL_APB_GEM2_REF_CTRL, + .control_reg = CRL_APB_GEM2_REF_CTRL, + .status_reg = 0, .parents = &((int32_t []) { - CLK_GEM2_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), - EXT_CLK_GEM2_EMIO | CLK_EXTERNAL_PARENT, + CLK_GEM2_REF, CLK_NA_PARENT }), - .nodes = &gem2_tx_nodes, - .num_nodes = ARRAY_SIZE(gem2_tx_nodes), + .nodes = &gem_tx_nodes, + .num_nodes = ARRAY_SIZE(gem_tx_nodes), }, - /* - * This clock control requires different registers for mux and gate. - * Use control and status registers for the same. - */ [CLK_GEM3_TX] = { .name = "gem3_tx", - .control_reg = IOU_SLCR_GEM_CLK_CTRL, - .status_reg = CRL_APB_GEM3_REF_CTRL, + .control_reg = CRL_APB_GEM3_REF_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_GEM3_REF, + CLK_NA_PARENT + }), + .nodes = &gem_tx_nodes, + .num_nodes = ARRAY_SIZE(gem_tx_nodes), + }, + [CLK_GEM0_RX] = { + .name = "gem0_rx", + .control_reg = CRL_APB_GEM0_REF_CTRL, + .status_reg = 0, .parents = &((int32_t []) { - CLK_GEM3_REF | (PARENT_CLK_NODE3 << CLK_PARENTS_ID_LEN), - EXT_CLK_GEM3_EMIO | CLK_EXTERNAL_PARENT, + EXT_CLK_GEM0_RX_EMIO | CLK_EXTERNAL_PARENT, CLK_NA_PARENT }), - .nodes = &gem3_tx_nodes, - .num_nodes = ARRAY_SIZE(gem3_tx_nodes), + .nodes = &gem_rx_nodes, + .num_nodes = ARRAY_SIZE(gem_rx_nodes), + }, + [CLK_GEM1_RX] = { + .name = "gem1_rx", + .control_reg = CRL_APB_GEM1_REF_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + EXT_CLK_GEM1_RX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem_rx_nodes, + .num_nodes = ARRAY_SIZE(gem_rx_nodes), + }, + [CLK_GEM2_RX] = { + .name = "gem2_rx", + .control_reg = CRL_APB_GEM2_REF_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + EXT_CLK_GEM2_RX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem_rx_nodes, + .num_nodes = ARRAY_SIZE(gem_rx_nodes), + }, + [CLK_GEM3_RX] = { + .name = "gem3_rx", + .control_reg = CRL_APB_GEM3_REF_CTRL, + .status_reg = 0, + .parents = &((int32_t []) { + EXT_CLK_GEM3_RX_EMIO | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &gem_rx_nodes, + .num_nodes = ARRAY_SIZE(gem_rx_nodes), }, [CLK_ACPU_HALF] = { .name = "acpu_half", @@ -2035,8 +2104,8 @@ static struct pm_clock clocks[] = { .nodes = &acpu_half_nodes, .num_nodes = ARRAY_SIZE(acpu_half_nodes), }, - [CLK_WDT] = { - .name = "wdt", + [CLK_FPD_WDT] = { + .name = "fpd_wdt", .control_reg = FPD_SLCR_WDT_CLK_SEL, .status_reg = 0, .parents = &((int32_t []) { @@ -2135,6 +2204,18 @@ static struct pm_clock clocks[] = { .nodes = &can1_nodes, .num_nodes = ARRAY_SIZE(can1_nodes), }, + [CLK_LPD_WDT] = { + .name = "lpd_wdt", + .control_reg = IOU_SLCR_WDT_CLK_SEL, + .status_reg = 0, + .parents = &((int32_t []) { + CLK_LPD_LSBUS, + EXT_CLK_SWDT1 | CLK_EXTERNAL_PARENT, + CLK_NA_PARENT + }), + .nodes = &wdt_nodes, + .num_nodes = ARRAY_SIZE(wdt_nodes), + }, }; static struct pm_ext_clock ext_clocks[] = { @@ -2159,17 +2240,29 @@ static struct pm_ext_clock ext_clocks[] = { [EXT_CLK_INDEX(EXT_CLK_SWDT1)] = { .name = "swdt1_ext_clk", }, - [EXT_CLK_INDEX(EXT_CLK_GEM0_EMIO)] = { - .name = "gem0_emio_clk", + [EXT_CLK_INDEX(EXT_CLK_GEM0_TX_EMIO)] = { + .name = "gem0_tx_ext", }, - [EXT_CLK_INDEX(EXT_CLK_GEM1_EMIO)] = { - .name = "gem1_emio_clk", + [EXT_CLK_INDEX(EXT_CLK_GEM1_TX_EMIO)] = { + .name = "gem1_tx_ext", }, - [EXT_CLK_INDEX(EXT_CLK_GEM2_EMIO)] = { - .name = "gem2_emio_clk", + [EXT_CLK_INDEX(EXT_CLK_GEM2_TX_EMIO)] = { + .name = "gem2_tx_ext", }, - [EXT_CLK_INDEX(EXT_CLK_GEM3_EMIO)] = { - .name = "gem3_emio_clk", + [EXT_CLK_INDEX(EXT_CLK_GEM3_TX_EMIO)] = { + .name = "gem3_tx_ext", + }, + [EXT_CLK_INDEX(EXT_CLK_GEM0_RX_EMIO)] = { + .name = "gem0_rx_ext", + }, + [EXT_CLK_INDEX(EXT_CLK_GEM1_RX_EMIO)] = { + .name = "gem1_rx_ext", + }, + [EXT_CLK_INDEX(EXT_CLK_GEM2_RX_EMIO)] = { + .name = "gem2_rx_ext", + }, + [EXT_CLK_INDEX(EXT_CLK_GEM3_RX_EMIO)] = { + .name = "gem3_rx_ext", }, [EXT_CLK_INDEX(EXT_CLK_MIO50_OR_MIO51)] = { .name = "mio_clk_50_51", @@ -2265,10 +2358,8 @@ static uint32_t pm_clk_invalid_list[] = {CLK_USB0, CLK_USB1, CLK_CSU_SPB, CLK_DBG_TSTMP, CLK_DDR_REF, CLK_TOPSW_MAIN, - CLK_TOPSW_LSBUS, CLK_GTGREF0_REF, CLK_LPD_SWITCH, - CLK_LPD_LSBUS, CLK_CPU_R5, CLK_CPU_R5_CORE, CLK_CSU_SPB, @@ -2376,6 +2467,7 @@ enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, struct pm_clock_node *clock_nodes; uint8_t num_nodes; unsigned int i; + uint16_t typeflags; if (!pm_clock_valid(clock_id)) return PM_RET_ERROR_ARGS; @@ -2395,11 +2487,14 @@ enum pm_ret_status pm_api_clock_get_topology(unsigned int clock_id, for (i = 0; i < 3U; i++) { if ((index + i) == num_nodes) break; - topology[i] = clock_nodes[index + i].type; + topology[i] = clock_nodes[index + i].type; topology[i] |= clock_nodes[index + i].clkflags << CLK_CLKFLAGS_SHIFT; - topology[i] |= clock_nodes[index + i].typeflags << + typeflags = clock_nodes[index + i].typeflags; + topology[i] |= (typeflags & CLK_TYPEFLAGS_BITS_MASK) << CLK_TYPEFLAGS_SHIFT; + topology[i] |= (typeflags & CLK_TYPEFLAGS2_BITS_MASK) >> + (CLK_TYPEFLAGS_BITS - CLK_TYPEFLAGS2_SHIFT); } return PM_RET_SUCCESS; @@ -2526,6 +2621,42 @@ enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, } /** + * pm_api_clock_get_max_divisor - PM call to get max divisor + * @clock_id Clock ID + * @div_type Divisor Type (TYPE_DIV1 or TYPE_DIV2) + * @max_div Maximum supported divisor + * + * This function is used by master to get maximum supported value. + * + * Return: Returns status, either success or error+reason. + */ +enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id, + uint8_t div_type, + uint32_t *max_div) +{ + uint32_t i; + struct pm_clock_node *nodes; + + if (clock_id >= CLK_MAX_OUTPUT_CLK) + return PM_RET_ERROR_ARGS; + + nodes = *clocks[clock_id].nodes; + for (i = 0; i < clocks[clock_id].num_nodes; i++) { + if (nodes[i].type == div_type) { + if (CLK_DIVIDER_POWER_OF_TWO & + nodes[i].typeflags) { + *max_div = (1 << (BIT(nodes[i].width) - 1)); + } else { + *max_div = BIT(nodes[i].width) - 1; + } + return PM_RET_SUCCESS; + } + } + + return PM_RET_ERROR_ARGS; +} + +/** * struct pm_pll - PLL related data required to map IOCTL-based PLL control * implemented by linux to system-level EEMI APIs * @nid: PLL node ID diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h index 9717ca86a..301ed24b6 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_clock.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_clock.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2019, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -43,7 +43,6 @@ #define CLK_IS_CRITICAL BIT(11) /* do not gate, ever */ /* parents need enable during gate/ungate, set rate and re-parent */ #define CLK_OPS_PARENT_ENABLE BIT(12) -#define CLK_FRAC BIT(13) #define CLK_DIVIDER_ONE_BASED BIT(0) #define CLK_DIVIDER_POWER_OF_TWO BIT(1) @@ -52,6 +51,7 @@ #define CLK_DIVIDER_ROUND_CLOSEST BIT(4) #define CLK_DIVIDER_READ_ONLY BIT(5) #define CLK_DIVIDER_MAX_AT_ZERO BIT(6) +#define CLK_FRAC BIT(8) #define END_OF_CLK "END_OF_CLK" @@ -102,14 +102,14 @@ enum clock_id { CLK_IOU_SWITCH, CLK_GEM_TSU_REF, CLK_GEM_TSU, - CLK_GEM0_REF, - CLK_GEM1_REF, - CLK_GEM2_REF, - CLK_GEM3_REF, CLK_GEM0_TX, CLK_GEM1_TX, CLK_GEM2_TX, CLK_GEM3_TX, + CLK_GEM0_RX, + CLK_GEM1_RX, + CLK_GEM2_RX, + CLK_GEM3_RX, CLK_QSPI_REF, CLK_SDIO0_REF, CLK_SDIO1_REF, @@ -132,7 +132,7 @@ enum clock_id { CLK_PL1_REF, CLK_PL2_REF, CLK_PL3_REF, - CLK_WDT, + CLK_FPD_WDT, CLK_IOPLL_INT, CLK_IOPLL_PRE_SRC, CLK_IOPLL_HALF, @@ -161,6 +161,15 @@ enum clock_id { CLK_CAN0_MIO, CLK_CAN1_MIO, CLK_ACPU_FULL, + CLK_GEM0_REF, + CLK_GEM1_REF, + CLK_GEM2_REF, + CLK_GEM3_REF, + CLK_GEM0_REF_UNGATED, + CLK_GEM1_REF_UNGATED, + CLK_GEM2_REF_UNGATED, + CLK_GEM3_REF_UNGATED, + CLK_LPD_WDT, END_OF_OUTPUT_CLKS, }; @@ -175,10 +184,14 @@ enum { EXT_CLK_GT_CRX_REF, EXT_CLK_SWDT0, EXT_CLK_SWDT1, - EXT_CLK_GEM0_EMIO, - EXT_CLK_GEM1_EMIO, - EXT_CLK_GEM2_EMIO, - EXT_CLK_GEM3_EMIO, + EXT_CLK_GEM0_TX_EMIO, + EXT_CLK_GEM1_TX_EMIO, + EXT_CLK_GEM2_TX_EMIO, + EXT_CLK_GEM3_TX_EMIO, + EXT_CLK_GEM0_RX_EMIO, + EXT_CLK_GEM1_RX_EMIO, + EXT_CLK_GEM2_RX_EMIO, + EXT_CLK_GEM3_RX_EMIO, EXT_CLK_MIO50_OR_MIO51, EXT_CLK_MIO0, EXT_CLK_MIO1, @@ -294,6 +307,9 @@ enum pm_ret_status pm_api_clock_get_parents(unsigned int clock_id, uint32_t *parents); enum pm_ret_status pm_api_clock_get_attributes(unsigned int clock_id, uint32_t *attr); +enum pm_ret_status pm_api_clock_get_max_divisor(enum clock_id clock_id, + uint8_t div_type, + uint32_t *max_div); enum pm_ret_status pm_clock_get_pll_node_id(enum clock_id clock_id, enum pm_node_id *node_id); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c index 44acb4bd5..60e80d907 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_ioctl.c @@ -58,7 +58,7 @@ static enum pm_ret_status pm_ioctl_set_rpu_oper_mode(unsigned int mode) { unsigned int val; - if (mmio_read_32(CRL_APB_RST_LPD_TOP) && CRL_APB_RPU_AMBA_RESET) + if (mmio_read_32(CRL_APB_RST_LPD_TOP) & CRL_APB_RPU_AMBA_RESET) return PM_RET_ERROR_ACCESS; val = mmio_read_32(ZYNQMP_RPU_GLBL_CNTL); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c index a900057e8..4b8dfb614 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_pinctrl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2018-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -1477,6 +1477,7 @@ static struct zynqmp_pin_group zynqmp_pin_groups[MAX_PIN] = { }, [PINCTRL_PIN_26] = { .groups = &((uint16_t []) { + PINCTRL_GRP_ETHERNET0_0, PINCTRL_GRP_GEMTSU0_0, PINCTRL_GRP_NAND0_1_CE, PINCTRL_GRP_PMU0_0, diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c index e0b9816e4..b1720d9f6 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.c +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -630,6 +630,22 @@ enum pm_ret_status pm_aes_engine(uint32_t address_high, } /** + * pm_get_callbackdata() - Read from IPI response buffer + * @data - array of PAYLOAD_ARG_CNT elements + * + * Read value from ipi buffer response buffer. + */ +void pm_get_callbackdata(uint32_t *data, size_t count) +{ + /* Return if interrupt is not from PMU */ + if (!pm_ipi_irq_status(primary_proc)) + return; + + pm_ipi_buff_read_callb(data, count); + pm_ipi_irq_clear(primary_proc); +} + +/** * pm_pinctrl_request() - Request Pin from firmware * @pin Pin number to request * @@ -741,6 +757,23 @@ enum pm_ret_status pm_ioctl(enum pm_node_id nid, } /** + * pm_clock_get_max_divisor - PM call to get max divisor + * @clock_id Clock ID + * @div_type Divisor ID (TYPE_DIV1 or TYPE_DIV2) + * @max_div Maximum supported divisor + * + * This function is used by master to get maximum supported value. + * + * Return: Returns status, either success or error+reason. + */ +static enum pm_ret_status pm_clock_get_max_divisor(unsigned int clock_id, + uint8_t div_type, + uint32_t *max_div) +{ + return pm_api_clock_get_max_divisor(clock_id, div_type, max_div); +} + +/** * pm_clock_get_num_clocks - PM call to request number of clocks * @nclockss: Number of clocks * @@ -1322,6 +1355,11 @@ enum pm_ret_status pm_query_data(enum pm_query_id qid, ret = pm_clock_get_num_clocks(&data[1]); data[0] = (unsigned int)ret; break; + + case PM_QID_CLOCK_GET_MAX_DIVISOR: + ret = pm_clock_get_max_divisor(arg1, arg2, &data[1]); + data[0] = (unsigned int)ret; + break; default: ret = PM_RET_ERROR_ARGS; WARN("Unimplemented query service call: 0x%x\n", qid); diff --git a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h index 282ca3dc6..ff66d3f02 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_api_sys.h +++ b/plat/xilinx/zynqmp/pm_service/pm_api_sys.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,7 @@ enum pm_query_id { PM_QID_PINCTRL_GET_FUNCTION_GROUPS, PM_QID_PINCTRL_GET_PIN_GROUPS, PM_QID_CLOCK_GET_NUM_CLOCKS, + PM_QID_CLOCK_GET_MAX_DIVISOR, }; /********************************************************** @@ -116,6 +117,7 @@ enum pm_ret_status pm_secure_rsaaes(uint32_t address_high, uint32_t size, uint32_t flags); unsigned int pm_get_shutdown_scope(void); +void pm_get_callbackdata(uint32_t *data, size_t count); enum pm_ret_status pm_pinctrl_request(unsigned int pin); enum pm_ret_status pm_pinctrl_release(unsigned int pin); enum pm_ret_status pm_pinctrl_get_function(unsigned int pin, diff --git a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c index faa282745..98dbe7d6e 100644 --- a/plat/xilinx/zynqmp/pm_service/pm_svc_main.c +++ b/plat/xilinx/zynqmp/pm_service/pm_svc_main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2018, ARM Limited and Contributors. All rights reserved. + * Copyright (c) 2013-2020, ARM Limited and Contributors. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -25,6 +25,7 @@ #include "pm_client.h" #include "pm_ipi.h" +#define PM_GET_CALLBACK_DATA 0xa01 #define PM_SET_SUSPEND_MODE 0xa02 #define PM_GET_TRUSTZONE_VERSION 0xa03 @@ -76,8 +77,12 @@ static void trigger_wdt_restart(void) INFO("Active Cores: %d\n", active_cores); - /* trigger SGI to active cores */ - gicv2_raise_sgi(ARM_IRQ_SEC_SGI_7, target_cpu_list); + for (i = PLATFORM_CORE_COUNT - 1; i >= 0; i--) { + if (target_cpu_list & (1 << i)) { + /* trigger SGI to active cores */ + plat_ic_raise_el3_sgi(ARM_IRQ_SEC_SGI_7, i); + } + } } /** @@ -105,6 +110,8 @@ static uint64_t ttc_fiq_handler(uint32_t id, uint32_t flags, void *handle, { INFO("BL31: Got TTC FIQ\n"); + plat_ic_end_of_interrupt(id); + /* Clear TTC interrupt by reading interrupt register */ mmio_read_32(TTC3_INTR_REGISTER_1); @@ -412,6 +419,16 @@ uint64_t pm_smc_handler(uint32_t smc_fid, uint64_t x1, uint64_t x2, uint64_t x3, pm_arg[3]); SMC_RET1(handle, (uint64_t)ret); + case PM_GET_CALLBACK_DATA: + { + uint32_t result[4] = {0}; + + pm_get_callbackdata(result, (sizeof(result)/sizeof(uint32_t))); + SMC_RET2(handle, + (uint64_t)result[0] | ((uint64_t)result[1] << 32), + (uint64_t)result[2] | ((uint64_t)result[3] << 32)); + } + case PM_PINCTRL_REQUEST: ret = pm_pinctrl_request(pm_arg[0]); SMC_RET1(handle, (uint64_t)ret); diff --git a/plat/xilinx/zynqmp/sip_svc_setup.c b/plat/xilinx/zynqmp/sip_svc_setup.c index edb81f5c3..9b182749c 100644 --- a/plat/xilinx/zynqmp/sip_svc_setup.c +++ b/plat/xilinx/zynqmp/sip_svc_setup.c @@ -9,7 +9,6 @@ #include <common/runtime_svc.h> #include <tools_share/uuid.h> -#include <plat_ipi.h> #include "ipi_mailbox_svc.h" #include "pm_svc_main.h" @@ -41,9 +40,6 @@ DEFINE_SVC_UUID2(zynqmp_sip_uuid, */ static int32_t sip_svc_setup(void) { - /* Configure IPI data for ZynqMP */ - zynqmp_ipi_config_table_init(); - /* PM implementation as SiP Service */ pm_setup(); |