blob: 71e4937ab54268560bda6f700296253dfb1546a7 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Rick Chen6eedd922017-12-26 13:55:49 +08002/*
3 * Copyright (C) 2017 Andes Technology Corporation
4 * Rick Chen, Andes Technology Corporation <rick@andestech.com>
Rick Chen6eedd922017-12-26 13:55:49 +08005 */
6
Simon Glass1d91ba72019-11-14 12:57:37 -07007#include <cpu_func.h>
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +00008#include <dm.h>
9#include <asm/insn-def.h>
10#include <linux/const.h>
11
12#define CBO_INVAL(base) \
13 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
14 RS1(base), SIMM12(0))
15#define CBO_CLEAN(base) \
16 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
17 RS1(base), SIMM12(1))
18#define CBO_FLUSH(base) \
19 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
20 RS1(base), SIMM12(2))
21enum {
22 CBO_CLEAN,
23 CBO_FLUSH,
24 CBO_INVAL
25} riscv_cbo_ops;
26static int zicbom_block_size;
Mayuresh Chitaleb7108532025-01-06 13:04:05 +000027extern unsigned int riscv_get_cbom_block_size(void);
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +000028static inline void do_cbo_clean(unsigned long base)
29{
30 asm volatile ("add a0, %0, zero\n" CBO_CLEAN(%0) ::
31 "r"(base) : "memory");
32}
33
34static inline void do_cbo_flush(unsigned long base)
35{
36 asm volatile ("add a0, %0, zero\n" CBO_FLUSH(%0) ::
37 "r"(base) : "memory");
38}
39
40static inline void do_cbo_inval(unsigned long base)
41{
42 asm volatile ("add a0, %0, zero\n" CBO_INVAL(%0) ::
43 "r"(base) : "memory");
44}
45
46static void cbo_op(int op_type, unsigned long start,
47 unsigned long end)
48{
49 unsigned long op_size = end - start, size = 0;
50 void (*fn)(unsigned long base);
51
52 switch (op_type) {
53 case CBO_CLEAN:
54 fn = do_cbo_clean;
55 break;
56 case CBO_FLUSH:
57 fn = do_cbo_flush;
58 break;
59 case CBO_INVAL:
60 fn = do_cbo_inval;
61 break;
62 }
63 start &= ~(UL(zicbom_block_size - 1));
64 while (size < op_size) {
65 fn(start + size);
66 size += zicbom_block_size;
67 }
68}
69
70void cbo_flush(unsigned long start, unsigned long end)
71{
72 if (zicbom_block_size)
73 cbo_op(CBO_FLUSH, start, end);
74}
75
76void cbo_inval(unsigned long start, unsigned long end)
77{
78 if (zicbom_block_size)
79 cbo_op(CBO_INVAL, start, end);
80}
81
Rick Chen842d5802018-11-07 09:34:06 +080082void invalidate_icache_all(void)
83{
84 asm volatile ("fence.i" ::: "memory");
85}
86
Lukas Auer6280e322019-01-04 01:37:29 +010087__weak void flush_dcache_all(void)
Rick Chen842d5802018-11-07 09:34:06 +080088{
Rick Chen842d5802018-11-07 09:34:06 +080089}
Lukas Auer6280e322019-01-04 01:37:29 +010090
91__weak void flush_dcache_range(unsigned long start, unsigned long end)
Rick Chen6eedd922017-12-26 13:55:49 +080092{
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +000093 cbo_flush(start, end);
Rick Chen6eedd922017-12-26 13:55:49 +080094}
95
Samuel Hollandac1c3d02023-10-31 00:37:20 -050096__weak void invalidate_icache_range(unsigned long start, unsigned long end)
Rick Chen6eedd922017-12-26 13:55:49 +080097{
Lukas Auer76562282018-11-22 11:26:23 +010098 /*
99 * RISC-V does not have an instruction for invalidating parts of the
100 * instruction cache. Invalidate all of it instead.
101 */
102 invalidate_icache_all();
103}
104
Lukas Auer6280e322019-01-04 01:37:29 +0100105__weak void invalidate_dcache_range(unsigned long start, unsigned long end)
Lukas Auer76562282018-11-22 11:26:23 +0100106{
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +0000107 cbo_inval(start, end);
Rick Chen6eedd922017-12-26 13:55:49 +0800108}
109
Rick Chen842d5802018-11-07 09:34:06 +0800110void cache_flush(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800111{
Rick Chen842d5802018-11-07 09:34:06 +0800112 invalidate_icache_all();
113 flush_dcache_all();
Rick Chen6eedd922017-12-26 13:55:49 +0800114}
115
116void flush_cache(unsigned long addr, unsigned long size)
117{
Lukas Auer09dfc3c2019-01-04 01:37:30 +0100118 invalidate_icache_range(addr, addr + size);
119 flush_dcache_range(addr, addr + size);
Rick Chen6eedd922017-12-26 13:55:49 +0800120}
121
Rick Chen842d5802018-11-07 09:34:06 +0800122__weak void icache_enable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800123{
124}
125
Rick Chen842d5802018-11-07 09:34:06 +0800126__weak void icache_disable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800127{
128}
129
Rick Chen842d5802018-11-07 09:34:06 +0800130__weak int icache_status(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800131{
132 return 0;
133}
134
Rick Chen842d5802018-11-07 09:34:06 +0800135__weak void dcache_enable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800136{
137}
138
Rick Chen842d5802018-11-07 09:34:06 +0800139__weak void dcache_disable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800140{
141}
142
Rick Chen842d5802018-11-07 09:34:06 +0800143__weak int dcache_status(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800144{
145 return 0;
146}
Zong Lia33070c2021-09-01 15:01:40 +0800147
148__weak void enable_caches(void)
149{
Mayuresh Chitaleb7108532025-01-06 13:04:05 +0000150 zicbom_block_size = riscv_get_cbom_block_size();
151 if (!zicbom_block_size)
152 log_debug("Zicbom not initialized.\n");
Zong Lia33070c2021-09-01 15:01:40 +0800153}