Skip to content

Commit f94a705

Browse files
committed
drivers: cache: Introduce bflb L1C cache driver
Introduce Bouffalo Lab L1C cache management functions This allows invalidating instructions and data on BL60x and BL70x Signed-off-by: Camille BAUD <[email protected]>
1 parent 8cccc59 commit f94a705

File tree

4 files changed

+232
-0
lines changed

4 files changed

+232
-0
lines changed

drivers/cache/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ zephyr_library_property(ALLOW_EMPTY TRUE)
77

88
zephyr_library_sources_ifdef(CONFIG_CACHE_ASPEED cache_aspeed.c)
99
zephyr_library_sources_ifdef(CONFIG_CACHE_ANDES cache_andes.c)
10+
zephyr_library_sources_ifdef(CONFIG_CACHE_BFLB_L1C cache_bflb_l1c.c)
1011
zephyr_library_sources_ifdef(CONFIG_USERSPACE cache_handlers.c)
1112
zephyr_library_sources_ifdef(CONFIG_CACHE_NRF_CACHE cache_nrf.c)
1213
zephyr_library_sources_ifdef(CONFIG_CACHE_NXP_XCACHE cache_nxp_xcache.c)

drivers/cache/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ source "drivers/cache/Kconfig.nrf"
2323
source "drivers/cache/Kconfig.andes"
2424
source "drivers/cache/Kconfig.nxp_xcache"
2525
source "drivers/cache/Kconfig.stm32"
26+
source "drivers/cache/Kconfig.bflb"
2627

2728
endif # CACHE

drivers/cache/Kconfig.bflb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# Copyright (c) 2025 MASSDRIVER EI <massdriver.space>
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config CACHE_BFLB_L1C
5+
bool "Bouffalolab L1C cache system driver"
6+
default y
7+
select CACHE_HAS_DRIVER
8+
depends on DT_HAS_BFLB_L1C_ENABLED
9+
help
10+
This option enables the cache driver for the Bouffalolab L1C cache system

