help
Support for the composable cache controller on SiFive platforms.
+config SIFIVE_FLUSH
+ bool "Support Level 2 Cache Controller Flush operation of SiFive Soc"
+
+if SIFIVE_FLUSH
+
+config SIFIVE_FLUSH_START
+ hex "Level 2 Cache Flush operation start"
+ default 0x80000000
+ default 0x40000000 if SOC_STARFIVE_JH7110
+
+config SIFIVE_FLUSH_SIZE
+ hex "Level 2 Cache Flush operation size"
+ default 0x800000000
+ default 0x400000000 if SOC_STARFIVE_JH7110
+
+endif # SIFIVE_FLUSH
endif
#define SIFIVE_CCACHE_MAX_ECCINTR 4
+#define SIFIVE_FLUSH64 0x200
+#define SIFIVE_FLUSH64_LINE_LEN 64
+
static void __iomem *ccache_base;
static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR];
static struct riscv_cacheinfo_ops ccache_cache_ops;
}
EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier);
+
+#ifdef CONFIG_SIFIVE_FLUSH
+void sifive_flush64_range(unsigned long start, unsigned long len)
+{
+ unsigned long line;
+
+ if(!ccache_base) {
+ pr_warn("CACHE: base addr invalid, skipping flush\n");
+ return;
+ }
+
+ /* TODO: if (len == 0), skipping flush or going on? */
+ if(!len) {
+ pr_debug("CACHE: flush64 range @ 0x%lx(len:0)\n", start);
+ return;
+ }
+
+ /* make sure the address is in the range */
+ if(start < CONFIG_SIFIVE_FLUSH_START ||
+ (start + len) > (CONFIG_SIFIVE_FLUSH_START +
+ CONFIG_SIFIVE_FLUSH_SIZE)) {
+ pr_warn("CACHE: flush64 out of range: %lx(%lx), skip flush\n",
+ start, len);
+ return;
+ }
+
+ mb(); /* sync */
+ for (line = start; line < start + len;
+ line += SIFIVE_FLUSH64_LINE_LEN) {
+ writeq(line, ccache_base + SIFIVE_FLUSH64);
+ mb();
+ }
+}
+EXPORT_SYMBOL_GPL(sifive_flush64_range);
+#endif
+
static int ccache_largest_wayenabled(void)
{
return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF;
#define SIFIVE_CCACHE_ERR_TYPE_CE 0
#define SIFIVE_CCACHE_ERR_TYPE_UE 1
+#ifdef CONFIG_SIFIVE_FLUSH
+void sifive_flush64_range(unsigned long start, unsigned long len);
+
+#define starfive_flush_dcache(start, len) \
+ sifive_flush64_range(start, len)
+#endif
+
#endif /* __SOC_SIFIVE_CCACHE_H */