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