diff options
Diffstat (limited to 'plat')
31 files changed, 1352 insertions, 148 deletions
diff --git a/plat/allwinner/common/include/sunxi_private.h b/plat/allwinner/common/include/sunxi_private.h index 1e1b0a4d1..11668797b 100644 --- a/plat/allwinner/common/include/sunxi_private.h +++ b/plat/allwinner/common/include/sunxi_private.h @@ -9,9 +9,9 @@ void sunxi_configure_mmu_el3(int flags); -void sunxi_cpu_on(unsigned int cluster, unsigned int core); -void sunxi_cpu_off(unsigned int cluster, unsigned int core); -void sunxi_disable_secondary_cpus(unsigned int primary_cpu); +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); int sunxi_pmic_setup(uint16_t socid, const void *fdt); diff --git a/plat/allwinner/common/sunxi_bl31_setup.c b/plat/allwinner/common/sunxi_bl31_setup.c index 7ffa65821..a24527c5d 100644 --- a/plat/allwinner/common/sunxi_bl31_setup.c +++ b/plat/allwinner/common/sunxi_bl31_setup.c @@ -11,6 +11,7 @@ #include <platform_def.h> #include <arch.h> +#include <arch_helpers.h> #include <common/debug.h> #include <drivers/arm/gicv2.h> #include <drivers/console.h> @@ -101,7 +102,7 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, SET_SECURITY_STATE(bl33_image_ep_info.h.attr, NON_SECURE); /* Turn off all secondary CPUs */ - sunxi_disable_secondary_cpus(plat_my_core_pos()); + sunxi_disable_secondary_cpus(read_mpidr()); } void bl31_plat_arch_setup(void) diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 6bb8968ce..3b44aab68 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -18,7 +18,7 @@ #include <sunxi_mmap.h> #include <sunxi_private.h> -static mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { +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), MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, diff --git a/plat/allwinner/common/sunxi_cpu_ops.c b/plat/allwinner/common/sunxi_cpu_ops.c index 8c086030a..b4c9fcc18 100644 --- a/plat/allwinner/common/sunxi_cpu_ops.c +++ b/plat/allwinner/common/sunxi_cpu_ops.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 */ @@ -45,9 +45,10 @@ static void sunxi_cpu_enable_power(unsigned int cluster, unsigned int core) mmio_write_32(SUNXI_CPU_POWER_CLAMP_REG(cluster, core), 0x00); } -void sunxi_cpu_off(unsigned int cluster, unsigned int core) +void sunxi_cpu_off(u_register_t mpidr) { - int corenr = cluster * PLATFORM_MAX_CPUS_PER_CLUSTER + core; + unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr); + unsigned int core = MPIDR_AFFLVL0_VAL(mpidr); VERBOSE("PSCI: Powering off cluster %d core %d\n", cluster, core); @@ -55,9 +56,9 @@ void sunxi_cpu_off(unsigned int cluster, unsigned int core) mmio_clrbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); /* We can't turn ourself off like this, but it works for other cores. */ - if (plat_my_core_pos() != corenr) { + if (read_mpidr() != mpidr) { /* Activate the core output clamps, but not for core 0. */ - if (corenr != 0) + if (core != 0) mmio_setbits_32(SUNXI_POWEROFF_GATING_REG(cluster), BIT(core)); /* Assert CPU power-on reset */ @@ -80,8 +81,11 @@ void sunxi_cpu_off(unsigned int cluster, unsigned int core) 0, BIT_32(core)); } -void sunxi_cpu_on(unsigned int cluster, unsigned int core) +void sunxi_cpu_on(u_register_t mpidr) { + unsigned int cluster = MPIDR_AFFLVL1_VAL(mpidr); + unsigned int core = MPIDR_AFFLVL0_VAL(mpidr); + VERBOSE("PSCI: Powering on cluster %d core %d\n", cluster, core); /* Assert CPU core reset */ @@ -102,12 +106,18 @@ void sunxi_cpu_on(unsigned int cluster, unsigned int core) mmio_setbits_32(SUNXI_CPUCFG_DBG_REG0, BIT(core)); } -void sunxi_disable_secondary_cpus(unsigned int primary_cpu) +void sunxi_disable_secondary_cpus(u_register_t primary_mpidr) { - for (unsigned int cpu = 0; cpu < PLATFORM_CORE_COUNT; cpu += 1) { - if (cpu == primary_cpu) - continue; - sunxi_cpu_off(cpu / PLATFORM_MAX_CPUS_PER_CLUSTER, - cpu % PLATFORM_MAX_CPUS_PER_CLUSTER); + unsigned int cluster; + unsigned int core; + + for (cluster = 0; cluster < PLATFORM_CLUSTER_COUNT; ++cluster) { + for (core = 0; core < PLATFORM_MAX_CPUS_PER_CLUSTER; ++core) { + u_register_t mpidr = (cluster << MPIDR_AFF1_SHIFT) | + (core << MPIDR_AFF0_SHIFT) | + BIT(31); + if (mpidr != primary_mpidr) + sunxi_cpu_off(mpidr); + } } } diff --git a/plat/allwinner/common/sunxi_pm.c b/plat/allwinner/common/sunxi_pm.c index 8cc715c27..1d2dc9385 100644 --- a/plat/allwinner/common/sunxi_pm.c +++ b/plat/allwinner/common/sunxi_pm.c @@ -35,7 +35,7 @@ static int sunxi_pwr_domain_on(u_register_t mpidr) if (mpidr_is_valid(mpidr) == 0) return PSCI_E_INTERN_FAIL; - sunxi_cpu_on(MPIDR_AFFLVL1_VAL(mpidr), MPIDR_AFFLVL0_VAL(mpidr)); + sunxi_cpu_on(mpidr); return PSCI_E_SUCCESS; } @@ -47,9 +47,7 @@ static void sunxi_pwr_domain_off(const psci_power_state_t *target_state) static void __dead2 sunxi_pwr_down_wfi(const psci_power_state_t *target_state) { - u_register_t mpidr = read_mpidr(); - - sunxi_cpu_off(MPIDR_AFFLVL1_VAL(mpidr), MPIDR_AFFLVL0_VAL(mpidr)); + sunxi_cpu_off(read_mpidr()); while (1) wfi(); @@ -64,7 +62,7 @@ static void sunxi_pwr_domain_on_finish(const psci_power_state_t *target_state) static void __dead2 sunxi_system_off(void) { /* Turn off all secondary CPUs */ - sunxi_disable_secondary_cpus(plat_my_core_pos()); + sunxi_disable_secondary_cpus(read_mpidr()); sunxi_power_down(); } diff --git a/plat/allwinner/common/sunxi_topology.c b/plat/allwinner/common/sunxi_topology.c index 7acc77a9a..45be1e03d 100644 --- a/plat/allwinner/common/sunxi_topology.c +++ b/plat/allwinner/common/sunxi_topology.c @@ -9,7 +9,7 @@ #include <arch.h> #include <plat/common/platform.h> -static unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = { +static const unsigned char plat_power_domain_tree_desc[PLAT_MAX_PWR_LVL + 1] = { /* One root node for the SoC */ 1, /* One node for each cluster */ diff --git a/plat/allwinner/sun50i_a64/sunxi_power.c b/plat/allwinner/sun50i_a64/sunxi_power.c index 706bfcecb..b4d16a068 100644 --- a/plat/allwinner/sun50i_a64/sunxi_power.c +++ b/plat/allwinner/sun50i_a64/sunxi_power.c @@ -175,7 +175,7 @@ static int fdt_get_regulator_millivolt(const void *fdt, int node) #define NO_SPLIT 0xff -struct axp_regulator { +static const struct axp_regulator { char *dt_name; uint16_t min_volt; uint16_t max_volt; @@ -247,7 +247,7 @@ static void setup_axp803_rails(const void *fdt) for (node = fdt_first_subnode(fdt, node); node != -FDT_ERR_NOTFOUND; node = fdt_next_subnode(fdt, node)) { - struct axp_regulator *reg; + const struct axp_regulator *reg; const char *name; int length; diff --git a/plat/arm/board/sgiclarkh/fdts/sgiclarkh_nt_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts index 3dedf1de2..41769217a 100644 --- a/plat/arm/board/sgiclarkh/fdts/sgiclarkh_nt_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_nt_fw_config.dts @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2019, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -7,7 +7,7 @@ /dts-v1/; / { /* compatible string */ - compatible = "arm,sgi-clark"; + compatible = "arm,rd-e1edge"; /* * Place holder for system-id node with default values. The diff --git a/plat/arm/board/sgiclarkh/fdts/sgiclarkh_tb_fw_config.dts b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts index 766dc00f5..766dc00f5 100644 --- a/plat/arm/board/sgiclarkh/fdts/sgiclarkh_tb_fw_config.dts +++ b/plat/arm/board/rde1edge/fdts/rde1edge_tb_fw_config.dts diff --git a/plat/arm/board/sgiclarkh/include/platform_def.h b/plat/arm/board/rde1edge/include/platform_def.h index fe8907bee..954a1cd48 100644 --- a/plat/arm/board/sgiclarkh/include/platform_def.h +++ b/plat/arm/board/rde1edge/include/platform_def.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Arm Limited. All rights reserved. + * Copyright (c) 2018-2019, Arm Limited. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ @@ -18,8 +18,8 @@ #define PLAT_CSS_MHU_BASE UL(0x45400000) /* Base address of DMC-620 instances */ -#define SGICLARKH_DMC620_BASE0 UL(0x4e000000) -#define SGICLARKH_DMC620_BASE1 UL(0x4e100000) +#define RDE1EDGE_DMC620_BASE0 UL(0x4e000000) +#define RDE1EDGE_DMC620_BASE1 UL(0x4e100000) #define PLAT_MAX_PWR_LVL ARM_PWR_LVL2 diff --git a/plat/arm/board/sgiclarkh/platform.mk b/plat/arm/board/rde1edge/platform.mk index 1e93d939c..833bb821a 100644 --- a/plat/arm/board/sgiclarkh/platform.mk +++ b/plat/arm/board/rde1edge/platform.mk @@ -6,34 +6,34 @@ include plat/arm/css/sgi/sgi-common.mk -SGICLARKH_BASE = plat/arm/board/sgiclarkh +RDE1EDGE_BASE = plat/arm/board/rde1edge -PLAT_INCLUDES += -I${SGICLARKH_BASE}/include/ +PLAT_INCLUDES += -I${RDE1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_e1.S BL1_SOURCES += ${SGI_CPU_SOURCES} -BL2_SOURCES += ${SGICLARKH_BASE}/sgiclarkh_plat.c \ - ${SGICLARKH_BASE}/sgiclarkh_security.c \ +BL2_SOURCES += ${RDE1EDGE_BASE}/rde1edge_plat.c \ + ${RDE1EDGE_BASE}/rde1edge_security.c \ drivers/arm/tzc/tzc_dmc620.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${SGI_CPU_SOURCES} \ - ${SGICLARKH_BASE}/sgiclarkh_plat.c \ + ${RDE1EDGE_BASE}/rde1edge_plat.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGICLARKH_BASE}/fdts/${PLAT}_tb_fw_config.dts +FDT_SOURCES += ${RDE1EDGE_BASE}/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)) -FDT_SOURCES += ${SGICLARKH_BASE}/fdts/${PLAT}_nt_fw_config.dts +FDT_SOURCES += ${RDE1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/board/sgiclarkh/sgiclarkh_plat.c b/plat/arm/board/rde1edge/rde1edge_plat.c index a1b8d621d..a1b8d621d 100644 --- a/plat/arm/board/sgiclarkh/sgiclarkh_plat.c +++ b/plat/arm/board/rde1edge/rde1edge_plat.c diff --git a/plat/arm/board/rde1edge/rde1edge_security.c b/plat/arm/board/rde1edge/rde1edge_security.c new file mode 100644 index 000000000..2123e0931 --- /dev/null +++ b/plat/arm/board/rde1edge/rde1edge_security.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/arm/tzc_dmc620.h> + +uintptr_t rde1edge_dmc_base[] = { + RDE1EDGE_DMC620_BASE0, + RDE1EDGE_DMC620_BASE1 +}; + +static const tzc_dmc620_driver_data_t rde1edge_plat_driver_data = { + .dmc_base = rde1edge_dmc_base, + .dmc_count = ARRAY_SIZE(rde1edge_dmc_base) +}; + +static const tzc_dmc620_acc_addr_data_t rde1edge_acc_addr_data[] = { + { + .region_base = ARM_AP_TZC_DRAM1_BASE, + .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, + .sec_attr = TZC_DMC620_REGION_S_RDWR + } +}; + +static const tzc_dmc620_config_data_t rde1edge_plat_config_data = { + .plat_drv_data = &rde1edge_plat_driver_data, + .plat_acc_addr_data = rde1edge_acc_addr_data, + .acc_addr_count = ARRAY_SIZE(rde1edge_acc_addr_data) +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + arm_tzc_dmc620_setup(&rde1edge_plat_config_data); +} diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka_nt_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts index 43bd85692..fff587476 100644 --- a/plat/arm/board/sgiclarka/fdts/sgiclarka_nt_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_nt_fw_config.dts @@ -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,7 +7,7 @@ /dts-v1/; / { /* compatible string */ - compatible = "arm,sgi-clark"; + compatible = "arm,rd-n1edge"; /* * Place holder for system-id node with default values. The diff --git a/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts index b14d7adca..b14d7adca 100644 --- a/plat/arm/board/sgiclarka/fdts/sgiclarka_tb_fw_config.dts +++ b/plat/arm/board/rdn1edge/fdts/rdn1edge_tb_fw_config.dts diff --git a/plat/arm/board/sgiclarka/include/platform_def.h b/plat/arm/board/rdn1edge/include/platform_def.h index d2cdb4974..2ca0dd4ec 100644 --- a/plat/arm/board/sgiclarka/include/platform_def.h +++ b/plat/arm/board/rdn1edge/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 */ @@ -18,8 +18,8 @@ #define PLAT_CSS_MHU_BASE UL(0x45400000) /* Base address of DMC-620 instances */ -#define SGICLARKA_DMC620_BASE0 UL(0x4e000000) -#define SGICLARKA_DMC620_BASE1 UL(0x4e100000) +#define RDN1EDGE_DMC620_BASE0 UL(0x4e000000) +#define RDN1EDGE_DMC620_BASE1 UL(0x4e100000) /* System power domain level */ #define CSS_SYSTEM_PWR_DMN_LVL ARM_PWR_LVL2 diff --git a/plat/arm/board/sgiclarka/platform.mk b/plat/arm/board/rdn1edge/platform.mk index 81e416efc..cacdaa13c 100644 --- a/plat/arm/board/sgiclarka/platform.mk +++ b/plat/arm/board/rdn1edge/platform.mk @@ -6,34 +6,34 @@ include plat/arm/css/sgi/sgi-common.mk -SGICLARKA_BASE = plat/arm/board/sgiclarka +RDN1EDGE_BASE = plat/arm/board/rdn1edge -PLAT_INCLUDES += -I${SGICLARKA_BASE}/include/ +PLAT_INCLUDES += -I${RDN1EDGE_BASE}/include/ SGI_CPU_SOURCES := lib/cpus/aarch64/neoverse_n1.S BL1_SOURCES += ${SGI_CPU_SOURCES} -BL2_SOURCES += ${SGICLARKA_BASE}/sgiclarka_plat.c \ - ${SGICLARKA_BASE}/sgiclarka_security.c \ +BL2_SOURCES += ${RDN1EDGE_BASE}/rdn1edge_plat.c \ + ${RDN1EDGE_BASE}/rdn1edge_security.c \ drivers/arm/tzc/tzc_dmc620.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c BL31_SOURCES += ${SGI_CPU_SOURCES} \ - ${SGICLARKA_BASE}/sgiclarka_plat.c \ + ${RDN1EDGE_BASE}/rdn1edge_plat.c \ drivers/cfi/v2m/v2m_flash.c \ lib/utils/mem_region.c \ plat/arm/common/arm_nor_psci_mem_protect.c # Add the FDT_SOURCES and options for Dynamic Config -FDT_SOURCES += ${SGICLARKA_BASE}/fdts/${PLAT}_tb_fw_config.dts +FDT_SOURCES += ${RDN1EDGE_BASE}/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)) -FDT_SOURCES += ${SGICLARKA_BASE}/fdts/${PLAT}_nt_fw_config.dts +FDT_SOURCES += ${RDN1EDGE_BASE}/fdts/${PLAT}_nt_fw_config.dts NT_FW_CONFIG := ${BUILD_PLAT}/fdts/${PLAT}_nt_fw_config.dtb # Add the NT_FW_CONFIG to FIP and specify the same to certtool diff --git a/plat/arm/board/sgiclarka/sgiclarka_plat.c b/plat/arm/board/rdn1edge/rdn1edge_plat.c index 3b7e5ee4e..3b7e5ee4e 100644 --- a/plat/arm/board/sgiclarka/sgiclarka_plat.c +++ b/plat/arm/board/rdn1edge/rdn1edge_plat.c diff --git a/plat/arm/board/rdn1edge/rdn1edge_security.c b/plat/arm/board/rdn1edge/rdn1edge_security.c new file mode 100644 index 000000000..ffa893524 --- /dev/null +++ b/plat/arm/board/rdn1edge/rdn1edge_security.c @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2019, ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <platform_def.h> + +#include <common/debug.h> +#include <drivers/arm/tzc_dmc620.h> + +uintptr_t rdn1edge_dmc_base[] = { + RDN1EDGE_DMC620_BASE0, + RDN1EDGE_DMC620_BASE1 +}; + +static const tzc_dmc620_driver_data_t rdn1edge_plat_driver_data = { + .dmc_base = rdn1edge_dmc_base, + .dmc_count = ARRAY_SIZE(rdn1edge_dmc_base) +}; + +static const tzc_dmc620_acc_addr_data_t rdn1edge_acc_addr_data[] = { + { + .region_base = ARM_AP_TZC_DRAM1_BASE, + .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, + .sec_attr = TZC_DMC620_REGION_S_RDWR + } +}; + +static const tzc_dmc620_config_data_t rdn1edge_plat_config_data = { + .plat_drv_data = &rdn1edge_plat_driver_data, + .plat_acc_addr_data = rdn1edge_acc_addr_data, + .acc_addr_count = ARRAY_SIZE(rdn1edge_acc_addr_data) +}; + +/* Initialize the secure environment */ +void plat_arm_security_setup(void) +{ + arm_tzc_dmc620_setup(&rdn1edge_plat_config_data); +} diff --git a/plat/arm/board/sgiclarka/sgiclarka_security.c b/plat/arm/board/sgiclarka/sgiclarka_security.c deleted file mode 100644 index c455111d1..000000000 --- a/plat/arm/board/sgiclarka/sgiclarka_security.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <common/debug.h> -#include <drivers/arm/tzc_dmc620.h> - -uintptr_t sgiclarka_dmc_base[] = { - SGICLARKA_DMC620_BASE0, - SGICLARKA_DMC620_BASE1 -}; - -static const tzc_dmc620_driver_data_t sgiclarka_plat_driver_data = { - .dmc_base = sgiclarka_dmc_base, - .dmc_count = ARRAY_SIZE(sgiclarka_dmc_base) -}; - -static const tzc_dmc620_acc_addr_data_t sgiclarka_acc_addr_data[] = { - { - .region_base = ARM_AP_TZC_DRAM1_BASE, - .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, - .sec_attr = TZC_DMC620_REGION_S_RDWR - } -}; - -static const tzc_dmc620_config_data_t sgiclarka_plat_config_data = { - .plat_drv_data = &sgiclarka_plat_driver_data, - .plat_acc_addr_data = sgiclarka_acc_addr_data, - .acc_addr_count = ARRAY_SIZE(sgiclarka_acc_addr_data) -}; - -/* Initialize the secure environment */ -void plat_arm_security_setup(void) -{ - arm_tzc_dmc620_setup(&sgiclarka_plat_config_data); -} diff --git a/plat/arm/board/sgiclarkh/sgiclarkh_security.c b/plat/arm/board/sgiclarkh/sgiclarkh_security.c deleted file mode 100644 index aaf9691ce..000000000 --- a/plat/arm/board/sgiclarkh/sgiclarkh_security.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2018, Arm Limited. All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -#include <platform_def.h> - -#include <common/debug.h> -#include <drivers/arm/tzc_dmc620.h> - -uintptr_t sgiclarkh_dmc_base[] = { - SGICLARKH_DMC620_BASE0, - SGICLARKH_DMC620_BASE1 -}; - -static const tzc_dmc620_driver_data_t sgiclarkh_plat_driver_data = { - .dmc_base = sgiclarkh_dmc_base, - .dmc_count = ARRAY_SIZE(sgiclarkh_dmc_base) -}; - -static const tzc_dmc620_acc_addr_data_t sgiclarkh_acc_addr_data[] = { - { - .region_base = ARM_AP_TZC_DRAM1_BASE, - .region_top = ARM_AP_TZC_DRAM1_BASE + ARM_TZC_DRAM1_SIZE - 1, - .sec_attr = TZC_DMC620_REGION_S_RDWR - } -}; - -static const tzc_dmc620_config_data_t sgiclarkh_plat_config_data = { - .plat_drv_data = &sgiclarkh_plat_driver_data, - .plat_acc_addr_data = sgiclarkh_acc_addr_data, - .acc_addr_count = ARRAY_SIZE(sgiclarkh_acc_addr_data) -}; - -/* Initialize the secure environment */ -void plat_arm_security_setup(void) -{ - arm_tzc_dmc620_setup(&sgiclarkh_plat_config_data); -} diff --git a/plat/intel/soc/stratix10/aarch64/plat_helpers.S b/plat/intel/soc/stratix10/aarch64/plat_helpers.S index 8f755be4c..f077cf324 100644 --- a/plat/intel/soc/stratix10/aarch64/plat_helpers.S +++ b/plat/intel/soc/stratix10/aarch64/plat_helpers.S @@ -19,8 +19,6 @@ .globl platform_mem_init .globl plat_get_my_entrypoint - .globl stratix10_sec_entry - .globl cpuid_release /* ----------------------------------------------------- * void plat_secondary_cold_boot_setup (void); @@ -34,11 +32,11 @@ func plat_secondary_cold_boot_setup /* Wait until the it gets reset signal from rstmgr gets populated */ poll_mailbox: - wfi + wfi - adr x0, stratix10_sec_entry + mov_imm x0, PLAT_S10_SEC_ENTRY ldr x1, [x0] - adr x2, cpuid_release + mov_imm x2, PLAT_CPUID_RELEASE ldr x3, [x2] mrs x4, mpidr_el1 and x4, x4, #0xff @@ -68,7 +66,7 @@ func plat_my_core_pos endfunc plat_my_core_pos func plat_get_my_entrypoint - adr x1,stratix10_sec_entry + mov_imm x1, PLAT_S10_SEC_ENTRY ldr x0, [x1] ret endfunc plat_get_my_entrypoint @@ -121,9 +119,3 @@ endfunc platform_mem_init .data .align 3 -stratix10_sec_entry: - .quad 0 - -cpuid_release: - .quad 0 - diff --git a/plat/intel/soc/stratix10/bl31_plat_setup.c b/plat/intel/soc/stratix10/bl31_plat_setup.c new file mode 100644 index 000000000..21a370875 --- /dev/null +++ b/plat/intel/soc/stratix10/bl31_plat_setup.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <assert.h> +#include <arch.h> +#include <arch_helpers.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 <platform_private.h> + +#include "aarch64/stratix10_private.h" +#include "s10_handoff.h" +#include "s10_reset_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; + +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 on this platform can have 0x0 as the entrypoint */ + if (next_image_info->pc) + return next_image_info; + else + return NULL; +} + +void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, + u_register_t arg2, u_register_t arg3) +{ + static console_16550_t console; + + console_16550_register(PLAT_UART0_BASE, PLAT_UART_CLOCK, PLAT_BAUDRATE, + &console); + /* + * Check params passed from BL31 should not be NULL, + */ + 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; + + 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; + } + 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) +}; + +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, + .interrupt_props = s10_interrupt_props, + .interrupt_props_num = ARRAY_SIZE(s10_interrupt_props), + .target_masks = target_mask_array, + .target_masks_num = ARRAY_SIZE(target_mask_array), +}; + +/******************************************************************************* + * Perform any BL3-1 platform setup code + ******************************************************************************/ +void bl31_platform_setup(void) +{ + /* Initialize the gic cpu and distributor interfaces */ + gicv2_driver_init(&plat_gicv2_gic_data); + gicv2_distif_init(); + gicv2_pcpu_distif_init(); + gicv2_cpuif_enable(); +} + +const mmap_region_t plat_stratix10_mmap[] = { + MAP_REGION_FLAT(DRAM_BASE, DRAM_SIZE, MT_MEMORY | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE1_BASE, DEVICE1_SIZE, MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(DEVICE2_BASE, DEVICE2_SIZE, MT_DEVICE | MT_RW | MT_NS), + MAP_REGION_FLAT(OCRAM_BASE, OCRAM_SIZE, + MT_NON_CACHEABLE | MT_RW | MT_SECURE), + MAP_REGION_FLAT(DEVICE3_BASE, DEVICE3_SIZE, + 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}, +}; + +/******************************************************************************* + * Perform the very early platform specific architectural setup here. At the + * moment this is only intializes the mmu in a quick and dirty way. + ******************************************************************************/ +void bl31_plat_arch_setup(void) +{ + const mmap_region_t bl_regions[] = { + MAP_REGION_FLAT(BL31_BASE, BL31_END - BL31_BASE, + MT_MEMORY | MT_RW | MT_SECURE), + 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 + MAP_REGION_FLAT(BL_COHERENT_RAM_BASE, + BL_COHERENT_RAM_END - BL_COHERENT_RAM_BASE, + MT_DEVICE | MT_RW | MT_SECURE), +#endif + {0}, + }; + + setup_page_tables(bl_regions, plat_stratix10_mmap); + enable_mmu_el3(0); +} + diff --git a/plat/intel/soc/stratix10/include/plat_macros.S b/plat/intel/soc/stratix10/include/plat_macros.S index 667f6c8ff..495aa9dd1 100644 --- a/plat/intel/soc/stratix10/include/plat_macros.S +++ b/plat/intel/soc/stratix10/include/plat_macros.S @@ -17,9 +17,6 @@ * --------------------------------------------- */ .macro plat_crash_print_regs - mov_imm x17, PLAT_GICC_BASE - mov_imm x16, PLAT_GICD_BASE - arm_print_gic_regs .endm #endif /* __PLAT_MACROS_S__ */ diff --git a/plat/intel/soc/stratix10/include/s10_mailbox.h b/plat/intel/soc/stratix10/include/s10_mailbox.h new file mode 100644 index 000000000..78db52059 --- /dev/null +++ b/plat/intel/soc/stratix10/include/s10_mailbox.h @@ -0,0 +1,125 @@ +/* + * 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 (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 + +/* 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/plat_psci.c b/plat/intel/soc/stratix10/plat_psci.c new file mode 100644 index 000000000..757852887 --- /dev/null +++ b/plat/intel/soc/stratix10/plat_psci.c @@ -0,0 +1,209 @@ +/* + * 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 "platform_private.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_S10_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 new file mode 100644 index 000000000..2c2332ba9 --- /dev/null +++ b/plat/intel/soc/stratix10/plat_sip_svc.c @@ -0,0 +1,378 @@ +/* + * 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_topology.c b/plat/intel/soc/stratix10/plat_topology.c new file mode 100644 index 000000000..4951f742a --- /dev/null +++ b/plat/intel/soc/stratix10/plat_topology.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2019, ARM Limited and Contributors. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <arch.h> +#include <platform_def.h> +#include <lib/psci/psci.h> +static const unsigned char plat_power_domain_tree_desc[] = {1, 4}; + +/******************************************************************************* + * This function returns the default topology tree information. + ******************************************************************************/ +const unsigned char *plat_get_power_domain_tree_desc(void) +{ + return plat_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; + + /* + * Validate cpu_id by checking whether it represents a CPU in + * one of the two clusters present on the platform. + */ + if (cpu_id >= PLATFORM_MAX_CPUS_PER_CLUSTER) + return -1; + + return (cpu_id + (cluster_id * 4)); +} + diff --git a/plat/intel/soc/stratix10/platform.mk b/plat/intel/soc/stratix10/platform.mk index 01b0c7679..debdea176 100644 --- a/plat/intel/soc/stratix10/platform.mk +++ b/plat/intel/soc/stratix10/platform.mk @@ -46,8 +46,23 @@ BL2_SOURCES += \ plat/intel/soc/stratix10/soc/s10_system_manager.c \ common/desc_image_load.c -# plat/intel/soc/stratix10/plat_topology.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/stratix10/plat_sip_svc.c \ + plat/intel/soc/stratix10/bl31_plat_setup.c \ + plat/intel/soc/stratix10/plat_psci.c \ + plat/intel/soc/stratix10/plat_topology.c \ + plat/intel/soc/stratix10/plat_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 \ PROGRAMMABLE_RESET_ADDRESS := 0 BL2_AT_EL3 := 1 MULTI_CONSOLE_API := 1 +USE_COHERENT_MEM := 1 diff --git a/plat/intel/soc/stratix10/platform_def.h b/plat/intel/soc/stratix10/platform_def.h index 88469eda9..3ed9023ac 100644 --- a/plat/intel/soc/stratix10/platform_def.h +++ b/plat/intel/soc/stratix10/platform_def.h @@ -15,6 +15,9 @@ #include <plat/common/common_def.h> +#define PLAT_CPUID_RELEASE 0xffe1b000 +#define PLAT_S10_SEC_ENTRY 0xffe1b008 + /* Define next boot image name and offset */ #define PLAT_NS_IMAGE_OFFSET 0x50000 #define PLAT_HANDOFF_OFFSET 0xFFE3F000 @@ -75,7 +78,7 @@ #define DRAM_SIZE (0x80000000) #define OCRAM_BASE (0xFFE00000) -#define OCRAM_SIZE (0x00100000) +#define OCRAM_SIZE (0x00040000) #define MEM64_BASE (0x0100000000) #define MEM64_SIZE (0x1F00000000) @@ -111,10 +114,10 @@ #define BL1_RW_SIZE (0x14000) #define BL2_BASE (0xffe00000) -#define BL2_LIMIT (0xffe1c000) +#define BL2_LIMIT (0xffe1b000) #define BL31_BASE (0xffe1c000) -#define BL31_LIMIT (0xffe3ffff) +#define BL31_LIMIT (0xffe3bfff) /******************************************************************************* * Platform specific page table and MMU setup constants diff --git a/plat/intel/soc/stratix10/soc/s10_mailbox.c b/plat/intel/soc/stratix10/soc/s10_mailbox.c new file mode 100644 index 000000000..00a07f33a --- /dev/null +++ b/plat/intel/soc/stratix10/soc/s10_mailbox.c @@ -0,0 +1,275 @@ +/* + * 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; +} + |