diff options
Diffstat (limited to 'plat/allwinner/common/sunxi_common.c')
-rw-r--r-- | plat/allwinner/common/sunxi_common.c | 119 |
1 files changed, 46 insertions, 73 deletions
diff --git a/plat/allwinner/common/sunxi_common.c b/plat/allwinner/common/sunxi_common.c index 0ca18adc33..62f4fcbd9e 100644 --- a/plat/allwinner/common/sunxi_common.c +++ b/plat/allwinner/common/sunxi_common.c @@ -1,36 +1,28 @@ /* - * 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 <errno.h> -#include <platform_def.h> - -#include <arch_helpers.h> #include <common/debug.h> #include <lib/mmio.h> +#include <lib/smccc.h> #include <lib/xlat_tables/xlat_tables_v2.h> -#include <plat/common/platform.h> +#include <services/arm_arch_svc.h> #include <sunxi_def.h> #include <sunxi_mmap.h> #include <sunxi_private.h> -static const mmap_region_t sunxi_mmap[PLATFORM_MMAP_REGIONS + 1] = { +static const mmap_region_t sunxi_mmap[MAX_STATIC_MMAP_REGIONS + 1] = { MAP_REGION_FLAT(SUNXI_SRAM_BASE, SUNXI_SRAM_SIZE, - MT_RW_DATA | MT_SECURE), - MAP_REGION_FLAT(SUNXI_SCP_BASE, SUNXI_SCP_SIZE, MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), MAP_REGION_FLAT(SUNXI_DEV_BASE, SUNXI_DEV_SIZE, MT_DEVICE | MT_RW | MT_SECURE | MT_EXECUTE_NEVER), - MAP_REGION(SUNXI_DRAM_BASE, SUNXI_DRAM_VIRT_BASE, SUNXI_DRAM_SEC_SIZE, - 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_RO_DATA | MT_NS), + MAP_REGION(PRELOADED_BL33_BASE, SUNXI_BL33_VIRT_BASE, + SUNXI_DRAM_MAP_SIZE, MT_RW_DATA | MT_NS), {}, }; @@ -39,26 +31,29 @@ unsigned int plat_get_syscnt_freq2(void) return SUNXI_OSC24M_CLK_IN_HZ; } -uintptr_t plat_get_ns_image_entrypoint(void) -{ -#ifdef PRELOADED_BL33_BASE - return PRELOADED_BL33_BASE; -#else - return PLAT_SUNXI_NS_IMAGE_OFFSET; -#endif -} - void sunxi_configure_mmu_el3(int flags) { mmap_add_region(BL_CODE_BASE, BL_CODE_BASE, BL_CODE_END - BL_CODE_BASE, MT_CODE | MT_SECURE); + mmap_add_region(BL_CODE_END, BL_CODE_END, + BL_END - BL_CODE_END, + MT_RW_DATA | MT_SECURE); +#if SEPARATE_CODE_AND_RODATA mmap_add_region(BL_RO_DATA_BASE, BL_RO_DATA_BASE, BL_RO_DATA_END - BL_RO_DATA_BASE, MT_RO_DATA | MT_SECURE); +#endif +#if SEPARATE_NOBITS_REGION + mmap_add_region(BL_NOBITS_BASE, BL_NOBITS_BASE, + BL_NOBITS_END - BL_NOBITS_BASE, + MT_RW_DATA | MT_SECURE); +#endif +#if USE_COHERENT_MEM 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); +#endif mmap_add(sunxi_mmap); init_xlat_tables(); @@ -125,11 +120,10 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) device_bit = BIT(6); break; case SUNXI_SOC_H6: - if (use_rsb) - return -ENODEV; - pin_func = 0x33; + case SUNXI_SOC_H616: + pin_func = use_rsb ? 0x22 : 0x33; device_bit = BIT(16); - reset_offset = 0x19c; + reset_offset = use_rsb ? 0x1bc : 0x19c; break; case SUNXI_SOC_A64: pin_func = use_rsb ? 0x22 : 0x33; @@ -141,7 +135,7 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) } /* un-gate R_PIO clock */ - if (socid != SUNXI_SOC_H6) + if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616) mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, BIT(0)); /* switch pins PL0 and PL1 to the desired function */ @@ -154,10 +148,10 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) mmio_clrsetbits_32(SUNXI_R_PIO_BASE + 0x1c, 0x0fU, 0x5U); /* un-gate clock */ - if (socid != SUNXI_SOC_H6) + if (socid != SUNXI_SOC_H6 && socid != SUNXI_SOC_H616) mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x28, device_bit); else - mmio_setbits_32(SUNXI_R_PRCM_BASE + 0x19c, device_bit | BIT(0)); + mmio_setbits_32(SUNXI_R_PRCM_BASE + reset_offset, BIT(0)); /* assert, then de-assert reset of I2C/RSB controller */ mmio_clrbits_32(SUNXI_R_PRCM_BASE + reset_offset, device_bit); @@ -166,49 +160,28 @@ int sunxi_init_platform_r_twi(uint16_t socid, bool use_rsb) return 0; } -/* This lock synchronises access to the arisc management processor. */ -DEFINE_BAKERY_LOCK(arisc_lock); +int32_t plat_is_smccc_feature_available(u_register_t fid) +{ + switch (fid) { + case SMCCC_ARCH_SOC_ID: + return SMC_ARCH_CALL_SUCCESS; + default: + return SMC_ARCH_CALL_NOT_SUPPORTED; + } +} + +int32_t plat_get_soc_version(void) +{ + int32_t ret; -/* - * Tell the "arisc" SCP core (an OpenRISC core) to execute some code. - * We don't have any service running there, so we place some OpenRISC code - * 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, uint16_t param) + ret = SOC_ID_SET_JEP_106(JEDEC_ALLWINNER_BKID, JEDEC_ALLWINNER_MFID); + + return ret | (sunxi_read_soc_id() & SOC_ID_IMPL_DEF_MASK); +} + +int32_t plat_get_soc_revision(void) { - uintptr_t arisc_reset_vec = SUNXI_SRAM_A2_BASE + 0x100; - - do { - bakery_lock_get(&arisc_lock); - /* Wait until the arisc is in reset state. */ - if (!(mmio_read_32(SUNXI_R_CPUCFG_BASE) & BIT(0))) - break; - - bakery_lock_release(&arisc_lock); - } while (1); - - /* Patch up the code to feed in an input parameter. */ - code[0] = (code[0] & ~0xffff) | param; - clean_dcache_range((uintptr_t)code, size); - - /* - * The OpenRISC unconditional branch has opcode 0, the branch offset - * is in the lower 26 bits, containing the distance to the target, - * in instruction granularity (32 bits). - */ - mmio_write_32(arisc_reset_vec, ((uintptr_t)code - arisc_reset_vec) / 4); - clean_dcache_range(arisc_reset_vec, 4); - - /* De-assert the arisc reset line to let it run. */ - mmio_setbits_32(SUNXI_R_CPUCFG_BASE, BIT(0)); - - /* - * We release the lock here, although the arisc is still busy. - * But as long as it runs, the reset line is high, so other users - * won't leave the loop above. - * Once it has finished, the code is supposed to clear the reset line, - * to signal this to other users. - */ - bakery_lock_release(&arisc_lock); + uint32_t reg = mmio_read_32(SRAM_VER_REG); + + return reg & SUNXI_VER_BITS_MASK; } |