Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/bus/stm32_rifsc.c
51283 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Copyright (C) 2023, STMicroelectronics - All Rights Reserved
4
*/
5
6
#include <linux/bitfield.h>
7
#include <linux/bits.h>
8
#include <linux/debugfs.h>
9
#include <linux/device.h>
10
#include <linux/err.h>
11
#include <linux/init.h>
12
#include <linux/io.h>
13
#include <linux/kernel.h>
14
#include <linux/module.h>
15
#include <linux/of.h>
16
#include <linux/of_platform.h>
17
#include <linux/platform_device.h>
18
#include <linux/types.h>
19
20
#include "stm32_firewall.h"
21
22
/*
23
* RIFSC offset register
24
*/
25
#define RIFSC_RISC_SECCFGR0 0x10
26
#define RIFSC_RISC_PRIVCFGR0 0x30
27
#define RIFSC_RISC_PER0_CIDCFGR 0x100
28
#define RIFSC_RISC_PER0_SEMCR 0x104
29
#define RIFSC_RISC_REG0_ACFGR 0x900
30
#define RIFSC_RISC_REG3_AADDR 0x924
31
#define RIFSC_RISC_HWCFGR2 0xFEC
32
33
/*
34
* SEMCR register
35
*/
36
#define SEMCR_MUTEX BIT(0)
37
38
/*
39
* HWCFGR2 register
40
*/
41
#define HWCFGR2_CONF1_MASK GENMASK(15, 0)
42
#define HWCFGR2_CONF2_MASK GENMASK(23, 16)
43
#define HWCFGR2_CONF3_MASK GENMASK(31, 24)
44
45
/*
46
* RIFSC miscellaneous
47
*/
48
#define RIFSC_RISC_CFEN_MASK BIT(0)
49
#define RIFSC_RISC_SEM_EN_MASK BIT(1)
50
#define RIFSC_RISC_SCID_MASK GENMASK(6, 4)
51
#define RIFSC_RISC_SEML_SHIFT 16
52
#define RIFSC_RISC_SEMWL_MASK GENMASK(23, 16)
53
#define RIFSC_RISC_PER_ID_MASK GENMASK(31, 24)
54
55
#define RIFSC_RISC_PERx_CID_MASK (RIFSC_RISC_CFEN_MASK | \
56
RIFSC_RISC_SEM_EN_MASK | \
57
RIFSC_RISC_SCID_MASK | \
58
RIFSC_RISC_SEMWL_MASK)
59
60
#define IDS_PER_RISC_SEC_PRIV_REGS 32
61
62
/* RIF miscellaneous */
63
/*
64
* CIDCFGR register fields
65
*/
66
#define CIDCFGR_CFEN BIT(0)
67
#define CIDCFGR_SEMEN BIT(1)
68
#define CIDCFGR_SEMWL(x) BIT(RIFSC_RISC_SEML_SHIFT + (x))
69
70
#define SEMWL_SHIFT 16
71
72
/* Compartiment IDs */
73
#define RIF_CID0 0x0
74
#define RIF_CID1 0x1
75
76
#if defined(CONFIG_DEBUG_FS)
77
#define RIFSC_RISUP_ENTRIES 128
78
#define RIFSC_RIMU_ENTRIES 16
79
#define RIFSC_RISAL_SUBREGIONS 2
80
#define RIFSC_RISAL_GRANULARITY 8
81
82
#define RIFSC_RIMC_ATTR0 0xC10
83
84
#define RIFSC_RIMC_CIDSEL BIT(2)
85
#define RIFSC_RIMC_MCID_MASK GENMASK(6, 4)
86
#define RIFSC_RIMC_MSEC BIT(8)
87
#define RIFSC_RIMC_MPRIV BIT(9)
88
89
#define RIFSC_RISC_SRCID_MASK GENMASK(6, 4)
90
#define RIFSC_RISC_SRPRIV BIT(9)
91
#define RIFSC_RISC_SRSEC BIT(8)
92
#define RIFSC_RISC_SRRLOCK BIT(1)
93
#define RIFSC_RISC_SREN BIT(0)
94
#define RIFSC_RISC_SRLENGTH_MASK GENMASK(27, 16)
95
#define RIFSC_RISC_SRSTART_MASK GENMASK(10, 0)
96
97
static const char *stm32mp21_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = {
98
"ETR",
99
"SDMMC1",
100
"SDMMC2",
101
"SDMMC3",
102
"OTG_HS",
103
"USBH",
104
"ETH1",
105
"ETH2",
106
"RESERVED",
107
"RESERVED",
108
"DCMIPP",
109
"LTDC_L1/L2",
110
"LTDC_L3",
111
"RESERVED",
112
"RESERVED",
113
"RESERVED",
114
};
115
116
static const char *stm32mp25_rifsc_rimu_names[RIFSC_RIMU_ENTRIES] = {
117
"ETR",
118
"SDMMC1",
119
"SDMMC2",
120
"SDMMC3",
121
"USB3DR",
122
"USBH",
123
"ETH1",
124
"ETH2",
125
"PCIE",
126
"GPU",
127
"DMCIPP",
128
"LTDC_L0/L1",
129
"LTDC_L2",
130
"LTDC_ROT",
131
"VDEC",
132
"VENC"
133
};
134
135
static const char *stm32mp21_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = {
136
"TIM1",
137
"TIM2",
138
"TIM3",
139
"TIM4",
140
"TIM5",
141
"TIM6",
142
"TIM7",
143
"TIM8",
144
"TIM10",
145
"TIM11",
146
"TIM12",
147
"TIM13",
148
"TIM14",
149
"TIM15",
150
"TIM16",
151
"TIM17",
152
"RESERVED",
153
"LPTIM1",
154
"LPTIM2",
155
"LPTIM3",
156
"LPTIM4",
157
"LPTIM5",
158
"SPI1",
159
"SPI2",
160
"SPI3",
161
"SPI4",
162
"SPI5",
163
"SPI6",
164
"RESERVED",
165
"RESERVED",
166
"SPDIFRX",
167
"USART1",
168
"USART2",
169
"USART3",
170
"UART4",
171
"UART5",
172
"USART6",
173
"UART7",
174
"RESERVED",
175
"RESERVED",
176
"LPUART1",
177
"I2C1",
178
"I2C2",
179
"I2C3",
180
"RESERVED",
181
"RESERVED",
182
"RESERVED",
183
"RESERVED",
184
"RESERVED",
185
"SAI1",
186
"SAI2",
187
"SAI3",
188
"SAI4",
189
"RESERVED",
190
"MDF1",
191
"RESERVED",
192
"FDCAN",
193
"HDP",
194
"ADC1",
195
"ADC2",
196
"ETH1",
197
"ETH2",
198
"RESERVED",
199
"USBH",
200
"RESERVED",
201
"RESERVED",
202
"OTG_HS",
203
"DDRPERFM",
204
"RESERVED",
205
"RESERVED",
206
"RESERVED",
207
"RESERVED",
208
"RESERVED",
209
"STGEN",
210
"OCTOSPI1",
211
"RESERVED",
212
"SDMMC1",
213
"SDMMC2",
214
"SDMMC3",
215
"RESERVED",
216
"LTDC_CMN",
217
"RESERVED",
218
"RESERVED",
219
"RESERVED",
220
"RESERVED",
221
"RESERVED",
222
"CSI",
223
"DCMIPP",
224
"DCMI_PSSI",
225
"RESERVED",
226
"RESERVED",
227
"RESERVED",
228
"RNG1",
229
"RNG2",
230
"PKA",
231
"SAES",
232
"HASH1",
233
"HASH2",
234
"CRYP1",
235
"CRYP2",
236
"IWDG1",
237
"IWDG2",
238
"IWDG3",
239
"IWDG4",
240
"WWDG1",
241
"RESERVED",
242
"VREFBUF",
243
"DTS",
244
"RAMCFG",
245
"CRC",
246
"SERC",
247
"RESERVED",
248
"RESERVED",
249
"RESERVED",
250
"I3C1",
251
"I3C2",
252
"I3C3",
253
"RESERVED",
254
"ICACHE_DCACHE",
255
"LTDC_L1L2",
256
"LTDC_L3",
257
"RESERVED",
258
"RESERVED",
259
"RESERVED",
260
"RESERVED",
261
"OTFDEC1",
262
"RESERVED",
263
"IAC",
264
};
265
266
static const char *stm32mp25_rifsc_risup_names[RIFSC_RISUP_ENTRIES] = {
267
"TIM1",
268
"TIM2",
269
"TIM3",
270
"TIM4",
271
"TIM5",
272
"TIM6",
273
"TIM7",
274
"TIM8",
275
"TIM10",
276
"TIM11",
277
"TIM12",
278
"TIM13",
279
"TIM14",
280
"TIM15",
281
"TIM16",
282
"TIM17",
283
"TIM20",
284
"LPTIM1",
285
"LPTIM2",
286
"LPTIM3",
287
"LPTIM4",
288
"LPTIM5",
289
"SPI1",
290
"SPI2",
291
"SPI3",
292
"SPI4",
293
"SPI5",
294
"SPI6",
295
"SPI7",
296
"SPI8",
297
"SPDIFRX",
298
"USART1",
299
"USART2",
300
"USART3",
301
"UART4",
302
"UART5",
303
"USART6",
304
"UART7",
305
"UART8",
306
"UART9",
307
"LPUART1",
308
"I2C1",
309
"I2C2",
310
"I2C3",
311
"I2C4",
312
"I2C5",
313
"I2C6",
314
"I2C7",
315
"I2C8",
316
"SAI1",
317
"SAI2",
318
"SAI3",
319
"SAI4",
320
"RESERVED",
321
"MDF1",
322
"ADF1",
323
"FDCAN",
324
"HDP",
325
"ADC12",
326
"ADC3",
327
"ETH1",
328
"ETH2",
329
"RESERVED",
330
"USBH",
331
"RESERVED",
332
"RESERVED",
333
"USB3DR",
334
"COMBOPHY",
335
"PCIE",
336
"UCPD1",
337
"ETHSW_DEIP",
338
"ETHSW_ACM_CF",
339
"ETHSW_ACM_MSGBU",
340
"STGEN",
341
"OCTOSPI1",
342
"OCTOSPI2",
343
"SDMMC1",
344
"SDMMC2",
345
"SDMMC3",
346
"GPU",
347
"LTDC_CMN",
348
"DSI_CMN",
349
"RESERVED",
350
"RESERVED",
351
"LVDS",
352
"RESERVED",
353
"CSI",
354
"DCMIPP",
355
"DCMI_PSSI",
356
"VDEC",
357
"VENC",
358
"RESERVED",
359
"RNG",
360
"PKA",
361
"SAES",
362
"HASH",
363
"CRYP1",
364
"CRYP2",
365
"IWDG1",
366
"IWDG2",
367
"IWDG3",
368
"IWDG4",
369
"IWDG5",
370
"WWDG1",
371
"WWDG2",
372
"RESERVED",
373
"VREFBUF",
374
"DTS",
375
"RAMCFG",
376
"CRC",
377
"SERC",
378
"OCTOSPIM",
379
"GICV2M",
380
"RESERVED",
381
"I3C1",
382
"I3C2",
383
"I3C3",
384
"I3C4",
385
"ICACHE_DCACHE",
386
"LTDC_L0L1",
387
"LTDC_L2",
388
"LTDC_ROT",
389
"DSI_TRIG",
390
"DSI_RDFIFO",
391
"RESERVED",
392
"OTFDEC1",
393
"OTFDEC2",
394
"IAC",
395
};
396
struct rifsc_risup_debug_data {
397
char dev_name[15];
398
u8 dev_cid;
399
u8 dev_sem_cids;
400
u8 dev_id;
401
bool dev_cid_filt_en;
402
bool dev_sem_en;
403
bool dev_priv;
404
bool dev_sec;
405
};
406
407
struct rifsc_rimu_debug_data {
408
char m_name[11];
409
u8 m_cid;
410
bool cidsel;
411
bool m_sec;
412
bool m_priv;
413
};
414
415
struct rifsc_subreg_debug_data {
416
bool sr_sec;
417
bool sr_priv;
418
u8 sr_cid;
419
bool sr_rlock;
420
bool sr_enable;
421
u16 sr_start;
422
u16 sr_length;
423
};
424
425
struct stm32_rifsc_resources_names {
426
const char **device_names;
427
const char **initiator_names;
428
};
429
struct rifsc_dbg_private {
430
const struct stm32_rifsc_resources_names *res_names;
431
void __iomem *mmio;
432
unsigned int nb_risup;
433
unsigned int nb_rimu;
434
unsigned int nb_risal;
435
};
436
437
static const struct stm32_rifsc_resources_names rifsc_mp21_res_names = {
438
.device_names = stm32mp21_rifsc_risup_names,
439
.initiator_names = stm32mp21_rifsc_rimu_names,
440
};
441
442
static const struct stm32_rifsc_resources_names rifsc_mp25_res_names = {
443
.device_names = stm32mp25_rifsc_risup_names,
444
.initiator_names = stm32mp25_rifsc_rimu_names,
445
};
446
447
static void stm32_rifsc_fill_rimu_dbg_entry(struct rifsc_dbg_private *rifsc,
448
struct rifsc_rimu_debug_data *dbg_entry, int i)
449
{
450
const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names;
451
u32 rimc_attr = readl_relaxed(rifsc->mmio + RIFSC_RIMC_ATTR0 + 0x4 * i);
452
453
snprintf(dbg_entry->m_name, sizeof(dbg_entry->m_name), "%s", dbg_names->initiator_names[i]);
454
dbg_entry->m_cid = FIELD_GET(RIFSC_RIMC_MCID_MASK, rimc_attr);
455
dbg_entry->cidsel = rimc_attr & RIFSC_RIMC_CIDSEL;
456
dbg_entry->m_sec = rimc_attr & RIFSC_RIMC_MSEC;
457
dbg_entry->m_priv = rimc_attr & RIFSC_RIMC_MPRIV;
458
}
459
460
static void stm32_rifsc_fill_dev_dbg_entry(struct rifsc_dbg_private *rifsc,
461
struct rifsc_risup_debug_data *dbg_entry, int i)
462
{
463
const struct stm32_rifsc_resources_names *dbg_names = rifsc->res_names;
464
u32 cid_cfgr, sec_cfgr, priv_cfgr;
465
u8 reg_id = i / IDS_PER_RISC_SEC_PRIV_REGS;
466
u8 reg_offset = i % IDS_PER_RISC_SEC_PRIV_REGS;
467
468
cid_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * i);
469
sec_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id);
470
priv_cfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_PRIVCFGR0 + 0x4 * reg_id);
471
472
snprintf(dbg_entry->dev_name, sizeof(dbg_entry->dev_name), "%s",
473
dbg_names->device_names[i]);
474
dbg_entry->dev_id = i;
475
dbg_entry->dev_cid_filt_en = cid_cfgr & CIDCFGR_CFEN;
476
dbg_entry->dev_sem_en = cid_cfgr & CIDCFGR_SEMEN;
477
dbg_entry->dev_cid = FIELD_GET(RIFSC_RISC_SCID_MASK, cid_cfgr);
478
dbg_entry->dev_sem_cids = FIELD_GET(RIFSC_RISC_SEMWL_MASK, cid_cfgr);
479
dbg_entry->dev_sec = sec_cfgr & BIT(reg_offset) ? true : false;
480
dbg_entry->dev_priv = priv_cfgr & BIT(reg_offset) ? true : false;
481
}
482
483
484
static void stm32_rifsc_fill_subreg_dbg_entry(struct rifsc_dbg_private *rifsc,
485
struct rifsc_subreg_debug_data *dbg_entry, int i,
486
int j)
487
{
488
u32 risc_xcfgr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG0_ACFGR + 0x10 * i + 0x8 * j);
489
u32 risc_xaddr;
490
491
dbg_entry->sr_sec = risc_xcfgr & RIFSC_RISC_SRSEC;
492
dbg_entry->sr_priv = risc_xcfgr & RIFSC_RISC_SRPRIV;
493
dbg_entry->sr_cid = FIELD_GET(RIFSC_RISC_SRCID_MASK, risc_xcfgr);
494
dbg_entry->sr_rlock = risc_xcfgr & RIFSC_RISC_SRRLOCK;
495
dbg_entry->sr_enable = risc_xcfgr & RIFSC_RISC_SREN;
496
if (i == 2) {
497
risc_xaddr = readl_relaxed(rifsc->mmio + RIFSC_RISC_REG3_AADDR + 0x8 * j);
498
dbg_entry->sr_length = FIELD_GET(RIFSC_RISC_SRLENGTH_MASK, risc_xaddr);
499
dbg_entry->sr_start = FIELD_GET(RIFSC_RISC_SRSTART_MASK, risc_xaddr);
500
} else {
501
dbg_entry->sr_start = 0;
502
dbg_entry->sr_length = U16_MAX;
503
}
504
}
505
506
static int stm32_rifsc_conf_dump_show(struct seq_file *s, void *data)
507
{
508
struct rifsc_dbg_private *rifsc = (struct rifsc_dbg_private *)s->private;
509
int i, j;
510
511
seq_puts(s, "\n=============================================\n");
512
seq_puts(s, " RIFSC dump\n");
513
seq_puts(s, "=============================================\n\n");
514
515
seq_puts(s, "\n=============================================\n");
516
seq_puts(s, " RISUP dump\n");
517
seq_puts(s, "=============================================\n");
518
519
seq_printf(s, "\n| %-15s |", "Peripheral name");
520
seq_puts(s, "| Firewall ID |");
521
seq_puts(s, "| N/SECURE |");
522
seq_puts(s, "| N/PRIVILEGED |");
523
seq_puts(s, "| CID filtering |");
524
seq_puts(s, "| Semaphore mode |");
525
seq_puts(s, "| SCID |");
526
seq_printf(s, "| %7s |\n", "SEMWL");
527
528
for (i = 0; i < RIFSC_RISUP_ENTRIES && i < rifsc->nb_risup; i++) {
529
struct rifsc_risup_debug_data d_dbg_entry;
530
531
stm32_rifsc_fill_dev_dbg_entry(rifsc, &d_dbg_entry, i);
532
533
seq_printf(s, "| %-15s |", d_dbg_entry.dev_name);
534
seq_printf(s, "| %-11d |", d_dbg_entry.dev_id);
535
seq_printf(s, "| %-8s |", d_dbg_entry.dev_sec ? "SEC" : "NSEC");
536
seq_printf(s, "| %-12s |", d_dbg_entry.dev_priv ? "PRIV" : "NPRIV");
537
seq_printf(s, "| %-13s |", str_enabled_disabled(d_dbg_entry.dev_cid_filt_en));
538
seq_printf(s, "| %-14s |", str_enabled_disabled(d_dbg_entry.dev_sem_en));
539
seq_printf(s, "| %-4d |", d_dbg_entry.dev_cid);
540
seq_printf(s, "| %#-7x |\n", d_dbg_entry.dev_sem_cids);
541
}
542
543
seq_puts(s, "\n=============================================\n");
544
seq_puts(s, " RIMU dump\n");
545
seq_puts(s, "=============================================\n");
546
547
seq_puts(s, "| RIMU's name |");
548
seq_puts(s, "| CIDSEL |");
549
seq_puts(s, "| MCID |");
550
seq_puts(s, "| N/SECURE |");
551
seq_puts(s, "| N/PRIVILEGED |\n");
552
553
for (i = 0; i < RIFSC_RIMU_ENTRIES && rifsc->nb_rimu; i++) {
554
struct rifsc_rimu_debug_data m_dbg_entry;
555
556
stm32_rifsc_fill_rimu_dbg_entry(rifsc, &m_dbg_entry, i);
557
558
seq_printf(s, "| %-11s |", m_dbg_entry.m_name);
559
seq_printf(s, "| %-6s |", m_dbg_entry.cidsel ? "CIDSEL" : "");
560
seq_printf(s, "| %-4d |", m_dbg_entry.m_cid);
561
seq_printf(s, "| %-8s |", m_dbg_entry.m_sec ? "SEC" : "NSEC");
562
seq_printf(s, "| %-12s |\n", m_dbg_entry.m_priv ? "PRIV" : "NPRIV");
563
}
564
565
if (rifsc->nb_risal > 0) {
566
seq_puts(s, "\n=============================================\n");
567
seq_puts(s, " RISAL dump\n");
568
seq_puts(s, "=============================================\n");
569
570
seq_puts(s, "| Memory |");
571
seq_puts(s, "| Subreg. |");
572
seq_puts(s, "| N/SECURE |");
573
seq_puts(s, "| N/PRIVILEGED |");
574
seq_puts(s, "| Subreg. CID |");
575
seq_puts(s, "| Resource lock |");
576
seq_puts(s, "| Subreg. enable |");
577
seq_puts(s, "| Subreg. start |");
578
seq_puts(s, "| Subreg. end |\n");
579
580
for (i = 0; i < rifsc->nb_risal; i++) {
581
for (j = 0; j < RIFSC_RISAL_SUBREGIONS; j++) {
582
struct rifsc_subreg_debug_data sr_dbg_entry;
583
584
stm32_rifsc_fill_subreg_dbg_entry(rifsc, &sr_dbg_entry, i, j);
585
586
seq_printf(s, "| LPSRAM%1d |", i + 1);
587
seq_printf(s, "| %1s |", (j == 0) ? "A" : "B");
588
seq_printf(s, "| %-8s |", sr_dbg_entry.sr_sec ? "SEC" : "NSEC");
589
seq_printf(s, "| %-12s |", sr_dbg_entry.sr_priv ? "PRIV" : "NPRIV");
590
seq_printf(s, "| 0x%-9x |", sr_dbg_entry.sr_cid);
591
seq_printf(s, "| %-13s |",
592
sr_dbg_entry.sr_rlock ? "locked (1)" : "unlocked (0)");
593
seq_printf(s, "| %-14s |",
594
str_enabled_disabled(sr_dbg_entry.sr_enable));
595
seq_printf(s, "| 0x%-11x |", sr_dbg_entry.sr_start);
596
seq_printf(s, "| 0x%-11x |\n", sr_dbg_entry.sr_start +
597
sr_dbg_entry.sr_length - 1);
598
}
599
}
600
}
601
602
return 0;
603
}
604
DEFINE_SHOW_ATTRIBUTE(stm32_rifsc_conf_dump);
605
606
static int stm32_rifsc_register_debugfs(struct stm32_firewall_controller *rifsc_controller,
607
u32 nb_risup, u32 nb_rimu, u32 nb_risal)
608
{
609
struct rifsc_dbg_private *rifsc_priv;
610
struct dentry *root = NULL;
611
612
rifsc_priv = devm_kzalloc(rifsc_controller->dev, sizeof(*rifsc_priv), GFP_KERNEL);
613
if (!rifsc_priv)
614
return -ENOMEM;
615
616
rifsc_priv->mmio = rifsc_controller->mmio;
617
rifsc_priv->nb_risup = nb_risup;
618
rifsc_priv->nb_rimu = nb_rimu;
619
rifsc_priv->nb_risal = nb_risal;
620
rifsc_priv->res_names = of_device_get_match_data(rifsc_controller->dev);
621
622
root = debugfs_lookup("stm32_firewall", NULL);
623
if (!root)
624
root = debugfs_create_dir("stm32_firewall", NULL);
625
626
if (IS_ERR(root))
627
return PTR_ERR(root);
628
629
debugfs_create_file("rifsc", 0444, root, rifsc_priv, &stm32_rifsc_conf_dump_fops);
630
631
return 0;
632
}
633
#endif /* defined(CONFIG_DEBUG_FS) */
634
635
static bool stm32_rifsc_is_semaphore_available(void __iomem *addr)
636
{
637
return !(readl(addr) & SEMCR_MUTEX);
638
}
639
640
static int stm32_rif_acquire_semaphore(struct stm32_firewall_controller *stm32_firewall_controller,
641
int id)
642
{
643
void __iomem *addr = stm32_firewall_controller->mmio + RIFSC_RISC_PER0_SEMCR + 0x8 * id;
644
645
writel(SEMCR_MUTEX, addr);
646
647
/* Check that CID1 has the semaphore */
648
if (stm32_rifsc_is_semaphore_available(addr) ||
649
FIELD_GET(RIFSC_RISC_SCID_MASK, readl(addr)) != RIF_CID1)
650
return -EACCES;
651
652
return 0;
653
}
654
655
static void stm32_rif_release_semaphore(struct stm32_firewall_controller *stm32_firewall_controller,
656
int id)
657
{
658
void __iomem *addr = stm32_firewall_controller->mmio + RIFSC_RISC_PER0_SEMCR + 0x8 * id;
659
660
if (stm32_rifsc_is_semaphore_available(addr))
661
return;
662
663
writel(SEMCR_MUTEX, addr);
664
665
/* Ok if another compartment takes the semaphore before the check */
666
WARN_ON(!stm32_rifsc_is_semaphore_available(addr) &&
667
FIELD_GET(RIFSC_RISC_SCID_MASK, readl(addr)) == RIF_CID1);
668
}
669
670
static int stm32_rifsc_grant_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
671
{
672
struct stm32_firewall_controller *rifsc_controller = ctrl;
673
u32 reg_offset, reg_id, sec_reg_value, cid_reg_value;
674
int rc;
675
676
if (firewall_id >= rifsc_controller->max_entries) {
677
dev_err(rifsc_controller->dev, "Invalid sys bus ID %u", firewall_id);
678
return -EINVAL;
679
}
680
681
/*
682
* RIFSC_RISC_PRIVCFGRx and RIFSC_RISC_SECCFGRx both handle configuration access for
683
* 32 peripherals. On the other hand, there is one _RIFSC_RISC_PERx_CIDCFGR register
684
* per peripheral
685
*/
686
reg_id = firewall_id / IDS_PER_RISC_SEC_PRIV_REGS;
687
reg_offset = firewall_id % IDS_PER_RISC_SEC_PRIV_REGS;
688
sec_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_SECCFGR0 + 0x4 * reg_id);
689
cid_reg_value = readl(rifsc_controller->mmio + RIFSC_RISC_PER0_CIDCFGR + 0x8 * firewall_id);
690
691
/* First check conditions for semaphore mode, which doesn't take into account static CID. */
692
if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
693
if (cid_reg_value & BIT(RIF_CID1 + SEMWL_SHIFT)) {
694
/* Static CID is irrelevant if semaphore mode */
695
goto skip_cid_check;
696
} else {
697
dev_dbg(rifsc_controller->dev,
698
"Invalid bus semaphore configuration: index %d\n", firewall_id);
699
return -EACCES;
700
}
701
}
702
703
/*
704
* Skip CID check if CID filtering isn't enabled or filtering is enabled on CID0, which
705
* corresponds to whatever CID.
706
*/
707
if (!(cid_reg_value & CIDCFGR_CFEN) ||
708
FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) == RIF_CID0)
709
goto skip_cid_check;
710
711
/* Coherency check with the CID configuration */
712
if (FIELD_GET(RIFSC_RISC_SCID_MASK, cid_reg_value) != RIF_CID1) {
713
dev_dbg(rifsc_controller->dev, "Invalid CID configuration for peripheral: %d\n",
714
firewall_id);
715
return -EACCES;
716
}
717
718
skip_cid_check:
719
/* Check security configuration */
720
if (sec_reg_value & BIT(reg_offset)) {
721
dev_dbg(rifsc_controller->dev,
722
"Invalid security configuration for peripheral: %d\n", firewall_id);
723
return -EACCES;
724
}
725
726
/*
727
* If the peripheral is in semaphore mode, take the semaphore so that
728
* the CID1 has the ownership.
729
*/
730
if ((cid_reg_value & CIDCFGR_SEMEN) && (cid_reg_value & CIDCFGR_CFEN)) {
731
rc = stm32_rif_acquire_semaphore(rifsc_controller, firewall_id);
732
if (rc) {
733
dev_err(rifsc_controller->dev,
734
"Couldn't acquire semaphore for peripheral: %d\n", firewall_id);
735
return rc;
736
}
737
}
738
739
return 0;
740
}
741
742
static void stm32_rifsc_release_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
743
{
744
stm32_rif_release_semaphore(ctrl, firewall_id);
745
}
746
747
static int stm32_rifsc_probe(struct platform_device *pdev)
748
{
749
struct stm32_firewall_controller *rifsc_controller;
750
struct device_node *np = pdev->dev.of_node;
751
u32 nb_risup, nb_rimu, nb_risal;
752
struct resource *res;
753
void __iomem *mmio;
754
int rc;
755
756
rifsc_controller = devm_kzalloc(&pdev->dev, sizeof(*rifsc_controller), GFP_KERNEL);
757
if (!rifsc_controller)
758
return -ENOMEM;
759
760
mmio = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
761
if (IS_ERR(mmio))
762
return PTR_ERR(mmio);
763
764
rifsc_controller->dev = &pdev->dev;
765
rifsc_controller->mmio = mmio;
766
rifsc_controller->name = dev_driver_string(rifsc_controller->dev);
767
rifsc_controller->type = STM32_PERIPHERAL_FIREWALL | STM32_MEMORY_FIREWALL;
768
rifsc_controller->grant_access = stm32_rifsc_grant_access;
769
rifsc_controller->release_access = stm32_rifsc_release_access;
770
771
/* Get number of RIFSC entries*/
772
nb_risup = FIELD_GET(HWCFGR2_CONF1_MASK,
773
readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2));
774
nb_rimu = FIELD_GET(HWCFGR2_CONF2_MASK,
775
readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2));
776
nb_risal = FIELD_GET(HWCFGR2_CONF3_MASK,
777
readl(rifsc_controller->mmio + RIFSC_RISC_HWCFGR2));
778
/*
779
* On STM32MP21, RIFSC_RISC_HWCFGR2 shows an incorrect number of RISAL (NUM_RISAL is 3
780
* instead of 0). A software workaround is implemented using the st,mem-map property in the
781
* device tree. This property is absent or left empty if there is no RISAL.
782
*/
783
if (of_device_is_compatible(np, "st,stm32mp21-rifsc"))
784
nb_risal = 0;
785
rifsc_controller->max_entries = nb_risup + nb_rimu + nb_risal;
786
787
platform_set_drvdata(pdev, rifsc_controller);
788
789
rc = stm32_firewall_controller_register(rifsc_controller);
790
if (rc) {
791
dev_err(rifsc_controller->dev, "Couldn't register as a firewall controller: %d",
792
rc);
793
return rc;
794
}
795
796
rc = stm32_firewall_populate_bus(rifsc_controller);
797
if (rc) {
798
dev_err(rifsc_controller->dev, "Couldn't populate RIFSC bus: %d",
799
rc);
800
return rc;
801
}
802
803
#if defined(CONFIG_DEBUG_FS)
804
rc = stm32_rifsc_register_debugfs(rifsc_controller, nb_risup, nb_rimu, nb_risal);
805
if (rc)
806
return dev_err_probe(rifsc_controller->dev, rc, "Failed creating debugfs entry\n");
807
#endif
808
809
/* Populate all allowed nodes */
810
return of_platform_populate(np, NULL, NULL, &pdev->dev);
811
}
812
813
static const struct of_device_id stm32_rifsc_of_match[] = {
814
{
815
.compatible = "st,stm32mp25-rifsc",
816
#if defined(CONFIG_DEBUG_FS)
817
.data = &rifsc_mp25_res_names,
818
#endif
819
},
820
{
821
.compatible = "st,stm32mp21-rifsc",
822
#if defined(CONFIG_DEBUG_FS)
823
.data = &rifsc_mp21_res_names,
824
#endif
825
},
826
{}
827
};
828
MODULE_DEVICE_TABLE(of, stm32_rifsc_of_match);
829
830
static struct platform_driver stm32_rifsc_driver = {
831
.probe = stm32_rifsc_probe,
832
.driver = {
833
.name = "stm32-rifsc",
834
.of_match_table = stm32_rifsc_of_match,
835
},
836
};
837
module_platform_driver(stm32_rifsc_driver);
838
839
MODULE_AUTHOR("Gatien Chevallier <[email protected]>");
840
MODULE_DESCRIPTION("STMicroelectronics RIFSC driver");
841
MODULE_LICENSE("GPL");
842
843