git: 50059a60edec - main - dwc: Rewrite clock and reset functions
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
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;