xref: /freebsd/sys/dev/clk/xilinx/zynqmp_reset.c (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25  * SUCH DAMAGE.
26  */
27 
28 #include <sys/cdefs.h>
29 
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/kernel.h>
33 #include <sys/module.h>
34 #include <sys/malloc.h>
35 #include <sys/bus.h>
36 #include <sys/cpu.h>
37 #include <machine/bus.h>
38 
39 #include <dev/ofw/openfirm.h>
40 #include <dev/ofw/ofw_bus.h>
41 #include <dev/ofw/ofw_bus_subr.h>
42 
43 #include <dev/hwreset/hwreset.h>
44 
45 #include <dev/firmware/xilinx/pm_defs.h>
46 
47 #include "hwreset_if.h"
48 #include "zynqmp_firmware_if.h"
49 
50 #define	ZYNQMP_RESET_PCIE_CFG		0
51 #define	ZYNQMP_RESET_PCIE_BRIDGE	1
52 #define	ZYNQMP_RESET_PCIE_CTRL		2
53 #define	ZYNQMP_RESET_DP			3
54 #define	ZYNQMP_RESET_SWDT_CRF		4
55 #define	ZYNQMP_RESET_AFI_FM5		5
56 #define	ZYNQMP_RESET_AFI_FM4		6
57 #define	ZYNQMP_RESET_AFI_FM3		7
58 #define	ZYNQMP_RESET_AFI_FM2		8
59 #define	ZYNQMP_RESET_AFI_FM1		9
60 #define	ZYNQMP_RESET_AFI_FM0		10
61 #define	ZYNQMP_RESET_GDMA		11
62 #define	ZYNQMP_RESET_GPU_PP1		12
63 #define	ZYNQMP_RESET_GPU_PP0		13
64 #define	ZYNQMP_RESET_GPU		14
65 #define	ZYNQMP_RESET_GT			15
66 #define	ZYNQMP_RESET_SATA		16
67 #define	ZYNQMP_RESET_ACPU3_PWRON	17
68 #define	ZYNQMP_RESET_ACPU2_PWRON	18
69 #define	ZYNQMP_RESET_ACPU1_PWRON	19
70 #define	ZYNQMP_RESET_ACPU0_PWRON	20
71 #define	ZYNQMP_RESET_APU_L2		21
72 #define	ZYNQMP_RESET_ACPU3		22
73 #define	ZYNQMP_RESET_ACPU2		23
74 #define	ZYNQMP_RESET_ACPU1		24
75 #define	ZYNQMP_RESET_ACPU0		25
76 #define	ZYNQMP_RESET_DDR		26
77 #define	ZYNQMP_RESET_APM_FPD		27
78 #define	ZYNQMP_RESET_SOFT		28
79 #define	ZYNQMP_RESET_GEM0		29
80 #define	ZYNQMP_RESET_GEM1		30
81 #define	ZYNQMP_RESET_GEM2		31
82 #define	ZYNQMP_RESET_GEM3		32
83 #define	ZYNQMP_RESET_QSPI		33
84 #define	ZYNQMP_RESET_UART0		34
85 #define	ZYNQMP_RESET_UART1		35
86 #define	ZYNQMP_RESET_SPI0		36
87 #define	ZYNQMP_RESET_SPI1		37
88 #define	ZYNQMP_RESET_SDIO0		38
89 #define	ZYNQMP_RESET_SDIO1		39
90 #define	ZYNQMP_RESET_CAN0		40
91 #define	ZYNQMP_RESET_CAN1		41
92 #define	ZYNQMP_RESET_I2C0		42
93 #define	ZYNQMP_RESET_I2C1		43
94 #define	ZYNQMP_RESET_TTC0		44
95 #define	ZYNQMP_RESET_TTC1		45
96 #define	ZYNQMP_RESET_TTC2		46
97 #define	ZYNQMP_RESET_TTC3		47
98 #define	ZYNQMP_RESET_SWDT_CRL		48
99 #define	ZYNQMP_RESET_NAND		49
100 #define	ZYNQMP_RESET_ADMA		50
101 #define	ZYNQMP_RESET_GPIO		51
102 #define	ZYNQMP_RESET_IOU_CC		52
103 #define	ZYNQMP_RESET_TIMESTAMP		53
104 #define	ZYNQMP_RESET_RPU_R50		54
105 #define	ZYNQMP_RESET_RPU_R51		55
106 #define	ZYNQMP_RESET_RPU_AMBA		56
107 #define	ZYNQMP_RESET_OCM		57
108 #define	ZYNQMP_RESET_RPU_PGE		58
109 #define	ZYNQMP_RESET_USB0_CORERESET	59
110 #define	ZYNQMP_RESET_USB1_CORERESET	60
111 #define	ZYNQMP_RESET_USB0_HIBERRESET	61
112 #define	ZYNQMP_RESET_USB1_HIBERRESET	62
113 #define	ZYNQMP_RESET_USB0_APB		63
114 #define	ZYNQMP_RESET_USB1_APB		64
115 #define	ZYNQMP_RESET_IPI		65
116 #define	ZYNQMP_RESET_APM_LPD		66
117 #define	ZYNQMP_RESET_RTC		67
118 #define	ZYNQMP_RESET_SYSMON		68
119 #define	ZYNQMP_RESET_AFI_FM6		69
120 #define	ZYNQMP_RESET_LPD_SWDT		70
121 #define	ZYNQMP_RESET_FPD		71
122 #define	ZYNQMP_RESET_RPU_DBG1		72
123 #define	ZYNQMP_RESET_RPU_DBG0		73
124 #define	ZYNQMP_RESET_DBG_LPD		74
125 #define	ZYNQMP_RESET_DBG_FPD		75
126 #define	ZYNQMP_RESET_APLL		76
127 #define	ZYNQMP_RESET_DPLL		77
128 #define	ZYNQMP_RESET_VPLL		78
129 #define	ZYNQMP_RESET_IOPLL		79
130 #define	ZYNQMP_RESET_RPLL		80
131 #define	ZYNQMP_RESET_GPO3_PL_0		81
132 #define	ZYNQMP_RESET_GPO3_PL_1		82
133 #define	ZYNQMP_RESET_GPO3_PL_2		83
134 #define	ZYNQMP_RESET_GPO3_PL_3		84
135 #define	ZYNQMP_RESET_GPO3_PL_4		85
136 #define	ZYNQMP_RESET_GPO3_PL_5		86
137 #define	ZYNQMP_RESET_GPO3_PL_6		87
138 #define	ZYNQMP_RESET_GPO3_PL_7		88
139 #define	ZYNQMP_RESET_GPO3_PL_8		89
140 #define	ZYNQMP_RESET_GPO3_PL_9		90
141 #define	ZYNQMP_RESET_GPO3_PL_10		91
142 #define	ZYNQMP_RESET_GPO3_PL_11		92
143 #define	ZYNQMP_RESET_GPO3_PL_12		93
144 #define	ZYNQMP_RESET_GPO3_PL_13		94
145 #define	ZYNQMP_RESET_GPO3_PL_14		95
146 #define	ZYNQMP_RESET_GPO3_PL_15		96
147 #define	ZYNQMP_RESET_GPO3_PL_16		97
148 #define	ZYNQMP_RESET_GPO3_PL_17		98
149 #define	ZYNQMP_RESET_GPO3_PL_18		99
150 #define	ZYNQMP_RESET_GPO3_PL_19		100
151 #define	ZYNQMP_RESET_GPO3_PL_20		101
152 #define	ZYNQMP_RESET_GPO3_PL_21		102
153 #define	ZYNQMP_RESET_GPO3_PL_22		103
154 #define	ZYNQMP_RESET_GPO3_PL_23		104
155 #define	ZYNQMP_RESET_GPO3_PL_24		105
156 #define	ZYNQMP_RESET_GPO3_PL_25		106
157 #define	ZYNQMP_RESET_GPO3_PL_26		107
158 #define	ZYNQMP_RESET_GPO3_PL_27		108
159 #define	ZYNQMP_RESET_GPO3_PL_28		109
160 #define	ZYNQMP_RESET_GPO3_PL_29		110
161 #define	ZYNQMP_RESET_GPO3_PL_30		111
162 #define	ZYNQMP_RESET_GPO3_PL_31		112
163 #define	ZYNQMP_RESET_RPU_LS		113
164 #define	ZYNQMP_RESET_PS_ONLY		114
165 #define	ZYNQMP_RESET_PL			115
166 #define	ZYNQMP_RESET_PS_PL0		116
167 #define	ZYNQMP_RESET_PS_PL1		117
168 #define	ZYNQMP_RESET_PS_PL2		118
169 #define	ZYNQMP_RESET_PS_PL3		119
170 #define	ZYNQMP_RESET_MAX		ZYNQMP_RESET_PS_PL3
171 
172 struct zynqmp_reset_softc {
173 	device_t	dev;
174 	device_t	parent;
175 };
176 
177 static int
178 zynqmp_reset_assert(device_t dev, intptr_t id, bool reset)
179 {
180 	struct zynqmp_reset_softc *sc;
181 	int rv;
182 
183 	if (id > ZYNQMP_RESET_MAX)
184 		return (EINVAL);
185 	sc = device_get_softc(dev);
186 	rv = ZYNQMP_FIRMWARE_RESET_ASSERT(sc->parent, id, reset);
187 	return (rv);
188 }
189 
190 static int
191 zynqmp_reset_is_asserted(device_t dev, intptr_t id, bool *reset)
192 {
193 	struct zynqmp_reset_softc *sc;
194 	int rv;
195 
196 	if (id > ZYNQMP_RESET_MAX)
197 		return (EINVAL);
198 	sc = device_get_softc(dev);
199 	rv = ZYNQMP_FIRMWARE_RESET_GET_STATUS(sc->parent, id, reset);
200 
201 	return (rv);
202 }
203 
204 static int
205 zynqmp_reset_probe(device_t dev)
206 {
207 
208 	if (!ofw_bus_status_okay(dev))
209 		return (ENXIO);
210 	if (!ofw_bus_is_compatible(dev, "xlnx,zynqmp-reset"))
211 		return (ENXIO);
212 	device_set_desc(dev, "ZynqMP Reset Controller");
213 
214 	return (BUS_PROBE_DEFAULT);
215 }
216 
217 static int
218 zynqmp_reset_attach(device_t dev)
219 {
220 	struct zynqmp_reset_softc *sc;
221 
222 	sc = device_get_softc(dev);
223 	sc->dev = dev;
224 	sc->parent = device_get_parent(dev);
225 
226 	/* register our self as a reset provider */
227 	hwreset_register_ofw_provider(dev);
228 
229 	return (0);
230 }
231 
232 static device_method_t zynqmp_reset_methods[] = {
233 	/* device_if */
234 	DEVMETHOD(device_probe, 	zynqmp_reset_probe),
235 	DEVMETHOD(device_attach, 	zynqmp_reset_attach),
236 
237 	/* Reset interface */
238 	DEVMETHOD(hwreset_assert,	zynqmp_reset_assert),
239 	DEVMETHOD(hwreset_is_asserted,	zynqmp_reset_is_asserted),
240 
241 	DEVMETHOD_END
242 };
243 
244 static driver_t zynqmp_reset_driver = {
245 	"zynqmp_reset",
246 	zynqmp_reset_methods,
247 	sizeof(struct zynqmp_reset_softc),
248 };
249 
250 EARLY_DRIVER_MODULE(zynqmp_reset, simplebus, zynqmp_reset_driver, 0, 0,
251     BUS_PASS_BUS + BUS_PASS_ORDER_LAST);
252