[PATCH v5 0/5] Support SiFive Composable cache driver

This patch set contains the SiFive composable cache support, and uses this driver to enable the ways of ccache by overwriting the enable_caches.
Changed in v5: - Fix build error on ae350 platform
Changed in v4: - Use generic enable_caches(), rather than cache_init(). - Rebase code base to v2021.10-rc3
Changed in v3: - Combine some patches - Drop the subdirectories of vendor in lib/ - Rebase codebase
Changed in v2: - Refine the ccache driver by Sean's suggestions - Introduce a common interface for cache initialization
Zong Li (5): cache: add sifive composable cache driver common: board_r: support enable_caches for RISC-V riscv: lib: implement enable_caches for sifive cache board: sifive: use ccache driver instead of helper function riscv: lib: modify the indent
arch/riscv/Kconfig | 5 ++ arch/riscv/cpu/fu540/Kconfig | 2 + arch/riscv/cpu/fu540/Makefile | 1 - arch/riscv/cpu/fu540/cache.c | 55 ----------------- arch/riscv/cpu/fu740/Kconfig | 2 + arch/riscv/cpu/fu740/Makefile | 1 - arch/riscv/cpu/fu740/cache.c | 55 ----------------- arch/riscv/include/asm/arch-fu540/cache.h | 14 ----- arch/riscv/include/asm/arch-fu740/cache.h | 14 ----- arch/riscv/include/asm/cache.h | 2 +- arch/riscv/lib/Makefile | 1 + arch/riscv/lib/cache.c | 4 ++ arch/riscv/lib/sifive_cache.c | 27 ++++++++ board/sifive/unleashed/unleashed.c | 10 +-- board/sifive/unmatched/unmatched.c | 11 +--- common/board_r.c | 4 +- drivers/cache/Kconfig | 7 +++ drivers/cache/Makefile | 1 + drivers/cache/cache-sifive-ccache.c | 75 +++++++++++++++++++++++ 19 files changed, 132 insertions(+), 159 deletions(-) delete mode 100644 arch/riscv/cpu/fu540/cache.c delete mode 100644 arch/riscv/cpu/fu740/cache.c delete mode 100644 arch/riscv/include/asm/arch-fu540/cache.h delete mode 100644 arch/riscv/include/asm/arch-fu740/cache.h create mode 100644 arch/riscv/lib/sifive_cache.c create mode 100644 drivers/cache/cache-sifive-ccache.c

This driver is currently responsible for enabling all ccache ways. Composable cache could be configure as RAM or cache, we will use it as RAM at the beginning to put the u-boot SPL there. In u-boot proper phrase, we will use the composable cache as cache, and try to enable the cache ways.
Signed-off-by: Zong Li zong.li@sifive.com Reviewed-by: Sean Anderson seanga2@gmail.com Reviewed-by: Rick Chen rick@andestech.com --- drivers/cache/Kconfig | 7 +++ drivers/cache/Makefile | 1 + drivers/cache/cache-sifive-ccache.c | 75 +++++++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 drivers/cache/cache-sifive-ccache.c
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index 1e452ad6d9..40f41a817c 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -39,4 +39,11 @@ config NCORE_CACHE controller. The driver initializes cache directories and coherent agent interfaces.
+config SIFIVE_CCACHE + bool "SiFive composable cache" + select CACHE + help + This driver is for SiFive Composable L2/L3 cache. It enables cache + ways of composable cache. + endmenu diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile index fed50be3f9..ad765774e3 100644 --- a/drivers/cache/Makefile +++ b/drivers/cache/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_SANDBOX) += sandbox_cache.o obj-$(CONFIG_L2X0_CACHE) += cache-l2x0.o obj-$(CONFIG_NCORE_CACHE) += cache-ncore.o obj-$(CONFIG_V5L2_CACHE) += cache-v5l2.o +obj-$(CONFIG_SIFIVE_CCACHE) += cache-sifive-ccache.o diff --git a/drivers/cache/cache-sifive-ccache.c b/drivers/cache/cache-sifive-ccache.c new file mode 100644 index 0000000000..76c0ab26ae --- /dev/null +++ b/drivers/cache/cache-sifive-ccache.c @@ -0,0 +1,75 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2021 SiFive + */ + +#include <common.h> +#include <cache.h> +#include <dm.h> +#include <asm/io.h> +#include <dm/device.h> +#include <linux/bitfield.h> + +#define SIFIVE_CCACHE_CONFIG 0x000 +#define SIFIVE_CCACHE_CONFIG_WAYS GENMASK(15, 8) + +#define SIFIVE_CCACHE_WAY_ENABLE 0x008 + +struct sifive_ccache { + void __iomem *base; +}; + +static int sifive_ccache_enable(struct udevice *dev) +{ + struct sifive_ccache *priv = dev_get_priv(dev); + u32 config; + u32 ways; + + /* Enable all ways of composable cache */ + config = readl(priv->base + SIFIVE_CCACHE_CONFIG); + ways = FIELD_GET(SIFIVE_CCACHE_CONFIG_WAYS, config); + + writel(ways - 1, priv->base + SIFIVE_CCACHE_WAY_ENABLE); + + return 0; +} + +static int sifive_ccache_get_info(struct udevice *dev, struct cache_info *info) +{ + struct sifive_ccache *priv = dev_get_priv(dev); + + info->base = (phys_addr_t)priv->base; + + return 0; +} + +static const struct cache_ops sifive_ccache_ops = { + .enable = sifive_ccache_enable, + .get_info = sifive_ccache_get_info, +}; + +static int sifive_ccache_probe(struct udevice *dev) +{ + struct sifive_ccache *priv = dev_get_priv(dev); + + priv->base = dev_read_addr_ptr(dev); + if (!priv->base) + return -EINVAL; + + return 0; +} + +static const struct udevice_id sifive_ccache_ids[] = { + { .compatible = "sifive,fu540-c000-ccache" }, + { .compatible = "sifive,fu740-c000-ccache" }, + {} +}; + +U_BOOT_DRIVER(sifive_ccache) = { + .name = "sifive_ccache", + .id = UCLASS_CACHE, + .of_match = sifive_ccache_ids, + .probe = sifive_ccache_probe, + .priv_auto = sizeof(struct sifive_ccache), + .ops = &sifive_ccache_ops, +};

