Skip to content

Commit b79f300

Browse files
prabhakarladpalmer-dabbelt
authored andcommitted
riscv: mm: dma-noncoherent: nonstandard cache operations support
Introduce support for nonstandard noncoherent systems in the RISC-V architecture. It enables function pointer support to handle cache management in such systems. This patch adds a new configuration option called "RISCV_NONSTANDARD_CACHE_OPS." This option is a boolean flag that depends on "RISCV_DMA_NONCOHERENT" and enables the function pointer support for cache management in nonstandard noncoherent systems. Signed-off-by: Lad Prabhakar <prabhakar.mahadev-lad.rj@bp.renesas.com> Reviewed-by: Conor Dooley <conor.dooley@microchip.com> Tested-by: Conor Dooley <conor.dooley@microchip.com> # tyre-kicking on a d1 Reviewed-by: Emil Renner Berthing <emil.renner.berthing@canonical.com> Tested-by: Emil Renner Berthing <emil.renner.berthing@canonical.com> # Link: https://lore.kernel.org/r/20230818135723.80612-4-prabhakar.mahadev-lad.rj@bp.renesas.com Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
1 parent e021ae7 commit b79f300

File tree

4 files changed

+91
-0
lines changed

4 files changed

+91
-0
lines changed

arch/riscv/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,13 @@ config RISCV_DMA_NONCOHERENT
269269
select ARCH_HAS_SYNC_DMA_FOR_DEVICE
270270
select DMA_DIRECT_REMAP
271271

272+
config RISCV_NONSTANDARD_CACHE_OPS
273+
bool
274+
depends on RISCV_DMA_NONCOHERENT
275+
help
276+
This enables function pointer support for non-standard noncoherent
277+
systems to handle cache management.
278+
272279
config AS_HAS_INSN
273280
def_bool $(as-instr,.insn r 51$(comma) 0$(comma) 0$(comma) t0$(comma) t0$(comma) zero)
274281

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/*
3+
* Copyright (C) 2023 Renesas Electronics Corp.
4+
*/
5+
6+
#ifndef __ASM_DMA_NONCOHERENT_H
7+
#define __ASM_DMA_NONCOHERENT_H
8+
9+
#include <linux/dma-direct.h>
10+
11+
/*
12+
* struct riscv_nonstd_cache_ops - Structure for non-standard CMO function pointers
13+
*
14+
* @wback: Function pointer for cache writeback
15+
* @inv: Function pointer for invalidating cache
16+
* @wback_inv: Function pointer for flushing the cache (writeback + invalidating)
17+
*/
18+
struct riscv_nonstd_cache_ops {
19+
void (*wback)(phys_addr_t paddr, size_t size);
20+
void (*inv)(phys_addr_t paddr, size_t size);
21+
void (*wback_inv)(phys_addr_t paddr, size_t size);
22+
};
23+
24+
extern struct riscv_nonstd_cache_ops noncoherent_cache_ops;
25+
26+
void riscv_noncoherent_register_cache_ops(const struct riscv_nonstd_cache_ops *ops);
27+
28+
#endif /* __ASM_DMA_NONCOHERENT_H */

arch/riscv/mm/dma-noncoherent.c

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,27 +9,54 @@
99
#include <linux/dma-map-ops.h>
1010
#include <linux/mm.h>
1111
#include <asm/cacheflush.h>
12+
#include <asm/dma-noncoherent.h>
1213

1314
static bool noncoherent_supported __ro_after_init;
1415

16+
struct riscv_nonstd_cache_ops noncoherent_cache_ops __ro_after_init = {
17+
.wback = NULL,
18+
.inv = NULL,
19+
.wback_inv = NULL,
20+
};
21+
1522
static inline void arch_dma_cache_wback(phys_addr_t paddr, size_t size)
1623
{
1724
void *vaddr = phys_to_virt(paddr);
1825

26+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
27+
if (unlikely(noncoherent_cache_ops.wback)) {
28+
noncoherent_cache_ops.wback(paddr, size);
29+
return;
30+
}
31+
#endif
1932
ALT_CMO_OP(clean, vaddr, size, riscv_cbom_block_size);
2033
}
2134

2235
static inline void arch_dma_cache_inv(phys_addr_t paddr, size_t size)
2336
{
2437
void *vaddr = phys_to_virt(paddr);
2538

39+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
40+
if (unlikely(noncoherent_cache_ops.inv)) {
41+
noncoherent_cache_ops.inv(paddr, size);
42+
return;
43+
}
44+
#endif
45+
2646
ALT_CMO_OP(inval, vaddr, size, riscv_cbom_block_size);
2747
}
2848

2949
static inline void arch_dma_cache_wback_inv(phys_addr_t paddr, size_t size)
3050
{
3151
void *vaddr = phys_to_virt(paddr);
3252

53+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
54+
if (unlikely(noncoherent_cache_ops.wback_inv)) {
55+
noncoherent_cache_ops.wback_inv(paddr, size);
56+
return;
57+
}
58+
#endif
59+
3360
ALT_CMO_OP(flush, vaddr, size, riscv_cbom_block_size);
3461
}
3562

@@ -95,6 +122,13 @@ void arch_dma_prep_coherent(struct page *page, size_t size)
95122
{
96123
void *flush_addr = page_address(page);
97124

125+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
126+
if (unlikely(noncoherent_cache_ops.wback_inv)) {
127+
noncoherent_cache_ops.wback_inv(page_to_phys(page), size);
128+
return;
129+
}
130+
#endif
131+
98132
ALT_CMO_OP(flush, flush_addr, size, riscv_cbom_block_size);
99133
}
100134

@@ -120,3 +154,12 @@ void riscv_noncoherent_supported(void)
120154
"Non-coherent DMA support enabled without a block size\n");
121155
noncoherent_supported = true;
122156
}
157+
158+
void riscv_noncoherent_register_cache_ops(const struct riscv_nonstd_cache_ops *ops)
159+
{
160+
if (!ops)
161+
return;
162+
163+
noncoherent_cache_ops = *ops;
164+
}
165+
EXPORT_SYMBOL_GPL(riscv_noncoherent_register_cache_ops);

arch/riscv/mm/pmem.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,28 @@
77
#include <linux/libnvdimm.h>
88

99
#include <asm/cacheflush.h>
10+
#include <asm/dma-noncoherent.h>
1011

1112
void arch_wb_cache_pmem(void *addr, size_t size)
1213
{
14+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
15+
if (unlikely(noncoherent_cache_ops.wback)) {
16+
noncoherent_cache_ops.wback(virt_to_phys(addr), size);
17+
return;
18+
}
19+
#endif
1320
ALT_CMO_OP(clean, addr, size, riscv_cbom_block_size);
1421
}
1522
EXPORT_SYMBOL_GPL(arch_wb_cache_pmem);
1623

1724
void arch_invalidate_pmem(void *addr, size_t size)
1825
{
26+
#ifdef CONFIG_RISCV_NONSTANDARD_CACHE_OPS
27+
if (unlikely(noncoherent_cache_ops.inv)) {
28+
noncoherent_cache_ops.inv(virt_to_phys(addr), size);
29+
return;
30+
}
31+
#endif
1932
ALT_CMO_OP(inval, addr, size, riscv_cbom_block_size);
2033
}
2134
EXPORT_SYMBOL_GPL(arch_invalidate_pmem);

0 commit comments

Comments
 (0)