mirror of
https://github.com/opnsense/src.git
synced 2026-06-09 08:43:19 -04:00
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
This commit is contained in:
parent
bdbbbbb321
commit
4c52dde5bd
1 changed files with 86 additions and 32 deletions
|
|
@ -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 ((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, "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 (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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue