blob: 50dececf77b78c502b42dc1352d11814cf59c0cb [file] [log] [blame]
Patrick Delaunaybb306502025-04-01 15:14:13 +02001// SPDX-License-Identifier: GPL-2.0-or-later OR BSD-3-Clause
2/*
3 * Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4 */
5
6#define LOG_CATEGORY UCLASS_NOP
7
8#include <dm.h>
9#include <asm/io.h>
10#include <dm/device.h>
11#include <dm/device_compat.h>
12#include <dm/lists.h>
13#include <linux/bitfield.h>
14#include <mach/rif.h>
15
16/* RIFSC offset register */
17#define RIFSC_RISC_SECCFGR0(id) (0x10 + 0x4 * (id))
18#define RIFSC_RISC_PER0_CIDCFGR(id) (0x100 + 0x8 * (id))
19#define RIFSC_RISC_PER0_SEMCR(id) (0x104 + 0x8 * (id))
20
21/*
22 * SEMCR register
23 */
24#define SEMCR_MUTEX BIT(0)
25
26/* RIFSC miscellaneous */
27#define RIFSC_RISC_SCID_MASK GENMASK(6, 4)
28#define RIFSC_RISC_SEMWL_MASK GENMASK(23, 16)
29
30#define IDS_PER_RISC_SEC_PRIV_REGS 32
31
32/*
33 * CIDCFGR register fields
34 */
35#define CIDCFGR_CFEN BIT(0)
36#define CIDCFGR_SEMEN BIT(1)
37
38#define SEMWL_SHIFT 16
39
40#define STM32MP25_RIFSC_ENTRIES 178
41
42/* Compartiment IDs */
43#define RIF_CID0 0x0
44#define RIF_CID1 0x1
45
46/*
47 * struct stm32_rifsc_plat: Information about RIFSC device
48 *
49 * @base: Base address of RIFSC
50 */
51struct stm32_rifsc_plat {
52 void *base;
53};
54
55/*
56 * struct stm32_rifsc_child_plat: Information about each child
57 *
58 * @domain_id: Domain id
59 */
60struct stm32_rifsc_child_plat {
61 u32 domain_id;
62};
63
64static bool stm32_rif_is_semaphore_available(void *base, u32 id)
65{
66 void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
67
68 return !(readl(addr) & SEMCR_MUTEX);
69}
70
71static int stm32_rif_acquire_semaphore(void *base, u32 id)
72{
73 void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
74
75 /* Check that the semaphore is available */
76 if (!stm32_rif_is_semaphore_available(base, id))
77 return -EACCES;
78
79 setbits_le32(addr, SEMCR_MUTEX);
80
81 /* Check that CID1 has the semaphore */
82 if (stm32_rif_is_semaphore_available(base, id) ||
83 FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) != RIF_CID1))
84 return -EACCES;
85
86 return 0;
87}
88
89static int stm32_rif_release_semaphore(void *base, u32 id)
90{
91 void *addr = base + RIFSC_RISC_PER0_SEMCR(id);
92
93 if (stm32_rif_is_semaphore_available(base, id))
94 return 0;
95
96 clrbits_le32(addr, SEMCR_MUTEX);
97
98 /* Ok if another compartment takes the semaphore before the check */
99 if (!stm32_rif_is_semaphore_available(base, id) &&
100 FIELD_GET(RIFSC_RISC_SCID_MASK, (readl(addr)) == RIF_CID1))
101 return -EACCES;
102
103 return 0;
104}
105
106static int rifsc_parse_access_controller(ofnode node, struct ofnode_phandle_args *args)
107{
108 int ret;
109
110 ret = ofnode_parse_phandle_with_args(node, "access-controllers",
111 "#access-controller-cells", 0,
112 0, args);
113 if (ret) {
114 log_debug("failed to parse access-controller (%d)\n", ret);
115 return ret;
116 }
117
118 if (args->args_count != 1) {
119 log_debug("invalid domain args_count: %d\n", args->args_count);
120 return -EINVAL;
121 }
122
123 if (args->args[0] >= STM32MP25_RIFSC_ENTRIES) {
124 log_err("Invalid sys bus ID for %s\n", ofnode_get_name(node));
125 return -EINVAL;
126 }
127
128 return 0;
129}
130
131static int rifsc_check_access(void *base, u32 id)
132{
133 u32 reg_offset, reg_id, sec_reg_value, cid_reg_value, sem_reg_value;
134
135 /*
136 * RIFSC_RISC_PRIVCFGRx and RIFSC_RISC_SECCFGRx both handle configuration access for
137 * 32 peripherals. On the other hand, there is one _RIFSC_RISC_PERx_CIDCFGR register
138 * per peripheral
139 */
140 reg_id = id / IDS_PER_RISC_SEC_PRIV_REGS;
141 reg_offset = id % IDS_PER_RISC_SEC_PRIV_REGS;
142 sec_reg_value = readl(base + RIFSC_RISC_SECCFGR0(reg_id));
143 cid_reg_value = readl(base + RIFSC_RISC_PER0_CIDCFGR(id));
144 sem_reg_value = readl(base + RIFSC_RISC_PER0_SEMCR(id));
145
146 /*
147 * First check conditions for semaphore mode, which doesn't take into
148 * account static CID.
149 */
150 if (cid_reg_value & CIDCFGR_SEMEN)
151 goto skip_cid_check;
152
153 /*
154 * Skip cid check if CID filtering isn't enabled or filtering is enabled on CID0, which
155 * corresponds to whatever CID.
156 */
157 if (!(cid_reg_value & CIDCFGR_CFEN) ||
158 FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0)
159 goto skip_cid_check;
160
161 /* Coherency check with the CID configuration */
162 if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
163 log_debug("Invalid CID configuration for peripheral %d\n", id);
164 return -EACCES;
165 }
166
167 /* Check semaphore accesses */
168 if (cid_reg_value & CIDCFGR_SEMEN) {
169 if (!(FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
170 log_debug("Not in semaphore whitelist for peripheral %d\n", id);
171 return -EACCES;
172 }
173 if (!stm32_rif_is_semaphore_available(base, id) &&
174 !(FIELD_GET(RIFSC_RISC_SCID_MASK, sem_reg_value) & BIT(RIF_CID1))) {
175 log_debug("Semaphore unavailable for peripheral %d\n", id);
176 return -EACCES;
177 }
178 }
179
180skip_cid_check:
181 /* Check security configuration */
182 if (sec_reg_value & BIT(reg_offset)) {
183 log_debug("Invalid security configuration for peripheral %d\n", id);
184 return -EACCES;
185 }
186
187 return 0;
188}
189
190int stm32_rifsc_check_access_by_id(ofnode device_node, u32 id)
191{
192 struct ofnode_phandle_args args;
193 int err;
194
195 if (id >= STM32MP25_RIFSC_ENTRIES)
196 return -EINVAL;
197
198 err = rifsc_parse_access_controller(device_node, &args);
199 if (err)
200 return err;
201
202 return rifsc_check_access((void *)ofnode_get_addr(args.node), id);
203}
204
205int stm32_rifsc_check_access(ofnode device_node)
206{
207 struct ofnode_phandle_args args;
208 int err;
209
210 err = rifsc_parse_access_controller(device_node, &args);
211 if (err)
212 return err;
213
214 return rifsc_check_access((void *)ofnode_get_addr(args.node), args.args[0]);
215}
216
217static int stm32_rifsc_child_pre_probe(struct udevice *dev)
218{
219 struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
220 struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
221 u32 cid_reg_value;
222 int err;
223 u32 id = child_plat->domain_id;
224
225 cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
226
227 /*
228 * If the peripheral is in semaphore mode, take the semaphore so that
229 * the CID1 has the ownership.
230 */
231 if (cid_reg_value & CIDCFGR_SEMEN &&
232 (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
233 err = stm32_rif_acquire_semaphore(plat->base, id);
234 if (err) {
235 dev_err(dev, "Couldn't acquire RIF semaphore for peripheral %d (%d)\n",
236 id, err);
237 return err;
238 }
239 dev_dbg(dev, "Acquiring semaphore for peripheral %d\n", id);
240 }
241
242 return 0;
243}
244
245static int stm32_rifsc_child_post_remove(struct udevice *dev)
246{
247 struct stm32_rifsc_plat *plat = dev_get_plat(dev->parent);
248 struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
249 u32 cid_reg_value;
250 int err;
251 u32 id = child_plat->domain_id;
252
253 cid_reg_value = readl(plat->base + RIFSC_RISC_PER0_CIDCFGR(id));
254
255 /*
256 * If the peripheral is in semaphore mode, release the semaphore so that
257 * there's no ownership.
258 */
259 if (cid_reg_value & CIDCFGR_SEMEN &&
260 (FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_reg_value) & BIT(RIF_CID1))) {
261 err = stm32_rif_release_semaphore(plat->base, id);
262 if (err)
263 dev_err(dev, "Couldn't release rif semaphore for peripheral %d (%d)\n",
264 id, err);
265 }
266
267 return 0;
268}
269
270static int stm32_rifsc_child_post_bind(struct udevice *dev)
271{
272 struct stm32_rifsc_child_plat *child_plat = dev_get_parent_plat(dev);
273 struct ofnode_phandle_args args;
274 int ret;
275
276 if (!dev_has_ofnode(dev))
277 return -EPERM;
278
279 ret = rifsc_parse_access_controller(dev_ofnode(dev), &args);
280 if (ret)
281 return ret;
282
283 child_plat->domain_id = args.args[0];
284
285 return 0;
286}
287
288static int stm32_rifsc_bind(struct udevice *dev)
289{
290 struct stm32_rifsc_plat *plat = dev_get_plat(dev);
291 struct ofnode_phandle_args args;
292 int ret = 0, err = 0;
293 ofnode node;
294
295 plat->base = dev_read_addr_ptr(dev);
296 if (!plat->base) {
297 dev_err(dev, "can't get registers base address\n");
298 return -ENOENT;
299 }
300
301 for (node = ofnode_first_subnode(dev_ofnode(dev));
302 ofnode_valid(node);
303 node = ofnode_next_subnode(node)) {
304 const char *node_name = ofnode_get_name(node);
305
306 if (!ofnode_is_enabled(node))
307 continue;
308
309 err = rifsc_parse_access_controller(node, &args);
310 if (err) {
311 dev_dbg(dev, "%s failed to parse child on bus (%d)\n", node_name, err);
312 continue;
313 }
314
315 err = rifsc_check_access(plat->base, args.args[0]);
316 if (err) {
317 dev_info(dev, "%s not allowed on bus (%d)\n", node_name, err);
318 continue;
319 }
320
321 err = lists_bind_fdt(dev, node, NULL, NULL,
322 gd->flags & GD_FLG_RELOC ? false : true);
323 if (err && !ret) {
324 ret = err;
325 dev_err(dev, "%s failed to bind on bus (%d)\n", node_name, ret);
326 }
327 }
328
329 if (ret)
330 dev_err(dev, "Some child failed to bind (%d)\n", ret);
331
332 return ret;
333}
334
335static int stm32_rifsc_remove(struct udevice *bus)
336{
337 struct udevice *dev;
338
339 /* Deactivate all child devices not yet removed */
340 for (device_find_first_child(bus, &dev); dev; device_find_next_child(&dev))
341 if (device_active(dev))
342 stm32_rifsc_child_post_remove(dev);
343
344 return 0;
345}
346
347static const struct udevice_id stm32_rifsc_ids[] = {
348 { .compatible = "st,stm32mp25-rifsc" },
349 {},
350};
351
352U_BOOT_DRIVER(stm32_rifsc) = {
353 .name = "stm32_rifsc",
354 .id = UCLASS_NOP,
355 .of_match = stm32_rifsc_ids,
356 .bind = stm32_rifsc_bind,
357 .remove = stm32_rifsc_remove,
358 .child_post_bind = stm32_rifsc_child_post_bind,
359 .child_pre_probe = stm32_rifsc_child_pre_probe,
360 .child_post_remove = stm32_rifsc_child_post_remove,
361 .plat_auto = sizeof(struct stm32_rifsc_plat),
362 .per_child_plat_auto = sizeof(struct stm32_rifsc_child_plat),
363 .flags = DM_FLAG_OS_PREPARE,
364};