The enable_caches is a generic hook for architecture-implemented, we leverage this function to enable caches for RISC-V
Signed-off-by: Zong Li zong.li@sifive.com --- arch/riscv/lib/cache.c | 4 ++++ common/board_r.c | 4 ++-- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/arch/riscv/lib/cache.c b/arch/riscv/lib/cache.c index b1d42bcc2b..686e699efb 100644 --- a/arch/riscv/lib/cache.c +++ b/arch/riscv/lib/cache.c @@ -70,3 +70,7 @@ __weak int dcache_status(void) { return 0; } + +__weak void enable_caches(void) +{ +} diff --git a/common/board_r.c b/common/board_r.c index e3e6248a1f..630c2451a2 100644 --- a/common/board_r.c +++ b/common/board_r.c @@ -114,7 +114,7 @@ static int initr_reloc(void) return 0; }
-#ifdef CONFIG_ARM +#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) /* * Some of these functions are needed purely because the functions they * call return void. If we change them to return 0, these stubs can go away. @@ -607,7 +607,7 @@ static init_fnc_t init_sequence_r[] = { initr_trace, initr_reloc, /* TODO: could x86/PPC have this also perhaps? */ -#ifdef CONFIG_ARM +#if defined(CONFIG_ARM) || defined(CONFIG_RISCV) initr_caches, /* Note: For Freescale LS2 SoCs, new MMU table is created in DDR. * A temporary mapping of IFC high region is since removed,

