xref: /freebsd/sys/dev/clk/xilinx/zynqmp_reset.c (revision 1f469a9fc498c3d406ef7c4e347232678f49da0a)
14e579ad0SEmmanuel Vadot /*-
24e579ad0SEmmanuel Vadot  * SPDX-License-Identifier: BSD-2-Clause
34e579ad0SEmmanuel Vadot  *
44e579ad0SEmmanuel Vadot  * Copyright (c) 2023 Beckhoff Automation GmbH & Co. KG
54e579ad0SEmmanuel Vadot  *
64e579ad0SEmmanuel Vadot  * Redistribution and use in source and binary forms, with or without
74e579ad0SEmmanuel Vadot  * modification, are permitted provided that the following conditions
84e579ad0SEmmanuel Vadot  * are met:
94e579ad0SEmmanuel Vadot  * 1. Redistributions of source code must retain the above copyright
104e579ad0SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer.
114e579ad0SEmmanuel Vadot  * 2. Redistributions in binary form must reproduce the above copyright
124e579ad0SEmmanuel Vadot  *    notice, this list of conditions and the following disclaimer in the
134e579ad0SEmmanuel Vadot  *    documentation and/or other materials provided with the distribution.
144e579ad0SEmmanuel Vadot  *
154e579ad0SEmmanuel Vadot  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
164e579ad0SEmmanuel Vadot  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
174e579ad0SEmmanuel Vadot  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
184e579ad0SEmmanuel Vadot  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
194e579ad0SEmmanuel Vadot  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
204e579ad0SEmmanuel Vadot  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
214e579ad0SEmmanuel Vadot  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
224e579ad0SEmmanuel Vadot  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
234e579ad0SEmmanuel Vadot  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
244e579ad0SEmmanuel Vadot  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
254e579ad0SEmmanuel Vadot  * SUCH DAMAGE.
264e579ad0SEmmanuel Vadot  */
274e579ad0SEmmanuel Vadot 
284e579ad0SEmmanuel Vadot #include <sys/cdefs.h>
294e579ad0SEmmanuel Vadot 
304e579ad0SEmmanuel Vadot #include <sys/param.h>
314e579ad0SEmmanuel Vadot #include <sys/systm.h>
324e579ad0SEmmanuel Vadot #include <sys/kernel.h>
334e579ad0SEmmanuel Vadot #include <sys/module.h>
344e579ad0SEmmanuel Vadot #include <sys/malloc.h>
354e579ad0SEmmanuel Vadot #include <sys/bus.h>
364e579ad0SEmmanuel Vadot #include <sys/cpu.h>
374e579ad0SEmmanuel Vadot #include <machine/bus.h>
384e579ad0SEmmanuel Vadot 
394e579ad0SEmmanuel Vadot #include <dev/ofw/openfirm.h>
404e579ad0SEmmanuel Vadot #include <dev/ofw/ofw_bus.h>
414e579ad0SEmmanuel Vadot #include <dev/ofw/ofw_bus_subr.h>
424e579ad0SEmmanuel Vadot 
43*1f469a9fSEmmanuel Vadot #include <dev/hwreset/hwreset.h>
444e579ad0SEmmanuel Vadot 
454e579ad0SEmmanuel Vadot #include <dev/firmware/xilinx/pm_defs.h>
464e579ad0SEmmanuel Vadot 
474e579ad0SEmmanuel Vadot #include "hwreset_if.h"
484e579ad0SEmmanuel Vadot #include "zynqmp_firmware_if.h"
494e579ad0SEmmanuel Vadot 
504e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PCIE_CFG		0
514e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PCIE_BRIDGE	1
524e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PCIE_CTRL		2
534e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_DP			3
544e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SWDT_CRF		4
554e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM5		5
564e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM4		6
574e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM3		7
584e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM2		8
594e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM1		9
604e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM0		10
614e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GDMA		11
624e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPU_PP1		12
634e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPU_PP0		13
644e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPU		14
654e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GT			15
664e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SATA		16
674e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU3_PWRON	17
684e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU2_PWRON	18
694e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU1_PWRON	19
704e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU0_PWRON	20
714e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_APU_L2		21
724e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU3		22
734e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU2		23
744e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU1		24
754e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ACPU0		25
764e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_DDR		26
774e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_APM_FPD		27
784e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SOFT		28
794e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GEM0		29
804e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GEM1		30
814e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GEM2		31
824e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GEM3		32
834e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_QSPI		33
844e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_UART0		34
854e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_UART1		35
864e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SPI0		36
874e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SPI1		37
884e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SDIO0		38
894e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SDIO1		39
904e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_CAN0		40
914e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_CAN1		41
924e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_I2C0		42
934e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_I2C1		43
944e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_TTC0		44
954e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_TTC1		45
964e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_TTC2		46
974e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_TTC3		47
984e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SWDT_CRL		48
994e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_NAND		49
1004e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_ADMA		50
1014e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPIO		51
1024e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_IOU_CC		52
1034e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_TIMESTAMP		53
1044e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_R50		54
1054e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_R51		55
1064e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_AMBA		56
1074e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_OCM		57
1084e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_PGE		58
1094e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB0_CORERESET	59
1104e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB1_CORERESET	60
1114e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB0_HIBERRESET	61
1124e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB1_HIBERRESET	62
1134e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB0_APB		63
1144e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_USB1_APB		64
1154e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_IPI		65
1164e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_APM_LPD		66
1174e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RTC		67
1184e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_SYSMON		68
1194e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_AFI_FM6		69
1204e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_LPD_SWDT		70
1214e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_FPD		71
1224e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_DBG1		72
1234e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_DBG0		73
1244e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_DBG_LPD		74
1254e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_DBG_FPD		75
1264e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_APLL		76
1274e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_DPLL		77
1284e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_VPLL		78
1294e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_IOPLL		79
1304e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPLL		80
1314e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_0		81
1324e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_1		82
1334e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_2		83
1344e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_3		84
1354e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_4		85
1364e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_5		86
1374e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_6		87
1384e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_7		88
1394e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_8		89
1404e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_9		90
1414e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_10		91
1424e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_11		92
1434e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_12		93
1444e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_13		94
1454e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_14		95
1464e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_15		96
1474e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_16		97
1484e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_17		98
1494e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_18		99
1504e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_19		100
1514e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_20		101
1524e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_21		102
1534e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_22		103
1544e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_23		104
1554e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_24		105
1564e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_25		106
1574e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_26		107
1584e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_27		108
1594e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_28		109
1604e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_29		110
1614e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_30		111
1624e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_GPO3_PL_31		112
1634e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_RPU_LS		113
1644e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PS_ONLY		114
1654e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PL			115
1664e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PS_PL0		116
1674e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PS_PL1		117
1684e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PS_PL2		118
1694e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_PS_PL3		119
1704e579ad0SEmmanuel Vadot #define	ZYNQMP_RESET_MAX		ZYNQMP_RESET_PS_PL3
1714e579ad0SEmmanuel Vadot 
1724e579ad0SEmmanuel Vadot struct zynqmp_reset_softc {
1734e579ad0SEmmanuel Vadot 	device_t	dev;
1744e579ad0SEmmanuel Vadot 	device_t	parent;
1754e579ad0SEmmanuel Vadot };
1764e579ad0SEmmanuel Vadot 
1774e579ad0SEmmanuel Vadot static int
zynqmp_reset_assert(device_t dev,intptr_t id,bool reset)1784e579ad0SEmmanuel Vadot zynqmp_reset_assert(device_t dev, intptr_t id, bool reset)
1794e579ad0SEmmanuel Vadot {
1804e579ad0SEmmanuel Vadot 	struct zynqmp_reset_softc *sc;
1814e579ad0SEmmanuel Vadot 	int rv;
1824e579ad0SEmmanuel Vadot 
1834e579ad0SEmmanuel Vadot 	if (id > ZYNQMP_RESET_MAX)
1844e579ad0SEmmanuel Vadot 		return (EINVAL);
1854e579ad0SEmmanuel Vadot 	sc = device_get_softc(dev);
1864e579ad0SEmmanuel Vadot 	rv = ZYNQMP_FIRMWARE_RESET_ASSERT(sc->parent, id, reset);
1874e579ad0SEmmanuel Vadot 	return (rv);
1884e579ad0SEmmanuel Vadot }
1894e579ad0SEmmanuel Vadot 
1904e579ad0SEmmanuel Vadot static int
zynqmp_reset_is_asserted(device_t dev,intptr_t id,bool * reset)1914e579ad0SEmmanuel Vadot zynqmp_reset_is_asserted(device_t dev, intptr_t id, bool *reset)
1924e579ad0SEmmanuel Vadot {
1934e579ad0SEmmanuel Vadot 	struct zynqmp_reset_softc *sc;
1944e579ad0SEmmanuel Vadot 	int rv;
1954e579ad0SEmmanuel Vadot 
1964e579ad0SEmmanuel Vadot 	if (id > ZYNQMP_RESET_MAX)
1974e579ad0SEmmanuel Vadot 		return (EINVAL);
1984e579ad0SEmmanuel Vadot 	sc = device_get_softc(dev);
1994e579ad0SEmmanuel Vadot 	rv = ZYNQMP_FIRMWARE_RESET_GET_STATUS(sc->parent, id, reset);
2004e579ad0SEmmanuel Vadot 
2014e579ad0SEmmanuel Vadot 	return (rv);
2024e579ad0SEmmanuel Vadot }
2034e579ad0SEmmanuel Vadot 
2044e579ad0SEmmanuel Vadot static int
zynqmp_reset_probe(device_t dev)2054e579ad0SEmmanuel Vadot zynqmp_reset_probe(device_t dev)
2064e579ad0SEmmanuel Vadot {
2074e579ad0SEmmanuel Vadot 
2084e579ad0SEmmanuel Vadot 	if (!ofw_bus_status_okay(dev))
2094e579ad0SEmmanuel Vadot 		return (ENXIO);
2104e579ad0SEmmanuel Vadot 	if (!ofw_bus_is_compatible(dev, "xlnx,zynqmp-reset"))
2114e579ad0SEmmanuel Vadot 		return (ENXIO);
2124e579ad0SEmmanuel Vadot 	device_set_desc(dev, "ZynqMP Reset Controller");
2134e579ad0SEmmanuel Vadot 
2144e579ad0SEmmanuel Vadot 	return (BUS_PROBE_DEFAULT);
2154e579ad0SEmmanuel Vadot }
2164e579ad0SEmmanuel Vadot 
2174e579ad0SEmmanuel Vadot static int
zynqmp_reset_attach(device_t dev)2184e579ad0SEmmanuel Vadot zynqmp_reset_attach(device_t dev)
2194e579ad0SEmmanuel Vadot {
2204e579ad0SEmmanuel Vadot 	struct zynqmp_reset_softc *sc;
2214e579ad0SEmmanuel Vadot 
2224e579ad0SEmmanuel Vadot 	sc = device_get_softc(dev);
2234e579ad0SEmmanuel Vadot 	sc->dev = dev;
2244e579ad0SEmmanuel Vadot 	sc->parent = device_get_parent(dev);
2254e579ad0SEmmanuel Vadot 
2264e579ad0SEmmanuel Vadot 	/* register our self as a reset provider */
2274e579ad0SEmmanuel Vadot 	hwreset_register_ofw_provider(dev);
2284e579ad0SEmmanuel Vadot 
2294e579ad0SEmmanuel Vadot 	return (0);
2304e579ad0SEmmanuel Vadot }
2314e579ad0SEmmanuel Vadot 
2324e579ad0SEmmanuel Vadot static device_method_t zynqmp_reset_methods[] = {
2334e579ad0SEmmanuel Vadot 	/* device_if */
2344e579ad0SEmmanuel Vadot 	DEVMETHOD(device_probe, 	zynqmp_reset_probe),
2354e579ad0SEmmanuel Vadot 	DEVMETHOD(device_attach, 	zynqmp_reset_attach),
2364e579ad0SEmmanuel Vadot 
2374e579ad0SEmmanuel Vadot 	/* Reset interface */
2384e579ad0SEmmanuel Vadot 	DEVMETHOD(hwreset_assert,	zynqmp_reset_assert),
2394e579ad0SEmmanuel Vadot 	DEVMETHOD(hwreset_is_asserted,	zynqmp_reset_is_asserted),
2404e579ad0SEmmanuel Vadot 
2414e579ad0SEmmanuel Vadot 	DEVMETHOD_END
2424e579ad0SEmmanuel Vadot };
2434e579ad0SEmmanuel Vadot 
2444e579ad0SEmmanuel Vadot static driver_t zynqmp_reset_driver = {
2454e579ad0SEmmanuel Vadot 	"zynqmp_reset",
2464e579ad0SEmmanuel Vadot 	zynqmp_reset_methods,
2474e579ad0SEmmanuel Vadot 	sizeof(struct zynqmp_reset_softc),
2484e579ad0SEmmanuel Vadot };
2494e579ad0SEmmanuel Vadot 
2504e579ad0SEmmanuel Vadot EARLY_DRIVER_MODULE(zynqmp_reset, simplebus, zynqmp_reset_driver, 0, 0,
2514e579ad0SEmmanuel Vadot     BUS_PASS_BUS + BUS_PASS_ORDER_LAST);
252