Skip to content

Commit d20ec75

Browse files
mmindpalmer-dabbelt
authored andcommitted
riscv: implement cache-management errata for T-Head SoCs
The T-Head C906 and C910 implement a scheme for handling cache operations different from the generic Zicbom extension. Add an errata for it next to the generic dma coherency ops. Reviewed-by: Samuel Holland <[email protected]> Tested-by: Samuel Holland <[email protected]> Reviewed-by: Guo Ren <[email protected]> Signed-off-by: Heiko Stuebner <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Palmer Dabbelt <[email protected]>
1 parent 1631ba1 commit d20ec75

File tree

3 files changed

+74
-5
lines changed

3 files changed

+74
-5
lines changed

arch/riscv/Kconfig.erratas

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,15 @@ config ERRATA_THEAD_PBMT
5555

5656
If you don't know what to do here, say "Y".
5757

58+
config ERRATA_THEAD_CMO
59+
bool "Apply T-Head cache management errata"
60+
depends on ERRATA_THEAD
61+
select RISCV_DMA_NONCOHERENT
62+
default y
63+
help
64+
This will apply the cache management errata to handle the
65+
non-standard handling on non-coherent operations on T-Head SoCs.
66+
67+
If you don't know what to do here, say "Y".
68+
5869
endmenu

arch/riscv/errata/thead/errata.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,23 @@ static bool errata_probe_pbmt(unsigned int stage,
2727
return false;
2828
}
2929

30+
static bool errata_probe_cmo(unsigned int stage,
31+
unsigned long arch_id, unsigned long impid)
32+
{
33+
#ifdef CONFIG_ERRATA_THEAD_CMO
34+
if (arch_id != 0 || impid != 0)
35+
return false;
36+
37+
if (stage == RISCV_ALTERNATIVES_EARLY_BOOT)
38+
return false;
39+
40+
riscv_noncoherent_supported();
41+
return true;
42+
#else
43+
return false;
44+
#endif
45+
}
46+
3047
static u32 thead_errata_probe(unsigned int stage,
3148
unsigned long archid, unsigned long impid)
3249
{
@@ -35,6 +52,9 @@ static u32 thead_errata_probe(unsigned int stage,
3552
if (errata_probe_pbmt(stage, archid, impid))
3653
cpu_req_errata |= (1U << ERRATA_THEAD_PBMT);
3754

55+
if (errata_probe_cmo(stage, archid, impid))
56+
cpu_req_errata |= (1U << ERRATA_THEAD_CMO);
57+
3858
return cpu_req_errata;
3959
}
4060

arch/riscv/include/asm/errata_list.h

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
#ifdef CONFIG_ERRATA_THEAD
1818
#define ERRATA_THEAD_PBMT 0
19-
#define ERRATA_THEAD_NUMBER 1
19+
#define ERRATA_THEAD_CMO 1
20+
#define ERRATA_THEAD_NUMBER 2
2021
#endif
2122

2223
#define CPUFEATURE_SVPBMT 0
@@ -94,17 +95,54 @@ asm volatile(ALTERNATIVE( \
9495
#define ALT_THEAD_PMA(_val)
9596
#endif
9697

98+
/*
99+
* dcache.ipa rs1 (invalidate, physical address)
100+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
101+
* 0000001 01010 rs1 000 00000 0001011
102+
* dache.iva rs1 (invalida, virtual address)
103+
* 0000001 00110 rs1 000 00000 0001011
104+
*
105+
* dcache.cpa rs1 (clean, physical address)
106+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
107+
* 0000001 01001 rs1 000 00000 0001011
108+
* dcache.cva rs1 (clean, virtual address)
109+
* 0000001 00100 rs1 000 00000 0001011
110+
*
111+
* dcache.cipa rs1 (clean then invalidate, physical address)
112+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
113+
* 0000001 01011 rs1 000 00000 0001011
114+
* dcache.civa rs1 (... virtual address)
115+
* 0000001 00111 rs1 000 00000 0001011
116+
*
117+
* sync.s (make sure all cache operations finished)
118+
* | 31 - 25 | 24 - 20 | 19 - 15 | 14 - 12 | 11 - 7 | 6 - 0 |
119+
* 0000000 11001 00000 000 00000 0001011
120+
*/
121+
#define THEAD_inval_A0 ".long 0x0265000b"
122+
#define THEAD_clean_A0 ".long 0x0245000b"
123+
#define THEAD_flush_A0 ".long 0x0275000b"
124+
#define THEAD_SYNC_S ".long 0x0190000b"
125+
97126
#define ALT_CMO_OP(_op, _start, _size, _cachesize) \
98-
asm volatile(ALTERNATIVE( \
99-
__nops(5), \
127+
asm volatile(ALTERNATIVE_2( \
128+
__nops(6), \
100129
"mv a0, %1\n\t" \
101130
"j 2f\n\t" \
102131
"3:\n\t" \
103132
"cbo." __stringify(_op) " (a0)\n\t" \
104133
"add a0, a0, %0\n\t" \
105134
"2:\n\t" \
106-
"bltu a0, %2, 3b\n\t", 0, \
107-
CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM) \
135+
"bltu a0, %2, 3b\n\t" \
136+
"nop", 0, CPUFEATURE_ZICBOM, CONFIG_RISCV_ISA_ZICBOM, \
137+
"mv a0, %1\n\t" \
138+
"j 2f\n\t" \
139+
"3:\n\t" \
140+
THEAD_##_op##_A0 "\n\t" \
141+
"add a0, a0, %0\n\t" \
142+
"2:\n\t" \
143+
"bltu a0, %2, 3b\n\t" \
144+
THEAD_SYNC_S, THEAD_VENDOR_ID, \
145+
ERRATA_THEAD_CMO, CONFIG_ERRATA_THEAD_CMO) \
108146
: : "r"(_cachesize), \
109147
"r"((unsigned long)(_start) & ~((_cachesize) - 1UL)), \
110148
"r"((unsigned long)(_start) + (_size)) \

0 commit comments

Comments
 (0)