Skip to content

Commit

Permalink
sifive/sifive_l2_cache: Add sifive_l2_flush64_range function
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom authored and esmil committed Jun 6, 2022
1 parent b422a12 commit 1c9c971
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
15 changes: 15 additions & 0 deletions drivers/soc/sifive/Kconfig
Expand Up @@ -7,4 +7,19 @@ config SIFIVE_L2
help
Support for the L2 cache controller on SiFive platforms.

config SIFIVE_L2_FLUSH
bool "Support Level 2 Cache Controller Flush operation of SiFive Soc"

if SIFIVE_L2_FLUSH

config SIFIVE_L2_FLUSH_START
hex "Level 2 Cache Flush operation start"
default 0x80000000

config SIFIVE_L2_FLUSH_SIZE
hex "Level 2 Cache Flush operation size"
default 0x800000000

endif # SIFIVE_L2_FLUSH

endif
42 changes: 41 additions & 1 deletion drivers/soc/sifive/sifive_l2_cache.c
Expand Up @@ -7,6 +7,7 @@
*/
#include <linux/debugfs.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/of_irq.h>
#include <linux/of_address.h>
#include <linux/device.h>
Expand All @@ -29,13 +30,17 @@
#define SIFIVE_L2_DATECCFAIL_HIGH 0x164
#define SIFIVE_L2_DATECCFAIL_COUNT 0x168

#define SIFIVE_L2_FLUSH64 0x200

#define SIFIVE_L2_CONFIG 0x00
#define SIFIVE_L2_WAYENABLE 0x08
#define SIFIVE_L2_ECCINJECTERR 0x40

#define SIFIVE_L2_MAX_ECCINTR 4

static void __iomem *l2_base;
#define SIFIVE_L2_FLUSH64_LINE_LEN 64

static void __iomem *l2_base = NULL;
static int g_irq[SIFIVE_L2_MAX_ECCINTR];
static struct riscv_cacheinfo_ops l2_cache_ops;

Expand Down Expand Up @@ -116,6 +121,41 @@ int unregister_sifive_l2_error_notifier(struct notifier_block *nb)
}
EXPORT_SYMBOL_GPL(unregister_sifive_l2_error_notifier);

#ifdef CONFIG_SIFIVE_L2_FLUSH
void sifive_l2_flush64_range(unsigned long start, unsigned long len)
{
unsigned long line;

if(!l2_base) {
pr_warn("L2CACHE: base addr invalid, skipping flush\n");
return;
}

/* TODO: if (len == 0), skipping flush or going on? */
if(!len) {
pr_debug("L2CACHE: flush64 range @ 0x%lx(len:0)\n", start);
return;
}

/* make sure the address is in the range */
if(start < CONFIG_SIFIVE_L2_FLUSH_START ||
(start + len) > (CONFIG_SIFIVE_L2_FLUSH_START +
CONFIG_SIFIVE_L2_FLUSH_SIZE)) {
pr_warn("L2CACHE: flush64 out of range: %lx(%lx), skip flush\n",
start, len);
return;
}

mb(); /* sync */
for (line = start; line < start + len;
line += SIFIVE_L2_FLUSH64_LINE_LEN) {
writeq(line, l2_base + SIFIVE_L2_FLUSH64);
mb();
}
}
EXPORT_SYMBOL_GPL(sifive_l2_flush64_range);
#endif

static int l2_largest_wayenabled(void)
{
return readl(l2_base + SIFIVE_L2_WAYENABLE) & 0xFF;
Expand Down
4 changes: 4 additions & 0 deletions include/soc/sifive/sifive_l2_cache.h
Expand Up @@ -7,6 +7,10 @@
#ifndef __SOC_SIFIVE_L2_CACHE_H
#define __SOC_SIFIVE_L2_CACHE_H

#ifdef CONFIG_SIFIVE_L2_FLUSH
extern void sifive_l2_flush64_range(unsigned long start, unsigned long len);
#endif

extern int register_sifive_l2_error_notifier(struct notifier_block *nb);
extern int unregister_sifive_l2_error_notifier(struct notifier_block *nb);

Expand Down

0 comments on commit 1c9c971

Please sign in to comment.