[PATCH v2] cache: sifive_ccache: Enable all ways on EIC7700

From: Pinkesh Vaghela

Date: Fri Oct 23 2026 - 09:52:09 EST


EIC7700 firmware leaves only way 0 enabled when no LIM is reserved, so
Linux can use only one of the implemented cache ways.

Add an EIC7700-specific quirk that reads and validates the implemented
way count, then enables all ways when the cache node has no
memory-region property. Leave WayEnable unchanged when the property is
present because enabled ways cannot be returned to LIM until reset.

Keep this behavior specific to EIC7700 because firmware on other
platforms may have already configured the cache/LIM partition.

Signed-off-by: Pinkesh Vaghela <pinkesh.vaghela@xxxxxxxxxxxxxx>
---
Changes in v2:
- Restrict automatic way enabling to EIC7700 using a device quirk.

Link to v1: https://lore.kernel.org/all/20261021130906.2501060-1-pinkesh.vaghela@xxxxxxxxxxxxxx

drivers/cache/sifive_ccache.c | 26 +++++++++++++++++++++++++-
1 file changed, 25 insertions(+), 1 deletion(-)

diff --git a/drivers/cache/sifive_ccache.c b/drivers/cache/sifive_ccache.c
index e1a283805ea7..b4eac620ad0b 100644
--- a/drivers/cache/sifive_ccache.c
+++ b/drivers/cache/sifive_ccache.c
@@ -68,6 +68,7 @@ enum {
enum {
QUIRK_NONSTANDARD_CACHE_OPS = BIT(0),
QUIRK_BROKEN_DATA_UNCORR = BIT(1),
+ QUIRK_ENABLE_ALL_WAYS = BIT(2),
};

#ifdef CONFIG_DEBUG_FS
@@ -117,9 +118,25 @@ static void ccache_config_read(void)
pr_info("Index of the largest way enabled: %u\n", cfg);
}

+static int ccache_enable_all_ways(void)
+{
+ u32 config, ways;
+
+ config = readl(ccache_base + SIFIVE_CCACHE_CONFIG);
+ ways = FIELD_GET(SIFIVE_CCACHE_CONFIG_WAYS_MASK, config);
+ if (!ways) {
+ pr_err("Invalid cache configuration: zero ways\n");
+ return -EINVAL;
+ }
+
+ writel(ways - 1, ccache_base + SIFIVE_CCACHE_WAYENABLE);
+
+ return 0;
+}
+
static const struct of_device_id sifive_ccache_ids[] = {
{ .compatible = "eswin,eic7700-l3-cache",
- .data = (void *)(QUIRK_NONSTANDARD_CACHE_OPS) },
+ .data = (void *)(QUIRK_NONSTANDARD_CACHE_OPS | QUIRK_ENABLE_ALL_WAYS) },
{ .compatible = "sifive,fu540-c000-ccache" },
{ .compatible = "sifive,fu740-c000-ccache" },
{ .compatible = "starfive,jh7100-ccache",
@@ -317,6 +334,13 @@ static int __init sifive_ccache_init(void)
goto err_unmap;
}

+ if ((quirks & QUIRK_ENABLE_ALL_WAYS) &&
+ !of_property_present(np, "memory-region")) {
+ rc = ccache_enable_all_ways();
+ if (rc)
+ goto err_unmap;
+ }
+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
if (quirks & QUIRK_NONSTANDARD_CACHE_OPS) {
riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE;
--
2.34.1