Skip to content

Commit 27a7cd5

Browse files
asmellbyjhedberg
authored andcommitted
drivers: retained_mem: Add driver for Silicon Labs BURAM
Add retained memory driver for BURAM on Silicon Labs Series 2 devices. This is a 128-byte register-based backup memory available in all power states. Signed-off-by: Aksel Skauge Mellbye <[email protected]>
1 parent 10f5c8f commit 27a7cd5

File tree

8 files changed

+217
-0
lines changed

8 files changed

+217
-0
lines changed

drivers/retained_mem/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,6 @@ zephyr_library()
66
zephyr_library_sources_ifdef(CONFIG_USERSPACE retained_mem_handlers.c)
77
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_GPREGRET retained_mem_nrf_gpregret.c)
88
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_NRF_RAM_CTRL retained_mem_nrf_ram_ctrl.c)
9+
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_SILABS_BURAM retained_mem_silabs_buram.c)
910
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_ZEPHYR_RAM retained_mem_zephyr_ram.c)
1011
zephyr_library_sources_ifdef(CONFIG_RETAINED_MEM_ZEPHYR_REG retained_mem_zephyr_reg.c)

drivers/retained_mem/Kconfig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ source "subsys/logging/Kconfig.template.log_config"
3535

3636
source "drivers/retained_mem/Kconfig.nrf"
3737

38+
source "drivers/retained_mem/Kconfig.silabs"
39+
3840
source "drivers/retained_mem/Kconfig.zephyr"
3941

