blob: 31aa30bc7d723ade3b337d8bc5a13ada89fe1da4 [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>
Ilias Apalodimase9e18652025-02-20 15:54:42 +020011#include <linux/errno.h>
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +000012
13#define CBO_INVAL(base) \
14 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
15 RS1(base), SIMM12(0))
16#define CBO_CLEAN(base) \
17 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
18 RS1(base), SIMM12(1))
19#define CBO_FLUSH(base) \
20 INSN_I(OPCODE_MISC_MEM, FUNC3(2), __RD(0), \
21 RS1(base), SIMM12(2))
22enum {
23 CBO_CLEAN,
24 CBO_FLUSH,
25 CBO_INVAL
26} riscv_cbo_ops;
27static int zicbom_block_size;
Mayuresh Chitaleb7108532025-01-06 13:04:05 +000028extern unsigned int riscv_get_cbom_block_size(void);
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +000029static inline void do_cbo_clean(unsigned long base)
30{
31 asm volatile ("add a0, %0, zero\n" CBO_CLEAN(%0) ::
32 "r"(base) : "memory");
33}
34
35static inline void do_cbo_flush(unsigned long base)
36{
37 asm volatile ("add a0, %0, zero\n" CBO_FLUSH(%0) ::
38 "r"(base) : "memory");
39}
40
41static inline void do_cbo_inval(unsigned long base)
42{
43 asm volatile ("add a0, %0, zero\n" CBO_INVAL(%0) ::
44 "r"(base) : "memory");
45}
46
47static void cbo_op(int op_type, unsigned long start,
48 unsigned long end)
49{
50 unsigned long op_size = end - start, size = 0;
51 void (*fn)(unsigned long base);
52
53 switch (op_type) {
54 case CBO_CLEAN:
55 fn = do_cbo_clean;
56 break;
57 case CBO_FLUSH:
58 fn = do_cbo_flush;
59 break;
60 case CBO_INVAL:
61 fn = do_cbo_inval;
62 break;
63 }
64 start &= ~(UL(zicbom_block_size - 1));
65 while (size < op_size) {
66 fn(start + size);
67 size += zicbom_block_size;
68 }
69}
70
71void cbo_flush(unsigned long start, unsigned long end)
72{
73 if (zicbom_block_size)
74 cbo_op(CBO_FLUSH, start, end);
75}
76
77void cbo_inval(unsigned long start, unsigned long end)
78{
79 if (zicbom_block_size)
80 cbo_op(CBO_INVAL, start, end);
81}
82
Rick Chen842d5802018-11-07 09:34:06 +080083void invalidate_icache_all(void)
84{
85 asm volatile ("fence.i" ::: "memory");
86}
87
Lukas Auer6280e322019-01-04 01:37:29 +010088__weak void flush_dcache_all(void)
Rick Chen842d5802018-11-07 09:34:06 +080089{
Rick Chen842d5802018-11-07 09:34:06 +080090}
Lukas Auer6280e322019-01-04 01:37:29 +010091
92__weak void flush_dcache_range(unsigned long start, unsigned long end)
Rick Chen6eedd922017-12-26 13:55:49 +080093{
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +000094 cbo_flush(start, end);
Rick Chen6eedd922017-12-26 13:55:49 +080095}
96
Samuel Hollandac1c3d02023-10-31 00:37:20 -050097__weak void invalidate_icache_range(unsigned long start, unsigned long end)
Rick Chen6eedd922017-12-26 13:55:49 +080098{
Lukas Auer76562282018-11-22 11:26:23 +010099 /*
100 * RISC-V does not have an instruction for invalidating parts of the
101 * instruction cache. Invalidate all of it instead.
102 */
103 invalidate_icache_all();
104}
105
Lukas Auer6280e322019-01-04 01:37:29 +0100106__weak void invalidate_dcache_range(unsigned long start, unsigned long end)
Lukas Auer76562282018-11-22 11:26:23 +0100107{
Mayuresh Chitalec3abcaa2024-08-23 09:41:26 +0000108 cbo_inval(start, end);
Rick Chen6eedd922017-12-26 13:55:49 +0800109}
110
Rick Chen842d5802018-11-07 09:34:06 +0800111void cache_flush(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800112{
Rick Chen842d5802018-11-07 09:34:06 +0800113 invalidate_icache_all();
114 flush_dcache_all();
Rick Chen6eedd922017-12-26 13:55:49 +0800115}
116
117void flush_cache(unsigned long addr, unsigned long size)
118{
Lukas Auer09dfc3c2019-01-04 01:37:30 +0100119 invalidate_icache_range(addr, addr + size);
120 flush_dcache_range(addr, addr + size);
Rick Chen6eedd922017-12-26 13:55:49 +0800121}
122
Rick Chen842d5802018-11-07 09:34:06 +0800123__weak void icache_enable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800124{
125}
126
Rick Chen842d5802018-11-07 09:34:06 +0800127__weak void icache_disable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800128{
129}
130
Rick Chen842d5802018-11-07 09:34:06 +0800131__weak int icache_status(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800132{
133 return 0;
134}
135
Rick Chen842d5802018-11-07 09:34:06 +0800136__weak void dcache_enable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800137{
138}
139
Rick Chen842d5802018-11-07 09:34:06 +0800140__weak void dcache_disable(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800141{
142}
143
Rick Chen842d5802018-11-07 09:34:06 +0800144__weak int dcache_status(void)
Rick Chen6eedd922017-12-26 13:55:49 +0800145{
146 return 0;
147}
Zong Lia33070c2021-09-01 15:01:40 +0800148
149__weak void enable_caches(void)
150{
Mayuresh Chitaleb7108532025-01-06 13:04:05 +0000151 zicbom_block_size = riscv_get_cbom_block_size();
152 if (!zicbom_block_size)
153 log_debug("Zicbom not initialized.\n");
Zong Lia33070c2021-09-01 15:01:40 +0800154}
Ilias Apalodimase9e18652025-02-20 15:54:42 +0200155
156int __weak pgprot_set_attrs(phys_addr_t addr, size_t size, enum pgprot_attrs perm)
157{
158 return -ENOSYS;
159}