diff options
Diffstat (limited to 'board/renesas/common')
| -rw-r--r-- | board/renesas/common/Makefile | 0 | ||||
| -rw-r--r-- | board/renesas/common/common.c | 71 | ||||
| -rw-r--r-- | board/renesas/common/gen3-common.c | 181 | ||||
| -rw-r--r-- | board/renesas/common/gen3-spl.c | 59 | ||||
| -rw-r--r-- | board/renesas/common/gen4-common.c | 90 | ||||
| -rw-r--r-- | board/renesas/common/gen4-spl.c | 119 | ||||
| -rw-r--r-- | board/renesas/common/v3-common.c | 41 |
7 files changed, 561 insertions, 0 deletions
diff --git a/board/renesas/common/Makefile b/board/renesas/common/Makefile new file mode 100644 index 00000000000..e69de29bb2d --- /dev/null +++ b/board/renesas/common/Makefile diff --git a/board/renesas/common/common.c b/board/renesas/common/common.c new file mode 100644 index 00000000000..7fba8d10ff5 --- /dev/null +++ b/board/renesas/common/common.c @@ -0,0 +1,71 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * board/renesas/common/common.c + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> + */ + +#include <dm.h> +#include <fdt_support.h> +#include <hang.h> +#include <init.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <dm/uclass-internal.h> +#include <asm/arch/renesas.h> +#include <asm/system.h> +#include <linux/libfdt.h> + +#ifdef CONFIG_RCAR_64 + +DECLARE_GLOBAL_DATA_PTR; + +int dram_init(void) +{ + int ret = fdtdec_setup_mem_size_base(); + + if (current_el() == 3 && gd->ram_base == 0x48000000) { + /* + * If this U-Boot runs in EL3, make the bottom 128 MiB + * available for loading of follow up firmware blobs. + */ + gd->ram_base -= 0x8000000; + gd->ram_size += 0x8000000; + } + + return ret; +} + +int dram_init_banksize(void) +{ + int bank; + + fdtdec_setup_memory_banksize(); + + if (current_el() != 3) + return 0; + + for (bank = 0; bank < CONFIG_NR_DRAM_BANKS; bank++) { + if (gd->bd->bi_dram[bank].start != 0x48000000) + continue; + + /* + * If this U-Boot runs in EL3, make the bottom 128 MiB + * available for loading of follow up firmware blobs. + */ + gd->bd->bi_dram[bank].start -= 0x8000000; + gd->bd->bi_dram[bank].size += 0x8000000; + break; + } + + return 0; +} + +int __weak board_init(void) +{ + return 0; +} + +#endif diff --git a/board/renesas/common/gen3-common.c b/board/renesas/common/gen3-common.c new file mode 100644 index 00000000000..05b01c846c6 --- /dev/null +++ b/board/renesas/common/gen3-common.c @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * board/renesas/common/gen3-common.c + * + * Copyright (C) 2013 Renesas Electronics Corporation + * Copyright (C) 2013 Nobuhiro Iwamatsu <nobuhiro.iwamatsu.yj@renesas.com> + * Copyright (C) 2015 Nobuhiro Iwamatsu <iwamatsu@nigauri.org> + */ + +#include <asm/armv8/cpu.h> +#include <dm.h> +#include <fdt_support.h> +#include <hang.h> +#include <init.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <dm/uclass-internal.h> +#include <asm/arch/renesas.h> +#include <linux/libfdt.h> + +#ifdef CONFIG_RCAR_64 + +DECLARE_GLOBAL_DATA_PTR; + +/* If the firmware passed a device tree use it for e.g. U-Boot DRAM setup. */ +extern u64 rcar_atf_boot_args[]; + +#define FDT_RPC_PATH "/soc/spi@ee200000" + +static void apply_atf_overlay(void *fdt_blob) +{ + void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]); + + if (fdt_magic(atf_fdt_blob) == FDT_MAGIC) + fdt_overlay_apply_node(fdt_blob, 0, atf_fdt_blob, 0); +} + +int fdtdec_board_setup(const void *fdt_blob) +{ + apply_atf_overlay((void *)fdt_blob); + + return 0; +} + +#define RST_BASE 0xE6160000 +#define RST_CA57RESCNT (RST_BASE + 0x40) +#define RST_CA53RESCNT (RST_BASE + 0x44) +#define RST_RSTOUTCR (RST_BASE + 0x58) +#define RST_CA57_CODE 0xA5A5000F +#define RST_CA53_CODE 0x5A5A000F + +void __weak reset_cpu(void) +{ + if (is_cortex_a53()) + writel(RST_CA53_CODE, RST_CA53RESCNT); + else if (is_cortex_a57()) + writel(RST_CA57_CODE, RST_CA57RESCNT); + else + hang(); +} + +#if defined(CONFIG_OF_BOARD_SETUP) +static int is_mem_overlap(void *blob, int first_mem_node, int curr_mem_node) +{ + struct fdt_resource first_mem_res, curr_mem_res; + int curr_mem_reg, first_mem_reg = 0; + int ret; + + for (;;) { + ret = fdt_get_resource(blob, first_mem_node, "reg", + first_mem_reg++, &first_mem_res); + if (ret) /* No more entries, no overlap found */ + return 0; + + curr_mem_reg = 0; + for (;;) { + ret = fdt_get_resource(blob, curr_mem_node, "reg", + curr_mem_reg++, &curr_mem_res); + if (ret) /* No more entries, check next tuple */ + break; + + if (curr_mem_res.end < first_mem_res.start) + continue; + + if (curr_mem_res.start >= first_mem_res.end) + continue; + + log_debug("Overlap found: 0x%llx..0x%llx / 0x%llx..0x%llx\n", + first_mem_res.start, first_mem_res.end, + curr_mem_res.start, curr_mem_res.end); + + return 1; + } + } + + return 0; +} + +static void scrub_duplicate_memory(void *blob) +{ + /* + * Scrub duplicate /memory@* node entries here. Some R-Car DTs might + * contain multiple /memory@* nodes, however fdt_fixup_memory_banks() + * either generates single /memory node or updates the first /memory + * node. Any remaining memory nodes are thus potential duplicates. + * + * However, it is not possible to delete all the memory nodes right + * away, since some of those might not be DRAM memory nodes, but some + * sort of other memory. Thus, delete only the memory nodes which are + * in the R-Car3 DBSC ranges. + */ + int mem = 0, first_mem_node = 0; + + for (;;) { + mem = fdt_node_offset_by_prop_value(blob, mem, + "device_type", "memory", 7); + if (mem < 0) + break; + if (!fdtdec_get_is_enabled(blob, mem)) + continue; + + /* First memory node, patched by U-Boot */ + if (!first_mem_node) { + first_mem_node = mem; + continue; + } + + /* Check the remaining nodes and delete duplicates */ + if (!is_mem_overlap(blob, first_mem_node, mem)) + continue; + + /* Delete duplicate node, start again */ + fdt_del_node(blob, mem); + first_mem_node = 0; + mem = 0; + } +} + +static void update_rpc_status(void *blob) +{ + void *atf_fdt_blob = (void *)(rcar_atf_boot_args[1]); + int offset, enabled; + + /* + * Check if the DT fragment received from TF-A had its RPC-IF device node + * enabled. + */ + if (fdt_magic(atf_fdt_blob) != FDT_MAGIC) + return; + + offset = fdt_path_offset(atf_fdt_blob, FDT_RPC_PATH); + if (offset < 0) + return; + + enabled = fdtdec_get_is_enabled(atf_fdt_blob, offset); + if (!enabled) + return; + + /* + * Find the RPC-IF device node, and enable it if it has a flash subnode. + */ + offset = fdt_path_offset(blob, FDT_RPC_PATH); + if (offset < 0) + return; + + if (fdt_subnode_offset(blob, offset, "flash") < 0) + return; + + fdt_status_okay(blob, offset); +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + apply_atf_overlay(blob); + scrub_duplicate_memory(blob); + update_rpc_status(blob); + + return 0; +} +#endif +#endif diff --git a/board/renesas/common/gen3-spl.c b/board/renesas/common/gen3-spl.c new file mode 100644 index 00000000000..44a20cef2df --- /dev/null +++ b/board/renesas/common/gen3-spl.c @@ -0,0 +1,59 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car Gen3 recovery SPL + * + * Copyright (C) 2019 Marek Vasut <marek.vasut@gmail.com> + */ + +#include <cpu_func.h> +#include <image.h> +#include <init.h> +#include <log.h> +#include <asm/io.h> +#include <spl.h> +#include <linux/bitops.h> + +#define RCAR_CNTC_BASE 0xE6080000 +#define CNTCR_EN BIT(0) + +void board_init_f(ulong dummy) +{ + writel(CNTCR_EN, RCAR_CNTC_BASE); + timer_init(); +} + +void spl_board_init(void) +{ + /* UART clocks enabled and gd valid - init serial console */ + preloader_console_init(); +} + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_UART; +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + debug("image entry point: 0x%lx\n", spl_image->entry_point); + if (spl_image->os == IH_OS_ARM_TRUSTED_FIRMWARE) { + typedef void (*image_entry_arg_t)(int, int, int, int) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t)(uintptr_t) spl_image->entry_point; + image_entry(IH_MAGIC, CONFIG_SPL_TEXT_BASE, 0, 0); + } else { + typedef void __noreturn (*image_entry_noargs_t)(void); + image_entry_noargs_t image_entry = + (image_entry_noargs_t)spl_image->entry_point; + image_entry(); + } +} + +void s_init(void) +{ +} + +void reset_cpu(void) +{ +} diff --git a/board/renesas/common/gen4-common.c b/board/renesas/common/gen4-common.c new file mode 100644 index 00000000000..52a0639073b --- /dev/null +++ b/board/renesas/common/gen4-common.c @@ -0,0 +1,90 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * board/renesas/common/gen4-common.c + * + * Copyright (C) 2021-2024 Renesas Electronics Corp. + */ + +#include <asm/arch/renesas.h> +#include <asm/arch/sys_proto.h> +#include <asm/global_data.h> +#include <asm/io.h> +#include <asm/mach-types.h> +#include <asm/processor.h> +#include <asm/system.h> +#include <linux/errno.h> + +#define RST_BASE 0xE6160000 /* Domain0 */ +#define RST_WDTRSTCR (RST_BASE + 0x10) +#define RST_RWDT 0xA55A8002 + +DECLARE_GLOBAL_DATA_PTR; + +static void init_generic_timer(void) +{ + const u32 freq = CONFIG_SYS_CLK_FREQ; + + /* Update memory mapped and register based freqency */ + asm volatile ("msr cntfrq_el0, %0" :: "r" (freq)); + writel(freq, CNTFID0); + + /* Enable counter */ + setbits_le32(CNTCR_BASE, CNTCR_EN); +} + +static void init_gic_v3(void) +{ + /* GIC v3 power on */ + writel(BIT(1), GICR_LPI_PWRR); + + /* Wait till the WAKER_CA_BIT changes to 0 */ + clrbits_le32(GICR_LPI_WAKER, BIT(1)); + while (readl(GICR_LPI_WAKER) & BIT(2)) + ; + + writel(0xffffffff, GICR_SGI_BASE + GICR_IGROUPR0); +} + +void s_init(void) +{ + if (current_el() == 3) + init_generic_timer(); +} + +int board_early_init_f(void) +{ + /* Unlock CPG access */ + writel(0x5A5AFFFF, CPGWPR); + writel(0xA5A50000, CPGWPCR); + + return 0; +} + +int board_init(void) +{ + if (current_el() != 3) + return 0; + init_gic_v3(); + + /* Enable RWDT reset on V3U in EL3 */ + if (IS_ENABLED(CONFIG_R8A779A0) && + renesas_get_cpu_type() == RENESAS_CPU_TYPE_R8A779A0) { + writel(RST_RWDT, RST_WDTRSTCR); + } + + return 0; +} + +#define RST_BASE 0xE6160000 /* Domain0 */ +#define RST_SRESCR0 (RST_BASE + 0x18) +#define RST_SPRES 0x5AA58000 + +void __weak reset_cpu(void) +{ + writel(RST_SPRES, RST_SRESCR0); +} + +int ft_board_setup(void *blob, struct bd_info *bd) +{ + return 0; +} diff --git a/board/renesas/common/gen4-spl.c b/board/renesas/common/gen4-spl.c new file mode 100644 index 00000000000..2aca8baf3dd --- /dev/null +++ b/board/renesas/common/gen4-spl.c @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * R-Car Gen4 Cortex-R52 SPL + * + * Copyright (C) 2024 Marek Vasut <marek.vasut+renesas@mailbox.org> + */ + +#include <asm/arch/renesas.h> +#include <asm/io.h> +#include <cpu_func.h> +#include <dm/uclass.h> +#include <dm/util.h> +#include <hang.h> +#include <image.h> +#include <init.h> +#include <linux/bitops.h> +#include <log.h> +#include <mapmem.h> +#include <spl.h> + +#define CNTCR_EN BIT(0) + +#ifdef CONFIG_SPL_BUILD +void board_debug_uart_init(void) +{ +} +#endif + +static void init_generic_timer(void) +{ + const u32 freq = CONFIG_SYS_CLK_FREQ; + + /* Update memory mapped and register based freqency */ + if (IS_ENABLED(CONFIG_ARM64)) + asm volatile("msr cntfrq_el0, %0" :: "r" (freq)); + else + asm volatile("mcr p15, 0, %0, c14, c0, 0" :: "r" (freq)); + + writel(freq, CNTFID0); + + /* Enable counter */ + setbits_le32(CNTCR_BASE, CNTCR_EN); +} + +void board_init_f(ulong dummy) +{ + struct udevice *dev; + int ret; + + if (CONFIG_IS_ENABLED(OF_CONTROL)) { + ret = spl_early_init(); + if (ret) { + debug("spl_early_init() failed: %d\n", ret); + hang(); + } + } + + preloader_console_init(); + + ret = uclass_get_device_by_name(UCLASS_NOP, "ram@e6780000", &dev); + if (ret) + printf("DBSC5 init failed: %d\n", ret); + + ret = uclass_get_device_by_name(UCLASS_RAM, "ram@ffec0000", &dev); + if (ret) + printf("RTVRAM init failed: %d\n", ret); +}; + +u32 spl_boot_device(void) +{ + return BOOT_DEVICE_SPI; +} + +struct legacy_img_hdr *spl_get_load_buffer(ssize_t offset, size_t size) +{ + return map_sysmem(CONFIG_SYS_LOAD_ADDR + offset, 0); +} + +void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image) +{ + debug("image entry point: 0x%lx\n", spl_image->entry_point); + if (spl_image->os == IH_OS_ARM_TRUSTED_FIRMWARE) { + typedef void (*image_entry_arg_t)(int, int, int, int) + __attribute__ ((noreturn)); + image_entry_arg_t image_entry = + (image_entry_arg_t)(uintptr_t) spl_image->entry_point; + image_entry(IH_MAGIC, CONFIG_SPL_TEXT_BASE, 0, 0); + } else { + typedef void __noreturn (*image_entry_noargs_t)(void); + image_entry_noargs_t image_entry = + (image_entry_noargs_t)spl_image->entry_point; + image_entry(); + } +} + +#define APMU_BASE 0xe6170000U +#define CL0GRP3_BIT BIT(3) +#define CL1GRP3_BIT BIT(7) +#define RTGRP3_BIT BIT(19) +#define APMU_ACC_ENB_FOR_ARM_CPU (CL0GRP3_BIT | CL1GRP3_BIT | RTGRP3_BIT) + +void s_init(void) +{ + /* Unlock CPG access */ + writel(0x5A5AFFFF, CPGWPR); + writel(0xA5A50000, CPGWPCR); + init_generic_timer(); + + /* Define for Work Around of APMU */ + writel(0x00ff00ff, APMU_BASE + 0x10); + writel(0x00ff00ff, APMU_BASE + 0x14); + writel(0x00ff00ff, APMU_BASE + 0x18); + writel(0x00ff00ff, APMU_BASE + 0x1c); + clrbits_le32(APMU_BASE + 0x68, BIT(29)); +} + +void reset_cpu(void) +{ +} diff --git a/board/renesas/common/v3-common.c b/board/renesas/common/v3-common.c new file mode 100644 index 00000000000..5d057edb0a6 --- /dev/null +++ b/board/renesas/common/v3-common.c @@ -0,0 +1,41 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2017-2023 Marek Vasut <marek.vasut+renesas@mailbox.org> + */ + +#include <clock_legacy.h> +#include <asm/arch/renesas.h> +#include <asm/io.h> + +#define CPGWPR 0xE6150900 +#define CPGWPCR 0xE6150904 + +/* PLL */ +#define PLL0CR 0xE61500D8 +#define PLL0_STC_MASK 0x7F000000 +#define PLL0_STC_OFFSET 24 + +#define CLK2MHZ(clk) (clk / 1000 / 1000) +void s_init(void) +{ + struct rcar_rwdt *rwdt = (struct rcar_rwdt *)RWDT_BASE; + struct rcar_swdt *swdt = (struct rcar_swdt *)SWDT_BASE; + u32 stc; + + /* Watchdog init */ + writel(0xA5A5A500, &rwdt->rwtcsra); + writel(0xA5A5A500, &swdt->swtcsra); + + /* CPU frequency setting. Set to 0.8GHz */ + stc = ((800 / CLK2MHZ(get_board_sys_clk())) - 1) << PLL0_STC_OFFSET; + clrsetbits_le32(PLL0CR, PLL0_STC_MASK, stc); +} + +int board_early_init_f(void) +{ + /* Unlock CPG access */ + writel(0xA5A5FFFF, CPGWPR); + writel(0x5A5A0000, CPGWPCR); + + return 0; +} |
