diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/riscv/Kconfig | 3 | ||||
-rw-r--r-- | arch/riscv/cpu/fu540/Makefile | 1 | ||||
-rw-r--r-- | arch/riscv/cpu/fu540/cache.c | 53 | ||||
-rw-r--r-- | arch/riscv/dts/fu540-c000-u-boot.dtsi | 10 | ||||
-rw-r--r-- | arch/riscv/include/asm/arch-fu540/cache.h | 14 | ||||
-rw-r--r-- | arch/riscv/lib/Makefile | 2 | ||||
-rw-r--r-- | arch/riscv/lib/fdt_fixup.c | 46 | ||||
-rw-r--r-- | arch/sandbox/dts/test.dts | 20 |
8 files changed, 132 insertions, 17 deletions
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 5d01f406a9..009a545fcf 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -287,4 +287,7 @@ config STACK_SIZE_SHIFT int default 14 +config OF_BOARD_FIXUP + default y if OF_SEPARATE + endmenu diff --git a/arch/riscv/cpu/fu540/Makefile b/arch/riscv/cpu/fu540/Makefile index 043fb961a5..088205ef57 100644 --- a/arch/riscv/cpu/fu540/Makefile +++ b/arch/riscv/cpu/fu540/Makefile @@ -8,4 +8,5 @@ obj-y += spl.o else obj-y += dram.o obj-y += cpu.o +obj-y += cache.o endif diff --git a/arch/riscv/cpu/fu540/cache.c b/arch/riscv/cpu/fu540/cache.c new file mode 100644 index 0000000000..9ee364b509 --- /dev/null +++ b/arch/riscv/cpu/fu540/cache.c @@ -0,0 +1,53 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2020 SiFive, Inc + * + * Authors: + * Pragnesh Patel <pragnesh.patel@sifive.com> + */ + +#include <common.h> +#include <asm/io.h> +#include <linux/bitops.h> + +/* Register offsets */ +#define L2_CACHE_CONFIG 0x000 +#define L2_CACHE_ENABLE 0x008 + +#define MASK_NUM_WAYS GENMASK(15, 8) +#define NUM_WAYS_SHIFT 8 + +DECLARE_GLOBAL_DATA_PTR; + +int cache_enable_ways(void) +{ + const void *blob = gd->fdt_blob; + int node = (-FDT_ERR_NOTFOUND); + fdt_addr_t base; + u32 config; + u32 ways; + + volatile u32 *enable; + + node = fdt_node_offset_by_compatible(blob, -1, + "sifive,fu540-c000-ccache"); + + if (node < 0) + return node; + + base = fdtdec_get_addr(blob, node, "reg"); + if (base == FDT_ADDR_T_NONE) + return FDT_ADDR_T_NONE; + + config = readl((volatile u32 *)base + L2_CACHE_CONFIG); + ways = (config & MASK_NUM_WAYS) >> NUM_WAYS_SHIFT; + + enable = (volatile u32 *)(base + L2_CACHE_ENABLE); + + /* memory barrier */ + mb(); + (*enable) = ways - 1; + /* memory barrier */ + mb(); + return 0; +} diff --git a/arch/riscv/dts/fu540-c000-u-boot.dtsi b/arch/riscv/dts/fu540-c000-u-boot.dtsi index 9bba554f9d..afdb4f4402 100644 --- a/arch/riscv/dts/fu540-c000-u-boot.dtsi +++ b/arch/riscv/dts/fu540-c000-u-boot.dtsi @@ -27,7 +27,7 @@ clocks = <&prci PRCI_CLK_COREPLL>; u-boot,dm-spl; cpu2_intc: interrupt-controller { - u-boot,dm-spl; + u-boot,dm-spl; }; }; cpu3: cpu@3 { @@ -50,7 +50,7 @@ u-boot,dm-spl; otp: otp@10070000 { compatible = "sifive,fu540-c000-otp"; - reg = <0x0 0x10070000 0x0 0x0FFF>; + reg = <0x0 0x10070000 0x0 0x1000>; fuse-count = <0x1000>; }; clint@2000000 { @@ -63,7 +63,7 @@ compatible = "sifive,fu540-c000-ddr"; reg = <0x0 0x100b0000 0x0 0x0800 0x0 0x100b2000 0x0 0x2000 - 0x0 0x100b8000 0x0 0x0fff>; + 0x0 0x100b8000 0x0 0x1000>; clocks = <&prci PRCI_CLK_DDRPLL>; clock-frequency = <933333324>; u-boot,dm-spl; @@ -87,3 +87,7 @@ assigned-clocks = <&prci PRCI_CLK_GEMGXLPLL>; assigned-clock-rates = <125000000>; }; + +&l2cache { + status = "okay"; +}; diff --git a/arch/riscv/include/asm/arch-fu540/cache.h b/arch/riscv/include/asm/arch-fu540/cache.h new file mode 100644 index 0000000000..135a17c679 --- /dev/null +++ b/arch/riscv/include/asm/arch-fu540/cache.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2020 SiFive, Inc. + * + * Authors: + * Pragnesh Patel <pragnesh.patel@sifve.com> + */ + +#ifndef _CACHE_SIFIVE_H +#define _CACHE_SIFIVE_H + +int cache_enable_ways(void); + +#endif /* _CACHE_SIFIVE_H */ diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index b5e93244e0..6c503ff2b2 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -20,7 +20,9 @@ obj-$(CONFIG_SBI) += sbi.o obj-$(CONFIG_SBI_IPI) += sbi_ipi.o endif obj-y += interrupts.o +ifeq ($(CONFIG_$(SPL_)SYSRESET),) obj-y += reset.o +endif obj-y += setjmp.o obj-$(CONFIG_$(SPL_)SMP) += smp.o obj-$(CONFIG_SPL_BUILD) += spl.o diff --git a/arch/riscv/lib/fdt_fixup.c b/arch/riscv/lib/fdt_fixup.c index 6db48ad04a..5b2420243f 100644 --- a/arch/riscv/lib/fdt_fixup.c +++ b/arch/riscv/lib/fdt_fixup.c @@ -4,6 +4,8 @@ * */ +#define LOG_CATEGORY LOGC_ARCH + #include <common.h> #include <fdt_support.h> #include <log.h> @@ -37,18 +39,30 @@ int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) offset = fdt_path_offset(src, "/reserved-memory"); if (offset < 0) { - printf("No reserved memory region found in source FDT\n"); + log_debug("No reserved memory region found in source FDT\n"); return 0; } + /* + * Extend the FDT by the following estimated size: + * + * Each PMP memory region entry occupies 64 bytes. + * With 16 PMP memory regions we need 64 * 16 = 1024 bytes. + */ + err = fdt_open_into(dst, dst, fdt_totalsize(dst) + 1024); + if (err < 0) { + printf("Device Tree can't be expanded to accommodate new node"); + return err; + } + fdt_for_each_subnode(node, src, offset) { name = fdt_get_name(src, node, NULL); - addr = fdtdec_get_addr_size_auto_noparent(src, node, - "reg", 0, &size, - false); + addr = fdtdec_get_addr_size_auto_parent(src, offset, node, + "reg", 0, &size, + false); if (addr == FDT_ADDR_T_NONE) { - debug("failed to read address/size for %s\n", name); + log_debug("failed to read address/size for %s\n", name); continue; } strncpy(basename, name, max_len); @@ -62,8 +76,8 @@ int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) pmp_mem.end = addr + size - 1; err = fdtdec_add_reserved_memory(dst, basename, &pmp_mem, &phandle); - if (err < 0) { - printf("failed to add reserved memory: %d\n", err); + if (err < 0 && err != -FDT_ERR_EXISTS) { + log_err("failed to add reserved memory: %d\n", err); return err; } if (!fdt_getprop(src, node, "no-map", NULL)) @@ -82,10 +96,9 @@ int riscv_fdt_copy_resv_mem_node(const void *src, void *dst) * @fdt: Pointer to the device tree in which reserved memory node needs to be * added. * - * In RISC-V, any board compiled with OF_SEPARATE needs to copy the reserved - * memory node from the device tree provided by the firmware to the device tree - * used by U-Boot. This is a common function that individual board fixup - * functions can invoke. + * In RISC-V, any board needs to copy the reserved memory node from the device + * tree provided by the firmware to the device tree used by U-Boot. This is a + * common function that individual board fixup functions can invoke. * * Return: 0 on success or error otherwise. */ @@ -95,6 +108,11 @@ int riscv_board_reserved_mem_fixup(void *fdt) void *src_fdt_addr; src_fdt_addr = map_sysmem(gd->arch.firmware_fdt_addr, 0); + + /* avoid the copy if we are using the same device tree */ + if (src_fdt_addr == fdt) + return 0; + err = riscv_fdt_copy_resv_mem_node(src_fdt_addr, fdt); if (err < 0) return err; @@ -109,7 +127,7 @@ int board_fix_fdt(void *fdt) err = riscv_board_reserved_mem_fixup(fdt); if (err < 0) { - printf("failed to fixup DT for reserved memory: %d\n", err); + log_err("failed to fixup DT for reserved memory: %d\n", err); return err; } @@ -127,14 +145,14 @@ int arch_fixup_fdt(void *blob) size = fdt_totalsize(blob); err = fdt_open_into(blob, blob, size + 32); if (err < 0) { - printf("Device Tree can't be expanded to accommodate new node"); + log_err("Device Tree can't be expanded to accommodate new node"); return err; } chosen_offset = fdt_path_offset(blob, "/chosen"); if (chosen_offset < 0) { err = fdt_add_subnode(blob, 0, "chosen"); if (err < 0) { - printf("chosen node can not be added\n"); + log_err("chosen node cannot be added\n"); return err; } } diff --git a/arch/sandbox/dts/test.dts b/arch/sandbox/dts/test.dts index d2a6af070b..07535a6b7d 100644 --- a/arch/sandbox/dts/test.dts +++ b/arch/sandbox/dts/test.dts @@ -343,6 +343,26 @@ #gpio-cells = <1>; gpio-bank-name = "a"; sandbox,gpio-count = <20>; + hog_input_active_low { + gpio-hog; + input; + gpios = <0 GPIO_ACTIVE_LOW>; + }; + hog_input_active_high { + gpio-hog; + input; + gpios = <1 GPIO_ACTIVE_HIGH>; + }; + hog_output_low { + gpio-hog; + output-low; + gpios = <2 GPIO_ACTIVE_HIGH>; + }; + hog_output_high { + gpio-hog; + output-high; + gpios = <3 GPIO_ACTIVE_HIGH>; + }; }; gpio_b: extra-gpios { |