The enable_caches is a generic hook for architecture-implemented, we define this function to enable composable cache of sifive platforms.
In sifive_cache, it invokes the generic cache_enable interface of cache uclass to execute the relative implementation in SiFive ccache driver.
Signed-off-by: Zong Li zong.li@sifive.com --- arch/riscv/Kconfig | 5 +++++ arch/riscv/lib/Makefile | 1 + arch/riscv/lib/sifive_cache.c | 27 +++++++++++++++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 arch/riscv/lib/sifive_cache.c
diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index 4b0c3dffa6..ec651fe0a4 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -179,6 +179,11 @@ config SPL_SIFIVE_CLINT The SiFive CLINT block holds memory-mapped control and status registers associated with software and timer interrupts.
+config SIFIVE_CACHE + bool + help + This enables the operations to configure SiFive cache + config ANDES_PLIC bool depends on RISCV_MMODE || SPL_RISCV_MMODE diff --git a/arch/riscv/lib/Makefile b/arch/riscv/lib/Makefile index c4cc41434b..06020fcc2a 100644 --- a/arch/riscv/lib/Makefile +++ b/arch/riscv/lib/Makefile @@ -10,6 +10,7 @@ obj-$(CONFIG_CMD_BOOTM) += bootm.o obj-$(CONFIG_CMD_BOOTI) += bootm.o image.o obj-$(CONFIG_CMD_GO) += boot.o obj-y += cache.o +obj-$(CONFIG_SIFIVE_CACHE) += sifive_cache.o ifeq ($(CONFIG_$(SPL_)RISCV_MMODE),y) obj-$(CONFIG_$(SPL_)SIFIVE_CLINT) += sifive_clint.o obj-$(CONFIG_ANDES_PLIC) += andes_plic.o diff --git a/arch/riscv/lib/sifive_cache.c b/arch/riscv/lib/sifive_cache.c new file mode 100644 index 0000000000..28154878fc --- /dev/null +++ b/arch/riscv/lib/sifive_cache.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (C) 2021 SiFive, Inc + */ + +#include <common.h> +#include <cache.h> +#include <cpu_func.h> +#include <dm.h> + +void enable_caches(void) +{ + struct udevice *dev; + int ret; + + /* Enable ways of ccache */ + ret = uclass_get_device_by_driver(UCLASS_CACHE, + DM_DRIVER_GET(sifive_ccache), + &dev); + if (ret) { + log_debug("Cannot enable cache ways"); + } else { + ret = cache_enable(dev); + if (ret) + log_debug("ccache enable failed"); + } +}

