The branch main has been updated by adrian:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=b12a863a1e14610f6b145f235aa7452602038f9a

commit b12a863a1e14610f6b145f235aa7452602038f9a
Author:     Adrian Chadd <adr...@freebsd.org>
AuthorDate: 2021-10-31 03:43:27 +0000
Commit:     Adrian Chadd <adr...@freebsd.org>
CommitDate: 2021-11-04 16:02:41 +0000

    ipq4018: add initial reset driver support for the clock/reset controller.
    
    This implements the "reset controller" side of the clock/reset controller.
    It's a simple array of registers and bits to set.
    
    The register table itself comes from Linux; the rest of the code is a
    reimplementation.
    
    It doesn't yet implement or expose the clock side - I have a lot of
    reverse engineering to do before that!
    
    Reviewed by: andrew, manu, imp
    Differential Revision: https://reviews.freebsd.org/D32723
    
    Obtained from: Linux (registers)
---
 sys/arm/qualcomm/qcom_gcc_ipq4018.c       | 167 +++++++++++++++++++++++++++
 sys/arm/qualcomm/qcom_gcc_ipq4018_reset.c | 181 ++++++++++++++++++++++++++++++
 sys/arm/qualcomm/qcom_gcc_ipq4018_var.h   |  50 +++++++++
 sys/arm/qualcomm/std.ipq4018              |   3 +
 4 files changed, 401 insertions(+)

