uboot-d1: add bootloader for upcoming d1 target
[openwrt/staging/mans0n.git] / package / boot / uboot-d1 / patches / 0076-riscv-cpu-Add-cache-operations-for-T-HEAD-CPUs.patch
1 From b6da98cd39612bb5660afbcad06e3a6bac43563e Mon Sep 17 00:00:00 2001
2 From: Samuel Holland <samuel@sholland.org>
3 Date: Sat, 11 Sep 2021 23:27:42 -0500
4 Subject: [PATCH 76/90] riscv: cpu: Add cache operations for T-HEAD CPUs
5
6 Signed-off-by: Samuel Holland <samuel@sholland.org>
7 ---
8 arch/riscv/cpu/Makefile | 1 +
9 arch/riscv/cpu/thead/cache.c | 119 +++++++++++++++++++++++++++++++++++
10 arch/riscv/lib/cache.c | 2 +-
11 3 files changed, 121 insertions(+), 1 deletion(-)
12 create mode 100644 arch/riscv/cpu/thead/cache.c
13
14 --- a/arch/riscv/cpu/Makefile
15 +++ b/arch/riscv/cpu/Makefile
16 @@ -5,3 +5,4 @@
17 extra-y = start.o
18
19 obj-y += cpu.o mtrap.o
20 +obj-y += thead/cache.o
21 --- /dev/null
22 +++ b/arch/riscv/cpu/thead/cache.c
23 @@ -0,0 +1,119 @@
24 +// SPDX-License-Identifier: GPL-2.0+
25 +
26 +#include <asm/cache.h>
27 +#include <asm/csr.h>
28 +
29 +#define CSR_MHCR 0x7c1
30 +#define CSR_MCOR 0x7c2
31 +#define CSR_MHINT 0x7c5
32 +
33 +#define MHCR_IE BIT(0) /* icache enable */
34 +#define MHCR_DE BIT(1) /* dcache enable */
35 +#define MHCR_WA BIT(2) /* dcache write allocate */
36 +#define MHCR_WB BIT(3) /* dcache write back */
37 +#define MHCR_RS BIT(4) /* return stack enable */
38 +#define MHCR_BPE BIT(5) /* branch prediction enable */
39 +#define MHCR_BTB BIT(6) /* branch target prediction enable */
40 +#define MHCR_WBR BIT(8) /* write burst enable */
41 +#define MHCR_L0BTB BIT(12)
42 +
43 +#define MCOR_CACHE_SEL_ICACHE (0x1 << 0)
44 +#define MCOR_CACHE_SEL_DCACHE (0x2 << 0)
45 +#define MCOR_CACHE_SEL_BOTH (0x3 << 0)
46 +#define MCOR_INV BIT(4)
47 +#define MCOR_CLR BIT(5)
48 +#define MCOR_BHT_INV BIT(16)
49 +#define MCOR_BTB_INV BIT(17)
50 +
51 +#define MHINT_DPLD BIT(2) /* dcache prefetch enable */
52 +#define MHINT_AMR_PAGE (0x0 << 3)
53 +#define MHINT_AMR_LIMIT_3 (0x1 << 3)
54 +#define MHINT_AMR_LIMIT_64 (0x2 << 3)
55 +#define MHINT_AMR_LIMIT_128 (0x3 << 3)
56 +#define MHINT_IPLD BIT(8) /* icache prefetch enable */
57 +#define MHINT_IWPE BIT(9) /* icache prediction enable */
58 +#define MHINT_DIS_PREFETCH_2 (0x0 << 13)
59 +#define MHINT_DIS_PREFETCH_4 (0x1 << 13)
60 +#define MHINT_DIS_PREFETCH_8 (0x2 << 13)
61 +#define MHINT_DIS_PREFETCH_16 (0x3 << 13)
62 +
63 +#define sync_i() asm volatile (".long 0x01a0000b" ::: "memory")
64 +
65 +void flush_dcache_all(void)
66 +{
67 + asm volatile (".long 0x0030000b" ::: "memory"); /* dcache.ciall */
68 + sync_i();
69 +}
70 +
71 +void flush_dcache_range(unsigned long start, unsigned long end)
72 +{
73 + register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
74 +
75 + for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
76 + asm volatile (".long 0x02b5000b" ::: "memory"); /* dcache.cipa a0 */
77 + sync_i();
78 +}
79 +
80 +void invalidate_icache_range(unsigned long start, unsigned long end)
81 +{
82 + register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
83 +
84 + for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
85 + asm volatile (".long 0x0385000b" ::: "memory"); /* icache.ipa a0 */
86 + sync_i();
87 +}
88 +
89 +void invalidate_dcache_range(unsigned long start, unsigned long end)
90 +{
91 + register unsigned long i asm("a0") = start & -CONFIG_SYS_CACHELINE_SIZE;
92 +
93 + for (; i < end; i += CONFIG_SYS_CACHELINE_SIZE)
94 + asm volatile (".long 0x02a5000b" ::: "memory"); /* dcache.ipa a0 */
95 + sync_i();
96 +}
97 +
98 +#if 0
99 +void icache_enable(void)
100 +{
101 + asm volatile (".long 0x0100000b" ::: "memory"); /* icache.iall */
102 + sync_i();
103 + csr_set(CSR_MHCR, MHCR_IE | MHCR_RS | MHCR_BPE | MHCR_BTB | MHCR_L0BTB);
104 + csr_set(CSR_MHINT, MHINT_IPLD | MHINT_IWPE);
105 +}
106 +
107 +void icache_disable(void)
108 +{
109 + csr_clear(CSR_MHCR, MHCR_IE);
110 +}
111 +
112 +int icache_status(void)
113 +{
114 + return csr_read(CSR_MHCR) & MHCR_IE;
115 +}
116 +
117 +void dcache_enable(void)
118 +{
119 + asm volatile (".long 0x0020000b" ::: "memory"); /* dcache.iall */
120 + sync_i();
121 + csr_set(CSR_MHCR, MHCR_DE | MHCR_WA | MHCR_WB | MHCR_WBR);
122 + csr_set(CSR_MHINT, MHINT_DPLD | MHINT_AMR_LIMIT_3);
123 +}
124 +
125 +void dcache_disable(void)
126 +{
127 + asm volatile (".long 0x0010000b" ::: "memory"); /* dcache.call */
128 + sync_i();
129 + csr_clear(CSR_MHCR, MHCR_DE);
130 +}
131 +
132 +int dcache_status(void)
133 +{
134 + return csr_read(CSR_MHCR) & MHCR_DE;
135 +}
136 +
137 +void enable_caches(void)
138 +{
139 + icache_enable();
140 + dcache_enable();
141 +}
142 +#endif
143 --- a/arch/riscv/lib/cache.c
144 +++ b/arch/riscv/lib/cache.c
145 @@ -20,7 +20,7 @@ __weak void flush_dcache_range(unsigned
146 {
147 }
148
149 -void invalidate_icache_range(unsigned long start, unsigned long end)
150 +__weak void invalidate_icache_range(unsigned long start, unsigned long end)
151 {
152 /*
153 * RISC-V does not have an instruction for invalidating parts of the