diff --git a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml index 8a6a78e1a7ab..7e8cebe21584 100644 --- a/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml +++ b/Documentation/devicetree/bindings/cache/sifive,ccache0.yaml @@ -38,7 +38,9 @@ properties: - sifive,fu740-c000-ccache - const: cache - items: - - const: starfive,jh7110-ccache + - enum: + - starfive,jh7100-ccache + - starfive,jh7110-ccache - const: sifive,ccache0 - const: cache - items: @@ -88,6 +90,7 @@ allOf: contains: enum: - sifive,fu740-c000-ccache + - starfive,jh7100-ccache - starfive,jh7110-ccache - microchip,mpfs-ccache @@ -111,6 +114,7 @@ allOf: contains: enum: - sifive,fu740-c000-ccache + - starfive,jh7100-ccache - starfive,jh7110-ccache then: diff --git a/MAINTAINERS b/MAINTAINERS index 089b8183e43c..31d89bc258be 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -19783,6 +19783,13 @@ S: Supported N: sifive K: [^@]sifive +SIFIVE CACHE DRIVER +M: Conor Dooley +L: linux-riscv@lists.infradead.org +S: Maintained +F: Documentation/devicetree/bindings/cache/sifive,ccache0.yaml +F: drivers/cache/sifive_ccache.c + SIFIVE FU540 SYSTEM-ON-CHIP M: Paul Walmsley M: Palmer Dabbelt @@ -19798,13 +19805,6 @@ S: Maintained F: Documentation/devicetree/bindings/dma/sifive,fu540-c000-pdma.yaml F: drivers/dma/sf-pdma/ -SIFIVE SOC DRIVERS -M: Conor Dooley -L: linux-riscv@lists.infradead.org -S: Maintained -T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/ -F: Documentation/devicetree/bindings/cache/sifive,ccache0.yaml -F: drivers/soc/sifive/ SILEAD TOUCHSCREEN DRIVER M: Hans de Goede diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata index e2c731cfed8c..f5c432b005e7 100644 --- a/arch/riscv/Kconfig.errata +++ b/arch/riscv/Kconfig.errata @@ -53,6 +53,25 @@ config ERRATA_SIFIVE_CIP_1200 If you don't know what to do here, say "Y". +config ERRATA_STARFIVE_JH7100 + bool "StarFive JH7100 support" + depends on ARCH_STARFIVE + depends on !DMA_DIRECT_REMAP + depends on NONPORTABLE + select DMA_GLOBAL_POOL + select RISCV_DMA_NONCOHERENT + select RISCV_NONSTANDARD_CACHE_OPS + select SIFIVE_CCACHE + default n + help + The StarFive JH7100 was a test chip for the JH7110 and has + caches that are non-coherent with respect to peripheral DMAs. + It was designed before the Zicbom extension so needs non-standard + cache operations through the SiFive cache controller. + + Say "Y" if you want to support the BeagleV Starlight and/or + StarFive VisionFive V1 boards. + config ERRATA_THEAD bool "T-HEAD errata" depends on RISCV_ALTERNATIVE diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig index d6e5e3abaad8..9345ce4976d7 100644 --- a/drivers/cache/Kconfig +++ b/drivers/cache/Kconfig @@ -8,4 +8,10 @@ config AX45MP_L2_CACHE help Support for the L2 cache controller on Andes Technology AX45MP platforms. +config SIFIVE_CCACHE + bool "Sifive Composable Cache controller" + depends on ARCH_SIFIVE || ARCH_STARFIVE + help + Support for the composable cache controller on SiFive platforms. + endmenu diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile index 2012e7fb978d..7657cff3bd6c 100644 --- a/drivers/cache/Makefile +++ b/drivers/cache/Makefile @@ -1,3 +1,4 @@ # SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o +obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o +obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o diff --git a/drivers/soc/sifive/sifive_ccache.c b/drivers/cache/sifive_ccache.c similarity index 81% rename from drivers/soc/sifive/sifive_ccache.c rename to drivers/cache/sifive_ccache.c index 3684f5b40a80..89ed6cd6b059 100644 --- a/drivers/soc/sifive/sifive_ccache.c +++ b/drivers/cache/sifive_ccache.c @@ -8,13 +8,16 @@ #define pr_fmt(fmt) "CCACHE: " fmt +#include #include #include #include #include #include #include +#include #include +#include #include #define SIFIVE_CCACHE_DIRECCFIX_LOW 0x100 @@ -39,10 +42,14 @@ #define SIFIVE_CCACHE_CONFIG_SETS_MASK GENMASK_ULL(23, 16) #define SIFIVE_CCACHE_CONFIG_BLKS_MASK GENMASK_ULL(31, 24) +#define SIFIVE_CCACHE_FLUSH64 0x200 +#define SIFIVE_CCACHE_FLUSH32 0x240 + #define SIFIVE_CCACHE_WAYENABLE 0x08 #define SIFIVE_CCACHE_ECCINJECTERR 0x40 #define SIFIVE_CCACHE_MAX_ECCINTR 4 +#define SIFIVE_CCACHE_LINE_SIZE 64 static void __iomem *ccache_base; static int g_irq[SIFIVE_CCACHE_MAX_ECCINTR]; @@ -56,6 +63,11 @@ enum { DIR_UNCORR, }; +enum { + QUIRK_NONSTANDARD_CACHE_OPS = BIT(0), + QUIRK_BROKEN_DATA_UNCORR = BIT(1), +}; + #ifdef CONFIG_DEBUG_FS static struct dentry *sifive_test; @@ -106,6 +118,8 @@ static void ccache_config_read(void) static const struct of_device_id sifive_ccache_ids[] = { { .compatible = "sifive,fu540-c000-ccache" }, { .compatible = "sifive,fu740-c000-ccache" }, + { .compatible = "starfive,jh7100-ccache", + .data = (void *)(QUIRK_NONSTANDARD_CACHE_OPS | QUIRK_BROKEN_DATA_UNCORR) }, { .compatible = "sifive,ccache0" }, { /* end of table */ } }; @@ -124,6 +138,34 @@ int unregister_sifive_ccache_error_notifier(struct notifier_block *nb) } EXPORT_SYMBOL_GPL(unregister_sifive_ccache_error_notifier); +#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS +static void ccache_flush_range(phys_addr_t start, size_t len) +{ + phys_addr_t end = start + len; + phys_addr_t line; + + if (!len) + return; + + mb(); + for (line = ALIGN_DOWN(start, SIFIVE_CCACHE_LINE_SIZE); line < end; + line += SIFIVE_CCACHE_LINE_SIZE) { +#ifdef CONFIG_32BIT + writel(line >> 4, ccache_base + SIFIVE_CCACHE_FLUSH32); +#else + writeq(line, ccache_base + SIFIVE_CCACHE_FLUSH64); +#endif + mb(); + } +} + +static const struct riscv_nonstd_cache_ops ccache_mgmt_ops __initconst = { + .wback = &ccache_flush_range, + .inv = &ccache_flush_range, + .wback_inv = &ccache_flush_range, +}; +#endif /* CONFIG_RISCV_NONSTANDARD_CACHE_OPS */ + static int ccache_largest_wayenabled(void) { return readl(ccache_base + SIFIVE_CCACHE_WAYENABLE) & 0xFF; @@ -210,11 +252,15 @@ static int __init sifive_ccache_init(void) struct device_node *np; struct resource res; int i, rc, intr_num; + const struct of_device_id *match; + unsigned long quirks; - np = of_find_matching_node(NULL, sifive_ccache_ids); + np = of_find_matching_node_and_match(NULL, sifive_ccache_ids, &match); if (!np) return -ENODEV; + quirks = (uintptr_t)match->data; + if (of_address_to_resource(np, 0, &res)) { rc = -ENODEV; goto err_node_put; @@ -240,6 +286,10 @@ static int __init sifive_ccache_init(void) for (i = 0; i < intr_num; i++) { g_irq[i] = irq_of_parse_and_map(np, i); + + if (i == DATA_UNCORR && (quirks & QUIRK_BROKEN_DATA_UNCORR)) + continue; + rc = request_irq(g_irq[i], ccache_int_handler, 0, "ccache_ecc", NULL); if (rc) { @@ -249,6 +299,14 @@ static int __init sifive_ccache_init(void) } of_node_put(np); +#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS + if (quirks & QUIRK_NONSTANDARD_CACHE_OPS) { + riscv_cbom_block_size = SIFIVE_CCACHE_LINE_SIZE; + riscv_noncoherent_supported(); + riscv_noncoherent_register_cache_ops(&ccache_mgmt_ops); + } +#endif + ccache_config_read(); ccache_cache_ops.get_priv_group = ccache_get_priv_group; @@ -269,4 +327,4 @@ err_node_put: return rc; } -device_initcall(sifive_ccache_init); +arch_initcall(sifive_ccache_init); diff --git a/drivers/soc/Kconfig b/drivers/soc/Kconfig index 10a9ff84ff41..5d924e946507 100644 --- a/drivers/soc/Kconfig +++ b/drivers/soc/Kconfig @@ -22,7 +22,6 @@ source "drivers/soc/qcom/Kconfig" source "drivers/soc/renesas/Kconfig" source "drivers/soc/rockchip/Kconfig" source "drivers/soc/samsung/Kconfig" -source "drivers/soc/sifive/Kconfig" source "drivers/soc/sunxi/Kconfig" source "drivers/soc/tegra/Kconfig" source "drivers/soc/ti/Kconfig" diff --git a/drivers/soc/Makefile b/drivers/soc/Makefile index 0706a27d13be..ba8f5b5460e1 100644 --- a/drivers/soc/Makefile +++ b/drivers/soc/Makefile @@ -28,7 +28,6 @@ obj-y += qcom/ obj-y += renesas/ obj-y += rockchip/ obj-$(CONFIG_SOC_SAMSUNG) += samsung/ -obj-y += sifive/ obj-y += sunxi/ obj-$(CONFIG_ARCH_TEGRA) += tegra/ obj-y += ti/ diff --git a/drivers/soc/sifive/Kconfig b/drivers/soc/sifive/Kconfig deleted file mode 100644 index 139884addc41..000000000000 --- a/drivers/soc/sifive/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -if ARCH_SIFIVE || ARCH_STARFIVE - -config SIFIVE_CCACHE - bool "Sifive Composable Cache controller" - help - Support for the composable cache controller on SiFive platforms. - -endif diff --git a/drivers/soc/sifive/Makefile b/drivers/soc/sifive/Makefile deleted file mode 100644 index 1f5dc339bf82..000000000000 --- a/drivers/soc/sifive/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -obj-$(CONFIG_SIFIVE_CCACHE) += sifive_ccache.o