From 50059a60edec3c8c37e2f7b490fef83ec288b2da Mon Sep 17 00:00:00 2001 From: Emmanuel Vadot Date: Sat, 23 Sep 2023 18:24:22 +0200 Subject: [PATCH] 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 +#include +#include + #include #include #include @@ -69,9 +72,6 @@ #include #include -#include -#include - #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 +#include +#include + #include #include #include #include #include -#include #include #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 #include -#include -#include -#include -#include - #include #include #include #include +#include +#include +#include +#include + #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 +#include +#include + #include #include #include 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;