All of lore.kernel.org
 help / color / mirror / Atom feed
From: Joshua Yeong <joshua.yeong@starfivetech.com>
To: paul.walmsley@sifive.com, palmer@dabbelt.com,
	aou@eecs.berkeley.edu, geert+renesas@glider.be,
	joshua.yeong@starfivetech.com,
	prabhakar.mahadev-lad.rj@bp.renesas.com,
	conor.dooley@microchip.com, alexghiti@rivosinc.com,
	evan@rivosinc.com, ajones@ventanamicro.com, heiko@sntech.de,
	guoren@kernel.org, uwu@icenowy.me, jszhang@kernel.org,
	conor@kernel.org, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
	leyfoon.tan@starfivetech.com, jeeheng.sia@starfivetech.com
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org
Subject: [PATCH 3/4] cache: Add StarLink-500 cache management for StarFive  JH8100 RISC-V core
Date: Thu, 14 Mar 2024 14:12:04 +0800	[thread overview]
Message-ID: <20240314061205.26143-4-joshua.yeong@starfivetech.com> (raw)
In-Reply-To: <20240314061205.26143-1-joshua.yeong@starfivetech.com>

Add software workaround for StarFive StarLink-500
on JH8100 SoC for CMO extension instructions.

Signed-off-by: Joshua Yeong <joshua.yeong@starfivetech.com>
---
 drivers/cache/Kconfig             |   9 ++
 drivers/cache/Makefile            |   1 +
 drivers/cache/starlink500_cache.c | 137 ++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/cache/starlink500_cache.c

diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 9345ce4976d7..e215379f6a73 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -14,4 +14,13 @@ config SIFIVE_CCACHE
 	help
 	  Support for the composable cache controller on SiFive platforms.
 
+config STARLINK_500_CACHE
+	bool "StarLink-500 Cache controller"
+	depends on RISCV_DMA_NONCOHERENT
+	depends on ERRATA_STARFIVE
+	select RISCV_NONSTANDARD_CACHE_OPS
+	default y
+	help
+	  Support for the StarLink-500 cache controller on StarFive platforms.
+
 endmenu
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
index 7657cff3bd6c..c515eb5714ea 100644
--- a/drivers/cache/Makefile
+++ b/drivers/cache/Makefile
@@ -2,3 +2,4 @@
 
 obj-$(CONFIG_AX45MP_L2_CACHE)	+= ax45mp_cache.o
 obj-$(CONFIG_SIFIVE_CCACHE)	+= sifive_ccache.o
