xref: /optee_os/core/drivers/rstctrl/stm32mp21_rstctrl.c (revision 3d476de463cc2fd581c4a30d7236de156eec48f0)
1*3d476de4SNicolas Le Bayon // SPDX-License-Identifier: BSD-2-Clause
2*3d476de4SNicolas Le Bayon /*
3*3d476de4SNicolas Le Bayon  * Copyright (C) 2025, STMicroelectronics
4*3d476de4SNicolas Le Bayon  */
5*3d476de4SNicolas Le Bayon 
6*3d476de4SNicolas Le Bayon #include <arm.h>
7*3d476de4SNicolas Le Bayon #include <drivers/rstctrl.h>
8*3d476de4SNicolas Le Bayon #include <drivers/stm32_shared_io.h>
9*3d476de4SNicolas Le Bayon #include <drivers/stm32mp21_rcc.h>
10*3d476de4SNicolas Le Bayon #include <drivers/stm32mp_dt_bindings.h>
11*3d476de4SNicolas Le Bayon #include <io.h>
12*3d476de4SNicolas Le Bayon #include <kernel/dt.h>
13*3d476de4SNicolas Le Bayon #include <kernel/dt_driver.h>
14*3d476de4SNicolas Le Bayon #include <stm32_util.h>
15*3d476de4SNicolas Le Bayon 
16*3d476de4SNicolas Le Bayon #include "stm32_rstctrl.h"
17*3d476de4SNicolas Le Bayon 
stm32_reset_update(struct rstctrl * rstctrl,bool state,unsigned int to_us)18*3d476de4SNicolas Le Bayon static TEE_Result stm32_reset_update(struct rstctrl *rstctrl, bool state,
19*3d476de4SNicolas Le Bayon 				     unsigned int to_us)
20*3d476de4SNicolas Le Bayon {
21*3d476de4SNicolas Le Bayon 	unsigned int id = to_stm32_rstline(rstctrl)->id;
22*3d476de4SNicolas Le Bayon 	const struct stm32_reset_data *data = to_stm32_rstline(rstctrl)->data;
23*3d476de4SNicolas Le Bayon 	const struct stm32_reset_cfg *rst_line = NULL;
24*3d476de4SNicolas Le Bayon 	vaddr_t address = stm32_rcc_base();
25*3d476de4SNicolas Le Bayon 	uint32_t bit_mask = 0;
26*3d476de4SNicolas Le Bayon 	uint32_t value = 0;
27*3d476de4SNicolas Le Bayon 
28*3d476de4SNicolas Le Bayon 	if (id >= data->nb_lines)
29*3d476de4SNicolas Le Bayon 		return TEE_ERROR_BAD_PARAMETERS;
30*3d476de4SNicolas Le Bayon 
31*3d476de4SNicolas Le Bayon 	rst_line = data->rst_lines[id];
32*3d476de4SNicolas Le Bayon 	if (!rst_line)
33*3d476de4SNicolas Le Bayon 		return TEE_SUCCESS;
34*3d476de4SNicolas Le Bayon 
35*3d476de4SNicolas Le Bayon 	address += rst_line->offset;
36*3d476de4SNicolas Le Bayon 	bit_mask = BIT(rst_line->bit_index);
37*3d476de4SNicolas Le Bayon 
38*3d476de4SNicolas Le Bayon 	if (!state && rst_line->no_deassert)
39*3d476de4SNicolas Le Bayon 		return TEE_SUCCESS;
40*3d476de4SNicolas Le Bayon 
41*3d476de4SNicolas Le Bayon 	state = rst_line->inverted ^ state;
42*3d476de4SNicolas Le Bayon 
43*3d476de4SNicolas Le Bayon 	if (state) {
44*3d476de4SNicolas Le Bayon 		if (rst_line->set_clr)
45*3d476de4SNicolas Le Bayon 			io_write32(address, bit_mask);
46*3d476de4SNicolas Le Bayon 		else
47*3d476de4SNicolas Le Bayon 			io_setbits32_stm32shregs(address, bit_mask);
48*3d476de4SNicolas Le Bayon 	} else {
49*3d476de4SNicolas Le Bayon 		if (rst_line->set_clr)
50*3d476de4SNicolas Le Bayon 			io_write32(address + RCC_MP_ENCLRR_OFFSET, bit_mask);
51*3d476de4SNicolas Le Bayon 		else
52*3d476de4SNicolas Le Bayon 			io_clrbits32_stm32shregs(address, bit_mask);
53*3d476de4SNicolas Le Bayon 	}
54*3d476de4SNicolas Le Bayon 
55*3d476de4SNicolas Le Bayon 	if (to_us && !rst_line->no_timeout) {
56*3d476de4SNicolas Le Bayon 		if (IO_READ32_POLL_TIMEOUT(address, value,
57*3d476de4SNicolas Le Bayon 					   ((value & bit_mask) == bit_mask) ==
58*3d476de4SNicolas Le Bayon 					   state, 0, to_us))
59*3d476de4SNicolas Le Bayon 			return TEE_ERROR_GENERIC;
60*3d476de4SNicolas Le Bayon 	} else {
61*3d476de4SNicolas Le Bayon 		/* Make sure the above write is performed */
62*3d476de4SNicolas Le Bayon 		dsb();
63*3d476de4SNicolas Le Bayon 	}
64*3d476de4SNicolas Le Bayon 
65*3d476de4SNicolas Le Bayon 	return TEE_SUCCESS;
66*3d476de4SNicolas Le Bayon }
67*3d476de4SNicolas Le Bayon 
stm32_reset_assert(struct rstctrl * rstctrl,unsigned int to_us)68*3d476de4SNicolas Le Bayon static TEE_Result stm32_reset_assert(struct rstctrl *rstctrl,
69*3d476de4SNicolas Le Bayon 				     unsigned int to_us)
70*3d476de4SNicolas Le Bayon {
71*3d476de4SNicolas Le Bayon 	return stm32_reset_update(rstctrl, true, to_us);
72*3d476de4SNicolas Le Bayon }
73*3d476de4SNicolas Le Bayon 
stm32_reset_deassert(struct rstctrl * rstctrl,unsigned int to_us)74*3d476de4SNicolas Le Bayon static TEE_Result stm32_reset_deassert(struct rstctrl *rstctrl,
75*3d476de4SNicolas Le Bayon 				       unsigned int to_us)
76*3d476de4SNicolas Le Bayon {
77*3d476de4SNicolas Le Bayon 	return stm32_reset_update(rstctrl, false, to_us);
78*3d476de4SNicolas Le Bayon }
79*3d476de4SNicolas Le Bayon 
80*3d476de4SNicolas Le Bayon static const struct rstctrl_ops stm32_rstctrl_ops = {
81*3d476de4SNicolas Le Bayon 	.assert_level = stm32_reset_assert,
82*3d476de4SNicolas Le Bayon 	.deassert_level = stm32_reset_deassert,
83*3d476de4SNicolas Le Bayon };
84*3d476de4SNicolas Le Bayon 
85*3d476de4SNicolas Le Bayon #define STM32_RESET(id, _offset, _bit_index, _set_clr, _inverted, _no_deassert,\
86*3d476de4SNicolas Le Bayon 		    _no_timeout)\
87*3d476de4SNicolas Le Bayon 	[(id)] = &(struct stm32_reset_cfg){\
88*3d476de4SNicolas Le Bayon 		.offset		= (_offset),\
89*3d476de4SNicolas Le Bayon 		.bit_index	= (_bit_index),\
90*3d476de4SNicolas Le Bayon 		.set_clr	= (_set_clr),\
91*3d476de4SNicolas Le Bayon 		.inverted	= (_inverted),\
92*3d476de4SNicolas Le Bayon 		.no_deassert	= (_no_deassert),\
93*3d476de4SNicolas Le Bayon 		.no_timeout	= (_no_timeout),\
94*3d476de4SNicolas Le Bayon 	}
95*3d476de4SNicolas Le Bayon 
96*3d476de4SNicolas Le Bayon #define RST(id, _offset, _bit_index)\
97*3d476de4SNicolas Le Bayon 	STM32_RESET((id), (_offset), (_bit_index), false, false, false, false)
98*3d476de4SNicolas Le Bayon 
99*3d476de4SNicolas Le Bayon #define RST_SETR(id, _offset, _bit_index)\
100*3d476de4SNicolas Le Bayon 	STM32_RESET((id), (_offset), (_bit_index), true, false, false, false)
101*3d476de4SNicolas Le Bayon 
102*3d476de4SNicolas Le Bayon #define RST_INV(id, _offset, _bit_index)\
103*3d476de4SNicolas Le Bayon 	STM32_RESET((id), (_offset), (_bit_index), false, true, false, false)
104*3d476de4SNicolas Le Bayon 
105*3d476de4SNicolas Le Bayon #define RST_SETR_NO_DEASSERT(id, _offset, _bit_index)\
106*3d476de4SNicolas Le Bayon 	STM32_RESET((id), (_offset), (_bit_index), false, false, true, false)
107*3d476de4SNicolas Le Bayon 
108*3d476de4SNicolas Le Bayon #define RST_SETR_NO_DEASSERT_TIMEOUT(id, _offset, _bit_index)\
109*3d476de4SNicolas Le Bayon 	STM32_RESET((id), (_offset), (_bit_index), false, false, true, true)
110*3d476de4SNicolas Le Bayon 
111*3d476de4SNicolas Le Bayon static
112*3d476de4SNicolas Le Bayon const struct stm32_reset_cfg *stm32mp21_reset_cfg[STM32MP21_LAST_RESET] = {
113*3d476de4SNicolas Le Bayon 	RST(TIM1_R,		RCC_TIM1CFGR,		0),
114*3d476de4SNicolas Le Bayon 	RST(TIM2_R,		RCC_TIM2CFGR,		0),
115*3d476de4SNicolas Le Bayon 	RST(TIM3_R,		RCC_TIM3CFGR,		0),
116*3d476de4SNicolas Le Bayon 	RST(TIM4_R,		RCC_TIM4CFGR,		0),
117*3d476de4SNicolas Le Bayon 	RST(TIM5_R,		RCC_TIM5CFGR,		0),
118*3d476de4SNicolas Le Bayon 	RST(TIM6_R,		RCC_TIM6CFGR,		0),
119*3d476de4SNicolas Le Bayon 	RST(TIM7_R,		RCC_TIM7CFGR,		0),
120*3d476de4SNicolas Le Bayon 	RST(TIM8_R,		RCC_TIM8CFGR,		0),
121*3d476de4SNicolas Le Bayon 	RST(TIM10_R,		RCC_TIM10CFGR,		0),
122*3d476de4SNicolas Le Bayon 	RST(TIM11_R,		RCC_TIM11CFGR,		0),
123*3d476de4SNicolas Le Bayon 	RST(TIM12_R,		RCC_TIM12CFGR,		0),
124*3d476de4SNicolas Le Bayon 	RST(TIM13_R,		RCC_TIM13CFGR,		0),
125*3d476de4SNicolas Le Bayon 	RST(TIM14_R,		RCC_TIM14CFGR,		0),
126*3d476de4SNicolas Le Bayon 	RST(TIM15_R,		RCC_TIM15CFGR,		0),
127*3d476de4SNicolas Le Bayon 	RST(TIM16_R,		RCC_TIM16CFGR,		0),
128*3d476de4SNicolas Le Bayon 	RST(TIM17_R,		RCC_TIM17CFGR,		0),
129*3d476de4SNicolas Le Bayon 	RST(LPTIM1_R,		RCC_LPTIM1CFGR,		0),
130*3d476de4SNicolas Le Bayon 	RST(LPTIM2_R,		RCC_LPTIM2CFGR,		0),
131*3d476de4SNicolas Le Bayon 	RST(LPTIM3_R,		RCC_LPTIM3CFGR,		0),
132*3d476de4SNicolas Le Bayon 	RST(LPTIM4_R,		RCC_LPTIM4CFGR,		0),
133*3d476de4SNicolas Le Bayon 	RST(LPTIM5_R,		RCC_LPTIM5CFGR,		0),
134*3d476de4SNicolas Le Bayon 	RST(SPI1_R,		RCC_SPI1CFGR,		0),
135*3d476de4SNicolas Le Bayon 	RST(SPI2_R,		RCC_SPI2CFGR,		0),
136*3d476de4SNicolas Le Bayon 	RST(SPI3_R,		RCC_SPI3CFGR,		0),
137*3d476de4SNicolas Le Bayon 	RST(SPI4_R,		RCC_SPI4CFGR,		0),
138*3d476de4SNicolas Le Bayon 	RST(SPI5_R,		RCC_SPI5CFGR,		0),
139*3d476de4SNicolas Le Bayon 	RST(SPI6_R,		RCC_SPI6CFGR,		0),
140*3d476de4SNicolas Le Bayon 	RST(SPDIFRX_R,		RCC_SPDIFRXCFGR,	0),
141*3d476de4SNicolas Le Bayon 	RST(USART1_R,		RCC_USART1CFGR,		0),
142*3d476de4SNicolas Le Bayon 	RST(USART2_R,		RCC_USART2CFGR,		0),
143*3d476de4SNicolas Le Bayon 	RST(USART3_R,		RCC_USART3CFGR,		0),
144*3d476de4SNicolas Le Bayon 	RST(UART4_R,		RCC_UART4CFGR,		0),
145*3d476de4SNicolas Le Bayon 	RST(UART5_R,		RCC_UART5CFGR,		0),
146*3d476de4SNicolas Le Bayon 	RST(USART6_R,		RCC_USART6CFGR,		0),
147*3d476de4SNicolas Le Bayon 	RST(UART7_R,		RCC_UART7CFGR,		0),
148*3d476de4SNicolas Le Bayon 	RST(LPUART1_R,		RCC_LPUART1CFGR,	0),
149*3d476de4SNicolas Le Bayon 	RST(I2C1_R,		RCC_I2C1CFGR,		0),
150*3d476de4SNicolas Le Bayon 	RST(I2C2_R,		RCC_I2C2CFGR,		0),
151*3d476de4SNicolas Le Bayon 	RST(I2C3_R,		RCC_I2C3CFGR,		0),
152*3d476de4SNicolas Le Bayon 	RST(SAI1_R,		RCC_SAI1CFGR,		0),
153*3d476de4SNicolas Le Bayon 	RST(SAI2_R,		RCC_SAI2CFGR,		0),
154*3d476de4SNicolas Le Bayon 	RST(SAI3_R,		RCC_SAI3CFGR,		0),
155*3d476de4SNicolas Le Bayon 	RST(SAI4_R,		RCC_SAI4CFGR,		0),
156*3d476de4SNicolas Le Bayon 	RST(MDF1_R,		RCC_MDF1CFGR,		0),
157*3d476de4SNicolas Le Bayon 	RST(FDCAN_R,		RCC_FDCANCFGR,		0),
158*3d476de4SNicolas Le Bayon 	RST(HDP_R,		RCC_HDPCFGR,		0),
159*3d476de4SNicolas Le Bayon 	RST(ADC1_R,		RCC_ADC1CFGR,		0),
160*3d476de4SNicolas Le Bayon 	RST(ADC2_R,		RCC_ADC2CFGR,		0),
161*3d476de4SNicolas Le Bayon 	RST(ETH1_R,		RCC_ETH1CFGR,		0),
162*3d476de4SNicolas Le Bayon 	RST(ETH2_R,		RCC_ETH2CFGR,		0),
163*3d476de4SNicolas Le Bayon 	RST(USBH_R,		RCC_USBHCFGR,		0),
164*3d476de4SNicolas Le Bayon 	RST(OTG_R,		RCC_OTGCFGR,		0),
165*3d476de4SNicolas Le Bayon 	RST(USB2PHY1_R,		RCC_USB2PHY1CFGR,	0),
166*3d476de4SNicolas Le Bayon 	RST(USB2PHY2_R,		RCC_USB2PHY2CFGR,	0),
167*3d476de4SNicolas Le Bayon 	RST(SDMMC1_R,		RCC_SDMMC1CFGR,		0),
168*3d476de4SNicolas Le Bayon 	RST(SDMMC1DLL_R,	RCC_SDMMC1CFGR,		16),
169*3d476de4SNicolas Le Bayon 	RST(SDMMC2_R,		RCC_SDMMC2CFGR,		0),
170*3d476de4SNicolas Le Bayon 	RST(SDMMC2DLL_R,	RCC_SDMMC2CFGR,		16),
171*3d476de4SNicolas Le Bayon 	RST(SDMMC3_R,		RCC_SDMMC3CFGR,		0),
172*3d476de4SNicolas Le Bayon 	RST(SDMMC3DLL_R,	RCC_SDMMC3CFGR,		16),
173*3d476de4SNicolas Le Bayon 	RST(LTDC_R,		RCC_LTDCCFGR,		0),
174*3d476de4SNicolas Le Bayon 	RST(CSI_R,		RCC_CSICFGR,		0),
175*3d476de4SNicolas Le Bayon 	RST(DCMIPP_R,		RCC_DCMIPPCFGR,		0),
176*3d476de4SNicolas Le Bayon 	RST(DCMIPSSI_R,		RCC_DCMIPSSICFGR,	0),
177*3d476de4SNicolas Le Bayon 	RST(WWDG1_R,		RCC_WWDG1CFGR,		0),
178*3d476de4SNicolas Le Bayon 	RST(VREF_R,		RCC_VREFCFGR,		0),
179*3d476de4SNicolas Le Bayon 	RST(DTS_R,		RCC_DTSCFGR,		0),
180*3d476de4SNicolas Le Bayon 	RST(CRC_R,		RCC_CRCCFGR,		0),
181*3d476de4SNicolas Le Bayon 	RST(SERC_R,		RCC_SERCCFGR,		0),
182*3d476de4SNicolas Le Bayon 	RST(I3C1_R,		RCC_I3C1CFGR,		0),
183*3d476de4SNicolas Le Bayon 	RST(I3C2_R,		RCC_I3C2CFGR,		0),
184*3d476de4SNicolas Le Bayon 	RST(I3C3_R,		RCC_I3C3CFGR,		0),
185*3d476de4SNicolas Le Bayon 	RST(RNG1_R,		RCC_RNG1CFGR,		0),
186*3d476de4SNicolas Le Bayon 	RST(RNG2_R,		RCC_RNG2CFGR,		0),
187*3d476de4SNicolas Le Bayon 	RST(PKA_R,		RCC_PKACFGR,		0),
188*3d476de4SNicolas Le Bayon 	RST(SAES_R,		RCC_SAESCFGR,		0),
189*3d476de4SNicolas Le Bayon 	RST(HASH1_R,		RCC_HASH1CFGR,		0),
190*3d476de4SNicolas Le Bayon 	RST(HASH2_R,		RCC_HASH2CFGR,		0),
191*3d476de4SNicolas Le Bayon 	RST(CRYP1_R,		RCC_CRYP1CFGR,		0),
192*3d476de4SNicolas Le Bayon 	RST(CRYP2_R,		RCC_CRYP2CFGR,		0),
193*3d476de4SNicolas Le Bayon 	RST(OSPI1_R,		RCC_OSPI1CFGR,		0),
194*3d476de4SNicolas Le Bayon 	RST(OSPI1DLL_R,		RCC_OSPI1CFGR,		16),
195*3d476de4SNicolas Le Bayon 	RST(DBG_R,		RCC_DBGCFGR,		12),
196*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG2_KER_R,	RCC_IWDGC1CFGSETR,	18),
197*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG4_KER_R,	RCC_IWDGC2CFGSETR,	18),
198*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG1_SYS_R,	RCC_IWDGC1CFGSETR,	0),
199*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG2_SYS_R,	RCC_IWDGC1CFGSETR,	2),
200*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG3_SYS_R,	RCC_IWDGC2CFGSETR,	0),
201*3d476de4SNicolas Le Bayon 	RST_SETR(IWDG4_SYS_R,	RCC_IWDGC2CFGSETR,	2),
202*3d476de4SNicolas Le Bayon 
203*3d476de4SNicolas Le Bayon 	RST_INV(C2_HOLDBOOT_R,	RCC_CPUBOOTCR,		0),
204*3d476de4SNicolas Le Bayon 	RST_INV(C1_HOLDBOOT_R,	RCC_CPUBOOTCR,		1),
205*3d476de4SNicolas Le Bayon 	RST_SETR_NO_DEASSERT_TIMEOUT(C1_R,	RCC_C1RSTCSETR,		0),
206*3d476de4SNicolas Le Bayon 	RST_SETR_NO_DEASSERT_TIMEOUT(C2_R,	RCC_C2RSTCSETR,		0),
207*3d476de4SNicolas Le Bayon 	RST_SETR_NO_DEASSERT_TIMEOUT(SYS_R,	RCC_GRSTCSETR,		0),
208*3d476de4SNicolas Le Bayon 
209*3d476de4SNicolas Le Bayon 	/*
210*3d476de4SNicolas Le Bayon 	 * Don't manage reset lines of RIF aware resources
211*3d476de4SNicolas Le Bayon 	 * DDRCP_R, DDRCAPB_R, DDRPHYCAPB_R, DDRCFG_R, DDR_R,
212*3d476de4SNicolas Le Bayon 	 * IPCC1_R,
213*3d476de4SNicolas Le Bayon 	 * HPDMA1_R, HPDMA2_R, HPDMA3_R,
214*3d476de4SNicolas Le Bayon 	 * GPIOA_R, GPIOB_R, GPIOC_R, GPIOD_R,
215*3d476de4SNicolas Le Bayon 	 * GPIOE_R, GPIOF_R, GPIOG_R, GPIOH_R,
216*3d476de4SNicolas Le Bayon 	 * GPIOI_R, GPIOZ_R,
217*3d476de4SNicolas Le Bayon 	 * FMC_R,
218*3d476de4SNicolas Le Bayon 	 */
219*3d476de4SNicolas Le Bayon };
220*3d476de4SNicolas Le Bayon 
stm32_reset_get_ops(unsigned int id __unused)221*3d476de4SNicolas Le Bayon static const struct rstctrl_ops *stm32_reset_get_ops(unsigned int id __unused)
222*3d476de4SNicolas Le Bayon {
223*3d476de4SNicolas Le Bayon 	return &stm32_rstctrl_ops;
224*3d476de4SNicolas Le Bayon }
225*3d476de4SNicolas Le Bayon 
226*3d476de4SNicolas Le Bayon static const struct stm32_reset_data stm32mp21_reset_data = {
227*3d476de4SNicolas Le Bayon 	.nb_lines = ARRAY_SIZE(stm32mp21_reset_cfg),
228*3d476de4SNicolas Le Bayon 	.rst_lines = stm32mp21_reset_cfg,
229*3d476de4SNicolas Le Bayon 	.get_rstctrl_ops = stm32_reset_get_ops,
230*3d476de4SNicolas Le Bayon };
231*3d476de4SNicolas Le Bayon 
232*3d476de4SNicolas Le Bayon static const struct dt_device_match stm32_rstctrl_match_table[] = {
233*3d476de4SNicolas Le Bayon 	{
234*3d476de4SNicolas Le Bayon 		.compatible = "st,stm32mp21-rcc",
235*3d476de4SNicolas Le Bayon 		.compat_data = &stm32mp21_reset_data,
236*3d476de4SNicolas Le Bayon 	},
237*3d476de4SNicolas Le Bayon 	{ }
238*3d476de4SNicolas Le Bayon };
239*3d476de4SNicolas Le Bayon 
240*3d476de4SNicolas Le Bayon DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = {
241*3d476de4SNicolas Le Bayon 	.name = "stm32_rstctrl",
242*3d476de4SNicolas Le Bayon 	.type = DT_DRIVER_RSTCTRL,
243*3d476de4SNicolas Le Bayon 	.match_table = stm32_rstctrl_match_table,
244*3d476de4SNicolas Le Bayon 	.probe = stm32_rstctrl_provider_probe,
245*3d476de4SNicolas Le Bayon };
246