git: 4c52dde5bda0 - main - if_cgem: Rewrite clock part
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 18 Sep 2023 13:24:55 UTC
The branch main has been updated by manu:
URL: https://cgit.FreeBSD.org/src/commit/?id=4c52dde5bda099936d43820da84e569dccc6f475
commit 4c52dde5bda099936d43820da84e569dccc6f475
Author: Emmanuel Vadot <manu@FreeBSD.org>
AuthorDate: 2023-09-14 08:57:19 +0000
Commit: Emmanuel Vadot <manu@FreeBSD.org>
CommitDate: 2023-09-18 13:24:27 +0000
if_cgem: Rewrite clock part
- pclk and hclk are mandatory so always try to get them.
Don't make it fatal if it fails as some platform (like Zynq) don't
have a proper clock driver.
- Always use pclk for the reference clock.
- Try to get all the possible clocks and enable them.
Reviewed-by: mhorne
Tested-by: Milan Obuch <bsd@dino.sk>
Differential Revision: https://reviews.freebsd.org/D41857
Sponsored by: Beckhoff Automation GmbH & Co. KG
---
sys/dev/cadence/if_cgem.c | 118 +++++++++++++++++++++++++++++++++-------------
1 file changed, 86 insertions(+), 32 deletions(-)
diff --git a/sys/dev/cadence/if_cgem.c b/sys/dev/cadence/if_cgem.c
index 43e35b2bf849..6e4a62f6e5ee 100644
--- a/sys/dev/cadence/if_cgem.c
+++ b/sys/dev/cadence/if_cgem.c
@@ -102,17 +102,15 @@
#define HWQUIRK_NONE 0
#define HWQUIRK_NEEDNULLQS 1
#define HWQUIRK_RXHANGWAR 2
-#define HWQUIRK_TXCLK 4
-#define HWQUIRK_PCLK 8
static struct ofw_compat_data compat_data[] = {
- { "cdns,zynq-gem", HWQUIRK_RXHANGWAR | HWQUIRK_TXCLK }, /* Deprecated */
- { "cdns,zynqmp-gem", HWQUIRK_NEEDNULLQS | HWQUIRK_TXCLK }, /* Deprecated */
- { "xlnx,zynq-gem", HWQUIRK_RXHANGWAR | HWQUIRK_TXCLK },
- { "xlnx,zynqmp-gem", HWQUIRK_NEEDNULLQS | HWQUIRK_TXCLK },
- { "microchip,mpfs-mss-gem", HWQUIRK_NEEDNULLQS | HWQUIRK_TXCLK },
- { "sifive,fu540-c000-gem", HWQUIRK_PCLK },
- { "sifive,fu740-c000-gem", HWQUIRK_PCLK },
+ { "cdns,zynq-gem", HWQUIRK_RXHANGWAR }, /* Deprecated */
+ { "cdns,zynqmp-gem", HWQUIRK_NEEDNULLQS }, /* Deprecated */
+ { "xlnx,zynq-gem", HWQUIRK_RXHANGWAR },
+ { "xlnx,zynqmp-gem", HWQUIRK_NEEDNULLQS },
+ { "microchip,mpfs-mss-gem", HWQUIRK_NEEDNULLQS },
+ { "sifive,fu540-c000-gem", HWQUIRK_NONE },
+ { "sifive,fu740-c000-gem", HWQUIRK_NONE },
{ NULL, 0 }
};
@@ -129,7 +127,11 @@ struct cgem_softc {
struct callout tick_ch;
uint32_t net_ctl_shadow;
uint32_t net_cfg_shadow;
- clk_t ref_clk;
+ clk_t clk_pclk;
+ clk_t clk_hclk;
+ clk_t clk_txclk;
+ clk_t clk_rxclk;
+ clk_t clk_tsuclk;
int neednullqs;
int phy_contype;
@@ -1497,9 +1499,9 @@ cgem_mediachange(struct cgem_softc *sc, struct mii_data *mii)
WR4(sc, CGEM_NET_CFG, sc->net_cfg_shadow);
- if (sc->ref_clk != NULL) {
+ if (sc->clk_pclk != NULL) {
CGEM_UNLOCK(sc);
- if (clk_set_freq(sc->ref_clk, ref_clk_freq, 0))
+ if (clk_set_freq(sc->clk_pclk, ref_clk_freq, 0))
device_printf(sc->dev, "could not set ref clk to %d\n",
ref_clk_freq);
CGEM_LOCK(sc);
@@ -1744,19 +1746,47 @@ cgem_attach(device_t dev)
sc->neednullqs = 1;
if ((hwquirks & HWQUIRK_RXHANGWAR) != 0)
sc->rxhangwar = 1;
- if ((hwquirks & HWQUIRK_TXCLK) != 0) {
- if (clk_get_by_ofw_name(dev, 0, "tx_clk", &sc->ref_clk) != 0)
- device_printf(dev,
- "could not retrieve reference clock.\n");
- else if (clk_enable(sc->ref_clk) != 0)
- device_printf(dev, "could not enable clock.\n");
+ /*
+ * Both pclk and hclk are mandatory but we don't have a proper
+ * clock driver for Zynq so don't make it fatal if we can't
+ * get them.
+ */
+ if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->clk_pclk) != 0)
+ device_printf(dev,
+ "could not retrieve pclk.\n");
+ else {
+ if (clk_enable(sc->clk_pclk) != 0)
+ device_printf(dev, "could not enable pclk.\n");
+ }
+ if (clk_get_by_ofw_name(dev, 0, "hclk", &sc->clk_hclk) != 0)
+ device_printf(dev,
+ "could not retrieve hclk.\n");
+ else {
+ if (clk_enable(sc->clk_hclk) != 0)
+ device_printf(dev, "could not enable hclk.\n");
+ }
+
+ /* Optional clocks */
+ if (clk_get_by_ofw_name(dev, 0, "tx_clk", &sc->clk_txclk) == 0) {
+ if (clk_enable(sc->clk_txclk) != 0) {
+ device_printf(dev, "could not enable tx_clk.\n");
+ err = ENXIO;
+ goto err_pclk;
+ }
+ }
+ if (clk_get_by_ofw_name(dev, 0, "rx_clk", &sc->clk_rxclk) == 0) {
+ if (clk_enable(sc->clk_rxclk) != 0) {
+ device_printf(dev, "could not enable rx_clk.\n");
+ err = ENXIO;
+ goto err_tx_clk;
+ }
}
- if ((hwquirks & HWQUIRK_PCLK) != 0) {
- if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->ref_clk) != 0)
- device_printf(dev,
- "could not retrieve reference clock.\n");
- else if (clk_enable(sc->ref_clk) != 0)
- device_printf(dev, "could not enable clock.\n");
+ if (clk_get_by_ofw_name(dev, 0, "tsu_clk", &sc->clk_tsuclk) == 0) {
+ if (clk_enable(sc->clk_tsuclk) != 0) {
+ device_printf(dev, "could not enable tsu_clk.\n");
+ err = ENXIO;
+ goto err_rx_clk;
+ }
}
node = ofw_bus_get_node(dev);
@@ -1768,7 +1798,8 @@ cgem_attach(device_t dev)
RF_ACTIVE);
if (sc->mem_res == NULL) {
device_printf(dev, "could not allocate memory resources.\n");
- return (ENOMEM);
+ err = ENOMEM;
+ goto err_tsu_clk;
}
/* Get IRQ resource. */
@@ -1824,7 +1855,7 @@ cgem_attach(device_t dev)
if (err) {
device_printf(dev, "could not set up dma mem for descs.\n");
cgem_detach(dev);
- return (ENOMEM);
+ goto err;
}
/* Get a MAC address. */
@@ -1841,12 +1872,29 @@ cgem_attach(device_t dev)
device_printf(dev, "could not set interrupt handler.\n");
ether_ifdetach(ifp);
cgem_detach(dev);
- return (err);
+ goto err;
}
cgem_add_sysctls(dev);
return (0);
+
+err_tsu_clk:
+ if (sc->clk_tsuclk)
+ clk_release(sc->clk_tsuclk);
+err_rx_clk:
+ if (sc->clk_rxclk)
+ clk_release(sc->clk_rxclk);
+err_tx_clk:
+ if (sc->clk_txclk)
+ clk_release(sc->clk_txclk);
+err_pclk:
+ if (sc->clk_pclk)
+ clk_release(sc->clk_pclk);
+ if (sc->clk_hclk)
+ clk_release(sc->clk_hclk);
+err:
+ return (err);
}
static int
@@ -1923,13 +1971,19 @@ cgem_detach(device_t dev)
sc->mbuf_dma_tag = NULL;
}
- if (sc->ref_clk != NULL) {
- clk_release(sc->ref_clk);
- sc->ref_clk = NULL;
- }
-
bus_generic_detach(dev);
+ if (sc->clk_tsuclk)
+ clk_release(sc->clk_tsuclk);
+ if (sc->clk_rxclk)
+ clk_release(sc->clk_rxclk);
+ if (sc->clk_txclk)
+ clk_release(sc->clk_txclk);
+ if (sc->clk_pclk)
+ clk_release(sc->clk_pclk);
+ if (sc->clk_hclk)
+ clk_release(sc->clk_hclk);
+
CGEM_LOCK_DESTROY(sc);
return (0);