diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index f8aa65ab7..b26bd65d2 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -69,6 +69,8 @@ void uniphier_gic_cpuif_enable(void); void uniphier_gic_cpuif_disable(void); void uniphier_gic_pcpu_init(void); +void uniphier_psci_init(unsigned int soc); + unsigned int uniphier_calc_core_pos(u_register_t mpidr); #endif /* UNIPHIER_H */ diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index dac08fb54..15ceed4bb 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -80,6 +80,8 @@ void bl31_platform_setup(void) /* Enable and initialize the System level generic timer */ mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); + + uniphier_psci_init(uniphier_soc); } void bl31_plat_arch_setup(void) diff --git a/plat/socionext/uniphier/uniphier_psci.c b/plat/socionext/uniphier/uniphier_psci.c index 2acc87440..a371705b1 100644 --- a/plat/socionext/uniphier/uniphier_psci.c +++ b/plat/socionext/uniphier/uniphier_psci.c @@ -1,9 +1,11 @@ /* - * 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 */ +#include <assert.h> + #include <arch_helpers.h> #include <common/debug.h> #include <errno.h> @@ -12,15 +14,18 @@ #include "uniphier.h" -#define UNIPHIER_ROM_RSV0 0x59801200 +#define UNIPHIER_ROM_RSV0 0x0 -#define UNIPHIER_SLFRSTSEL 0x61843010 +#define UNIPHIER_SLFRSTSEL 0x10 #define UNIPHIER_SLFRSTSEL_MASK GENMASK(1, 0) -#define UNIPHIER_SLFRSTCTL 0x61843014 +#define UNIPHIER_SLFRSTCTL 0x14 #define UNIPHIER_SLFRSTCTL_RST BIT(0) #define MPIDR_AFFINITY_INVALID ((u_register_t)-1) +static uintptr_t uniphier_rom_rsv_base; +static uintptr_t uniphier_slfrst_base; + uintptr_t uniphier_sec_entrypoint; void uniphier_warmboot_entrypoint(void); @@ -34,7 +39,7 @@ static int uniphier_psci_pwr_domain_on(u_register_t mpidr) flush_dcache_range((uint64_t)&uniphier_holding_pen_release, sizeof(uniphier_holding_pen_release)); - mmio_write_64(UNIPHIER_ROM_RSV0, + mmio_write_64(uniphier_rom_rsv_base + UNIPHIER_ROM_RSV0, (uint64_t)&uniphier_warmboot_entrypoint); sev(); @@ -71,8 +76,10 @@ static void __dead2 uniphier_psci_pwr_domain_pwr_down_wfi( static void uniphier_self_system_reset(void) { - mmio_clrbits_32(UNIPHIER_SLFRSTSEL, UNIPHIER_SLFRSTSEL_MASK); - mmio_setbits_32(UNIPHIER_SLFRSTCTL, UNIPHIER_SLFRSTCTL_RST); + mmio_clrbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTSEL, + UNIPHIER_SLFRSTSEL_MASK); + mmio_setbits_32(uniphier_slfrst_base + UNIPHIER_SLFRSTCTL, + UNIPHIER_SLFRSTCTL_RST); } static void __dead2 uniphier_psci_system_off(void) @@ -114,13 +121,40 @@ 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; + uniphier_sec_entrypoint = sec_entrypoint; + flush_dcache_range((uint64_t)&uniphier_sec_entrypoint, + sizeof(uniphier_sec_entrypoint)); - soc = uniphier_get_soc_id(); - if (soc == UNIPHIER_SOC_UNKNOWN) { - ERROR("unsupported SoC\n"); - return -ENOTSUP; - } + *psci_ops = &uniphier_psci_ops; + + return 0; +} + +struct uniphier_psci_ctrl_base { + uintptr_t rom_rsv_base; + uintptr_t slfrst_base; +}; + +static const struct uniphier_psci_ctrl_base uniphier_psci_ctrl_base[] = { + [UNIPHIER_SOC_LD11] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, + [UNIPHIER_SOC_LD20] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, + [UNIPHIER_SOC_PXS3] = { + .rom_rsv_base = 0x59801200, + .slfrst_base = 0x61843000, + }, +}; + +void uniphier_psci_init(unsigned int soc) +{ + assert(soc < ARRAY_SIZE(uniphier_psci_ctrl_base)); + uniphier_rom_rsv_base = uniphier_psci_ctrl_base[soc].rom_rsv_base; + uniphier_slfrst_base = uniphier_psci_ctrl_base[soc].slfrst_base; if (uniphier_get_boot_master(soc) == UNIPHIER_BOOT_MASTER_SCP) { uniphier_psci_scp_mode = uniphier_scp_is_running(); @@ -130,12 +164,4 @@ int plat_setup_psci_ops(uintptr_t sec_entrypoint, 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)); - - *psci_ops = &uniphier_psci_ops; - - return 0; }