File Index
Files and directories
Sign in
FILE

stm32_rifsc.c

File preview with syntax highlighting.

linux-6.19.14/drivers/bus/stm32_rifsc.c C
  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
 97static 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
116static 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
135static 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
266static 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};
396struct 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
407struct 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
415struct 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
425struct stm32_rifsc_resources_names {
426	const char **device_names;
427	const char **initiator_names;
428};
429struct 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
437static 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
442static 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
447static 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
460static 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
484static 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
506static 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}
604DEFINE_SHOW_ATTRIBUTE(stm32_rifsc_conf_dump);
605
606static 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
635static bool stm32_rifsc_is_semaphore_available(void __iomem *addr)
636{
637	return !(readl(addr) & SEMCR_MUTEX);
638}
639
640static 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
655static 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
670static 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
718skip_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
742static void stm32_rifsc_release_access(struct stm32_firewall_controller *ctrl, u32 firewall_id)
743{
744	stm32_rif_release_semaphore(ctrl, firewall_id);
745}
746
747static 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
813static 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};
828MODULE_DEVICE_TABLE(of, stm32_rifsc_of_match);
829
830static 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};
837module_platform_driver(stm32_rifsc_driver);
838
839MODULE_AUTHOR("Gatien Chevallier <gatien.chevallier@foss.st.com>");
840MODULE_DESCRIPTION("STMicroelectronics RIFSC driver");
841MODULE_LICENSE("GPL");
~/ Read-only file preview.