+obj-$(CONFIG_STARLINK_500_CACHE) += starlink500_cache.o
diff --git a/drivers/cache/starlink500_cache.c b/drivers/cache/starlink500_cache.c
new file mode 100644
index 000000000000..eaf8303cb086
--- /dev/null
+++ b/drivers/cache/starlink500_cache.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Non-coherent cache functions for StarFive's StarLink-500 cache controller
+ *
+ * Copyright (C) 2024 Shanghai StarFive Technology Co., Ltd.
+ *
+ * Author: Joshua Yeong <joshua.yeong@starfivetech.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cacheflush.h>
+#include <linux/cacheinfo.h>
+#include <linux/delay.h>
+#include <linux/dma-direction.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/processor.h>
+
+#include <asm/dma-noncoherent.h>
+
+#define STARFIVE_SL500_CMO_FLUSH_START_ADDR		0x0
+#define STARFIVE_SL500_CMO_FLUSH_END_ADDR		0x8
+#define STARFIVE_SL500_CMO_FLUSH_CTL			0x10
+#define STARFIVE_SL500_CMO_CACHE_ALIGN			0x40
+
+#define STARFIVE_SL500_ADDRESS_RANGE_MASK		GENMASK(39, 0)
+#define STARFIVE_SL500_FLUSH_CTL_MODE_MASK		GENMASK(2, 1)
+#define STARFIVE_SL500_FLUSH_CTL_ENABLE_MASK		BIT(0)
+
+#define STARFIVE_SL500_FLUSH_CTL_CLEAN_INVALIDATE	0
+#define STARFIVE_SL500_FLUSH_CTL_MAKE_INVALIDATE	1
+#define STARFIVE_SL500_FLUSH_CTL_CLEAN_SHARED		2
+
+struct starfive_sl500_cache_priv {
+	void __iomem *base_addr;
+};
+
+static struct starfive_sl500_cache_priv starfive_sl500_cache_priv;
+
+static void starfive_sl500_cmo_flush_complete(void)
+{
+	ktime_t timeout;
+
+	volatile void __iomem *_ctl = starfive_sl500_cache_priv.base_addr +
+                                      STARFIVE_SL500_CMO_FLUSH_CTL;
+	timeout = ktime_add_ms(ktime_get(), 5000);
+
+	do {
+		if(!(ioread64(_ctl) & STARFIVE_SL500_FLUSH_CTL_ENABLE_MASK))
+			return;
+		msleep(50);
+	} while (ktime_before(ktime_get(), timeout));
+
+	pr_err("StarFive CMO operation timeout\n");
+	dump_stack();
+}
+
+void starfive_sl500_dma_cache_wback(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_CLEAN_SHARED),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+void starfive_sl500_dma_cache_invalidate(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_MAKE_INVALIDATE),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+void starfive_sl500_dma_cache_wback_inv(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_CLEAN_INVALIDATE),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+static const struct riscv_nonstd_cache_ops starfive_sl500_cmo_ops = {
+	.wback = &starfive_sl500_dma_cache_wback,
+	.inv = &starfive_sl500_dma_cache_invalidate,
+	.wback_inv = &starfive_sl500_dma_cache_wback_inv,
+};
+
+static const struct of_device_id starfive_sl500_cache_ids[] = {
+	{ .compatible = "starfive,starlink-500-cache" },
+	{ /* sentinel */ }
+};
+
+static int __init starfive_sl500_cache_init(void)
+{
+	struct device_node *np;
+	struct resource res;
+	int ret;
+
+	np = of_find_matching_node(NULL, starfive_sl500_cache_ids);
+	if (!of_device_is_available(np))
+		return -ENODEV;
+
+	ret = of_address_to_resource(np, 0, &res);
+	if (ret)
+		return ret;
+
+	starfive_sl500_cache_priv.base_addr = ioremap(res.start, resource_size(&res));
+	if (!starfive_sl500_cache_priv.base_addr)
+		return -ENOMEM;
+
+	riscv_noncoherent_register_cache_ops(&starfive_sl500_cmo_ops);
+
+	return 0;
+}
+early_initcall(starfive_sl500_cache_init);
-- 
2.25.1


_______________________________________________
linux-riscv mailing list
linux-riscv@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-riscv

WARNING: multiple messages have this Message-ID (diff)
From: Joshua Yeong <joshua.yeong@starfivetech.com>
To: paul.walmsley@sifive.com, palmer@dabbelt.com,
	aou@eecs.berkeley.edu, geert+renesas@glider.be,
	joshua.yeong@starfivetech.com,
	prabhakar.mahadev-lad.rj@bp.renesas.com,
	conor.dooley@microchip.com, alexghiti@rivosinc.com,
	evan@rivosinc.com, ajones@ventanamicro.com, heiko@sntech.de,
	guoren@kernel.org, uwu@icenowy.me, jszhang@kernel.org,
	conor@kernel.org, robh+dt@kernel.org,
	krzysztof.kozlowski+dt@linaro.org, conor+dt@kernel.org,
	leyfoon.tan@starfivetech.com, jeeheng.sia@starfivetech.com
Cc: linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org,
	devicetree@vger.kernel.org
Subject: [PATCH 3/4] cache: Add StarLink-500 cache management for StarFive  JH8100 RISC-V core
Date: Thu, 14 Mar 2024 14:12:04 +0800	[thread overview]
Message-ID: <20240314061205.26143-4-joshua.yeong@starfivetech.com> (raw)
In-Reply-To: <20240314061205.26143-1-joshua.yeong@starfivetech.com>

Add software workaround for StarFive StarLink-500
on JH8100 SoC for CMO extension instructions.

Signed-off-by: Joshua Yeong <joshua.yeong@starfivetech.com>
---
 drivers/cache/Kconfig             |   9 ++
 drivers/cache/Makefile            |   1 +
 drivers/cache/starlink500_cache.c | 137 ++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)
 create mode 100644 drivers/cache/starlink500_cache.c

diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
index 9345ce4976d7..e215379f6a73 100644
--- a/drivers/cache/Kconfig
+++ b/drivers/cache/Kconfig
@@ -14,4 +14,13 @@ config SIFIVE_CCACHE
 	help
 	  Support for the composable cache controller on SiFive platforms.
 