4042
endif # RETAINED_MEM
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2025 Silicon Laboratories Inc.
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
config RETAINED_MEM_SILABS_BURAM
5+
bool "Silicon Labs BURAM driver"
6+
default y
7+
depends on DT_HAS_SILABS_BURAM_ENABLED
8+
help
9+
Enable driver for Silicon Labs BURAM-based retained memory register support.
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
/*
2+
* Copyright (c) 2023, Nordic Semiconductor ASA
3+
* Copyright (c) 2023, Bjarki Arge Andreasen
4+
* Copyright (c) 2025 Silicon Laboratories Inc.
5+
*
6+
* SPDX-License-Identifier: Apache-2.0
7+
*/
8+
9+
#define DT_DRV_COMPAT silabs_buram
10+
11+
#include <string.h>
12+
#include <zephyr/device.h>
13+
#include <zephyr/devicetree.h>
14+
#include <zephyr/drivers/clock_control.h>
15+
#include <zephyr/drivers/clock_control/clock_control_silabs.h>
16+
#include <zephyr/drivers/retained_mem.h>
17+
#include <zephyr/kernel.h>
18+
#include <zephyr/sys/util.h>
19+
#include <zephyr/logging/log.h>
20+
21+
LOG_MODULE_REGISTER(retained_mem_silabs_buram, CONFIG_RETAINED_MEM_LOG_LEVEL);
22+
23+
struct silabs_buram_data {
24+
#ifdef CONFIG_RETAINED_MEM_MUTEXES
25+
struct k_mutex lock;
26+
#endif
27+
};
28+
29+
struct silabs_buram_config {
30+
uint8_t *address;
31+
size_t size;
32+
const struct device *clock_dev;
33+
const struct silabs_clock_control_cmu_config clock_cfg;
34+
};
35+
36+
static inline void silabs_buram_lock_take(const struct device *dev)
37+
{
38+
#ifdef CONFIG_RETAINED_MEM_MUTEXES
39+
struct silabs_buram_data *data = dev->data;
40+
41+
k_mutex_lock(&data->lock, K_FOREVER);
42+
#else
43+
ARG_UNUSED(dev);
44+
#endif
45+
}
46+
47+
static inline void silabs_buram_lock_release(const struct device *dev)
48+
{
49+
#ifdef CONFIG_RETAINED_MEM_MUTEXES
50+
struct silabs_buram_data *data = dev->data;
51+
52+
k_mutex_unlock(&data->lock);
53+
#else
54+
ARG_UNUSED(dev);
55+
#endif
56+
}
57+
58+
static int silabs_buram_init(const struct device *dev)
59+
{
60+
const struct silabs_buram_config *config = dev->config;
61+
int err;
62+
63+
#ifdef CONFIG_RETAINED_MEM_MUTEXES
64+
struct silabs_buram_data *data = dev->data;
65+
66+
k_mutex_init(&data->lock);
67+
#endif
68+
69+
if (!config->clock_dev) {
70+
/* BURAM is automatically clocked */
71+
return 0;
72+
}
73+
74+
err = clock_control_on(config->clock_dev, (clock_control_subsys_t)&config->clock_cfg);
75+
if (err < 0 && err != -EALREADY) {
76+
return err;
77+
}
78+
79+
return 0;
80+
}
81+
82+
static ssize_t silabs_buram_size(const struct device *dev)
83+
{
84+
const struct silabs_buram_config *config = dev->config;
85+
86+
return (ssize_t)config->size;
87+
}
88+
89+
static int silabs_buram_read(const struct device *dev, off_t offset, uint8_t *buffer, size_t size)
90+
{
91+
const struct silabs_buram_config *config = dev->config;
92+
93+
silabs_buram_lock_take(dev);
94+
95+
memcpy(buffer, (config->address + offset), size);
96+
97+
silabs_buram_lock_release(dev);
98+
99+
return 0;
100+
}
101+
102+
static int silabs_buram_write(const struct device *dev, off_t offset, const uint8_t *buffer,
103+
size_t size)
104+
{
105+
const struct silabs_buram_config *config = dev->config;
106+
107+
silabs_buram_lock_take(dev);
108+
109+
memcpy((config->address + offset), buffer, size);
110+
111+
silabs_buram_lock_release(dev);
112+
113+
return 0;
114+
}
115+
116+
static int silabs_buram_clear(const struct device *dev)
117+
{
118+
const struct silabs_buram_config *config = dev->config;
119+
120+
silabs_buram_lock_take(dev);
121+
122+
memset(config->address, 0, config->size);
123+
124+
silabs_buram_lock_release(dev);
125+
126+
return 0;
127+
}
128+
129+
static DEVICE_API(retained_mem, silabs_buram_api) = {
130+
.size = silabs_buram_size,
131+
.read = silabs_buram_read,
132+
.write = silabs_buram_write,
133+
.clear = silabs_buram_clear,
134+
};
135+
136+
#define SILABS_BURAM_DEVICE(inst) \
137+
static struct silabs_buram_data silabs_buram_data_##inst; \
138+
static const struct silabs_buram_config silabs_buram_config_##inst = { \
139+
.address = (uint8_t *)DT_INST_REG_ADDR(inst), \
140+
.size = DT_INST_REG_SIZE(inst), \
141+
.clock_dev = COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(inst, 0), \
142+
(DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(inst))), \
143+
(NULL)), \
144+
.clock_cfg = COND_CODE_1(DT_INST_CLOCKS_HAS_IDX(inst, 0), \
145+
(SILABS_DT_INST_CLOCK_CFG(inst)), \
146+
({0})), \
147+
}; \
148+
DEVICE_DT_INST_DEFINE(inst, &silabs_buram_init, NULL, &silabs_buram_data_##inst, \
149+
&silabs_buram_config_##inst, POST_KERNEL, \
150+
CONFIG_RETAINED_MEM_INIT_PRIORITY, &silabs_buram_api);
151+
152+
DT_INST_FOREACH_STATUS_OKAY(SILABS_BURAM_DEVICE)
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Silicon Laboratories Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
retainedmemtestdevice = &buram;
10+
};
11+
};
12+
13+
&buram {
14+
status = "okay";
15+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Silicon Laboratories Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
retainedmemtestdevice = &buram;
10+
};
11+
};
12+
13+
&buram {
14+
status = "okay";
15+
};
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
/*
2+
* Copyright (c) 2025 Silicon Laboratories Inc.
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
aliases {
9+
retainedmemtestdevice = &buram;
10+
};
11+
};
12+
13+
&buram {
14+
status = "okay";
15+
};

tests/drivers/retained_mem/api/testcase.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,11 @@ tests:
2929
tags:
3030
- drivers
3131
- retained_mem
32+
drivers.retained_mem.api.buram:
33+
platform_allow:
34+
- slwrb4180b
35+
- xg24_rb4187c
36+
- xg29_rb4412a
37+
tags:
38+
- drivers
39+
- retained_mem

0 commit comments

Comments
 (0)