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.
This commit is contained in:
Emmanuel Vadot 2023-09-23 18:24:22 +02:00
parent b69c49d106
commit 50059a60ed
5 changed files with 98 additions and 54 deletions

View file

@ -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)) {

View file

@ -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"

View file

@ -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);

View file

@ -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>

View file

@ -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;