+config STARLINK_500_CACHE
+	bool "StarLink-500 Cache controller"
+	depends on RISCV_DMA_NONCOHERENT
+	depends on ERRATA_STARFIVE
+	select RISCV_NONSTANDARD_CACHE_OPS
+	default y
+	help
+	  Support for the StarLink-500 cache controller on StarFive platforms.
+
 endmenu
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
index 7657cff3bd6c..c515eb5714ea 100644
--- a/drivers/cache/Makefile
+++ b/drivers/cache/Makefile
@@ -2,3 +2,4 @@
 
 obj-$(CONFIG_AX45MP_L2_CACHE)	+= ax45mp_cache.o
 obj-$(CONFIG_SIFIVE_CCACHE)	+= sifive_ccache.o
+obj-$(CONFIG_STARLINK_500_CACHE) += starlink500_cache.o
diff --git a/drivers/cache/starlink500_cache.c b/drivers/cache/starlink500_cache.c
new file mode 100644
index 000000000000..eaf8303cb086
--- /dev/null
+++ b/drivers/cache/starlink500_cache.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Non-coherent cache functions for StarFive's StarLink-500 cache controller
+ *
+ * Copyright (C) 2024 Shanghai StarFive Technology Co., Ltd.
+ *
+ * Author: Joshua Yeong <joshua.yeong@starfivetech.com>
+ */
+
+#include <linux/bitfield.h>
+#include <linux/cacheflush.h>
+#include <linux/cacheinfo.h>
+#include <linux/delay.h>
+#include <linux/dma-direction.h>
+#include <linux/io.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/processor.h>
+
+#include <asm/dma-noncoherent.h>
+
+#define STARFIVE_SL500_CMO_FLUSH_START_ADDR		0x0
+#define STARFIVE_SL500_CMO_FLUSH_END_ADDR		0x8
+#define STARFIVE_SL500_CMO_FLUSH_CTL			0x10
+#define STARFIVE_SL500_CMO_CACHE_ALIGN			0x40
+
+#define STARFIVE_SL500_ADDRESS_RANGE_MASK		GENMASK(39, 0)
+#define STARFIVE_SL500_FLUSH_CTL_MODE_MASK		GENMASK(2, 1)
+#define STARFIVE_SL500_FLUSH_CTL_ENABLE_MASK		BIT(0)
+
+#define STARFIVE_SL500_FLUSH_CTL_CLEAN_INVALIDATE	0
+#define STARFIVE_SL500_FLUSH_CTL_MAKE_INVALIDATE	1
+#define STARFIVE_SL500_FLUSH_CTL_CLEAN_SHARED		2
+
+struct starfive_sl500_cache_priv {
+	void __iomem *base_addr;
+};
+
+static struct starfive_sl500_cache_priv starfive_sl500_cache_priv;
+
+static void starfive_sl500_cmo_flush_complete(void)
+{
+	ktime_t timeout;
+
+	volatile void __iomem *_ctl = starfive_sl500_cache_priv.base_addr +
+                                      STARFIVE_SL500_CMO_FLUSH_CTL;
+	timeout = ktime_add_ms(ktime_get(), 5000);
+
+	do {
+		if(!(ioread64(_ctl) & STARFIVE_SL500_FLUSH_CTL_ENABLE_MASK))
+			return;
+		msleep(50);
+	} while (ktime_before(ktime_get(), timeout));
+
+	pr_err("StarFive CMO operation timeout\n");
+	dump_stack();
+}
+
+void starfive_sl500_dma_cache_wback(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_CLEAN_SHARED),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+void starfive_sl500_dma_cache_invalidate(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_MAKE_INVALIDATE),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+void starfive_sl500_dma_cache_wback_inv(phys_addr_t paddr, unsigned long size)
+{
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_START_ADDR);
+	writeq(FIELD_PREP(STARFIVE_SL500_ADDRESS_RANGE_MASK, paddr + size),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_END_ADDR);
+
+	mb();
+	writeq(FIELD_PREP(STARFIVE_SL500_FLUSH_CTL_MODE_MASK,
+	       STARFIVE_SL500_FLUSH_CTL_CLEAN_INVALIDATE),
+	       starfive_sl500_cache_priv.base_addr + STARFIVE_SL500_CMO_FLUSH_CTL);
+
+	starfive_sl500_cmo_flush_complete();
+}
+
+static const struct riscv_nonstd_cache_ops starfive_sl500_cmo_ops = {
+	.wback = &starfive_sl500_dma_cache_wback,
+	.inv = &starfive_sl500_dma_cache_invalidate,
+	.wback_inv = &starfive_sl500_dma_cache_wback_inv,
+};
+
+static const struct of_device_id starfive_sl500_cache_ids[] = {
+	{ .compatible = "starfive,starlink-500-cache" },
+	{ /* sentinel */ }
+};
+
+static int __init starfive_sl500_cache_init(void)
+{
+	struct device_node *np;
+	struct resource res;
+	int ret;
+
+	np = of_find_matching_node(NULL, starfive_sl500_cache_ids);
+	if (!of_device_is_available(np))
+		return -ENODEV;
+
+	ret = of_address_to_resource(np, 0, &res);
+	if (ret)
+		return ret;
+
+	starfive_sl500_cache_priv.base_addr = ioremap(res.start, resource_size(&res));
+	if (!starfive_sl500_cache_priv.base_addr)
+		return -ENOMEM;
+
+	riscv_noncoherent_register_cache_ops(&starfive_sl500_cmo_ops);
+
+	return 0;
+}
+early_initcall(starfive_sl500_cache_init);
-- 
2.25.1


  parent reply	other threads:[~2024-03-14  6:13 UTC|newest]

