diff options
Diffstat (limited to 'plat/socionext/uniphier')
-rw-r--r-- | plat/socionext/uniphier/include/platform_def.h | 1 | ||||
-rw-r--r-- | plat/socionext/uniphier/platform.mk | 20 | ||||
-rw-r--r-- | plat/socionext/uniphier/tsp/uniphier_tsp_setup.c | 15 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier.h | 15 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_bl2_setup.c | 25 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_bl31_setup.c | 37 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_boot_device.c | 48 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_console.S | 9 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_console_setup.c | 54 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_emmc.c | 48 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_image_desc.c | 4 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_io_storage.c | 47 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_nand.c | 18 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_psci.c | 68 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_soc_info.c | 13 | ||||
-rw-r--r-- | plat/socionext/uniphier/uniphier_xlat_setup.c | 48 |
16 files changed, 322 insertions, 148 deletions
diff --git a/plat/socionext/uniphier/include/platform_def.h b/plat/socionext/uniphier/include/platform_def.h index 7c6341d14..b23386d8b 100644 --- a/plat/socionext/uniphier/include/platform_def.h +++ b/plat/socionext/uniphier/include/platform_def.h @@ -62,7 +62,6 @@ #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 9 #define MAX_MMAP_REGIONS 13 diff --git a/plat/socionext/uniphier/platform.mk b/plat/socionext/uniphier/platform.mk index 8e96b68bb..6edd181f4 100644 --- a/plat/socionext/uniphier/platform.mk +++ b/plat/socionext/uniphier/platform.mk @@ -14,6 +14,16 @@ override ENABLE_SVE_FOR_NS := 0 # UNIPHIER_MEM_BASE so that all TF images are loaded at their link addresses. override ENABLE_PIE := 1 +ALLOW_RO_XLAT_TABLES := 1 + +ifeq ($(ALLOW_RO_XLAT_TABLES),1) +BL31_CPPFLAGS += -DPLAT_RO_XLAT_TABLES +BL32_CPPFLAGS += -DPLAT_RO_XLAT_TABLES +endif + +# The dynamic xlat table is only used in BL2 +BL2_CPPFLAGS += -DPLAT_XLAT_TABLES_DYNAMIC + # Cortex-A53 revision r0p4-51rel0 # needed for LD20, unneeded for LD11, PXs3 (no ACE) ERRATA_A53_855873 := 1 @@ -55,10 +65,11 @@ BL2_SOURCES += common/desc_image_load.c \ $(PLAT_PATH)/uniphier_scp.c \ $(PLAT_PATH)/uniphier_usb.c +# Include GICv3 driver files +include drivers/arm/gic/v3/gicv3.mk + BL31_SOURCES += drivers/arm/cci/cci.c \ - drivers/arm/gic/common/gic_common.c \ - drivers/arm/gic/v3/gicv3_helpers.c \ - drivers/arm/gic/v3/gicv3_main.c \ + ${GICV3_SOURCES} \ lib/cpus/aarch64/cortex_a53.S \ lib/cpus/aarch64/cortex_a72.S \ plat/common/plat_gicv3.c \ @@ -81,7 +92,8 @@ include drivers/auth/mbedtls/mbedtls_x509.mk BL2_SOURCES += drivers/auth/auth_mod.c \ drivers/auth/crypto_mod.c \ drivers/auth/img_parser_mod.c \ - drivers/auth/tbbr/tbbr_cot.c \ + drivers/auth/tbbr/tbbr_cot_common.c \ + drivers/auth/tbbr/tbbr_cot_bl2.c \ plat/common/tbbr/plat_tbbr.c \ $(PLAT_PATH)/uniphier_rotpk.S \ $(PLAT_PATH)/uniphier_tbbr.c diff --git a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c index 4f58b683c..4bbb2595c 100644 --- a/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c +++ b/plat/socionext/uniphier/tsp/uniphier_tsp_setup.c @@ -4,16 +4,24 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <errno.h> + #include <platform_def.h> #include <common/bl_common.h> -#include <lib/xlat_tables/xlat_mmu_helpers.h> +#include <plat/common/platform.h> #include "../uniphier.h" +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; + void tsp_early_platform_setup(void) { - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); } void tsp_platform_setup(void) @@ -22,6 +30,5 @@ void tsp_platform_setup(void) void tsp_plat_arch_setup(void) { - uniphier_mmap_setup(); - enable_mmu_el1(0); + uniphier_mmap_setup(uniphier_soc); } diff --git a/plat/socionext/uniphier/uniphier.h b/plat/socionext/uniphier/uniphier.h index 729dc5caa..ee520ad23 100644 --- a/plat/socionext/uniphier/uniphier.h +++ b/plat/socionext/uniphier/uniphier.h @@ -25,7 +25,8 @@ unsigned int uniphier_get_boot_device(unsigned int soc); #define UNIPHIER_BOOT_DEVICE_EMMC 0 #define UNIPHIER_BOOT_DEVICE_NAND 1 #define UNIPHIER_BOOT_DEVICE_NOR 2 -#define UNIPHIER_BOOT_DEVICE_USB 3 +#define UNIPHIER_BOOT_DEVICE_SD 3 +#define UNIPHIER_BOOT_DEVICE_USB 4 #define UNIPHIER_BOOT_DEVICE_RSV 0xffffffff unsigned int uniphier_get_boot_master(unsigned int soc); @@ -34,11 +35,13 @@ unsigned int uniphier_get_boot_master(unsigned int soc); #define UNIPHIER_BOOT_MASTER_SCP 1 #define UNIPHIER_BOOT_MASTER_EXT 2 -void uniphier_console_setup(void); +void uniphier_console_setup(unsigned int soc); 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_emmc_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec); +int uniphier_nand_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec); int uniphier_usb_init(unsigned int soc, struct io_block_dev_spec **block_dev_spec); @@ -54,7 +57,7 @@ void uniphier_scp_open_com(void); void uniphier_scp_system_off(void); void uniphier_scp_system_reset(void); -void uniphier_mmap_setup(void); +void uniphier_mmap_setup(unsigned int soc); void uniphier_cci_init(unsigned int soc); void uniphier_cci_enable(void); @@ -66,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_bl2_setup.c b/plat/socionext/uniphier/uniphier_bl2_setup.c index 11d837cf4..4524610c0 100644 --- a/plat/socionext/uniphier/uniphier_bl2_setup.c +++ b/plat/socionext/uniphier/uniphier_bl2_setup.c @@ -21,43 +21,40 @@ #include "uniphier.h" -#define UNIPHIER_IMAGE_BUF_OFFSET 0x04300000UL -#define UNIPHIER_IMAGE_BUF_SIZE 0x00100000UL +#define UNIPHIER_IMAGE_BUF_OFFSET 0x03800000UL +#define UNIPHIER_IMAGE_BUF_SIZE 0x00800000UL static uintptr_t uniphier_mem_base = UNIPHIER_MEM_BASE; +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; static int uniphier_bl2_kick_scp; void bl2_el3_early_platform_setup(u_register_t x0, u_register_t x1, u_register_t x2, u_register_t x3) { - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); } void bl2_el3_plat_arch_setup(void) { - unsigned int soc; int skip_scp = 0; int ret; - uniphier_mmap_setup(); - enable_mmu_el3(0); + uniphier_mmap_setup(uniphier_soc); /* 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, uniphier_mem_base); + ret = uniphier_io_setup(uniphier_soc, uniphier_mem_base); if (ret) { ERROR("failed to setup io devices\n"); plat_error_handler(ret); } - switch (uniphier_get_boot_master(soc)) { + switch (uniphier_get_boot_master(uniphier_soc)) { case UNIPHIER_BOOT_MASTER_THIS: INFO("Booting from this SoC\n"); skip_scp = 1; diff --git a/plat/socionext/uniphier/uniphier_bl31_setup.c b/plat/socionext/uniphier/uniphier_bl31_setup.c index 47f2378bc..c2baebde9 100644 --- a/plat/socionext/uniphier/uniphier_bl31_setup.c +++ b/plat/socionext/uniphier/uniphier_bl31_setup.c @@ -14,13 +14,13 @@ #include <common/debug.h> #include <drivers/console.h> #include <lib/mmio.h> -#include <lib/xlat_tables/xlat_mmu_helpers.h> #include <plat/common/platform.h> #include "uniphier.h" static entry_point_info_t bl32_image_ep_info; static entry_point_info_t bl33_image_ep_info; +static unsigned int uniphier_soc = UNIPHIER_SOC_UNKNOWN; entry_point_info_t *bl31_plat_get_next_image_ep_info(uint32_t type) { @@ -37,7 +37,11 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, bl_params_node_t *bl_params = ((bl_params_t *)from_bl2)->head; - uniphier_console_setup(); + uniphier_soc = uniphier_get_soc_id(); + if (uniphier_soc == UNIPHIER_SOC_UNKNOWN) + plat_error_handler(-ENOTSUP); + + uniphier_console_setup(uniphier_soc); while (bl_params) { if (bl_params->image_id == BL32_IMAGE_ID) @@ -53,32 +57,33 @@ void bl31_early_platform_setup2(u_register_t arg0, u_register_t arg1, panic(); } -#define UNIPHIER_SYS_CNTCTL_BASE 0x60E00000 +static const uintptr_t uniphier_cntctl_base[] = { + [UNIPHIER_SOC_LD11] = 0x60e00000, + [UNIPHIER_SOC_LD20] = 0x60e00000, + [UNIPHIER_SOC_PXS3] = 0x60e00000, +}; void bl31_platform_setup(void) { - unsigned int soc; + uintptr_t cntctl_base; - soc = uniphier_get_soc_id(); - if (soc == UNIPHIER_SOC_UNKNOWN) { - ERROR("unsupported SoC\n"); - plat_error_handler(-ENOTSUP); - } - - uniphier_cci_init(soc); + uniphier_cci_init(uniphier_soc); uniphier_cci_enable(); /* Initialize the GIC driver, cpu and distributor interfaces */ - uniphier_gic_driver_init(soc); + uniphier_gic_driver_init(uniphier_soc); uniphier_gic_init(); + assert(uniphier_soc < ARRAY_SIZE(uniphier_cntctl_base)); + cntctl_base = uniphier_cntctl_base[uniphier_soc]; + /* Enable and initialize the System level generic timer */ - mmio_write_32(UNIPHIER_SYS_CNTCTL_BASE + CNTCR_OFF, - CNTCR_FCREQ(0U) | CNTCR_EN); + mmio_write_32(cntctl_base + CNTCR_OFF, CNTCR_FCREQ(0U) | CNTCR_EN); + + uniphier_psci_init(uniphier_soc); } void bl31_plat_arch_setup(void) { - uniphier_mmap_setup(); - enable_mmu_el3(0); + uniphier_mmap_setup(uniphier_soc); } diff --git a/plat/socionext/uniphier/uniphier_boot_device.c b/plat/socionext/uniphier/uniphier_boot_device.c index 462c0859c..36a9908be 100644 --- a/plat/socionext/uniphier/uniphier_boot_device.c +++ b/plat/socionext/uniphier/uniphier_boot_device.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 */ @@ -13,22 +13,29 @@ #include "uniphier.h" -#define UNIPHIER_PINMON0 0x5f900100 -#define UNIPHIER_PINMON2 0x5f900108 +#define UNIPHIER_PINMON0 0x0 +#define UNIPHIER_PINMON2 0x8 -static int uniphier_ld11_is_usb_boot(uint32_t pinmon) +static const uintptr_t uniphier_pinmon_base[] = { + [UNIPHIER_SOC_LD11] = 0x5f900100, + [UNIPHIER_SOC_LD20] = 0x5f900100, + [UNIPHIER_SOC_PXS3] = 0x5f900100, +}; + +static bool uniphier_ld11_is_usb_boot(uint32_t pinmon) { return !!(~pinmon & 0x00000080); } -static int uniphier_ld20_is_usb_boot(uint32_t pinmon) +static bool uniphier_ld20_is_usb_boot(uint32_t pinmon) { return !!(~pinmon & 0x00000780); } -static int uniphier_pxs3_is_usb_boot(uint32_t pinmon) +static bool uniphier_pxs3_is_usb_boot(uint32_t pinmon) { - uint32_t pinmon2 = mmio_read_32(UNIPHIER_PINMON2); + uintptr_t pinmon_base = uniphier_pinmon_base[UNIPHIER_SOC_PXS3]; + uint32_t pinmon2 = mmio_read_32(pinmon_base + UNIPHIER_PINMON2); return !!(pinmon2 & BIT(31)); } @@ -106,20 +113,25 @@ static unsigned int uniphier_pxs3_get_boot_device(uint32_t pinmon) } struct uniphier_boot_device_info { - int (*is_usb_boot)(uint32_t pinmon); + bool have_boot_swap; + bool (*is_sd_boot)(uint32_t pinmon); + bool (*is_usb_boot)(uint32_t pinmon); unsigned int (*get_boot_device)(uint32_t pinmon); }; static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { [UNIPHIER_SOC_LD11] = { + .have_boot_swap = true, .is_usb_boot = uniphier_ld11_is_usb_boot, .get_boot_device = uniphier_ld11_get_boot_device, }, [UNIPHIER_SOC_LD20] = { + .have_boot_swap = true, .is_usb_boot = uniphier_ld20_is_usb_boot, .get_boot_device = uniphier_ld11_get_boot_device, }, [UNIPHIER_SOC_PXS3] = { + .have_boot_swap = true, .is_usb_boot = uniphier_pxs3_is_usb_boot, .get_boot_device = uniphier_pxs3_get_boot_device, }, @@ -128,17 +140,24 @@ static const struct uniphier_boot_device_info uniphier_boot_device_info[] = { unsigned int uniphier_get_boot_device(unsigned int soc) { const struct uniphier_boot_device_info *info; + uintptr_t pinmon_base; uint32_t pinmon; assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); info = &uniphier_boot_device_info[soc]; - pinmon = mmio_read_32(UNIPHIER_PINMON0); + assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); + pinmon_base = uniphier_pinmon_base[soc]; + + pinmon = mmio_read_32(pinmon_base + UNIPHIER_PINMON0); - if (!(pinmon & BIT(29))) + if (info->have_boot_swap && !(pinmon & BIT(29))) return UNIPHIER_BOOT_DEVICE_NOR; - if (info->is_usb_boot(pinmon)) + if (info->is_sd_boot && info->is_sd_boot(pinmon)) + return UNIPHIER_BOOT_DEVICE_SD; + + if (info->is_usb_boot && info->is_usb_boot(pinmon)) return UNIPHIER_BOOT_DEVICE_USB; return info->get_boot_device(pinmon); @@ -155,7 +174,12 @@ unsigned int uniphier_get_boot_master(unsigned int soc) assert(soc < ARRAY_SIZE(uniphier_have_onchip_scp)); if (uniphier_have_onchip_scp[soc]) { - if (mmio_read_32(UNIPHIER_PINMON0) & BIT(27)) + uintptr_t pinmon_base; + + assert(soc < ARRAY_SIZE(uniphier_boot_device_info)); + pinmon_base = uniphier_pinmon_base[soc]; + + if (mmio_read_32(pinmon_base + UNIPHIER_PINMON0) & BIT(27)) return UNIPHIER_BOOT_MASTER_THIS; else return UNIPHIER_BOOT_MASTER_SCP; diff --git a/plat/socionext/uniphier/uniphier_console.S b/plat/socionext/uniphier/uniphier_console.S index 1113c6e81..48927f414 100644 --- a/plat/socionext/uniphier/uniphier_console.S +++ b/plat/socionext/uniphier/uniphier_console.S @@ -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 */ @@ -17,7 +17,7 @@ */ .globl uniphier_console_putc func uniphier_console_putc - ldr x1, [x1, #CONSOLE_T_DRVDATA] + ldr x1, [x1, #CONSOLE_T_BASE] /* Wait until the transmitter FIFO gets empty */ 0: ldr w2, [x1, #UNIPHIER_UART_LSR] @@ -36,7 +36,7 @@ endfunc uniphier_console_putc */ .globl uniphier_console_getc func uniphier_console_getc - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] ldr w1, [x0, #UNIPHIER_UART_LSR] tbz w1, #UNIPHIER_UART_LSR_DR_BIT, 0f @@ -55,12 +55,11 @@ endfunc uniphier_console_getc */ .global uniphier_console_flush func uniphier_console_flush - ldr x0, [x0, #CONSOLE_T_DRVDATA] + ldr x0, [x0, #CONSOLE_T_BASE] /* wait until the transmitter gets empty */ 0: ldr w1, [x0, #UNIPHIER_UART_LSR] tbz w1, #UNIPHIER_UART_LSR_TEMT_BIT, 0b - mov w0, #0 ret endfunc uniphier_console_flush diff --git a/plat/socionext/uniphier/uniphier_console_setup.c b/plat/socionext/uniphier/uniphier_console_setup.c index 64ee79714..9fda26e93 100644 --- a/plat/socionext/uniphier/uniphier_console_setup.c +++ b/plat/socionext/uniphier/uniphier_console_setup.c @@ -1,9 +1,11 @@ /* - * Copyright (c) 2019, Socionext Inc. All rights reserved. + * Copyright (c) 2019-2020, Socionext Inc. All rights reserved. * * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> + #include <drivers/console.h> #include <errno.h> #include <lib/mmio.h> @@ -12,44 +14,46 @@ #include "uniphier.h" #include "uniphier_console.h" -#define UNIPHIER_UART_BASE 0x54006800 -#define UNIPHIER_UART_END 0x54006c00 #define UNIPHIER_UART_OFFSET 0x100 - -struct uniphier_console { - struct console console; - uintptr_t base; -}; +#define UNIPHIER_UART_NR_PORTS 4 /* These callbacks are implemented in assembly to use crash_console_helpers.S */ int uniphier_console_putc(int character, struct console *console); int uniphier_console_getc(struct console *console); -int uniphier_console_flush(struct console *console); +void uniphier_console_flush(struct console *console); -static struct uniphier_console uniphier_console = { - .console = { - .flags = CONSOLE_FLAG_BOOT | +static console_t uniphier_console = { + .flags = CONSOLE_FLAG_BOOT | #if DEBUG - CONSOLE_FLAG_RUNTIME | + CONSOLE_FLAG_RUNTIME | #endif - CONSOLE_FLAG_CRASH | - CONSOLE_FLAG_TRANSLATE_CRLF, - .putc = uniphier_console_putc, - .getc = uniphier_console_getc, - .flush = uniphier_console_flush, - }, + CONSOLE_FLAG_CRASH | + CONSOLE_FLAG_TRANSLATE_CRLF, + .putc = uniphier_console_putc, + .getc = uniphier_console_getc, + .flush = uniphier_console_flush, +}; + +static const uintptr_t uniphier_uart_base[] = { + [UNIPHIER_SOC_LD11] = 0x54006800, + [UNIPHIER_SOC_LD20] = 0x54006800, + [UNIPHIER_SOC_PXS3] = 0x54006800, }; /* * There are 4 UART ports available on this platform. By default, we want to * use the same one as used in the previous firmware stage. */ -static uintptr_t uniphier_console_get_base(void) +static uintptr_t uniphier_console_get_base(unsigned int soc) { - uintptr_t base = UNIPHIER_UART_BASE; + uintptr_t base, end; uint32_t div; - while (base < UNIPHIER_UART_END) { + assert(soc < ARRAY_SIZE(uniphier_uart_base)); + base = uniphier_uart_base[soc]; + end = base + UNIPHIER_UART_OFFSET * UNIPHIER_UART_NR_PORTS; + + while (base < end) { div = mmio_read_32(base + UNIPHIER_UART_DLR); if (div) return base; @@ -66,16 +70,16 @@ static void uniphier_console_init(uintptr_t base) UNIPHIER_UART_LCR_WLEN8 << 8); } -void uniphier_console_setup(void) +void uniphier_console_setup(unsigned int soc) { uintptr_t base; - base = uniphier_console_get_base(); + base = uniphier_console_get_base(soc); if (!base) plat_error_handler(-EINVAL); uniphier_console.base = base; - console_register(&uniphier_console.console); + console_register(&uniphier_console); /* * The hardware might be still printing characters queued up in the diff --git a/plat/socionext/uniphier/uniphier_emmc.c b/plat/socionext/uniphier/uniphier_emmc.c index d666ba781..b3d23cbed 100644 --- a/plat/socionext/uniphier/uniphier_emmc.c +++ b/plat/socionext/uniphier/uniphier_emmc.c @@ -87,7 +87,12 @@ struct uniphier_mmc_cmd { unsigned int is_data; }; -static int uniphier_emmc_block_addressing; +struct uniphier_emmc_host { + uintptr_t base; + bool is_block_addressing; +}; + +static struct uniphier_emmc_host uniphier_emmc_host; static int uniphier_emmc_send_cmd(uintptr_t host_base, struct uniphier_mmc_cmd *cmd) @@ -157,7 +162,8 @@ static int uniphier_emmc_switch_part(uintptr_t host_base, int part_num) return uniphier_emmc_send_cmd(host_base, &cmd); } -static int uniphier_emmc_is_over_2gb(uintptr_t host_base) +static int uniphier_emmc_check_device_size(uintptr_t host_base, + bool *is_block_addressing) { struct uniphier_mmc_cmd cmd = {0}; uint32_t csd40, csd72; /* CSD[71:40], CSD[103:72] */ @@ -174,7 +180,10 @@ static int uniphier_emmc_is_over_2gb(uintptr_t host_base) csd40 = mmio_read_32(host_base + SDHCI_RESPONSE + 4); csd72 = mmio_read_32(host_base + SDHCI_RESPONSE + 8); - return !(~csd40 & 0xffc00380) && !(~csd72 & 0x3); + /* C_SIZE == 0xfff && C_SIZE_MULT == 0x7 ? */ + *is_block_addressing = !(~csd40 & 0xffc00380) && !(~csd72 & 0x3); + + return 0; } static int uniphier_emmc_load_image(uintptr_t host_base, @@ -210,15 +219,15 @@ static int uniphier_emmc_load_image(uintptr_t host_base, static size_t uniphier_emmc_read(int lba, uintptr_t buf, size_t size) { - uintptr_t host_base = 0x5a000200; int ret; inv_dcache_range(buf, size); - if (!uniphier_emmc_block_addressing) + if (!uniphier_emmc_host.is_block_addressing) lba *= 512; - ret = uniphier_emmc_load_image(host_base, lba, buf, size / 512); + ret = uniphier_emmc_load_image(uniphier_emmc_host.base, + lba, buf, size / 512); inv_dcache_range(buf, size); @@ -232,10 +241,10 @@ static struct io_block_dev_spec uniphier_emmc_dev_spec = { .block_size = 512, }; -static int uniphier_emmc_hw_init(void) +static int uniphier_emmc_hw_init(struct uniphier_emmc_host *host) { - uintptr_t host_base = 0x5a000200; struct uniphier_mmc_cmd cmd = {0}; + uintptr_t host_base = uniphier_emmc_host.base; int ret; /* @@ -253,12 +262,11 @@ static int uniphier_emmc_hw_init(void) while (mmio_read_8(host_base + SDHCI_SOFTWARE_RESET)) ; - ret = uniphier_emmc_is_over_2gb(host_base); - if (ret < 0) + ret = uniphier_emmc_check_device_size(host_base, + &uniphier_emmc_host.is_block_addressing); + if (ret) return ret; - uniphier_emmc_block_addressing = ret; - cmd.cmdarg = UNIPHIER_EMMC_RCA << 16; /* select card again */ @@ -274,11 +282,23 @@ static int uniphier_emmc_hw_init(void) return 0; } -int uniphier_emmc_init(struct io_block_dev_spec **block_dev_spec) +static const uintptr_t uniphier_emmc_base[] = { + [UNIPHIER_SOC_LD11] = 0x5a000200, + [UNIPHIER_SOC_LD20] = 0x5a000200, + [UNIPHIER_SOC_PXS3] = 0x5a000200, +}; + +int uniphier_emmc_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec) { int ret; - ret = uniphier_emmc_hw_init(); + assert(soc < ARRAY_SIZE(uniphier_emmc_base)); + uniphier_emmc_host.base = uniphier_emmc_base[soc]; + if (uniphier_emmc_host.base == 0UL) + return -ENOTSUP; + + ret = uniphier_emmc_hw_init(&uniphier_emmc_host); if (ret) return ret; diff --git a/plat/socionext/uniphier/uniphier_image_desc.c b/plat/socionext/uniphier/uniphier_image_desc.c index 8c232ba31..dd62d1ebb 100644 --- a/plat/socionext/uniphier/uniphier_image_desc.c +++ b/plat/socionext/uniphier/uniphier_image_desc.c @@ -14,9 +14,9 @@ #include "uniphier.h" #define UNIPHIER_BL33_OFFSET 0x04000000UL -#define UNIPHIER_BL33_MAX_SIZE 0x00100000UL +#define UNIPHIER_BL33_MAX_SIZE 0x00800000UL -#define UNIPHIER_SCP_OFFSET 0x04100000UL +#define UNIPHIER_SCP_OFFSET 0x04800000UL #define UNIPHIER_SCP_MAX_SIZE 0x00020000UL static struct bl_mem_params_node uniphier_image_descs[] = { diff --git a/plat/socionext/uniphier/uniphier_io_storage.c b/plat/socionext/uniphier/uniphier_io_storage.c index 89c8718b4..92e15b09a 100644 --- a/plat/socionext/uniphier/uniphier_io_storage.c +++ b/plat/socionext/uniphier/uniphier_io_storage.c @@ -21,13 +21,12 @@ #include "uniphier.h" #define UNIPHIER_ROM_REGION_BASE 0x00000000ULL -#define UNIPHIER_ROM_REGION_SIZE 0x10000000ULL +#define UNIPHIER_ROM_REGION_SIZE 0x04000000ULL -#define UNIPHIER_OCM_REGION_BASE 0x30000000ULL #define UNIPHIER_OCM_REGION_SIZE 0x00040000ULL -#define UNIPHIER_BLOCK_BUF_OFFSET 0x04200000UL -#define UNIPHIER_BLOCK_BUF_SIZE 0x00100000UL +#define UNIPHIER_BLOCK_BUF_OFFSET 0x03000000UL +#define UNIPHIER_BLOCK_BUF_SIZE 0x00800000UL static const io_dev_connector_t *uniphier_fip_dev_con; static uintptr_t uniphier_fip_dev_handle; @@ -249,24 +248,24 @@ 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, size_t buffer_offset) +static int uniphier_io_emmc_setup(unsigned int soc, size_t buffer_offset) { struct io_block_dev_spec *block_dev_spec; int ret; - ret = uniphier_emmc_init(&block_dev_spec); + ret = uniphier_emmc_init(soc, &block_dev_spec); if (ret) return ret; return uniphier_io_block_setup(0x20000, block_dev_spec, buffer_offset); } -static int uniphier_io_nand_setup(unsigned int soc_id, size_t buffer_offset) +static int uniphier_io_nand_setup(unsigned int soc, size_t buffer_offset) { struct io_block_dev_spec *block_dev_spec; int ret; - ret = uniphier_nand_init(&block_dev_spec); + ret = uniphier_nand_init(soc, &block_dev_spec); if (ret) return ret; @@ -278,12 +277,20 @@ 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, size_t buffer_offset) +static const uintptr_t uniphier_ocm_base[] = { + [UNIPHIER_SOC_LD11] = 0x30000000, + [UNIPHIER_SOC_LD20] = 0x30000000, + [UNIPHIER_SOC_PXS3] = 0x30000000, +}; + +static int uniphier_io_rom_api_setup(unsigned int soc) { - struct io_block_dev_spec *block_dev_spec; + uintptr_t ocm_base; int ret; - /* use ROM API for loading images from USB storage */ + assert(soc < ARRAY_SIZE(uniphier_ocm_base)); + ocm_base = uniphier_ocm_base[soc]; + ret = mmap_add_dynamic_region(UNIPHIER_ROM_REGION_BASE, UNIPHIER_ROM_REGION_BASE, UNIPHIER_ROM_REGION_SIZE, @@ -296,14 +303,26 @@ static int uniphier_io_usb_setup(unsigned int soc_id, size_t buffer_offset) * load functions provided by the ROM use this memory region as a work * area, but do not cater to cache coherency. */ - ret = mmap_add_dynamic_region(UNIPHIER_OCM_REGION_BASE, - UNIPHIER_OCM_REGION_BASE, + ret = mmap_add_dynamic_region(ocm_base, ocm_base, UNIPHIER_OCM_REGION_SIZE, MT_DEVICE | MT_RW | MT_SECURE); if (ret) return ret; - ret = uniphier_usb_init(soc_id, &block_dev_spec); + return 0; +} + +static int uniphier_io_usb_setup(unsigned int soc, size_t buffer_offset) +{ + struct io_block_dev_spec *block_dev_spec; + int ret; + + /* use ROM API for loading images from USB storage */ + ret = uniphier_io_rom_api_setup(soc); + if (ret) + return ret; + + ret = uniphier_usb_init(soc, &block_dev_spec); if (ret) return ret; diff --git a/plat/socionext/uniphier/uniphier_nand.c b/plat/socionext/uniphier/uniphier_nand.c index 3925177ed..71cb96c0a 100644 --- a/plat/socionext/uniphier/uniphier_nand.c +++ b/plat/socionext/uniphier/uniphier_nand.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> #include <stdint.h> #include <platform_def.h> @@ -237,8 +238,7 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand) for (i = 0; i < ARRAY_SIZE(nand->bbt); i++) nand->bbt[i] = UNIPHIER_NAND_BBT_UNKNOWN; - nand->host_base = 0x68000000; - nand->reg_base = 0x68100000; + nand->reg_base = nand->host_base + 0x100000; nand->pages_per_block = mmio_read_32(nand->reg_base + DENALI_PAGES_PER_BLOCK); @@ -255,10 +255,22 @@ static int uniphier_nand_hw_init(struct uniphier_nand *nand) return 0; } -int uniphier_nand_init(struct io_block_dev_spec **block_dev_spec) +static const uintptr_t uniphier_nand_base[] = { + [UNIPHIER_SOC_LD11] = 0x68000000, + [UNIPHIER_SOC_LD20] = 0x68000000, + [UNIPHIER_SOC_PXS3] = 0x68000000, +}; + +int uniphier_nand_init(unsigned int soc, + struct io_block_dev_spec **block_dev_spec) { int ret; + assert(soc < ARRAY_SIZE(uniphier_nand_base)); + uniphier_nand.host_base = uniphier_nand_base[soc]; + if (!uniphier_nand.host_base) + return -ENOTSUP; + ret = uniphier_nand_hw_init(&uniphier_nand); if (ret) return ret; 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; } diff --git a/plat/socionext/uniphier/uniphier_soc_info.c b/plat/socionext/uniphier/uniphier_soc_info.c index 377532deb..0e7a2d11a 100644 --- a/plat/socionext/uniphier/uniphier_soc_info.c +++ b/plat/socionext/uniphier/uniphier_soc_info.c @@ -4,18 +4,25 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <common/bl_common.h> #include <lib/mmio.h> #include "uniphier.h" -#define UNIPHIER_REVISION 0x5f800000 +#define UNIPHIER_REVISION 0x5f800000UL +#define UNIPHIER_REVISION_NEW 0x1f800000UL static unsigned int uniphier_get_revision_field(unsigned int mask, unsigned int shift) { - uint32_t revision = mmio_read_32(UNIPHIER_REVISION); + uintptr_t reg; - return (revision >> shift) & mask; + if (BL_CODE_BASE >= 0x80000000UL) + reg = UNIPHIER_REVISION; + else + reg = UNIPHIER_REVISION_NEW; + + return (mmio_read_32(reg) >> shift) & mask; } unsigned int uniphier_get_soc_type(void) diff --git a/plat/socionext/uniphier/uniphier_xlat_setup.c b/plat/socionext/uniphier/uniphier_xlat_setup.c index 18d2f9e93..5043f4b59 100644 --- a/plat/socionext/uniphier/uniphier_xlat_setup.c +++ b/plat/socionext/uniphier/uniphier_xlat_setup.c @@ -4,15 +4,37 @@ * SPDX-License-Identifier: BSD-3-Clause */ +#include <assert.h> + #include <platform_def.h> #include <common/debug.h> #include <lib/xlat_tables/xlat_tables_v2.h> +#include <plat/common/platform.h> + +#include "uniphier.h" + +struct uniphier_reg_region { + uintptr_t base; + size_t size; +}; -#define UNIPHIER_REG_REGION_BASE 0x50000000ULL -#define UNIPHIER_REG_REGION_SIZE 0x20000000ULL +static const struct uniphier_reg_region uniphier_reg_region[] = { + [UNIPHIER_SOC_LD11] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, + [UNIPHIER_SOC_LD20] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, + [UNIPHIER_SOC_PXS3] = { + .base = 0x50000000UL, + .size = 0x20000000UL, + }, +}; -void uniphier_mmap_setup(void) +void uniphier_mmap_setup(unsigned int soc) { VERBOSE("Trusted RAM seen by this BL image: %p - %p\n", (void *)BL_CODE_BASE, (void *)BL_END); @@ -35,9 +57,25 @@ void uniphier_mmap_setup(void) MT_DEVICE | MT_RW | MT_SECURE); /* register region */ - mmap_add_region(UNIPHIER_REG_REGION_BASE, UNIPHIER_REG_REGION_BASE, - UNIPHIER_REG_REGION_SIZE, + assert(soc < ARRAY_SIZE(uniphier_reg_region)); + mmap_add_region(uniphier_reg_region[soc].base, + uniphier_reg_region[soc].base, + uniphier_reg_region[soc].size, MT_DEVICE | MT_RW | MT_SECURE); init_xlat_tables(); + + enable_mmu(0); + +#if PLAT_RO_XLAT_TABLES + { + int ret; + + ret = xlat_make_tables_readonly(); + if (ret) { + ERROR("Failed to make translation tables read-only."); + plat_error_handler(ret); + } + } +#endif } |