[PATCH 2/2] sifive: ccache: add clear LIM area
Ben Dooks
ben.dooks at codethink.co.uk
Fri Sep 8 15:37:07 CEST 2023
Add option to clear the LIM area on startup, just in case this
is the cause of some of the data-errors on startup.
Signed-off-by: Ben Dooks <ben.dooks at codethink.co.uk>
[ben.dooks at codethink.co.uk: changed from sifive.com address]
---
drivers/cache/Kconfig | 8 ++++++
drivers/cache/cache-sifive-ccache.c | 40 +++++++++++++++++++++++++++++
2 files changed, 48 insertions(+)
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index abe7de9abf..9d5cbaedea 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -46,6 +46,14 @@ config SIFIVE_CCACHE
This driver is for SiFive Composable L2/L3 cache. It enables cache
ways of composable cache.
+config SIFIVE_CCACHE_LIMZERO
+ bool "Zero LIM (loosely integrated memory) on startup"
+ depends on SIFIVE_CCACHE
+ help
+ Select this option to clear the LIM (cache memory) block before
+ enabling the cache. This will increase the init time but may
+ help with some of the errors being seen on OS startup.
+
config SIFIVE_PL2CACHE
bool "SiFive per-core L2 cache"
select CACHE
diff --git a/drivers/cache/cache-sifive-ccache.c b/drivers/cache/cache-sifive-ccache.c
index 178bdcc82d..a84b5c9d04 100644
--- a/drivers/cache/cache-sifive-ccache.c
+++ b/drivers/cache/cache-sifive-ccache.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <asm/io.h>
#include <dm/device.h>
+#include <dm/device_compat.h>
#include <linux/bitfield.h>
#define SIFIVE_CCACHE_CONFIG 0x000
@@ -43,6 +44,43 @@ static int sifive_ccache_get_info(struct udevice *dev, struct cache_info *info)
return 0;
}
+#ifdef CONFIG_SIFIVE_CCACHE_LIMZERO
+static int sifive_clear_lim(struct udevice *dev)
+{
+
+ fdt_addr_t base, size;
+ ofnode mem_node;
+ u32 handle = 0;
+ int ret;
+
+ ret = ofnode_read_u32(dev_ofnode(dev), "memory-region", &handle);
+ if (ret) {
+ dev_err(dev, "no memory-region for lim\n");
+ return -EINVAL;
+ }
+
+ mem_node = ofnode_get_by_phandle(handle);
+ if (!ofnode_valid(mem_node)) {
+ dev_err(dev, "invalid memory region for lim\n");
+ return -EINVAL;
+ }
+
+ base = ofnode_get_addr_size_index(mem_node, 0, &size);
+
+ /* note, we assume this is called so early none of the ways of
+ * the cache have been enabled, so just clear the entire cache
+ * memory
+ */
+
+ dev_info(dev, "clearing l3lim %llx..%llx\n", base, base+size);
+ memset((void *)base, 0x0, size);
+
+ return 0;
+}
+#else
+static inline int sifive_clear_lim(struct udevice *dev) { return 0; }
+#endif
+
static const struct cache_ops sifive_ccache_ops = {
.enable = sifive_ccache_enable,
.get_info = sifive_ccache_get_info,
@@ -63,6 +101,8 @@ static int sifive_ccache_probe(struct udevice *dev)
(void)readl(base + 0x148);
(void)readl(base + 0x168);
+ sifive_clear_lim(dev);
+
return 0;
}
--
2.40.1
More information about the U-Boot
mailing list