Thread overview: 28+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-03-14  6:12 [PATCH 0/4] Add StarFive's StarLink-500 Cache Controller Joshua Yeong
2024-03-14  6:12 ` Joshua Yeong
2024-03-14  6:12 ` [PATCH 1/4] riscv: asm: vendorid_list: Add StarFive Technology to vendors list Joshua Yeong
2024-03-14  6:12   ` Joshua Yeong
2024-03-14  6:12 ` [PATCH 2/4] riscv: errata: Add StarFive alternative ports Joshua Yeong
2024-03-14  6:12   ` Joshua Yeong
2024-03-15 23:13   ` Samuel Holland
2024-03-15 23:13     ` Samuel Holland
2024-03-17 15:04     ` Conor Dooley
2024-03-17 15:04       ` Conor Dooley
2024-03-14  6:12 ` Joshua Yeong [this message]
2024-03-14  6:12   ` [PATCH 3/4] cache: Add StarLink-500 cache management for StarFive JH8100 RISC-V core Joshua Yeong
2024-03-15  8:22   ` kernel test robot
2024-03-15  8:22     ` kernel test robot
2024-03-15 23:33   ` Samuel Holland
2024-03-15 23:33     ` Samuel Holland
2024-03-14  6:12 ` [PATCH 4/4] dt-bindings: cache: Add docs for StarFive StarLink-500 cache controller Joshua Yeong
2024-03-14  6:12   ` Joshua Yeong
2024-03-15 16:36   ` Rob Herring
2024-03-15 16:36     ` Rob Herring
2024-03-17 14:58     ` Conor Dooley
2024-03-17 14:58       ` Conor Dooley
2024-03-17 15:01 ` [PATCH 0/4] Add StarFive's StarLink-500 Cache Controller Conor Dooley
2024-03-17 15:01   ` Conor Dooley
2024-03-20  8:08   ` Conor Dooley
2024-03-20  8:08     ` Conor Dooley
2024-03-22  6:16     ` Joshua Yeong
2024-03-22  6:16       ` Joshua Yeong

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240314061205.26143-4-joshua.yeong@starfivetech.com \
    --to=joshua.yeong@starfivetech.com \
    --cc=ajones@ventanamicro.com \
    --cc=alexghiti@rivosinc.com \
    --cc=aou@eecs.berkeley.edu \
    --cc=conor+dt@kernel.org \
    --cc=conor.dooley@microchip.com \
    --cc=conor@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=evan@rivosinc.com \
    --cc=geert+renesas@glider.be \
    --cc=guoren@kernel.org \
    --cc=heiko@sntech.de \
    --cc=jeeheng.sia@starfivetech.com \
    --cc=jszhang@kernel.org \
    --cc=krzysztof.kozlowski+dt@linaro.org \
    --cc=leyfoon.tan@starfivetech.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-riscv@lists.infradead.org \
    --cc=palmer@dabbelt.com \
    --cc=paul.walmsley@sifive.com \
    --cc=prabhakar.mahadev-lad.rj@bp.renesas.com \
    --cc=robh+dt@kernel.org \
    --cc=uwu@icenowy.me \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.