drivers/cache/cache_bflb_l1c.c

Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
/*
2+
* Copyright (c) 2025 MASSDRIVER EI (massdriver.space)
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/init.h>
8+
#include <zephyr/kernel.h>
9+
#include <zephyr/drivers/cache.h>
10+
#include <zephyr/logging/log.h>
11+
12+
#include <bflb_soc.h>
13+
#include <hbn_reg.h>
14+
#include <l1c_reg.h>
15+
#include <zephyr/drivers/clock_control/clock_control_bflb_common.h>
16+
17+
#define DT_DRV_COMPAT bflb_l1c
18+
19+
#define INVLD_TIMEOUT 4194304
20+
21+
LOG_MODULE_REGISTER(cache_bflb_l1c, CONFIG_CACHE_LOG_LEVEL);
22+
23+
struct cache_config {
24+
uint32_t ways_mask;
25+
};
26+
27+
static struct cache_config cache_cfg = {
28+
.ways_mask = (1 << DT_INST_PROP(0, ways_disabled)) - 1,
29+
};
30+
31+
/* L1C supports basically a single type of invalidate & flush */
32+
int bflb_cache_invalidate(uint32_t timeout)
33+
{
34+
uint32_t tmp;
35+
36+
tmp = *((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET));
37+
tmp |= 1 << L1C_BYPASS_POS;
38+
tmp &= ~(1 << L1C_CACHEABLE_POS);
39+
tmp &= ~L1C_WAY_DIS_MSK;
40+
tmp &= ~(1 << L1C_CNT_EN_POS);
41+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
42+
43+
tmp &= ~(1 << L1C_INVALID_EN_POS);
44+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
45+
__asm__ volatile (".rept 4 ; nop ; .endr");
46+
47+
tmp |= (1 << L1C_INVALID_EN_POS);
48+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
49+
__asm__ volatile (".rept 4 ; nop ; .endr");
50+
51+
while ((*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET))
52+
& L1C_INVALID_DONE_MSK) == 0 && timeout > 0) {
53+
clock_bflb_settle();
54+
clock_bflb_settle();
55+
timeout--;
56+
}
57+
58+
if (!timeout) {
59+
return -EIO;
60+
}
61+
62+
#ifdef SOC_SERIES_BL70X
63+
tmp &= ~(1 << L1C_FLUSH_EN_POS);
64+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
65+
__asm__ volatile (".rept 4 ; nop ; .endr");
66+
tmp |= (1 << L1C_FLUSH_EN_POS);
67+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
68+
__asm__ volatile (".rept 4 ; nop ; .endr");
69+
70+
while ((*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET))
71+
& L1C_FLUSH_DONE_MSK) == 0 && timeout > 0) {
72+
clock_bflb_settle();
73+
clock_bflb_settle();
74+
timeout--;
75+
}
76+
77+
if (!timeout) {
78+
return -EIO;
79+
}
80+
81+
tmp &= ~(1 << L1C_FLUSH_EN_POS);
82+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
83+
#endif
84+
85+
tmp = *((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET));
86+
tmp |= 1 << L1C_BYPASS_POS;
87+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
88+
89+
tmp &= ~(1 << L1C_BYPASS_POS);
90+
tmp |= 1 << L1C_CNT_EN_POS;
91+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
92+
93+
tmp &= ~L1C_WAY_DIS_MSK;
94+
tmp |= cache_cfg.ways_mask << L1C_WAY_DIS_POS;
95+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
96+
97+
tmp |= 1 << L1C_CACHEABLE_POS;
98+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
99+
100+
clock_bflb_settle();
101+
clock_bflb_settle();
102+
return 0;
103+
}
104+
105+
void cache_instr_enable(void)
106+
{
107+
cache_data_enable();
108+
}
109+
110+
void cache_data_enable(void)
111+
{
112+
uint32_t tmp;
113+
114+
tmp = *((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET));
115+
tmp &= ~(1 << L1C_BYPASS_POS);
116+
tmp |= 1 << L1C_CNT_EN_POS;
117+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
118+
tmp &= ~L1C_WAY_DIS_MSK;
119+
tmp |= cache_cfg.ways_mask << L1C_WAY_DIS_POS;
120+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
121+
tmp |= 1 << L1C_CACHEABLE_POS;
122+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
123+
}
124+
125+
void cache_instr_disable(void)
126+
{
127+
cache_data_disable();
128+
}
129+
130+
void cache_data_disable(void)
131+
{
132+
uint32_t tmp;
133+
134+
tmp = *((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET));
135+
tmp |= 1 << L1C_BYPASS_POS;
136+
tmp &= ~(1 << L1C_CACHEABLE_POS);
137+
tmp &= ~L1C_WAY_DIS_MSK;
138+
tmp &= ~(1 << L1C_CNT_EN_POS);
139+
*((volatile uint32_t *)(L1C_BASE + L1C_CONFIG_OFFSET)) = tmp;
140+
}
141+
142+
143+
int cache_data_invd_all(void)
144+
{
145+
return bflb_cache_invalidate(INVLD_TIMEOUT);
146+
}
147+
148+
int cache_data_invd_range(void *addr, size_t size)
149+
{
150+
ARG_UNUSED(addr);
151+
ARG_UNUSED(size);
152+
153+
return -ENOTSUP;
154+
}
155+
156+
int cache_instr_invd_all(void)
157+
{
158+
return bflb_cache_invalidate(INVLD_TIMEOUT);
159+
}
160+
161+
int cache_instr_invd_range(void *addr, size_t size)
162+
{
163+
ARG_UNUSED(addr);
164+
ARG_UNUSED(size);
165+
166+
return -ENOTSUP;
167+
}
168+
169+
int cache_data_flush_all(void)
170+
{
171+
return bflb_cache_invalidate(INVLD_TIMEOUT);
172+
}
173+
174+
int cache_data_flush_range(void *addr, size_t size)
175+
{
176+
ARG_UNUSED(addr);
177+
ARG_UNUSED(size);
178+
179+
return -ENOTSUP;
180+
}
181+
182+
int cache_data_flush_and_invd_all(void)
183+
{
184+
return bflb_cache_invalidate(INVLD_TIMEOUT);
185+
}
186+
187+
188+
int cache_data_flush_and_invd_range(void *addr, size_t size)
189+
{
190+
ARG_UNUSED(addr);
191+
ARG_UNUSED(size);
192+
193+
return -ENOTSUP;
194+
}
195+
196+
int cache_instr_flush_all(void)
197+
{
198+
return -ENOTSUP;
199+
}
200+
201+
int cache_instr_flush_and_invd_all(void)
202+
{
203+
return -ENOTSUP;
204+
}
205+
206+
int cache_instr_flush_range(void *addr, size_t size)
207+
{
208+
ARG_UNUSED(addr);
209+
ARG_UNUSED(size);
210+
211+
return -ENOTSUP;
212+
}
213+
214+
int cache_instr_flush_and_invd_range(void *addr, size_t size)
215+
{
216+
ARG_UNUSED(addr);
217+
ARG_UNUSED(size);
218+
219+
return -ENOTSUP;
220+
}

0 commit comments

Comments
 (0)