Skip to content

Commit e6ad1da

Browse files
VynDragonkartben
authored andcommitted
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 63a5205 commit e6ad1da

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+
uintptr_t base;
25+
uint32_t dcache_ways_mask;
26+
};
27+
28+
static const struct cache_config cache_cfg = {
29+
.dcache_ways_mask = (1 << DT_INST_PROP(0, dcache_ways_disabled)) - 1,
30+
.base = DT_INST_REG_ADDR(0),
31+
};
32+
33+
/* L1C supports basically a single type of invalidate & flush */
34+
int bflb_cache_invalidate(uint32_t timeout)
35+
{
36+
uint32_t tmp;
37+
38+
tmp = *((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET));
39+
tmp |= 1 << L1C_BYPASS_POS;
40+
tmp &= ~(1 << L1C_CACHEABLE_POS);
41+
tmp &= ~L1C_WAY_DIS_MSK;
42+
tmp &= ~(1 << L1C_CNT_EN_POS);
43+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
44+
45+
tmp &= ~(1 << L1C_INVALID_EN_POS);
46+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
47+
__asm__ volatile (".rept 4 ; nop ; .endr");
48+
49+
tmp |= (1 << L1C_INVALID_EN_POS);
50+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
51+
__asm__ volatile (".rept 4 ; nop ; .endr");
52+
53+
while ((*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET))
54+
& L1C_INVALID_DONE_MSK) == 0 && timeout > 0) {
55+
clock_bflb_settle();
56+
clock_bflb_settle();
57+
timeout--;
58+
}
59+
60+
if (!timeout) {
61+
return -EIO;
62+
}
63+
64+
#ifdef SOC_SERIES_BL70X
65+
tmp &= ~(1 << L1C_FLUSH_EN_POS);
66+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
67+
__asm__ volatile (".rept 4 ; nop ; .endr");
68+
tmp |= (1 << L1C_FLUSH_EN_POS);
69+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
70+
__asm__ volatile (".rept 4 ; nop ; .endr");
71+
72+
while ((*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET))
73+
& L1C_FLUSH_DONE_MSK) == 0 && timeout > 0) {
74+
clock_bflb_settle();
75+
clock_bflb_settle();
76+
timeout--;
77+
}
78+
79+
if (!timeout) {
80+
return -EIO;
81+
}
82+
83+
tmp &= ~(1 << L1C_FLUSH_EN_POS);
84+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
85+
#endif
86+
87+
tmp = *((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET));
88+
tmp |= 1 << L1C_BYPASS_POS;
89+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
90+
91+
tmp &= ~(1 << L1C_BYPASS_POS);
92+
tmp |= 1 << L1C_CNT_EN_POS;
93+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
94+
95+
tmp &= ~L1C_WAY_DIS_MSK;
96+
tmp |= cache_cfg.dcache_ways_mask << L1C_WAY_DIS_POS;
97+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
98+
99+
tmp |= 1 << L1C_CACHEABLE_POS;
100+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
101+
102+
clock_bflb_settle();
103+
clock_bflb_settle();
104+
return 0;
105+
}
106+
107+
void cache_instr_enable(void)
108+
{
109+
cache_data_enable();
110+
}
111+
112+
void cache_data_enable(void)
113+
{
114+
uint32_t tmp;
115+
116+
tmp = *((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET));
117+
tmp &= ~(1 << L1C_BYPASS_POS);
118+
tmp |= 1 << L1C_CNT_EN_POS;
119+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
120+
tmp &= ~L1C_WAY_DIS_MSK;
121+
tmp |= cache_cfg.dcache_ways_mask << L1C_WAY_DIS_POS;
122+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
123+
tmp |= 1 << L1C_CACHEABLE_POS;
124+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
125+
}
126+
127+
void cache_instr_disable(void)
128+
{
129+
cache_data_disable();
130+
}
131+
132+
void cache_data_disable(void)
133+
{
134+
uint32_t tmp;
135+
136+
tmp = *((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET));
137+
tmp |= 1 << L1C_BYPASS_POS;
138+
tmp &= ~(1 << L1C_CACHEABLE_POS);
139+
tmp &= ~L1C_WAY_DIS_MSK;
140+
tmp &= ~(1 << L1C_CNT_EN_POS);
141+
*((volatile uint32_t *)(cache_cfg.base + L1C_CONFIG_OFFSET)) = tmp;
142+
}
143+
144+
int cache_data_invd_all(void)
145+
{
146+
return bflb_cache_invalidate(INVLD_TIMEOUT);
147+
}
148+
149+
int cache_data_invd_range(void *addr, size_t size)
150+
{
151+
ARG_UNUSED(addr);
152+
ARG_UNUSED(size);
153+
154+
return -ENOTSUP;
155+
}
156+
157+
int cache_instr_invd_all(void)
158+
{
159+
return bflb_cache_invalidate(INVLD_TIMEOUT);
160+
}
161+
162+
int cache_instr_invd_range(void *addr, size_t size)
163+
{
164+
ARG_UNUSED(addr);
165+
ARG_UNUSED(size);
166+
167+
return -ENOTSUP;
168+
}
169+
170+
int cache_data_flush_all(void)
171+
{
172+
return bflb_cache_invalidate(INVLD_TIMEOUT);
173+
}
174+
175+
int cache_data_flush_range(void *addr, size_t size)
176+
{
177+
ARG_UNUSED(addr);
178+
ARG_UNUSED(size);
179+
180+
return -ENOTSUP;
181+
}
182+
183+
int cache_data_flush_and_invd_all(void)
184+
{
185+
return bflb_cache_invalidate(INVLD_TIMEOUT);
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)