From: Hoegeun Kwon Date: Thu, 8 Jun 2023 11:26:29 +0000 (+0900) Subject: soc: sifive: ccache: Add flush feature X-Git-Tag: accepted/tizen/unified/riscv/20230718.024919~25 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f58f63f427bb6067477b01136815e5843749b648;p=platform%2Fkernel%2Flinux-starfive.git soc: sifive: ccache: Add flush feature Add the ccache flush feature applied to kernel v5.15. This feature flushes the garbage cache when output the screen. Change-Id: I855fd37416f028f6d7c9b9e1459462e4da7e1740 Signed-off-by: Hoegeun Kwon --- diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig index ed4c571..d37cfc6 100644 --- a/drivers/soc/sifive/Kconfig +++ b/drivers/soc/sifive/Kconfig @@ -7,4 +7,20 @@ config SIFIVE_CCACHE 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 diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/soc/sifive/sifive_ccache.c index 3684f5b..79de317 100644 --- a/drivers/soc/sifive/sifive_ccache.c +++ b/drivers/soc/sifive/sifive_ccache.c @@ -44,6 +44,9 @@ #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; @@ -124,6 +127,42 @@ int unregister_sifive_ccache_error_notifier(struct notifier_block *nb) } 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; diff --git a/include/soc/sifive/sifive_ccache.h b/include/soc/sifive/sifive_ccache.h index 4d4ed49..e580a09 100644 --- a/include/soc/sifive/sifive_ccache.h +++ b/include/soc/sifive/sifive_ccache.h @@ -13,4 +13,11 @@ extern int unregister_sifive_ccache_error_notifier(struct notifier_block *nb); #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 */