diff --git a/sys/arm/qualcomm/qcom_gcc_ipq4018.c 
b/sys/arm/qualcomm/qcom_gcc_ipq4018.c
new file mode 100644
index 000000000000..3002ae32a597
--- /dev/null
+++ b/sys/arm/qualcomm/qcom_gcc_ipq4018.c
@@ -0,0 +1,167 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021, Adrian Chadd <adr...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Driver for Qualcomm IPQ4018 clock and reset device */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sglist.h>
+#include <sys/random.h>
+#include <sys/stdatomic.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/hwreset/hwreset.h>
+
+#include "hwreset_if.h"
+
+#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
+
+#include <arm/qualcomm/qcom_gcc_ipq4018_var.h>
+
+
+static int     qcom_gcc_ipq4018_modevent(module_t, int, void *);
+
+static int     qcom_gcc_ipq4018_probe(device_t);
+static int     qcom_gcc_ipq4018_attach(device_t);
+static int     qcom_gcc_ipq4018_detach(device_t);
+
+static int
+qcom_gcc_ipq4018_modevent(module_t mod, int type, void *unused)
+{
+       int error;
+
+       switch (type) {
+       case MOD_LOAD:
+       case MOD_QUIESCE:
+       case MOD_UNLOAD:
+       case MOD_SHUTDOWN:
+               error = 0;
+               break;
+       default:
+               error = EOPNOTSUPP;
+               break;
+       }
+
+       return (error);
+}
+
+static int
+qcom_gcc_ipq4018_probe(device_t dev)
+{
+       if (! ofw_bus_status_okay(dev))
+               return (ENXIO);
+
+       if (ofw_bus_is_compatible(dev, "qcom,gcc-ipq4019") == 0)
+               return (ENXIO);
+
+       return (0);
+}
+
+static int
+qcom_gcc_ipq4018_attach(device_t dev)
+{
+       struct qcom_gcc_ipq4018_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       /* Found a compatible device! */
+       sc->dev = dev;
+
+       sc->reg_rid = 0;
+       sc->reg = bus_alloc_resource_anywhere(dev, SYS_RES_MEMORY,
+           &sc->reg_rid, 0x60000, RF_ACTIVE);
+       if (sc->reg == NULL) {
+               device_printf(dev, "Couldn't allocate memory resource!\n");
+               return (ENXIO);
+       }
+
+       device_set_desc(dev, "Qualcomm IPQ4018 Clock/Reset Controller");
+
+       mtx_init(&sc->mtx, device_get_nameunit(dev), NULL, MTX_DEF);
+
+       /*
+        * Register as a reset provider.
+        */
+       hwreset_register_ofw_provider(dev);
+
+       return (0);
+}
+
+static int
+qcom_gcc_ipq4018_detach(device_t dev)
+{
+       struct qcom_gcc_ipq4018_softc *sc;
+
+       sc = device_get_softc(dev);
+
+       if (sc->reg != NULL) {
+               bus_release_resource(sc->dev, SYS_RES_MEMORY,
+                   sc->reg_rid, sc->reg);
+       }
+       return (0);
+}
+
+static device_method_t qcom_gcc_ipq4018_methods[] = {
+       /* Device methods. */
+       DEVMETHOD(device_probe,         qcom_gcc_ipq4018_probe),
+       DEVMETHOD(device_attach,        qcom_gcc_ipq4018_attach),
+       DEVMETHOD(device_detach,        qcom_gcc_ipq4018_detach),
+
+       /* Reset interface */
+       DEVMETHOD(hwreset_assert,       qcom_gcc_ipq4018_hwreset_assert),
+       DEVMETHOD(hwreset_is_asserted,  qcom_gcc_ipq4018_hwreset_is_asserted),
+
+       DEVMETHOD_END
+};
+
+static driver_t qcom_gcc_ipq4018_driver = {
+       "qcom_gcc",
+       qcom_gcc_ipq4018_methods,
+       sizeof(struct qcom_gcc_ipq4018_softc)
+};
+static devclass_t qcom_gcc_ipq4018_devclass;
+
+EARLY_DRIVER_MODULE(qcom_gcc_ipq4018, simplebus, qcom_gcc_ipq4018_driver,
+    qcom_gcc_ipq4018_devclass, qcom_gcc_ipq4018_modevent, 0,
+    BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
+EARLY_DRIVER_MODULE(qcom_gcc_ipq4018, ofwbus, qcom_gcc_ipq4018_driver,
+    qcom_gcc_ipq4018_devclass, qcom_gcc_ipq4018_modevent, 0,
+    BUS_PASS_RESOURCE + BUS_PASS_ORDER_MIDDLE);
+MODULE_VERSION(qcom_gcc_ipq4018_random, 1);
diff --git a/sys/arm/qualcomm/qcom_gcc_ipq4018_reset.c 
b/sys/arm/qualcomm/qcom_gcc_ipq4018_reset.c
new file mode 100644
index 000000000000..754e7636ff6e
--- /dev/null
+++ b/sys/arm/qualcomm/qcom_gcc_ipq4018_reset.c
@@ -0,0 +1,181 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021, Adrian Chadd <adr...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice unmodified, this list of conditions, and the following
+ *    disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Driver for Qualcomm IPQ4018 clock and reset device */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/sglist.h>
+#include <sys/random.h>
+#include <sys/stdatomic.h>
+#include <sys/mutex.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/bus.h>
+
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/extres/hwreset/hwreset.h>
+
+#include "hwreset_if.h"
+
+#include <dt-bindings/clock/qcom,gcc-ipq4019.h>
+
+#include <arm/qualcomm/qcom_gcc_ipq4018_var.h>
+
+
+static const struct qcom_gcc_ipq4018_reset_entry gcc_ipq4019_reset_list[] = {
+       [WIFI0_CPU_INIT_RESET] = { 0x1f008, 5 },
+       [WIFI0_RADIO_SRIF_RESET] = { 0x1f008, 4 },
+       [WIFI0_RADIO_WARM_RESET] = { 0x1f008, 3 },
+       [WIFI0_RADIO_COLD_RESET] = { 0x1f008, 2 },
+       [WIFI0_CORE_WARM_RESET] = { 0x1f008, 1 },
+       [WIFI0_CORE_COLD_RESET] = { 0x1f008, 0 },
+       [WIFI1_CPU_INIT_RESET] = { 0x20008, 5 },
+       [WIFI1_RADIO_SRIF_RESET] = { 0x20008, 4 },
+       [WIFI1_RADIO_WARM_RESET] = { 0x20008, 3 },
+       [WIFI1_RADIO_COLD_RESET] = { 0x20008, 2 },
+       [WIFI1_CORE_WARM_RESET] = { 0x20008, 1 },
+       [WIFI1_CORE_COLD_RESET] = { 0x20008, 0 },
+       [USB3_UNIPHY_PHY_ARES] = { 0x1e038, 5 },
+       [USB3_HSPHY_POR_ARES] = { 0x1e038, 4 },
+       [USB3_HSPHY_S_ARES] = { 0x1e038, 2 },
+       [USB2_HSPHY_POR_ARES] = { 0x1e01c, 4 },
+       [USB2_HSPHY_S_ARES] = { 0x1e01c, 2 },
+       [PCIE_PHY_AHB_ARES] = { 0x1d010, 11 },
+       [PCIE_AHB_ARES] = { 0x1d010, 10 },
+       [PCIE_PWR_ARES] = { 0x1d010, 9 },
+       [PCIE_PIPE_STICKY_ARES] = { 0x1d010, 8 },
+       [PCIE_AXI_M_STICKY_ARES] = { 0x1d010, 7 },
+       [PCIE_PHY_ARES] = { 0x1d010, 6 },
+       [PCIE_PARF_XPU_ARES] = { 0x1d010, 5 },
+       [PCIE_AXI_S_XPU_ARES] = { 0x1d010, 4 },
+       [PCIE_AXI_M_VMIDMT_ARES] = { 0x1d010, 3 },
+       [PCIE_PIPE_ARES] = { 0x1d010, 2 },
+       [PCIE_AXI_S_ARES] = { 0x1d010, 1 },
+       [PCIE_AXI_M_ARES] = { 0x1d010, 0 },
+       [ESS_RESET] = { 0x12008, 0},
+       [GCC_BLSP1_BCR] = {0x01000, 0},
+       [GCC_BLSP1_QUP1_BCR] = {0x02000, 0},
+       [GCC_BLSP1_UART1_BCR] = {0x02038, 0},
+       [GCC_BLSP1_QUP2_BCR] = {0x03008, 0},
+       [GCC_BLSP1_UART2_BCR] = {0x03028, 0},
+       [GCC_BIMC_BCR] = {0x04000, 0},
+       [GCC_TLMM_BCR] = {0x05000, 0},
+       [GCC_IMEM_BCR] = {0x0E000, 0},
+       [GCC_ESS_BCR] = {0x12008, 0},
+       [GCC_PRNG_BCR] = {0x13000, 0},
+       [GCC_BOOT_ROM_BCR] = {0x13008, 0},
+       [GCC_CRYPTO_BCR] = {0x16000, 0},
+       [GCC_SDCC1_BCR] = {0x18000, 0},
+       [GCC_SEC_CTRL_BCR] = {0x1A000, 0},
+       [GCC_AUDIO_BCR] = {0x1B008, 0},
+       [GCC_QPIC_BCR] = {0x1C000, 0},
+       [GCC_PCIE_BCR] = {0x1D000, 0},
+       [GCC_USB2_BCR] = {0x1E008, 0},
+       [GCC_USB2_PHY_BCR] = {0x1E018, 0},
+       [GCC_USB3_BCR] = {0x1E024, 0},
+       [GCC_USB3_PHY_BCR] = {0x1E034, 0},
+       [GCC_SYSTEM_NOC_BCR] = {0x21000, 0},
+       [GCC_PCNOC_BCR] = {0x2102C, 0},
+       [GCC_DCD_BCR] = {0x21038, 0},
+       [GCC_SNOC_BUS_TIMEOUT0_BCR] = {0x21064, 0},
+       [GCC_SNOC_BUS_TIMEOUT1_BCR] = {0x2106C, 0},
+       [GCC_SNOC_BUS_TIMEOUT2_BCR] = {0x21074, 0},
+       [GCC_SNOC_BUS_TIMEOUT3_BCR] = {0x2107C, 0},
+       [GCC_PCNOC_BUS_TIMEOUT0_BCR] = {0x21084, 0},
+       [GCC_PCNOC_BUS_TIMEOUT1_BCR] = {0x2108C, 0},
+       [GCC_PCNOC_BUS_TIMEOUT2_BCR] = {0x21094, 0},
+       [GCC_PCNOC_BUS_TIMEOUT3_BCR] = {0x2109C, 0},
+       [GCC_PCNOC_BUS_TIMEOUT4_BCR] = {0x210A4, 0},
+       [GCC_PCNOC_BUS_TIMEOUT5_BCR] = {0x210AC, 0},
+       [GCC_PCNOC_BUS_TIMEOUT6_BCR] = {0x210B4, 0},
+       [GCC_PCNOC_BUS_TIMEOUT7_BCR] = {0x210BC, 0},
+       [GCC_PCNOC_BUS_TIMEOUT8_BCR] = {0x210C4, 0},
+       [GCC_PCNOC_BUS_TIMEOUT9_BCR] = {0x210CC, 0},
+       [GCC_TCSR_BCR] = {0x22000, 0},
+       [GCC_MPM_BCR] = {0x24000, 0},
+       [GCC_SPDM_BCR] = {0x25000, 0},
+};
+
+int
+qcom_gcc_ipq4018_hwreset_assert(device_t dev, intptr_t id, bool reset)
+{
+       struct qcom_gcc_ipq4018_softc *sc;
+       uint32_t reg;
+
+       sc = device_get_softc(dev);
+
+       if (id > nitems(gcc_ipq4019_reset_list)) {
+               device_printf(dev, "%s: invalid id (%d)\n", __func__, id);
+               return (EINVAL);
+       }
+
+       device_printf(dev, "%s: called; id=%d, reset=%d\n", __func__, id, 
reset);
+       mtx_lock(&sc->mtx);
+       reg = bus_read_4(sc->reg, gcc_ipq4019_reset_list[id].reg);
+       if (reset)
+               reg |= (1U << gcc_ipq4019_reset_list[id].bit);
+       else
+               reg &= ~(1U << gcc_ipq4019_reset_list[id].bit);
+       bus_write_4(sc->reg, gcc_ipq4019_reset_list[id].reg, reg);
+       mtx_unlock(&sc->mtx);
+       return (0);
+}
+
+int
+qcom_gcc_ipq4018_hwreset_is_asserted(device_t dev, intptr_t id, bool *reset)
+{
+       struct qcom_gcc_ipq4018_softc *sc;
+       uint32_t reg;
+
+       sc = device_get_softc(dev);
+
+       if (id > nitems(gcc_ipq4019_reset_list)) {
+               device_printf(dev, "%s: invalid id (%d)\n", __func__, id);
+               return (EINVAL);
+       }
+       mtx_lock(&sc->mtx);
+       reg = bus_read_4(sc->reg, gcc_ipq4019_reset_list[id].reg);
+       if (reg & ((1U << gcc_ipq4019_reset_list[id].bit)))
+               *reset = true;
+       else
+               *reset = false;
+       mtx_unlock(&sc->mtx);
+
+       device_printf(dev, "called; id=%d\n", id);
+       return (0);
+}
+
diff --git a/sys/arm/qualcomm/qcom_gcc_ipq4018_var.h 
b/sys/arm/qualcomm/qcom_gcc_ipq4018_var.h
new file mode 100644
index 000000000000..3997e1860e43
--- /dev/null
+++ b/sys/arm/qualcomm/qcom_gcc_ipq4018_var.h
@@ -0,0 +1,50 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Adrian Chadd <adr...@freebsd.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef        __QCOM_GCC_IPQ4018_VAR_H__
+#define        __QCOM_GCC_IPQ4018_VAR_H__
+
+struct qcom_gcc_ipq4018_reset_entry {
+       uint32_t        reg;
+       uint32_t        bit;
+};
+
+struct qcom_gcc_ipq4018_softc {
+       device_t                dev;
+       int                     reg_rid;
+       struct resource         *reg;
+       struct mtx              mtx;
+};
+
+extern int qcom_gcc_ipq4018_hwreset_assert(device_t dev, intptr_t id,
+           bool reset);
+extern int qcom_gcc_ipq4018_hwreset_is_asserted(device_t dev, intptr_t id,
+           bool *reset);
+
+#endif /* __QCOM_GCC_IPQ4018_VAR_H__ */
diff --git a/sys/arm/qualcomm/std.ipq4018 b/sys/arm/qualcomm/std.ipq4018
index 099fd81b5171..7e8ac39e7222 100644
--- a/sys/arm/qualcomm/std.ipq4018
+++ b/sys/arm/qualcomm/std.ipq4018
@@ -4,3 +4,6 @@ arm/qualcomm/qcom_scm_legacy.c          standard
 arm/qualcomm/qcom_cpu_kpssv2.c         optional smp
 
 dev/qcom_rnd/qcom_rnd.c                        optional qcom_rnd
+arm/qualcomm/qcom_gcc_ipq4018.c                optional qcom_gcc_ipq4018
+arm/qualcomm/qcom_gcc_ipq4018_reset.c  optional qcom_gcc_ipq4018
+

Reply via email to