xref: /optee_os/core/drivers/rstctrl/stm32mp1_rstctrl.c (revision 9f34db38245c9b3a4e6e7e63eb78a75e23ab2da3)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright (c) 2021-2022, Linaro Limited
4  * Copyright (c) 2018-2024, STMicroelectronics
5  */
6 
7 #include <arm.h>
8 #include <drivers/rstctrl.h>
9 #include <drivers/stm32mp1_rcc.h>
10 #include <drivers/stm32mp_dt_bindings.h>
11 #include <io.h>
12 #include <keep.h>
13 #include <kernel/dt.h>
14 #include <kernel/dt_driver.h>
15 #include <stm32_util.h>
16 
17 #include "stm32_rstctrl.h"
18 
19 #define RESET_ID_MASK		GENMASK_32(31, 5)
20 #define RESET_ID_SHIFT		U(5)
21 #define RESET_BIT_POS_MASK	GENMASK_32(4, 0)
22 #define RESET_OFFSET_MAX	U(1024)
23 
24 static size_t reset_id2reg_offset(unsigned int id)
25 {
26 	size_t offset = (id & RESET_ID_MASK) >> RESET_ID_SHIFT;
27 
28 	assert(offset < RESET_OFFSET_MAX);
29 	return offset * sizeof(uint32_t);
30 }
31 
32 static uint32_t reset_id2reg_bit_pos(unsigned int reset_id)
33 {
34 	uint32_t pos = reset_id & RESET_BIT_POS_MASK;
35 
36 	assert(pos < 32);
37 	return pos;
38 }
39 
40 static TEE_Result reset_assert(struct rstctrl *rstctrl, unsigned int to_us)
41 {
42 	unsigned int id = to_stm32_rstline(rstctrl)->id;
43 	vaddr_t rcc_base = stm32_rcc_base();
44 	uint32_t bit_mask = 0;
45 	size_t offset = 0;
46 
47 #ifdef CFG_STM32MP15
48 	switch (id) {
49 	case MCU_HOLD_BOOT_R:
50 		/*
51 		 * The RCC_MP_GCR is a read/write register.
52 		 * Assert the MCU HOLD_BOOT means clear the BOOT_MCU bit
53 		 */
54 		io_clrbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
55 
56 		return TEE_SUCCESS;
57 	case MCU_R:
58 		/* MCU reset can only be written */
59 		to_us = 0;
60 		break;
61 	default:
62 		break;
63 	}
64 #endif
65 
66 	offset = reset_id2reg_offset(id);
67 	bit_mask = BIT(reset_id2reg_bit_pos(id));
68 
69 	io_write32(rcc_base + offset, bit_mask);
70 
71 	if (to_us) {
72 		uint32_t value = 0;
73 
74 		if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value,
75 					   value & bit_mask, 0, to_us))
76 			return TEE_ERROR_GENERIC;
77 	} else {
78 		/* Make sure the above write is performed */
79 		dsb();
80 	}
81 
82 	return TEE_SUCCESS;
83 }
84 
85 static TEE_Result reset_deassert(struct rstctrl *rstctrl, unsigned int to_us)
86 {
87 	unsigned int id = to_stm32_rstline(rstctrl)->id;
88 	vaddr_t rcc_base = stm32_rcc_base();
89 	uint32_t bit_mask = 0;
90 	size_t offset = 0;
91 
92 #ifdef CFG_STM32MP15
93 	switch (id) {
94 	case MCU_HOLD_BOOT_R:
95 		/*
96 		 * The RCC_MP_GCR is a read/write register.
97 		 * Deassert the MCU HOLD_BOOT means set the BOOT_MCU the bit
98 		 */
99 		io_setbits32(rcc_base + RCC_MP_GCR, RCC_MP_GCR_BOOT_MCU);
100 
101 		return TEE_SUCCESS;
102 	case MCU_R:
103 		/* MCU reset deasserts by its own */
104 		return TEE_SUCCESS;
105 	default:
106 		break;
107 	}
108 #endif
109 
110 	offset = reset_id2reg_offset(id) + RCC_MP_RSTCLRR_OFFSET;
111 	bit_mask = BIT(reset_id2reg_bit_pos(id));
112 
113 	io_write32(rcc_base + offset, bit_mask);
114 
115 	if (to_us) {
116 		uint32_t value = 0;
117 
118 		if (IO_READ32_POLL_TIMEOUT(rcc_base + offset, value,
119 					   !(value & bit_mask), 0, to_us))
120 			return TEE_ERROR_GENERIC;
121 	} else {
122 		/* Make sure the above write is performed */
123 		dsb();
124 	}
125 
126 	return TEE_SUCCESS;
127 }
128 
129 static const struct rstctrl_ops stm32_rstctrl_ops = {
130 	.assert_level = reset_assert,
131 	.deassert_level = reset_deassert,
132 };
133 DECLARE_KEEP_PAGER(stm32_rstctrl_ops);
134 
135 static const struct rstctrl_ops *stm32_reset_get_ops(unsigned int id __unused)
136 {
137 	return &stm32_rstctrl_ops;
138 }
139 
140 static const struct stm32_reset_data stm32mp1_reset_data = {
141 	.get_rstctrl_ops = stm32_reset_get_ops
142 };
143 DECLARE_KEEP_PAGER(stm32mp1_reset_data);
144 
145 static const struct dt_device_match stm32_rstctrl_match_table[] = {
146 	{
147 		.compatible = "st,stm32mp1-rcc",
148 		.compat_data = &stm32mp1_reset_data,
149 	},
150 	{
151 		.compatible = "st,stm32mp1-rcc-secure",
152 		.compat_data = &stm32mp1_reset_data,
153 	},
154 	{
155 		.compatible = "st,stm32mp13-rcc",
156 		.compat_data = &stm32mp1_reset_data,
157 	},
158 	{ }
159 };
160 
161 DEFINE_DT_DRIVER(stm32_rstctrl_dt_driver) = {
162 	.name = "stm32_rstctrl",
163 	.type = DT_DRIVER_RSTCTRL,
164 	.match_table = stm32_rstctrl_match_table,
165 	.probe = stm32_rstctrl_provider_probe,
166 };
167