From: Lad Prabhakar <[email protected]>
Hi All,
non-coherent DMA support for AX45MP
====================================
On the Andes AX45MP core, cache coherency is a specification option so it
may not be supported. In this case DMA will fail. To get around with this
issue this patch series does the below:
1] Andes alternative ports is implemented as errata which checks if the IOCP
is missing and only then applies to CMO errata. One vendor specific SBI EXT
(ANDES_SBI_EXT_IOCP_SW_WORKAROUND) is implemented as part of errata.
Below are the configs which Andes port provides (and are selected by RZ/Five):
- ERRATA_ANDES
- ERRATA_ANDES_CMO
OpenSBI patch supporting ANDES_SBI_EXT_IOCP_SW_WORKAROUND SBI can be found here,
https://patchwork.ozlabs.org/project/opensbi/patch/[email protected]/
2] Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
block that allows dynamic adjustment of memory attributes in the runtime.
It contains a configurable amount of PMA entries implemented as CSR
registers to control the attributes of memory locations in interest.
OpenSBI configures the PMA regions as required and creates a reserve memory
node and propagates it to the higher boot stack.
Currently OpenSBI (upstream) configures the required PMA region and passes
this a shared DMA pool to Linux.
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
pma_resv0@58000000 {
compatible = "shared-dma-pool";
reg = <0x0 0x58000000 0x0 0x08000000>;
no-map;
linux,dma-default;
};
};
The above shared DMA pool gets appended to Linux DTB so the DMA memory
requests go through this region.
3] We provide callbacks to synchronize specific content between memory and
cache.
4] RZ/Five SoC selects the below configs
- AX45MP_L2_CACHE
- DMA_GLOBAL_POOL
- ERRATA_ANDES
- ERRATA_ANDES_CMO
----------x---------------------x--------------------x---------------x--------------
Note,
- This series requires testing on Cores with zicbom and T-Head SoCs
- Ive used GCC 12.2.0 for compilation
- Tested all the IP blocks on RZ/Five which use DMA
- Patch series is dependent on the series from Arnd,
https://patchwork.kernel.org/project/linux-riscv/cover/[email protected]/
- Patches applies on top of palmer/for-next (d34a6b715a23)
v7 -> v8
* Dropped using function pointers and switched to ALTERNATIVE_X()
* Added new patches (#1, #2)
v6 -> v7
* Reworked the code based on Arnd's work
* Fixed review comments pointed by Arnd
* Fixed review comments pointed by Conor
v5.1 -> v6
* Dropped use of ALTERNATIVE_x() macro
* Now switched to used function pointers for CMO
* Moved driver to drivers/cache folder
v5 -> v5.1
* https://patchwork.kernel.org/project/linux-riscv/list/?series=708610&state=%2A&archive=both
v4 -> v5
* Rebased ALTERNATIVE_3() macro on top of Andrew's patches
* Rebased the changes on top of Heiko's alternative call patches
* Dropped configuring the PMA from Linux
* Dropped configuring the L2 cache from Linux and dropped the binding for same
* Now using runtime patching mechanism instead of compile time config
RFC v3 -> v4
* Implemented ALTERNATIVE_3() macro
* Now using runtime patching mechanism instead of compile time config
* Added Andes CMO as and errata
* Fixed comments pointed by Geert
RFC v2-> RFC v3
* Fixed review comments pointed by Conor
* Move DT binding into cache folder
* Fixed DT binding check issue
* Added andestech,ax45mp-cache.h header file
* Now passing the flags for the PMA setup as part of andestech,pma-regions
property.
* Added andestech,inst/data-prefetch and andestech,tag/data-ram-ctl
properties to configure the L2 cache.
* Registered the cache driver as platform driver
RFC v1-> RFC v2
* Moved out the code from arc/riscv to drivers/soc/renesas
* Now handling the PMA setup as part of the L2 cache
* Now making use of dma-noncoherent.c instead SoC specific implementation.
* Dropped arch_dma_alloc() and arch_dma_free()
* Switched to RISCV_DMA_NONCOHERENT
* Included DT binding doc
RFC v2: https://patchwork.kernel.org/project/linux-renesas-soc/cover/[email protected]/
RFC v1: https://patchwork.kernel.org/project/linux-renesas-soc/cover/[email protected]/
Cheers,
Prabhakar
Lad Prabhakar (7):
riscv: asm: alternative-macros: Introduce ALTERNATIVE_3() macro
riscv: asm: vendorid_list: Add Andes Technology to the vendors list
riscv: errata: Add Andes alternative ports
dt-bindings: cache: andestech,ax45mp-cache: Add DT binding
documentation for L2 cache controller
cache: Add L2 cache management for Andes AX45MP RISC-V core
riscv: errata: Hookup the Andes AX45MP non-coherent handling
soc: renesas: Kconfig: Select the required configs for RZ/Five SoC
.../cache/andestech,ax45mp-cache.yaml | 81 +++++++
MAINTAINERS | 7 +
arch/riscv/Kconfig.errata | 21 ++
arch/riscv/errata/Makefile | 1 +
arch/riscv/errata/andes/Makefile | 1 +
arch/riscv/errata/andes/errata.c | 104 ++++++++
arch/riscv/include/asm/alternative-macros.h | 51 +++-
arch/riscv/include/asm/alternative.h | 3 +
arch/riscv/include/asm/cacheflush.h | 9 +
arch/riscv/include/asm/errata_list.h | 38 ++-
arch/riscv/include/asm/vendorid_list.h | 1 +
arch/riscv/kernel/alternative.c | 5 +
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/cache/Kconfig | 10 +
drivers/cache/Makefile | 3 +
drivers/cache/ax45mp_cache.c | 222 ++++++++++++++++++
drivers/soc/renesas/Kconfig | 4 +
18 files changed, 552 insertions(+), 12 deletions(-)
create mode 100644 Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
create mode 100644 arch/riscv/errata/andes/Makefile
create mode 100644 arch/riscv/errata/andes/errata.c
create mode 100644 drivers/cache/Kconfig
create mode 100644 drivers/cache/Makefile
create mode 100644 drivers/cache/ax45mp_cache.c
--
2.25.1
From: Lad Prabhakar <[email protected]>
Introduce ALTERNATIVE_3() macro.
A vendor wants to replace an old_content, but another vendor has used
ALTERNATIVE_2() to patch its customized content at the same location.
In this case, this vendor can use macro ALTERNATIVE_3() and then replace
ALTERNATIVE_2() with ALTERNATIVE_3() to append its customized content.
While at it update comment above ALTERNATIVE_2() macro and make it generic
so that the comment holds good for any new addition of ALTERNATIVE_X()
macros.
Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Heiko Stuebner <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
v5->v8
* Added RB tags from Conor and Heiko
* Fixed review comments pointed by Geert and Conor
v4->v5
* Rebased the patch on top of Andrew's series (now in Palmers for next-branch)
* Updated comment for ALTERNATIVE_x() as suggested by Heiko
RFC v3 -> v4
* New patch
---
arch/riscv/include/asm/alternative-macros.h | 51 +++++++++++++++++++--
1 file changed, 46 insertions(+), 5 deletions(-)
diff --git a/arch/riscv/include/asm/alternative-macros.h b/arch/riscv/include/asm/alternative-macros.h
index b8c55fb3ab2c..fd5f99714f29 100644
--- a/arch/riscv/include/asm/alternative-macros.h
+++ b/arch/riscv/include/asm/alternative-macros.h
@@ -50,8 +50,17 @@
ALT_NEW_CONTENT \vendor_id_2, \patch_id_2, \enable_2, "\new_c_2"
.endm
+.macro ALTERNATIVE_CFG_3 old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \
+ new_c_2, vendor_id_2, errata_id_2, enable_2, \
+ new_c_3, vendor_id_3, errata_id_3, enable_3
+ ALTERNATIVE_CFG_2 "\old_c", "\new_c_1", \vendor_id_1, \errata_id_1, \enable_1, \
+ "\new_c_2", \vendor_id_2, \errata_id_2, \enable_2
+ ALT_NEW_CONTENT \vendor_id_3, \errata_id_3, \enable_3, "\new_c_3"
+.endm
+
#define __ALTERNATIVE_CFG(...) ALTERNATIVE_CFG __VA_ARGS__
#define __ALTERNATIVE_CFG_2(...) ALTERNATIVE_CFG_2 __VA_ARGS__
+#define __ALTERNATIVE_CFG_3(...) ALTERNATIVE_CFG_3 __VA_ARGS__
#else /* !__ASSEMBLY__ */
@@ -98,6 +107,13 @@
__ALTERNATIVE_CFG(old_c, new_c_1, vendor_id_1, patch_id_1, enable_1) \
ALT_NEW_CONTENT(vendor_id_2, patch_id_2, enable_2, new_c_2)
+#define __ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \
+ new_c_2, vendor_id_2, errata_id_2, enable_2, \
+ new_c_3, vendor_id_3, errata_id_3, enable_3) \
+ __ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, errata_id_1, enable_1, \
+ new_c_2, vendor_id_2, errata_id_2, enable_2) \
+ ALT_NEW_CONTENT(vendor_id_3, errata_id_3, enable_3, new_c_3)
+
#endif /* __ASSEMBLY__ */
#define _ALTERNATIVE_CFG(old_c, new_c, vendor_id, patch_id, CONFIG_k) \
@@ -108,6 +124,13 @@
__ALTERNATIVE_CFG_2(old_c, new_c_1, vendor_id_1, patch_id_1, IS_ENABLED(CONFIG_k_1), \
new_c_2, vendor_id_2, patch_id_2, IS_ENABLED(CONFIG_k_2))
+#define _ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
+ new_c_2, vendor_id_2, errata_id_2, CONFIG_k_2, \
+ new_c_3, vendor_id_3, errata_id_3, CONFIG_k_3) \
+ __ALTERNATIVE_CFG_3(old_c, new_c_1, vendor_id_1, errata_id_1, IS_ENABLED(CONFIG_k_1), \
+ new_c_2, vendor_id_2, errata_id_2, IS_ENABLED(CONFIG_k_2), \
+ new_c_3, vendor_id_3, errata_id_3, IS_ENABLED(CONFIG_k_3))
+
#else /* CONFIG_RISCV_ALTERNATIVE */
#ifdef __ASSEMBLY__
@@ -121,6 +144,9 @@
#define _ALTERNATIVE_CFG_2(old_c, ...) \
ALTERNATIVE_CFG old_c
+#define _ALTERNATIVE_CFG_3(old_c, ...) \
+ ALTERNATIVE_CFG old_c
+
#else /* !__ASSEMBLY__ */
#define __ALTERNATIVE_CFG(old_c) \
@@ -132,6 +158,9 @@
#define _ALTERNATIVE_CFG_2(old_c, ...) \
__ALTERNATIVE_CFG(old_c)
+#define _ALTERNATIVE_CFG_3(old_c, ...) \
+ __ALTERNATIVE_CFG(old_c)
+
#endif /* __ASSEMBLY__ */
#endif /* CONFIG_RISCV_ALTERNATIVE */
@@ -152,15 +181,27 @@
_ALTERNATIVE_CFG(old_content, new_content, vendor_id, patch_id, CONFIG_k)
/*
- * A vendor wants to replace an old_content, but another vendor has used
- * ALTERNATIVE() to patch its customized content at the same location. In
- * this case, this vendor can create a new macro ALTERNATIVE_2() based
- * on the following sample code and then replace ALTERNATIVE() with
- * ALTERNATIVE_2() to append its customized content.
+ * ALTERNATIVE_x macros allow providing multiple replacement options
+ * for an ALTERNATIVE code section. This is helpful if multiple
+ * implementation variants for the same functionality.
+ *
+ * Usage:
+ * ALTERNATIVE_x(old_content,
+ * new_content1, vendor_id1, errata_id1, CONFIG_k1,
+ * new_content2, vendor_id2, errata_id2, CONFIG_k2,
+ * ...
+ * new_contentx, vendor_idx, errata_idx, CONFIG_kx)
*/
#define ALTERNATIVE_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1, \
new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2) \
_ALTERNATIVE_CFG_2(old_content, new_content_1, vendor_id_1, patch_id_1, CONFIG_k_1, \
new_content_2, vendor_id_2, patch_id_2, CONFIG_k_2)
+#define ALTERNATIVE_3(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
+ new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2, \
+ new_content_3, vendor_id_3, errata_id_3, CONFIG_k_3) \
+ _ALTERNATIVE_CFG_3(old_content, new_content_1, vendor_id_1, errata_id_1, CONFIG_k_1, \
+ new_content_2, vendor_id_2, errata_id_2, CONFIG_k_2, \
+ new_content_3, vendor_id_3, errata_id_3, CONFIG_k_3)
+
#endif
--
2.25.1
From: Lad Prabhakar <[email protected]>
Add required ports of the Alternative scheme for Andes CPU cores.
I/O Coherence Port (IOCP) provides an AXI interface for connecting external
non-caching masters, such as DMA controllers. IOCP is a specification
option and is disabled on the Renesas RZ/Five SoC due to this reason cache
management needs a software workaround.
Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
v7 -> v8
* Now patching the code using patch_text_nosync() and riscv_alternative_fix_offsets()
v6 -> v7
* Renamed RZFIVE_SBI_EXT_IOCP_SW_WORKAROUND -> ANDES_SBI_EXT_IOCP_SW_WORKAROUND
* Dropped "depends on !XIP_KERNEL" for ERRATA_ANDES config
v5 -> v6
* Dropped patching alternative and now just probing IOCP
v4 -> v5
* Sorted the Kconfig/Makefile/Switch based on Core name
* Added a comments
* Introduced RZFIVE_SBI_EXT_IOCP_SW_WORKAROUND SBI EXT ID to check if
CMO needs to be applied. Is there a way we can access the DTB while patching
as we can drop this SBI EXT ID and add a DT property instead for cmo?
RFC v3 -> v4
* New patch
---
arch/riscv/Kconfig.errata | 21 ++++++
arch/riscv/errata/Makefile | 1 +
arch/riscv/errata/andes/Makefile | 1 +
arch/riscv/errata/andes/errata.c | 104 +++++++++++++++++++++++++++
arch/riscv/include/asm/alternative.h | 3 +
arch/riscv/include/asm/errata_list.h | 5 ++
arch/riscv/kernel/alternative.c | 5 ++
7 files changed, 140 insertions(+)
create mode 100644 arch/riscv/errata/andes/Makefile
create mode 100644 arch/riscv/errata/andes/errata.c
diff --git a/arch/riscv/Kconfig.errata b/arch/riscv/Kconfig.errata
index 0c8f4652cd82..92c779764b27 100644
--- a/arch/riscv/Kconfig.errata
+++ b/arch/riscv/Kconfig.errata
@@ -1,5 +1,26 @@
menu "CPU errata selection"
+config ERRATA_ANDES
+ bool "Andes AX45MP errata"
+ depends on RISCV_ALTERNATIVE
+ help
+ All Andes errata Kconfig depend on this Kconfig. Disabling
+ this Kconfig will disable all Andes errata. Please say "Y"
+ here if your platform uses Andes CPU cores.
+
+ Otherwise, please say "N" here to avoid unnecessary overhead.
+
+config ERRATA_ANDES_CMO
+ bool "Apply Andes cache management errata"
+ depends on ERRATA_ANDES && MMU && ARCH_R9A07G043
+ select RISCV_DMA_NONCOHERENT
+ default y
+ help
+ This will apply the cache management errata to handle the
+ non-standard handling on non-coherent operations on Andes cores.
+
+ If you don't know what to do here, say "Y".
+
config ERRATA_SIFIVE
bool "SiFive errata"
depends on RISCV_ALTERNATIVE
diff --git a/arch/riscv/errata/Makefile b/arch/riscv/errata/Makefile
index a1055965fbee..6f1c693af92d 100644
--- a/arch/riscv/errata/Makefile
+++ b/arch/riscv/errata/Makefile
@@ -1,2 +1,3 @@
+obj-$(CONFIG_ERRATA_ANDES) += andes/
obj-$(CONFIG_ERRATA_SIFIVE) += sifive/
obj-$(CONFIG_ERRATA_THEAD) += thead/
diff --git a/arch/riscv/errata/andes/Makefile b/arch/riscv/errata/andes/Makefile
new file mode 100644
index 000000000000..2d644e19caef
--- /dev/null
+++ b/arch/riscv/errata/andes/Makefile
@@ -0,0 +1 @@
+obj-y += errata.o
diff --git a/arch/riscv/errata/andes/errata.c b/arch/riscv/errata/andes/errata.c
new file mode 100644
index 000000000000..49315f36022e
--- /dev/null
+++ b/arch/riscv/errata/andes/errata.c
@@ -0,0 +1,104 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Erratas to be applied for Andes CPU cores
+ *
+ * Copyright (C) 2023 Renesas Electronics Corporation.
+ *
+ * Author: Lad Prabhakar <[email protected]>
+ */
+
+#include <linux/memory.h>
+#include <linux/module.h>
+
+#include <asm/alternative.h>
+#include <asm/cacheflush.h>
+#include <asm/errata_list.h>
+#include <asm/patch.h>
+#include <asm/processor.h>
+#include <asm/sbi.h>
+#include <asm/vendorid_list.h>
+
+#define ANDESTECH_AX45MP_MARCHID 0x8000000000008a45UL
+#define ANDESTECH_AX45MP_MIMPID 0x500UL
+#define ANDESTECH_SBI_EXT_ANDES 0x0900031E
+
+#define ANDES_SBI_EXT_IOCP_SW_WORKAROUND 1
+
+static long ax45mp_iocp_sw_workaround(void)
+{
+ struct sbiret ret;
+
+ /*
+ * ANDES_SBI_EXT_IOCP_SW_WORKAROUND SBI EXT checks if the IOCP is missing and
+ * cache is controllable only then CMO will be applied to the platform.
+ */
+ ret = sbi_ecall(ANDESTECH_SBI_EXT_ANDES, ANDES_SBI_EXT_IOCP_SW_WORKAROUND,
+ 0, 0, 0, 0, 0, 0);
+
+ return ret.error ? 0 : ret.value;
+}
+
+static bool errata_probe_iocp(unsigned int stage, unsigned long arch_id, unsigned long impid)
+{
+ if (!IS_ENABLED(CONFIG_ERRATA_ANDES_CMO))
+ return false;
+
+ if (arch_id != ANDESTECH_AX45MP_MARCHID || impid != ANDESTECH_AX45MP_MIMPID)
+ return false;
+
+ if (!ax45mp_iocp_sw_workaround())
+ return false;
+
+ /* Set this just to make core cbo code happy */
+ riscv_cbom_block_size = 1;
+ riscv_noncoherent_supported();
+
+ return true;
+}
+
+static u32 andes_errata_probe(unsigned int stage, unsigned long archid, unsigned long impid)
+{
+ u32 cpu_req_errata = 0;
+
+ /*
+ * In the absence of the I/O Coherency Port, access to certain peripherals
+ * requires vendor specific DMA handling.
+ */
+ if (errata_probe_iocp(stage, archid, impid))
+ cpu_req_errata |= BIT(ERRATA_ANDESTECH_NO_IOCP);
+
+ return cpu_req_errata;
+}
+
+void __init_or_module andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
+ unsigned long archid, unsigned long impid,
+ unsigned int stage)
+{
+ u32 cpu_req_errata = andes_errata_probe(stage, archid, impid);
+ void *oldptr, *altptr;
+ struct alt_entry *alt;
+ u32 tmp;
+
+ if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
+ return;
+
+ for (alt = begin; alt < end; alt++) {
+ if (alt->vendor_id != ANDESTECH_VENDOR_ID)
+ continue;
+ if (alt->patch_id >= ERRATA_ANDESTECH_NUMBER)
+ continue;
+
+ tmp = BIT(alt->patch_id);
+ if (cpu_req_errata & tmp) {
+ oldptr = ALT_OLD_PTR(alt);
+ altptr = ALT_ALT_PTR(alt);
+
+ mutex_lock(&text_mutex);
+ patch_text_nosync(oldptr, altptr, alt->alt_len);
+
+ riscv_alternative_fix_offsets(oldptr, alt->alt_len,
+ oldptr - altptr);
+ mutex_unlock(&text_mutex);
+ }
+ }
+}
diff --git a/arch/riscv/include/asm/alternative.h b/arch/riscv/include/asm/alternative.h
index 58ccd2f8cab7..3c2b59b25017 100644
--- a/arch/riscv/include/asm/alternative.h
+++ b/arch/riscv/include/asm/alternative.h
@@ -45,6 +45,9 @@ struct alt_entry {
u32 patch_id; /* The patch ID (erratum ID or cpufeature ID) */
};
+void andes_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
+ unsigned long archid, unsigned long impid,
+ unsigned int stage);
void sifive_errata_patch_func(struct alt_entry *begin, struct alt_entry *end,
unsigned long archid, unsigned long impid,
unsigned int stage);
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index fb1a810f3d8c..e2ecd01bfac7 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -11,6 +11,11 @@
#include <asm/hwcap.h>
#include <asm/vendorid_list.h>
+#ifdef CONFIG_ERRATA_ANDES
+#define ERRATA_ANDESTECH_NO_IOCP 0
+#define ERRATA_ANDESTECH_NUMBER 1
+#endif
+
#ifdef CONFIG_ERRATA_SIFIVE
#define ERRATA_SIFIVE_CIP_453 0
#define ERRATA_SIFIVE_CIP_1200 1
diff --git a/arch/riscv/kernel/alternative.c b/arch/riscv/kernel/alternative.c
index 2354c69dc7d1..8a34e72c2b5e 100644
--- a/arch/riscv/kernel/alternative.c
+++ b/arch/riscv/kernel/alternative.c
@@ -42,6 +42,11 @@ static void __init_or_module riscv_fill_cpu_mfr_info(struct cpu_manufacturer_inf
#endif
switch (cpu_mfr_info->vendor_id) {
+#ifdef CONFIG_ERRATA_ANDES
+ case ANDESTECH_VENDOR_ID:
+ cpu_mfr_info->patch_func = andes_errata_patch_func;
+ break;
+#endif
#ifdef CONFIG_ERRATA_SIFIVE
case SIFIVE_VENDOR_ID:
cpu_mfr_info->patch_func = sifive_errata_patch_func;
--
2.25.1
From: Lad Prabhakar <[email protected]>
Add DT binding documentation for L2 cache controller found on RZ/Five SoC.
The Renesas RZ/Five microprocessor includes a RISC-V CPU Core (AX45MP
Single) from Andes. The AX45MP core has an L2 cache controller, this patch
describes the L2 cache block.
Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Rob Herring <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
v7 -> v8
* Updated commit header message
v6 -> v7
* No Change
v5 -> v6
* Included RB tag from Rob
v4 -> v5
* Dropped L2 cache configuration properties
* Dropped PMA configuration properties
* Ordered the required list to match the properties list
RFC v3 -> v4
* Dropped l2 cache configuration parameters
* s/larger/large
* Added minItems/maxItems for andestech,pma-regions
---
.../cache/andestech,ax45mp-cache.yaml | 81 +++++++++++++++++++
1 file changed, 81 insertions(+)
create mode 100644 Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
diff --git a/Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml b/Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
new file mode 100644
index 000000000000..9ab5f0c435d4
--- /dev/null
+++ b/Documentation/devicetree/bindings/cache/andestech,ax45mp-cache.yaml
@@ -0,0 +1,81 @@
+# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
+# Copyright (C) 2023 Renesas Electronics Corp.
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/cache/andestech,ax45mp-cache.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Andestech AX45MP L2 Cache Controller
+
+maintainers:
+ - Lad Prabhakar <[email protected]>
+
+description:
+ A level-2 cache (L2C) is used to improve the system performance by providing
+ a large amount of cache line entries and reasonable access delays. The L2C
+ is shared between cores, and a non-inclusive non-exclusive policy is used.
+
+select:
+ properties:
+ compatible:
+ contains:
+ enum:
+ - andestech,ax45mp-cache
+
+ required:
+ - compatible
+
+properties:
+ compatible:
+ items:
+ - const: andestech,ax45mp-cache
+ - const: cache
+
+ reg:
+ maxItems: 1
+
+ interrupts:
+ maxItems: 1
+
+ cache-line-size:
+ const: 64
+
+ cache-level:
+ const: 2
+
+ cache-sets:
+ const: 1024
+
+ cache-size:
+ enum: [131072, 262144, 524288, 1048576, 2097152]
+
+ cache-unified: true
+
+ next-level-cache: true
+
+additionalProperties: false
+
+required:
+ - compatible
+ - reg
+ - interrupts
+ - cache-line-size
+ - cache-level
+ - cache-sets
+ - cache-size
+ - cache-unified
+
+examples:
+ - |
+ #include <dt-bindings/interrupt-controller/irq.h>
+
+ cache-controller@2010000 {
+ compatible = "andestech,ax45mp-cache", "cache";
+ reg = <0x13400000 0x100000>;
+ interrupts = <508 IRQ_TYPE_LEVEL_HIGH>;
+ cache-line-size = <64>;
+ cache-level = <2>;
+ cache-sets = <1024>;
+ cache-size = <262144>;
+ cache-unified;
+ };
--
2.25.1
From: Lad Prabhakar <[email protected]>
Explicitly select the required Cache management and Errata configs
required for the RZ/Five SoC.
Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Reviewed-by: Geert Uytterhoeven <[email protected]>
Acked-by: Geert Uytterhoeven <[email protected]>
---
v7->v8
* Included RB tag from Geert
v6->v7
* Included RB tag from Conor
v5->v6
* New patch
---
drivers/soc/renesas/Kconfig | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/soc/renesas/Kconfig b/drivers/soc/renesas/Kconfig
index de31589ed054..67604f24973e 100644
--- a/drivers/soc/renesas/Kconfig
+++ b/drivers/soc/renesas/Kconfig
@@ -334,6 +334,10 @@ if RISCV
config ARCH_R9A07G043
bool "RISC-V Platform support for RZ/Five"
select ARCH_RZG2L
+ select AX45MP_L2_CACHE
+ select DMA_GLOBAL_POOL
+ select ERRATA_ANDES
+ select ERRATA_ANDES_CMO
help
This enables support for the Renesas RZ/Five SoC.
--
2.25.1
From: Lad Prabhakar <[email protected]>
Add Andes Technology to the vendors list.
Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Heiko Stuebner <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
---
v7 -> v8
* No change
v6 -> v7
* No change
v5 -> v6
* No change
v4 -> v5
* Included RB tags
RFC v3 -> v4
* New patch
---
arch/riscv/include/asm/vendorid_list.h | 1 +
1 file changed, 1 insertion(+)
diff --git a/arch/riscv/include/asm/vendorid_list.h b/arch/riscv/include/asm/vendorid_list.h
index cb89af3f0704..e55407ace0c3 100644
--- a/arch/riscv/include/asm/vendorid_list.h
+++ b/arch/riscv/include/asm/vendorid_list.h
@@ -5,6 +5,7 @@
#ifndef ASM_VENDOR_LIST_H
#define ASM_VENDOR_LIST_H
+#define ANDESTECH_VENDOR_ID 0x31e
#define SIFIVE_VENDOR_ID 0x489
#define THEAD_VENDOR_ID 0x5b7
--
2.25.1
From: Lad Prabhakar <[email protected]>
I/O Coherence Port (IOCP) provides an AXI interface for connecting
external non-caching masters, such as DMA controllers. The accesses
from IOCP are coherent with D-Caches and L2 Cache.
IOCP is a specification option and is disabled on the Renesas RZ/Five
SoC due to this reason IP blocks using DMA will fail.
The Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
block that allows dynamic adjustment of memory attributes in the runtime.
It contains a configurable amount of PMA entries implemented as CSR
registers to control the attributes of memory locations in interest.
Below are the memory attributes supported:
* Device, Non-bufferable
* Device, bufferable
* Memory, Non-cacheable, Non-bufferable
* Memory, Non-cacheable, Bufferable
* Memory, Write-back, No-allocate
* Memory, Write-back, Read-allocate
* Memory, Write-back, Write-allocate
* Memory, Write-back, Read and Write-allocate
More info about PMA (section 10.3):
Link: http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
As a workaround for SoCs with IOCP disabled CMO needs to be handled by
software. Firstly OpenSBI configures the memory region as
"Memory, Non-cacheable, Bufferable" and passes this region as a global
shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
allocations happen from this region and synchronization callbacks are
implemented to synchronize when doing DMA transactions.
Example PMA region passes as a DT node from OpenSBI:
reserved-memory {
#address-cells = <2>;
#size-cells = <2>;
ranges;
pma_resv0@58000000 {
compatible = "shared-dma-pool";
reg = <0x0 0x58000000 0x0 0x08000000>;
no-map;
linux,dma-default;
};
};
Signed-off-by: Lad Prabhakar <[email protected]>
---
v7 -> v8
* Dropped function pointer usage
* Now exporting the functions for clean/inval/flush
* Switched to using early_initcall instead of arch_initcall
* Dropped entry for "include/cache" from MAINTAINERS
* Dropped dependency of RISCV on AX45MP_L2_CACHE
* Returning error in case of cache line mismatch
* Renamed clean/inval/flush functions
v6 -> v7
* Implemented flush callback
* Dropped using riscv_dma_noncoherent_cmo_ops
v5 -> v6
* Moved driver to cache folder
* Switched to new API for CMO
v4 -> v5
* Dropped code for configuring L2 cache
* Dropped code for configuring PMA
* Updated commit message
* Added comments
* Changed static branch enable/disable order
RFC v3 -> v4
* Made use of runtime patching instead of compile time
* Now just exposing single function ax45mp_no_iocp_cmo() for CMO handling
* Added a check to make sure cache line size is always 64 bytes
* Renamed folder rzf -> rzfive
* Improved Kconfig description
* Dropped L2 cache configuration
* Dropped unnecessary casts
* Fixed comments pointed by Geert.
---
MAINTAINERS | 7 ++
drivers/Kconfig | 2 +
drivers/Makefile | 1 +
drivers/cache/Kconfig | 10 ++
drivers/cache/Makefile | 3 +
drivers/cache/ax45mp_cache.c | 222 +++++++++++++++++++++++++++++++++++
6 files changed, 245 insertions(+)
create mode 100644 drivers/cache/Kconfig
create mode 100644 drivers/cache/Makefile
create mode 100644 drivers/cache/ax45mp_cache.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 3afd45f71043..9afd39a23524 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -19898,6 +19898,13 @@ S: Supported
T: git git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging.git
F: drivers/staging/
+STANDALONE CACHE CONTROLLER DRIVERS
+M: Conor Dooley <[email protected]>
+L: [email protected]
+S: Maintained
+T: git https://git.kernel.org/pub/scm/linux/kernel/git/conor/linux.git/
+F: drivers/cache
+
STARFIRE/DURALAN NETWORK DRIVER
M: Ion Badulescu <[email protected]>
S: Odd Fixes
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 968bd0a6fd78..44abd2cba3a3 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -15,6 +15,8 @@ source "drivers/base/Kconfig"
source "drivers/bus/Kconfig"
+source "drivers/cache/Kconfig"
+
source "drivers/connector/Kconfig"
source "drivers/firmware/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index 20b118dca999..db5a8115093f 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -11,6 +11,7 @@ ifdef building_out_of_srctree
MAKEFLAGS += --include-dir=$(srctree)
endif
+obj-y += cache/
obj-y += irqchip/
obj-y += bus/
diff --git a/drivers/cache/Kconfig b/drivers/cache/Kconfig
new file mode 100644
index 000000000000..b97269cbd149
--- /dev/null
+++ b/drivers/cache/Kconfig
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
+menu "Cache Drivers"
+
+config AX45MP_L2_CACHE
+ bool "Andes Technology AX45MP L2 Cache controller"
+ depends on RISCV_DMA_NONCOHERENT
+ help
+ Support for the L2 cache controller on Andes Technology AX45MP platforms.
+
+endmenu
diff --git a/drivers/cache/Makefile b/drivers/cache/Makefile
new file mode 100644
index 000000000000..2012e7fb978d
--- /dev/null
+++ b/drivers/cache/Makefile
@@ -0,0 +1,3 @@
+# SPDX-License-Identifier: GPL-2.0
+
+obj-$(CONFIG_AX45MP_L2_CACHE) += ax45mp_cache.o
diff --git a/drivers/cache/ax45mp_cache.c b/drivers/cache/ax45mp_cache.c
new file mode 100644
index 000000000000..cfc40b967c55
--- /dev/null
+++ b/drivers/cache/ax45mp_cache.c
@@ -0,0 +1,222 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * non-coherent cache functions for Andes AX45MP
+ *
+ * Copyright (C) 2023 Renesas Electronics Corp.
+ */
+
+#include <linux/cacheflush.h>
+#include <linux/cacheinfo.h>
+#include <linux/dma-direction.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+
+/* L2 cache registers */
+#define AX45MP_L2C_REG_CTL_OFFSET 0x8
+
+#define AX45MP_L2C_REG_C0_CMD_OFFSET 0x40
+#define AX45MP_L2C_REG_C0_ACC_OFFSET 0x48
+#define AX45MP_L2C_REG_STATUS_OFFSET 0x80
+
+/* D-cache operation */
+#define AX45MP_CCTL_L1D_VA_INVAL 0 /* Invalidate an L1 cache entry */
+#define AX45MP_CCTL_L1D_VA_WB 1 /* Write-back an L1 cache entry */
+
+/* L2 CCTL status */
+#define AX45MP_CCTL_L2_STATUS_IDLE 0
+
+/* L2 CCTL status cores mask */
+#define AX45MP_CCTL_L2_STATUS_C0_MASK 0xf
+
+/* L2 cache operation */
+#define AX45MP_CCTL_L2_PA_INVAL 0x8 /* Invalidate an L2 cache entry */
+#define AX45MP_CCTL_L2_PA_WB 0x9 /* Write-back an L2 cache entry */
+
+#define AX45MP_L2C_REG_PER_CORE_OFFSET 0x10
+#define AX45MP_CCTL_L2_STATUS_PER_CORE_OFFSET 4
+
+#define AX45MP_L2C_REG_CN_CMD_OFFSET(n) \
+ (AX45MP_L2C_REG_C0_CMD_OFFSET + ((n) * AX45MP_L2C_REG_PER_CORE_OFFSET))
+#define AX45MP_L2C_REG_CN_ACC_OFFSET(n) \
+ (AX45MP_L2C_REG_C0_ACC_OFFSET + ((n) * AX45MP_L2C_REG_PER_CORE_OFFSET))
+#define AX45MP_CCTL_L2_STATUS_CN_MASK(n) \
+ (AX45MP_CCTL_L2_STATUS_C0_MASK << ((n) * AX45MP_CCTL_L2_STATUS_PER_CORE_OFFSET))
+
+#define AX45MP_CCTL_REG_UCCTLBEGINADDR_NUM 0x80b
+#define AX45MP_CCTL_REG_UCCTLCOMMAND_NUM 0x80c
+
+#define AX45MP_CACHE_LINE_SIZE 64
+
+struct ax45mp_priv {
+ void __iomem *l2c_base;
+ u32 ax45mp_cache_line_size;
+};
+
+static struct ax45mp_priv ax45mp_priv;
+
+/* L2 Cache operations */
+static inline uint32_t ax45mp_cpu_l2c_get_cctl_status(void)
+{
+ return readl(ax45mp_priv.l2c_base + AX45MP_L2C_REG_STATUS_OFFSET);
+}
+
+static void ax45mp_cpu_cache_operation(unsigned long start, unsigned long end,
+ unsigned long line_size, unsigned int l1_op,
+ unsigned int l2_op)
+{
+ void __iomem *base = ax45mp_priv.l2c_base;
+ int mhartid = smp_processor_id();
+ unsigned long pa;
+
+ while (end > start) {
+ csr_write(AX45MP_CCTL_REG_UCCTLBEGINADDR_NUM, start);
+ csr_write(AX45MP_CCTL_REG_UCCTLCOMMAND_NUM, l1_op);
+
+ pa = virt_to_phys((void *)start);
+ writel(pa, base + AX45MP_L2C_REG_CN_ACC_OFFSET(mhartid));
+ writel(l2_op, base + AX45MP_L2C_REG_CN_CMD_OFFSET(mhartid));
+ while ((ax45mp_cpu_l2c_get_cctl_status() &
+ AX45MP_CCTL_L2_STATUS_CN_MASK(mhartid)) !=
+ AX45MP_CCTL_L2_STATUS_IDLE)
+ ;
+
+ start += line_size;
+ }
+}
+
+/* Write-back L1 and L2 cache entry */
+static inline void ax45mp_cpu_dcache_wb_range(unsigned long start, unsigned long end,
+ unsigned long line_size)
+{
+ ax45mp_cpu_cache_operation(start, end, line_size,
+ AX45MP_CCTL_L1D_VA_WB,
+ AX45MP_CCTL_L2_PA_WB);
+}
+
+/* Invalidate the L1 and L2 cache entry */
+static inline void ax45mp_cpu_dcache_inval_range(unsigned long start, unsigned long end,
+ unsigned long line_size)
+{
+ ax45mp_cpu_cache_operation(start, end, line_size,
+ AX45MP_CCTL_L1D_VA_INVAL,
+ AX45MP_CCTL_L2_PA_INVAL);
+}
+
+void ax45mp_dma_cache_inv(void *vaddr, unsigned long size)
+{
+ unsigned long start = (unsigned long)vaddr;
+ char cache_buf[2][AX45MP_CACHE_LINE_SIZE];
+ unsigned long end = start + size;
+ unsigned long old_start = start;
+ unsigned long old_end = end;
+ unsigned long line_size;
+ unsigned long flags;
+
+ if (unlikely(start == end))
+ return;
+
+ line_size = ax45mp_priv.ax45mp_cache_line_size;
+
+ memset(&cache_buf, 0x0, sizeof(cache_buf));
+ start = start & (~(line_size - 1));
+ end = ((end + line_size - 1) & (~(line_size - 1)));
+
+ local_irq_save(flags);
+ if (unlikely(start != old_start))
+ memcpy(&cache_buf[0][0], (void *)start, line_size);
+
+ if (unlikely(end != old_end))
+ memcpy(&cache_buf[1][0], (void *)(old_end & (~(line_size - 1))), line_size);
+
+ ax45mp_cpu_dcache_inval_range(start, end, line_size);
+
+ if (unlikely(start != old_start))
+ memcpy((void *)start, &cache_buf[0][0], (old_start & (line_size - 1)));
+
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ax45mp_dma_cache_inv);
+
+void ax45mp_dma_cache_wback(void *vaddr, unsigned long size)
+{
+ unsigned long start = (unsigned long)vaddr;
+ unsigned long end = start + size;
+ unsigned long line_size;
+ unsigned long flags;
+
+ line_size = ax45mp_priv.ax45mp_cache_line_size;
+ start = start & (~(line_size - 1));
+ local_irq_save(flags);
+ ax45mp_cpu_dcache_wb_range(start, end, line_size);
+ local_irq_restore(flags);
+}
+EXPORT_SYMBOL_GPL(ax45mp_dma_cache_wback);
+
+void ax45mp_dma_cache_wback_inv(void *vaddr, unsigned long size)
+{
+ ax45mp_dma_cache_wback(vaddr, size);
+ ax45mp_dma_cache_inv(vaddr, size);
+}
+EXPORT_SYMBOL_GPL(ax45mp_dma_cache_wback_inv);
+
+static int ax45mp_get_l2_line_size(struct device_node *np)
+{
+ int ret;
+
+ ret = of_property_read_u32(np, "cache-line-size", &ax45mp_priv.ax45mp_cache_line_size);
+ if (ret) {
+ pr_err("Failed to get cache-line-size, defaulting to 64 bytes\n");
+ return ret;
+ }
+
+ if (ax45mp_priv.ax45mp_cache_line_size != AX45MP_CACHE_LINE_SIZE) {
+ pr_err("Expected cache-line-size to be 64 bytes (found:%u)\n",
+ ax45mp_priv.ax45mp_cache_line_size);
+ return ret;
+ }
+
+ return 0;
+}
+
+static const struct of_device_id ax45mp_cache_ids[] = {
+ { .compatible = "andestech,ax45mp-cache" },
+ { /* sentinel */ }
+};
+
+static int __init ax45mp_cache_init(void)
+{
+ struct device_node *np;
+ struct resource res;
+ int ret;
+
+ np = of_find_matching_node(NULL, ax45mp_cache_ids);
+ if (!of_device_is_available(np))
+ return -ENODEV;
+
+ ret = of_address_to_resource(np, 0, &res);
+ if (ret)
+ return ret;
+
+ /*
+ * If IOCP is present on the Andes AX45MP core riscv_cbom_block_size
+ * will be 0 for sure, so we can definitely rely on it. If
+ * riscv_cbom_block_size = 0 we don't need to handle CMO using SW any
+ * more so we just return success here and only if its being set we
+ * continue further in the probe path.
+ */
+ if (!riscv_cbom_block_size)
+ return 0;
+
+ ax45mp_priv.l2c_base = ioremap(res.start, resource_size(&res));
+ if (!ax45mp_priv.l2c_base)
+ return -ENOMEM;
+
+ ret = ax45mp_get_l2_line_size(np);
+ if (ret) {
+ iounmap(ax45mp_priv.l2c_base);
+ return ret;
+ }
+
+ return 0;
+}
+early_initcall(ax45mp_cache_init);
--
2.25.1
From: Lad Prabhakar <[email protected]>
Hookup the Andes AX45MP non-coherent handling by updating the
ALT_CMO_OP() macro which will be used by dma-noncoherent.c for
non-coherent platforms.
Signed-off-by: Lad Prabhakar <[email protected]>
---
v7->v8
* New patch
---
arch/riscv/include/asm/cacheflush.h | 9 ++++++++
arch/riscv/include/asm/errata_list.h | 33 ++++++++++++++++++++++------
2 files changed, 35 insertions(+), 7 deletions(-)
diff --git a/arch/riscv/include/asm/cacheflush.h b/arch/riscv/include/asm/cacheflush.h
index 8091b8bf4883..a8503cc04fdb 100644
--- a/arch/riscv/include/asm/cacheflush.h
+++ b/arch/riscv/include/asm/cacheflush.h
@@ -59,6 +59,15 @@ void riscv_noncoherent_supported(void);
static inline void riscv_noncoherent_supported(void) {}
#endif
+#ifdef CONFIG_AX45MP_L2_CACHE
+extern asmlinkage void ax45mp_dma_cache_wback_inv(void *vaddr, unsigned long size);
+extern asmlinkage void ax45mp_dma_cache_wback(void *vaddr, unsigned long size);
+extern asmlinkage void ax45mp_dma_cache_inv(void *vaddr, unsigned long size);
+#else
+static inline void ax45mp_dma_cache_wback_inv(void *vaddr, unsigned long size) {}
+static inline void ax45mp_dma_cache_wback(void *vaddr, unsigned long size) {}
+static inline void ax45mp_dma_cache_inv(void *vaddr, unsigned long size) {}
+#endif
/*
* Bits in sys_riscv_flush_icache()'s flags argument.
*/
diff --git a/arch/riscv/include/asm/errata_list.h b/arch/riscv/include/asm/errata_list.h
index e2ecd01bfac7..8e9811c14ba3 100644
--- a/arch/riscv/include/asm/errata_list.h
+++ b/arch/riscv/include/asm/errata_list.h
@@ -122,9 +122,13 @@ asm volatile(ALTERNATIVE( \
#define THEAD_flush_A0 ".long 0x0275000b"
#define THEAD_SYNC_S ".long 0x0190000b"
+#define ANDESTECH_AX45MP_clean "call ax45mp_dma_cache_wback"
+#define ANDESTECH_AX45MP_inval "call ax45mp_dma_cache_inv"
+#define ANDESTECH_AX45MP_flush "call ax45mp_dma_cache_wback_inv"
+
#define ALT_CMO_OP(_op, _start, _size, _cachesize) \
-asm volatile(ALTERNATIVE_2( \
- __nops(6), \
+asm volatile(ALTERNATIVE_3( \
+ __nops(11), \
"mv a0, %1\n\t" \
"j 2f\n\t" \
"3:\n\t" \
@@ -132,7 +136,7 @@ asm volatile(ALTERNATIVE_2( \
"add a0, a0, %0\n\t" \
"2:\n\t" \
"bltu a0, %2, 3b\n\t" \
- "nop", 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
+ __nops(6), 0, RISCV_ISA_EXT_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
"mv a0, %1\n\t" \
"j 2f\n\t" \
"3:\n\t" \
@@ -140,12 +144,27 @@ asm volatile(ALTERNATIVE_2( \
"add a0, a0, %0\n\t" \
"2:\n\t" \
"bltu a0, %2, 3b\n\t" \
- THEAD_SYNC_S, THEAD_VENDOR_ID, \
- ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO) \
+ THEAD_SYNC_S "\n\t" \
+ __nops(5), THEAD_VENDOR_ID, \
+ ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO, \
+ "addi sp,sp,-16\n\t" \
+ "sd s0,0(sp)\n\t" \
+ "sd ra,8(sp)\n\t" \
+ "addi s0,sp,16\n\t" \
+ "mv a1,%4\n\t" \
+ "mv a0,%3\n\t" \
+ ANDESTECH_AX45MP_##_op "\n\t" \
+ "ld ra,8(sp)\n\t" \
+ "ld s0,0(sp)\n\t" \
+ "addi sp,sp,16\n\t", \
+ ANDESTECH_VENDOR_ID, ERRATA_ANDESTECH_NO_IOCP, \
+ CONFIG_ERRATA_ANDES) \
: : "r"(_cachesize), \
"r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \
- "r"((unsigned long)(_start) + (_size)) \
- : "a0")
+ "r"((unsigned long)(_start) + (_size)), \
+ "r"((void *)(_start)), \
+ "r"((unsigned long)(_size)) \
+ : "a0", "a1")
#define THEAD_C9XX_RV_IRQ_PMU 17
#define THEAD_C9XX_CSR_SCOUNTEROF 0x5c5
--
2.25.1
On Wed, Apr 12, 2023 at 12:08:58PM +0100, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> I/O Coherence Port (IOCP) provides an AXI interface for connecting
> external non-caching masters, such as DMA controllers. The accesses
> from IOCP are coherent with D-Caches and L2 Cache.
>
> IOCP is a specification option and is disabled on the Renesas RZ/Five
> SoC due to this reason IP blocks using DMA will fail.
>
> The Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
> block that allows dynamic adjustment of memory attributes in the runtime.
> It contains a configurable amount of PMA entries implemented as CSR
> registers to control the attributes of memory locations in interest.
> Below are the memory attributes supported:
> * Device, Non-bufferable
> * Device, bufferable
> * Memory, Non-cacheable, Non-bufferable
> * Memory, Non-cacheable, Bufferable
> * Memory, Write-back, No-allocate
> * Memory, Write-back, Read-allocate
> * Memory, Write-back, Write-allocate
> * Memory, Write-back, Read and Write-allocate
>
> More info about PMA (section 10.3):
> Link: http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
>
> As a workaround for SoCs with IOCP disabled CMO needs to be handled by
> software. Firstly OpenSBI configures the memory region as
> "Memory, Non-cacheable, Bufferable" and passes this region as a global
> shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
> allocations happen from this region and synchronization callbacks are
> implemented to synchronize when doing DMA transactions.
>
> Example PMA region passes as a DT node from OpenSBI:
> reserved-memory {
> #address-cells = <2>;
> #size-cells = <2>;
> ranges;
>
> pma_resv0@58000000 {
> compatible = "shared-dma-pool";
> reg = <0x0 0x58000000 0x0 0x08000000>;
> no-map;
> linux,dma-default;
> };
> };
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> ---
> v7 -> v8
> * Dropped function pointer usage
> * Now exporting the functions for clean/inval/flush
> * Switched to using early_initcall instead of arch_initcall
> * Dropped entry for "include/cache" from MAINTAINERS
> * Dropped dependency of RISCV on AX45MP_L2_CACHE
> * Returning error in case of cache line mismatch
> * Renamed clean/inval/flush functions
I kinda screwed you with that request given Hellwig's NAK on the
function pointer based stuff. Ah well, I prefer matching the proposed
naming of the dma core to what RVI chose for the instructions.
Reviewed-by: Conor Dooley <[email protected]>
I suppose this will need a resubmission once Arnd's stuff gets applied,
but I would like to see it have a run through the build bots etc.
Cheers,
Conor.
On Wed, Apr 12, 2023 at 12:08:59PM +0100, Prabhakar wrote:
> From: Lad Prabhakar <[email protected]>
>
> Hookup the Andes AX45MP non-coherent handling by updating the
> ALT_CMO_OP() macro which will be used by dma-noncoherent.c for
> non-coherent platforms.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
Reviewed-by: Conor Dooley <[email protected]>
Thanks,
Conor.
On Wed, Apr 12, 2023 at 12:08:53PM +0100, Prabhakar wrote:
> Note,
> - This series requires testing on Cores with zicbom and T-Head SoCs
As I said last time, I dunno what actual Zicbom stuff exists, other than
perhaps the Ventana lads having something. I did some tyre kicking on my
D1 and it was fine, although nothing has actually changed materially for
either of them with this series in v8..
Cheers,
Conor.
On Wed, Apr 12, 2023 at 09:25:34PM +0100, Conor Dooley wrote:
> On Wed, Apr 12, 2023 at 12:08:58PM +0100, Prabhakar wrote:
> > From: Lad Prabhakar <[email protected]>
> >
> > I/O Coherence Port (IOCP) provides an AXI interface for connecting
> > external non-caching masters, such as DMA controllers. The accesses
> > from IOCP are coherent with D-Caches and L2 Cache.
> >
> > IOCP is a specification option and is disabled on the Renesas RZ/Five
> > SoC due to this reason IP blocks using DMA will fail.
> >
> > The Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
> > block that allows dynamic adjustment of memory attributes in the runtime.
> > It contains a configurable amount of PMA entries implemented as CSR
> > registers to control the attributes of memory locations in interest.
> > Below are the memory attributes supported:
> > * Device, Non-bufferable
> > * Device, bufferable
> > * Memory, Non-cacheable, Non-bufferable
> > * Memory, Non-cacheable, Bufferable
> > * Memory, Write-back, No-allocate
> > * Memory, Write-back, Read-allocate
> > * Memory, Write-back, Write-allocate
> > * Memory, Write-back, Read and Write-allocate
> >
> > More info about PMA (section 10.3):
> > Link: http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
> >
> > As a workaround for SoCs with IOCP disabled CMO needs to be handled by
> > software. Firstly OpenSBI configures the memory region as
> > "Memory, Non-cacheable, Bufferable" and passes this region as a global
> > shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
> > allocations happen from this region and synchronization callbacks are
> > implemented to synchronize when doing DMA transactions.
> >
> > Example PMA region passes as a DT node from OpenSBI:
> > reserved-memory {
> > #address-cells = <2>;
> > #size-cells = <2>;
> > ranges;
> >
> > pma_resv0@58000000 {
> > compatible = "shared-dma-pool";
> > reg = <0x0 0x58000000 0x0 0x08000000>;
> > no-map;
> > linux,dma-default;
> > };
> > };
> >
> > Signed-off-by: Lad Prabhakar <[email protected]>
> > ---
> > v7 -> v8
> > * Dropped function pointer usage
> > * Now exporting the functions for clean/inval/flush
> > * Switched to using early_initcall instead of arch_initcall
> > * Dropped entry for "include/cache" from MAINTAINERS
> > * Dropped dependency of RISCV on AX45MP_L2_CACHE
> > * Returning error in case of cache line mismatch
>
> > * Renamed clean/inval/flush functions
>
> I kinda screwed you with that request given Hellwig's NAK on the
> function pointer based stuff. Ah well, I prefer matching the proposed
> naming of the dma core to what RVI chose for the instructions.
>
> Reviewed-by: Conor Dooley <[email protected]>
>
> I suppose this will need a resubmission once Arnd's stuff gets applied,
> but I would like to see it have a run through the build bots etc.
So apparently my build bot did actually run against this series?
https://patchwork.kernel.org/project/linux-riscv/list/?series=739109
To be quite honest, I am not sure at all how it managed to apply the
series w/ Arnd's pre-reqs. Perhaps it has achieved some from of
sentience. There's a build failure for 32-bit that appeared on the final
patch, but is not really its fault:
../arch/riscv/mm/dma-noncoherent.c: Assembler messages:
../arch/riscv/mm/dma-noncoherent.c:104: Error: unrecognized opcode `sd s0,0(sp)'
../arch/riscv/mm/dma-noncoherent.c:105: Error: unrecognized opcode `sd ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:110: Error: unrecognized opcode `ld ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:111: Error: unrecognized opcode `ld s0,0(sp)'
../arch/riscv/mm/dma-noncoherent.c:111: Error: unrecognized opcode `sd s0,0(sp)'
../arch/riscv/mm/dma-noncoherent.c:112: Error: unrecognized opcode `sd ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:117: Error: unrecognized opcode `ld ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:118: Error: unrecognized opcode `ld s0,0(sp)'
../arch/riscv/mm/pmem.c: Assembler messages:
../arch/riscv/mm/pmem.c:98: Error: unrecognized opcode `sd s0,0(sp)'
../arch/riscv/mm/pmem.c:99: Error: unrecognized opcode `sd ra,8(sp)'
../arch/riscv/mm/pmem.c:104: Error: unrecognized opcode `ld ra,8(sp)'
../arch/riscv/mm/pmem.c:105: Error: unrecognized opcode `ld s0,0(sp)'
../arch/riscv/mm/dma-noncoherent.c:138: Error: unrecognized opcode `sd s0,0(sp)'
../arch/riscv/mm/dma-noncoherent.c:139: Error: unrecognized opcode `sd ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:144: Error: unrecognized opcode `ld ra,8(sp)'
../arch/riscv/mm/dma-noncoherent.c:145: Error: unrecognized opcode `ld s0,0(sp)'
../arch/riscv/mm/pmem.c:104: Error: unrecognized opcode `sd s0,0(sp)'
../arch/riscv/mm/pmem.c:105: Error: unrecognized opcode `sd ra,8(sp)'
../arch/riscv/mm/pmem.c:110: Error: unrecognized opcode `ld ra,8(sp)'
../arch/riscv/mm/pmem.c:111: Error: unrecognized opcode `ld s0,0(sp)'
../arch/riscv/mm/pmem.c:110: Error: attempt to move .org backwards
../arch/riscv/mm/pmem.c:116: Error: attempt to move .org backwards
../arch/riscv/mm/dma-noncoherent.c:116: Error: attempt to move .org backwards
../arch/riscv/mm/dma-noncoherent.c:123: Error: attempt to move .org backwards
../arch/riscv/mm/dma-noncoherent.c:150: Error: attempt to move .org backwards
make[4]: *** [../scripts/Makefile.build:252: arch/riscv/mm/pmem.o] Error 1
make[4]: *** [../scripts/Makefile.build:252: arch/riscv/mm/dma-noncoherent.o] Error 1
make[4]: Target 'arch/riscv/mm/' not remade because of errors.
make[3]: *** [../scripts/Makefile.build:494: arch/riscv/mm] Error 2
make[3]: Target 'arch/riscv/' not remade because of errors.
make[2]: *** [../scripts/Makefile.build:494: arch/riscv] Error 2
The simplest solution may to just be making the erratum depend on 64BIT?
Cheers,
Conor.
Hi Conor,
On Thu, Apr 13, 2023 at 8:06 AM Conor Dooley <[email protected]> wrote:
>
> On Wed, Apr 12, 2023 at 09:25:34PM +0100, Conor Dooley wrote:
> > On Wed, Apr 12, 2023 at 12:08:58PM +0100, Prabhakar wrote:
> > > From: Lad Prabhakar <[email protected]>
> > >
> > > I/O Coherence Port (IOCP) provides an AXI interface for connecting
> > > external non-caching masters, such as DMA controllers. The accesses
> > > from IOCP are coherent with D-Caches and L2 Cache.
> > >
> > > IOCP is a specification option and is disabled on the Renesas RZ/Five
> > > SoC due to this reason IP blocks using DMA will fail.
> > >
> > > The Andes AX45MP core has a Programmable Physical Memory Attributes (PMA)
> > > block that allows dynamic adjustment of memory attributes in the runtime.
> > > It contains a configurable amount of PMA entries implemented as CSR
> > > registers to control the attributes of memory locations in interest.
> > > Below are the memory attributes supported:
> > > * Device, Non-bufferable
> > > * Device, bufferable
> > > * Memory, Non-cacheable, Non-bufferable
> > > * Memory, Non-cacheable, Bufferable
> > > * Memory, Write-back, No-allocate
> > > * Memory, Write-back, Read-allocate
> > > * Memory, Write-back, Write-allocate
> > > * Memory, Write-back, Read and Write-allocate
> > >
> > > More info about PMA (section 10.3):
> > > Link: http://www.andestech.com/wp-content/uploads/AX45MP-1C-Rev.-5.0.0-Datasheet.pdf
> > >
> > > As a workaround for SoCs with IOCP disabled CMO needs to be handled by
> > > software. Firstly OpenSBI configures the memory region as
> > > "Memory, Non-cacheable, Bufferable" and passes this region as a global
> > > shared dma pool as a DT node. With DMA_GLOBAL_POOL enabled all DMA
> > > allocations happen from this region and synchronization callbacks are
> > > implemented to synchronize when doing DMA transactions.
> > >
> > > Example PMA region passes as a DT node from OpenSBI:
> > > reserved-memory {
> > > #address-cells = <2>;
> > > #size-cells = <2>;
> > > ranges;
> > >
> > > pma_resv0@58000000 {
> > > compatible = "shared-dma-pool";
> > > reg = <0x0 0x58000000 0x0 0x08000000>;
> > > no-map;
> > > linux,dma-default;
> > > };
> > > };
> > >
> > > Signed-off-by: Lad Prabhakar <[email protected]>
> > > ---
> > > v7 -> v8
> > > * Dropped function pointer usage
> > > * Now exporting the functions for clean/inval/flush
> > > * Switched to using early_initcall instead of arch_initcall
> > > * Dropped entry for "include/cache" from MAINTAINERS
> > > * Dropped dependency of RISCV on AX45MP_L2_CACHE
> > > * Returning error in case of cache line mismatch
> >
> > > * Renamed clean/inval/flush functions
> >
> > I kinda screwed you with that request given Hellwig's NAK on the
> > function pointer based stuff. Ah well, I prefer matching the proposed
> > naming of the dma core to what RVI chose for the instructions.
> >
> > Reviewed-by: Conor Dooley <[email protected]>
> >
> > I suppose this will need a resubmission once Arnd's stuff gets applied,
> > but I would like to see it have a run through the build bots etc.
>
> So apparently my build bot did actually run against this series?
> https://patchwork.kernel.org/project/linux-riscv/list/?series=739109
>
> To be quite honest, I am not sure at all how it managed to apply the
> series w/ Arnd's pre-reqs. Perhaps it has achieved some from of
> sentience. There's a build failure for 32-bit that appeared on the final
> patch, but is not really its fault:
> ../arch/riscv/mm/dma-noncoherent.c: Assembler messages:
> ../arch/riscv/mm/dma-noncoherent.c:104: Error: unrecognized opcode `sd s0,0(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:105: Error: unrecognized opcode `sd ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:110: Error: unrecognized opcode `ld ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:111: Error: unrecognized opcode `ld s0,0(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:111: Error: unrecognized opcode `sd s0,0(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:112: Error: unrecognized opcode `sd ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:117: Error: unrecognized opcode `ld ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:118: Error: unrecognized opcode `ld s0,0(sp)'
> ../arch/riscv/mm/pmem.c: Assembler messages:
> ../arch/riscv/mm/pmem.c:98: Error: unrecognized opcode `sd s0,0(sp)'
> ../arch/riscv/mm/pmem.c:99: Error: unrecognized opcode `sd ra,8(sp)'
> ../arch/riscv/mm/pmem.c:104: Error: unrecognized opcode `ld ra,8(sp)'
> ../arch/riscv/mm/pmem.c:105: Error: unrecognized opcode `ld s0,0(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:138: Error: unrecognized opcode `sd s0,0(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:139: Error: unrecognized opcode `sd ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:144: Error: unrecognized opcode `ld ra,8(sp)'
> ../arch/riscv/mm/dma-noncoherent.c:145: Error: unrecognized opcode `ld s0,0(sp)'
> ../arch/riscv/mm/pmem.c:104: Error: unrecognized opcode `sd s0,0(sp)'
> ../arch/riscv/mm/pmem.c:105: Error: unrecognized opcode `sd ra,8(sp)'
> ../arch/riscv/mm/pmem.c:110: Error: unrecognized opcode `ld ra,8(sp)'
> ../arch/riscv/mm/pmem.c:111: Error: unrecognized opcode `ld s0,0(sp)'
> ../arch/riscv/mm/pmem.c:110: Error: attempt to move .org backwards
> ../arch/riscv/mm/pmem.c:116: Error: attempt to move .org backwards
> ../arch/riscv/mm/dma-noncoherent.c:116: Error: attempt to move .org backwards
> ../arch/riscv/mm/dma-noncoherent.c:123: Error: attempt to move .org backwards
> ../arch/riscv/mm/dma-noncoherent.c:150: Error: attempt to move .org backwards
> make[4]: *** [../scripts/Makefile.build:252: arch/riscv/mm/pmem.o] Error 1
> make[4]: *** [../scripts/Makefile.build:252: arch/riscv/mm/dma-noncoherent.o] Error 1
> make[4]: Target 'arch/riscv/mm/' not remade because of errors.
> make[3]: *** [../scripts/Makefile.build:494: arch/riscv/mm] Error 2
> make[3]: Target 'arch/riscv/' not remade because of errors.
> make[2]: *** [../scripts/Makefile.build:494: arch/riscv] Error 2
>
> The simplest solution may to just be making the erratum depend on 64BIT?
>
I dont think this will work, as pmem.c is compiled unconditionally. Is
dma-noncoherent.c also valid for RISCV-32? If not then we can make
pmem.c compile conditionally if DMA non-coherenet is enabled and we
make DMA non-coherent depend on 64bit.
Cheers,
Prabhakar
On Thu, Apr 13, 2023 at 07:26:02PM +0100, Lad, Prabhakar wrote:
> > The simplest solution may to just be making the erratum depend on 64BIT?
> >
> I dont think this will work, as pmem.c is compiled unconditionally.
That'll teach me to write things like this first thing in the morning.
I somehow got it in my head that the alternative would be removed by the
preprocessor if it was not enabled. After testing it, that's not what
happened.
My excuse is being tired from the gym and insufficiently caffeinated,
sorry!
> Is
> dma-noncoherent.c also valid for RISCV-32? If not then we can make
> pmem.c compile conditionally if DMA non-coherenet is enabled and we
> make DMA non-coherent depend on 64bit.
Could you drop the {s,l}d in exchange for {s,l}w instead, or am I
progressing even further into braino territory?
On Thu, Apr 13, 2023 at 7:46 PM Conor Dooley <[email protected]> wrote:
>
> > Is
> > dma-noncoherent.c also valid for RISCV-32? If not then we can make
> > pmem.c compile conditionally if DMA non-coherenet is enabled and we
> > make DMA non-coherent depend on 64bit.
>
> Could you drop the {s,l}d in exchange for {s,l}w instead, or am I
> progressing even further into braino territory?
Just the direct exchange wont work in addition shifting + oring to
take care of 64-bit will require. (Correct me if I'm wrong here)
I was wondering now if we need to store/restore the s0 and ra
registers. I stumbled on an X86 implementation which has call [0] in
the ALTERNATIVE_X() macro but here we dont store/restore the
registers. Is the RISC-V implementation of ALT macro different
compared to x86?
[0] https://elixir.bootlin.com/linux/latest/source/arch/x86/include/asm/uaccess_64.h#L105
Cheers,
Prabhakar
On Thu, Apr 13, 2023 at 10:06 PM Lad, Prabhakar
<[email protected]> wrote:
>
> On Thu, Apr 13, 2023 at 7:46 PM Conor Dooley <[email protected]> wrote:
> >
> > > Is
> > > dma-noncoherent.c also valid for RISCV-32? If not then we can make
> > > pmem.c compile conditionally if DMA non-coherenet is enabled and we
> > > make DMA non-coherent depend on 64bit.
> >
> > Could you drop the {s,l}d in exchange for {s,l}w instead, or am I
> > progressing even further into braino territory?
> Just the direct exchange wont work in addition shifting + oring to
> take care of 64-bit will require. (Correct me if I'm wrong here)
>
> I was wondering now if we need to store/restore the s0 and ra
> registers. I stumbled on an X86 implementation which has call [0] in
> the ALTERNATIVE_X() macro but here we dont store/restore the
> registers. Is the RISC-V implementation of ALT macro different
> compared to x86?
>
I did try a call without stroe/restore of s0 and ra registers and that
didn't work!. So I have re-written the assembly code which makes
32-bit RISC-V compilers happy. Once done with the testing I'll send a
new version of this series. Hopefully the last ;)
Cheers,
Prabhakar
On Wed, Apr 12, 2023 at 09:32:30PM +0100, Conor Dooley wrote:
> On Wed, Apr 12, 2023 at 12:08:53PM +0100, Prabhakar wrote:
>
> > Note,
> > - This series requires testing on Cores with zicbom and T-Head SoCs
>
> As I said last time, I dunno what actual Zicbom stuff exists, other than
> perhaps the Ventana lads having something. I did some tyre kicking on my
> D1 and it was fine, although nothing has actually changed materially for
> either of them with this series in v8..
And as saying before, there is absolutely no reason to add non-standard
non-coherent DMA support and let this cancer creep. If you want Linux
support implement Zicbom, be that in hardware or the SBI.
On Wed, Apr 12, 2023 at 1:09 PM Prabhakar <[email protected]> wrote:
> From: Lad Prabhakar <[email protected]>
>
> Add Andes Technology to the vendors list.
>
> Signed-off-by: Lad Prabhakar <[email protected]>
> Reviewed-by: Heiko Stuebner <[email protected]>
> Reviewed-by: Conor Dooley <[email protected]>
Reviewed-by: Geert Uytterhoeven <[email protected]>
Gr{oetje,eeting}s,
Geert
--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]
In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
-- Linus Torvalds
On Sun, 16 Apr 2023 23:53:17 PDT (-0700), Christoph Hellwig wrote:
> On Wed, Apr 12, 2023 at 09:32:30PM +0100, Conor Dooley wrote:
>> On Wed, Apr 12, 2023 at 12:08:53PM +0100, Prabhakar wrote:
>>
>> > Note,
>> > - This series requires testing on Cores with zicbom and T-Head SoCs
>>
>> As I said last time, I dunno what actual Zicbom stuff exists, other than
>> perhaps the Ventana lads having something. I did some tyre kicking on my
>> D1 and it was fine, although nothing has actually changed materially for
>> either of them with this series in v8..
>
> And as saying before, there is absolutely no reason to add non-standard
> non-coherent DMA support and let this cancer creep. If you want Linux
> support implement Zicbom, be that in hardware or the SBI.
IMO we should just take the support in Linux: trying to hide stuff behind the
SBI leads to more more headaches than it's worth, we end up with a bunch of
broken firmware to try and work around. We've already got a mess here because
of the D1 support, we might as well just live with it.
In practice there's just going to be a ton of mess in arch/riscv, as the ISA
has been missing many core features for many years and hardware vendors are
allowed to do whatever they want. That's obviously a huge headache, but I
think there's nothing we can really do about it.
On Wed, Apr 19, 2023 at 08:59:03AM -0700, Palmer Dabbelt wrote:
> IMO we should just take the support in Linux: trying to hide stuff behind the
> SBI leads to more more headaches than it's worth, we end up with a bunch of
> broken firmware to try and work around. We've already got a mess here because
> of the D1 support, we might as well just live with it.
I strongly disagree. Adding more and more per-vendor ops simply does
not scale. We're getting us into a giant long-time mess that will be
unfixable.