git: 50059a60edec - main - dwc: Rewrite clock and reset functions

From: Emmanuel Vadot <manu_at_FreeBSD.org>
Date: Thu, 05 Oct 2023 15:34:59 UTC
The branch main has been updated by manu:

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

commit 50059a60edec3c8c37e2f7b490fef83ec288b2da
Author:     Emmanuel Vadot <manu@FreeBSD.org>
AuthorDate: 2023-09-23 16:24:22 +0000
Commit:     Emmanuel Vadot <manu@FreeBSD.org>
CommitDate: 2023-10-05 15:34:38 +0000

    dwc: Rewrite clock and reset functions
    
    snps,dwmac have one required clock named stmmaceth and one optional pclk,
    correctly handle both in if_dwc, no need to get/enable stmmacseth again
    in if_dwc_rk.
    It also have one required reset also named stmmaceth and one optional ahb,
    correctly handle both.
    Rockchip have another optional clock named clk_mac_speed, get it and enable it
    if present. Also fix the optional RMII clocks, they were previously wrongly
    enabled in RGMII case.
---
 sys/dev/dwc/if_dwc.c         | 100 +++++++++++++++++++++++++++++--------------
 sys/dev/dwc/if_dwc_aw.c      |   4 +-
 sys/dev/dwc/if_dwc_rk.c      |  39 ++++++++---------
 sys/dev/dwc/if_dwc_socfpga.c |   3 ++
 sys/dev/dwc/if_dwcvar.h      |   6 +++
 5 files changed, 98 insertions(+), 54 deletions(-)

diff --git a/sys/dev/dwc/if_dwc.c b/sys/dev/dwc/if_dwc.c
index 7b9cd936681d..981e823a6fcc 100644
--- a/sys/dev/dwc/if_dwc.c
+++ b/sys/dev/dwc/if_dwc.c
@@ -61,6 +61,9 @@
 
 #include <machine/bus.h>
 
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
 #include <dev/dwc/if_dwc.h>
 #include <dev/dwc/if_dwcvar.h>
 #include <dev/mii/mii.h>
@@ -69,9 +72,6 @@
 #include <dev/ofw/ofw_bus_subr.h>
 #include <dev/mii/mii_fdt.h>
 
-#include <dev/extres/clk/clk.h>
-#include <dev/extres/hwreset/hwreset.h>
-
 #include "if_dwc_if.h"
 #include "gpio_if.h"
 #include "miibus_if.h"
@@ -1544,37 +1544,65 @@ dwc_reset_phy(struct dwc_softc *sc)
 }
 
 static int
-dwc_clock_init(device_t dev)
+dwc_clock_init(struct dwc_softc *sc)
 {
-	hwreset_t rst;
-	clk_t clk;
-	int error;
+	int rv;
 	int64_t freq;
 
-	/* Enable clocks */
-	if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &clk) == 0) {
-		error = clk_enable(clk);
-		if (error != 0) {
-			device_printf(dev, "could not enable main clock\n");
-			return (error);
-		}
-		if (bootverbose) {
-			clk_get_freq(clk, &freq);
-			device_printf(dev, "MAC clock(%s) freq: %jd\n",
-					clk_get_name(clk), (intmax_t)freq);
-		}
+	/* Required clock */
+	rv = clk_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->clk_stmmaceth);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get GMAC main clock\n");
+		return (ENXIO);
 	}