Invokes the common cache_init function to initialize ccache.
Signed-off-by: Zong Li zong.li@sifive.com Reviewed-by: Sean Anderson seanga2@gmail.com --- arch/riscv/cpu/fu540/Kconfig | 2 + arch/riscv/cpu/fu540/Makefile | 1 - arch/riscv/cpu/fu540/cache.c | 55 ----------------------- arch/riscv/cpu/fu740/Kconfig | 2 + arch/riscv/cpu/fu740/Makefile | 1 - arch/riscv/cpu/fu740/cache.c | 55 ----------------------- arch/riscv/include/asm/arch-fu540/cache.h | 14 ------ arch/riscv/include/asm/arch-fu740/cache.h | 14 ------ board/sifive/unleashed/unleashed.c | 10 +---- board/sifive/unmatched/unmatched.c | 11 ++--- 10 files changed, 9 insertions(+), 156 deletions(-) delete mode 100644 arch/riscv/cpu/fu540/cache.c delete mode 100644 arch/riscv/cpu/fu740/cache.c delete mode 100644 arch/riscv/include/asm/arch-fu540/cache.h delete mode 100644 arch/riscv/include/asm/arch-fu740/cache.h
diff --git a/arch/riscv/cpu/fu540/Kconfig b/arch/riscv/cpu/fu540/Kconfig index 05463b2625..1604b412b4 100644 --- a/arch/riscv/cpu/fu540/Kconfig +++ b/arch/riscv/cpu/fu540/Kconfig @@ -19,6 +19,8 @@ config SIFIVE_FU540 imply SMP imply CLK_SIFIVE imply CLK_SIFIVE_PRCI + imply SIFIVE_CACHE + imply SIFIVE_CCACHE imply SIFIVE_SERIAL imply MACB imply MII diff --git a/arch/riscv/cpu/fu540/Makefile b/arch/riscv/cpu/fu540/Makefile index 088205ef57..043fb961a5 100644 --- a/arch/riscv/cpu/fu540/Makefile +++ b/arch/riscv/cpu/fu540/Makefile @@ -8,5 +8,4 @@ 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 deleted file mode 100644 index 0fc4ef6c00..0000000000 --- a/arch/riscv/cpu/fu540/cache.c +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2020 SiFive, Inc - * - * Authors: - * Pragnesh Patel pragnesh.patel@sifive.com - */ - -#include <common.h> -#include <asm/global_data.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_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_size_auto_parent(blob, 0, node, "reg", 0, - NULL, false); - 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/cpu/fu740/Kconfig b/arch/riscv/cpu/fu740/Kconfig index 408195f149..049a0a0584 100644 --- a/arch/riscv/cpu/fu740/Kconfig +++ b/arch/riscv/cpu/fu740/Kconfig @@ -19,6 +19,8 @@ config SIFIVE_FU740 imply SMP imply CLK_SIFIVE imply CLK_SIFIVE_PRCI + imply SIFIVE_CACHE + imply SIFIVE_CCACHE imply SIFIVE_SERIAL imply MACB imply MII diff --git a/arch/riscv/cpu/fu740/Makefile b/arch/riscv/cpu/fu740/Makefile index 5ef8ac18a7..1d1ad98ba7 100644 --- a/arch/riscv/cpu/fu740/Makefile +++ b/arch/riscv/cpu/fu740/Makefile @@ -8,5 +8,4 @@ obj-y += spl.o else obj-y += dram.o obj-y += cpu.o -obj-y += cache.o endif diff --git a/arch/riscv/cpu/fu740/cache.c b/arch/riscv/cpu/fu740/cache.c deleted file mode 100644 index 680955c9e3..0000000000 --- a/arch/riscv/cpu/fu740/cache.c +++ /dev/null @@ -1,55 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2020-2021 SiFive, Inc - * - * Authors: - * Pragnesh Patel pragnesh.patel@sifive.com - */ - -#include <common.h> -#include <asm/io.h> -#include <linux/bitops.h> -#include <asm/global_data.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_addr_t base; - u32 config; - u32 ways; - - volatile u32 *enable; - - node = fdt_node_offset_by_compatible(blob, -1, - "sifive,fu740-c000-ccache"); - - if (node < 0) - return node; - - base = fdtdec_get_addr_size_auto_parent(blob, 0, node, "reg", 0, - NULL, false); - 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/include/asm/arch-fu540/cache.h b/arch/riscv/include/asm/arch-fu540/cache.h deleted file mode 100644 index 135a17c679..0000000000 --- a/arch/riscv/include/asm/arch-fu540/cache.h +++ /dev/null @@ -1,14 +0,0 @@ -/* 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/include/asm/arch-fu740/cache.h b/arch/riscv/include/asm/arch-fu740/cache.h deleted file mode 100644 index 7d4fe9942b..0000000000 --- a/arch/riscv/include/asm/arch-fu740/cache.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2020-2021 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/board/sifive/unleashed/unleashed.c b/board/sifive/unleashed/unleashed.c index fa65fcade0..8cd514df30 100644 --- a/board/sifive/unleashed/unleashed.c +++ b/board/sifive/unleashed/unleashed.c @@ -6,6 +6,7 @@ * Anup Patel anup.patel@wdc.com */
+#include <cpu_func.h> #include <dm.h> #include <env.h> #include <init.h> @@ -15,7 +16,6 @@ #include <linux/delay.h> #include <misc.h> #include <spl.h> -#include <asm/arch/cache.h> #include <asm/sections.h>
/* @@ -126,14 +126,8 @@ void *board_fdt_blob_setup(void)
int board_init(void) { - int ret; - /* enable all cache ways */ - ret = cache_enable_ways(); - if (ret) { - debug("%s: could not enable cache ways\n", __func__); - return ret; - } + enable_caches();
return 0; } diff --git a/board/sifive/unmatched/unmatched.c b/board/sifive/unmatched/unmatched.c index da23a6ce24..d90b252bae 100644 --- a/board/sifive/unmatched/unmatched.c +++ b/board/sifive/unmatched/unmatched.c @@ -7,8 +7,8 @@ */
#include <common.h> +#include <cpu_func.h> #include <dm.h> -#include <asm/arch/cache.h> #include <asm/sections.h>
void *board_fdt_blob_setup(void) @@ -23,13 +23,8 @@ void *board_fdt_blob_setup(void)
int board_init(void) { - int ret; - /* enable all cache ways */ - ret = cache_enable_ways(); - if (ret) { - debug("%s: could not enable cache ways\n", __func__); - return ret; - } + enable_caches(); + return 0; }

We usually use a space in function declaration, rather than a tab.
Signed-off-by: Zong Li zong.li@sifive.com Reviewed-by: Sean Anderson seanga2@gmail.com --- arch/riscv/include/asm/cache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/cache.h b/arch/riscv/include/asm/cache.h index ec8fe201d3..874963d731 100644 --- a/arch/riscv/include/asm/cache.h +++ b/arch/riscv/include/asm/cache.h @@ -8,7 +8,7 @@ #define _ASM_RISCV_CACHE_H
/* cache */ -void cache_flush(void); +void cache_flush(void);
/* * The current upper bound for RISCV L1 data cache line sizes is 32 bytes.
participants (1)
-
Zong Li