-	else {
-		device_printf(dev, "could not find clock stmmaceth\n");
+	if ((rv = clk_enable(sc->clk_stmmaceth)) != 0) {
+		device_printf(sc->dev, "could not enable main clock\n");
+		return (rv);
 	}
 
-	/* De-assert reset */
-	if (hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst) == 0) {
-		error = hwreset_deassert(rst);
-		if (error != 0) {
-			device_printf(dev, "could not de-assert reset\n");
-			return (error);
-		}
+	/* Optional clock */
+	rv = clk_get_by_ofw_name(sc->dev, 0, "pclk", &sc->clk_pclk);
+	if (rv != 0)
+		return (0);
+	if ((rv = clk_enable(sc->clk_pclk)) != 0) {
+		device_printf(sc->dev, "could not enable peripheral clock\n");
+		return (rv);
+	}
+
+	if (bootverbose) {
+		clk_get_freq(sc->clk_stmmaceth, &freq);
+		device_printf(sc->dev, "MAC clock(%s) freq: %jd\n",
+		    clk_get_name(sc->clk_stmmaceth), (intmax_t)freq);
+	}
+
+	return (0);
+}
+
+static int
+dwc_reset_deassert(struct dwc_softc *sc)
+{
+	int rv;
+
+	/* Required reset */
+	rv = hwreset_get_by_ofw_name(sc->dev, 0, "stmmaceth", &sc->rst_stmmaceth);
+	if (rv != 0) {
+		device_printf(sc->dev, "Cannot get GMAC reset\n");
+		return (ENXIO);
+	}
+	rv = hwreset_deassert(sc->rst_stmmaceth);
+	if (rv != 0) {
+		device_printf(sc->dev, "could not de-assert GMAC reset\n");
+		return (rv);
+	}
+
+	/* Optional reset */
+	rv = hwreset_get_by_ofw_name(sc->dev, 0, "ahb", &sc->rst_ahb);
+	if (rv != 0)
+		return (0);
+	rv = hwreset_deassert(sc->rst_ahb);
+	if (rv != 0) {
+		device_printf(sc->dev, "could not de-assert AHB reset\n");
+		return (rv);
 	}
 
 	return (0);
@@ -1654,10 +1682,20 @@ dwc_attach(device_t dev)
 	if (OF_hasprop(sc->node, "snps,aal") == 1)
 		aal = true;
 
-	if (IF_DWC_INIT(dev) != 0)
-		return (ENXIO);
+	error = clk_set_assigned(dev, ofw_bus_get_node(dev));
+	if (error != 0) {
+		device_printf(dev, "clk_set_assigned failed\n");
+		return (error);
+	}
 
-	if (dwc_clock_init(dev) != 0)
+	/* Enable main clock */
+	if ((error = dwc_clock_init(sc)) != 0)
+		return (error);
+	/* De-assert main reset */
+	if ((error = dwc_reset_deassert(sc)) != 0)
+		return (error);
+
+	if (IF_DWC_INIT(dev) != 0)
 		return (ENXIO);
 
 	if (bus_alloc_resources(dev, dwc_spec, sc->res)) {
diff --git a/sys/dev/dwc/if_dwc_aw.c b/sys/dev/dwc/if_dwc_aw.c
index 5992a652facb..2e34a311b0a7 100644
--- a/sys/dev/dwc/if_dwc_aw.c
+++ b/sys/dev/dwc/if_dwc_aw.c
@@ -36,13 +36,15 @@
 
 #include <machine/bus.h>
 
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
 #include <dev/dwc/if_dwc.h>
 #include <dev/dwc/if_dwcvar.h>
 #include <dev/ofw/ofw_bus.h>
 #include <dev/ofw/ofw_bus_subr.h>
 
 #include <arm/allwinner/aw_machdep.h>
-#include <dev/extres/clk/clk.h>
 #include <dev/extres/regulator/regulator.h>
 
 #include "if_dwc_if.h"
diff --git a/sys/dev/dwc/if_dwc_rk.c b/sys/dev/dwc/if_dwc_rk.c
index 7c8a6c2ab668..49cf5fef7808 100644
--- a/sys/dev/dwc/if_dwc_rk.c
+++ b/sys/dev/dwc/if_dwc_rk.c
@@ -38,16 +38,16 @@
 #include <net/if.h>
 #include <net/if_media.h>
 
-#include <dev/dwc/if_dwc.h>
-#include <dev/dwc/if_dwcvar.h>
-#include <dev/ofw/ofw_bus.h>
-#include <dev/ofw/ofw_bus_subr.h>
-
 #include <dev/extres/clk/clk.h>
 #include <dev/extres/hwreset/hwreset.h>
 #include <dev/extres/regulator/regulator.h>
 #include <dev/extres/syscon/syscon.h>
 
+#include <dev/dwc/if_dwc.h>
+#include <dev/dwc/if_dwcvar.h>
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
 #include "if_dwc_if.h"
 #include "syscon_if.h"
 
@@ -130,6 +130,7 @@ struct if_dwc_rk_softc {
 	clk_t			aclk_mac;
 	clk_t			pclk_mac;
 	clk_t			clk_stmmaceth;
+	clk_t			clk_mac_speed;
 	/* RMII clocks */
 	clk_t			clk_mac_ref;
 	clk_t			clk_mac_refout;
@@ -391,26 +392,10 @@ static int
 if_dwc_rk_init_clocks(device_t dev)
 {
 	struct if_dwc_rk_softc *sc;
-	int error;
 
 	sc = device_get_softc(dev);
-	error = clk_set_assigned(dev, ofw_bus_get_node(dev));
-	if (error != 0) {
-		device_printf(dev, "clk_set_assigned failed\n");
-		return (error);
-	}
 
 	/* Enable clocks */
-	error = clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->clk_stmmaceth);
-	if (error != 0) {
-		device_printf(dev, "could not find clock stmmaceth\n");
-		return (error);
-	}
-
-	if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
-		device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
-		sc->mac_clk_rx = NULL;
-	}
 
 	if (clk_get_by_ofw_name(dev, 0, "mac_clk_tx", &sc->mac_clk_tx) != 0) {
 		device_printf(sc->base.dev, "could not get mac_clk_tx clock\n");
@@ -427,7 +412,15 @@ if_dwc_rk_init_clocks(device_t dev)
 		sc->pclk_mac = NULL;
 	}
 
-	if (sc->base.phy_mode == PHY_MODE_RGMII) {
+	/* Optional clock */
+	clk_get_by_ofw_name(dev, 0, "clk_mac_speed", &sc->clk_mac_speed);
+
+	if (sc->base.phy_mode == PHY_MODE_RMII) {
+		if (clk_get_by_ofw_name(dev, 0, "mac_clk_rx", &sc->mac_clk_rx) != 0) {
+			device_printf(sc->base.dev, "could not get mac_clk_rx clock\n");
+			sc->mac_clk_rx = NULL;
+		}
+
 		if (clk_get_by_ofw_name(dev, 0, "clk_mac_ref", &sc->clk_mac_ref) != 0) {
 			device_printf(sc->base.dev, "could not get clk_mac_ref clock\n");
 			sc->clk_mac_ref = NULL;
@@ -470,6 +463,8 @@ if_dwc_rk_init_clocks(device_t dev)
 		clk_enable(sc->pclk_mac);
 	if (sc->mac_clk_tx)
 		clk_enable(sc->mac_clk_tx);
+	if (sc->clk_mac_speed)
+		clk_enable(sc->clk_mac_speed);
 
 	DELAY(50);
 
diff --git a/sys/dev/dwc/if_dwc_socfpga.c b/sys/dev/dwc/if_dwc_socfpga.c
index ac8c78326df7..63a19ed12977 100644
--- a/sys/dev/dwc/if_dwc_socfpga.c
+++ b/sys/dev/dwc/if_dwc_socfpga.c
@@ -42,6 +42,9 @@
 
 #include <machine/bus.h>
 
+#include <dev/extres/clk/clk.h>
+#include <dev/extres/hwreset/hwreset.h>
+
 #include <dev/dwc/if_dwc.h>
 #include <dev/dwc/if_dwcvar.h>
 #include <dev/ofw/ofw_bus.h>
diff --git a/sys/dev/dwc/if_dwcvar.h b/sys/dev/dwc/if_dwcvar.h
index 5e5792974560..da31fa8c6575 100644
--- a/sys/dev/dwc/if_dwcvar.h
+++ b/sys/dev/dwc/if_dwcvar.h
@@ -76,6 +76,12 @@ struct dwc_softc {
 	int			stats_harvest_count;
 	int			phy_mode;
 
+	/* clocks and reset */
+	clk_t			clk_stmmaceth;
+	clk_t			clk_pclk;
+	hwreset_t		rst_stmmaceth;
+	hwreset_t		rst_ahb;
+
 	/* RX */
 	bus_dma_tag_t		rxdesc_tag;
 	bus_dmamap_t		rxdesc_map;