Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F148915885
D45600.1789150652.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D45600.1789150652.diff
View Options
diff --git a/sys/dev/eqos/if_eqos.c b/sys/dev/eqos/if_eqos.c
--- a/sys/dev/eqos/if_eqos.c
+++ b/sys/dev/eqos/if_eqos.c
@@ -456,7 +456,7 @@
int retry;
WR4(sc, GMAC_DMA_MODE, GMAC_DMA_MODE_SWR);
- for (retry = 2000; retry > 0; retry--) {
+ for (retry = 5000; retry > 0; retry--) {
DELAY(1000);
val = RD4(sc, GMAC_DMA_MODE);
if (!(val & GMAC_DMA_MODE_SWR))
@@ -491,7 +491,7 @@
struct eqos_softc *sc = if_softc;
if_t ifp = sc->ifp;
struct mii_data *mii = device_get_softc(sc->miibus);
- uint32_t val;
+ uint32_t val, mtl_tx_val, mtl_rx_val;
if (if_getdrvflags(ifp) & IFF_DRV_RUNNING)
return;
@@ -508,13 +508,18 @@
val = RD4(sc, GMAC_DMA_CHAN0_CONTROL);
val &= ~GMAC_DMA_CHAN0_CONTROL_DSL_MASK;
val |= ((DESC_ALIGN - 16) / 8) << GMAC_DMA_CHAN0_CONTROL_DSL_SHIFT;
- val |= GMAC_DMA_CHAN0_CONTROL_PBLX8;
+ if (sc->pblx8)
+ val |= GMAC_DMA_CHAN0_CONTROL_PBLX8;
WR4(sc, GMAC_DMA_CHAN0_CONTROL, val);
val = RD4(sc, GMAC_DMA_CHAN0_TX_CONTROL);
+ if (sc->txpbl > 0)
+ val |= (sc->txpbl << GMAC_DMA_CHAN0_TXRX_PBL_SHIFT);
val |= GMAC_DMA_CHAN0_TX_CONTROL_OSP;
val |= GMAC_DMA_CHAN0_TX_CONTROL_START;
WR4(sc, GMAC_DMA_CHAN0_TX_CONTROL, val);
val = RD4(sc, GMAC_DMA_CHAN0_RX_CONTROL);
+ if (sc->rxpbl > 0)
+ val |= (sc->rxpbl << GMAC_DMA_CHAN0_TXRX_PBL_SHIFT);
val &= ~GMAC_DMA_CHAN0_RX_CONTROL_RBSZ_MASK;
val |= (MCLBYTES << GMAC_DMA_CHAN0_RX_CONTROL_RBSZ_SHIFT);
val |= GMAC_DMA_CHAN0_RX_CONTROL_START;
@@ -527,11 +532,19 @@
GMAC_MMC_CONTROL_CNTPRSTLVL);
/* Configure operation modes */
+ if (sc->thresh_dma_mode) {
+ mtl_tx_val = sc->ttc;
+ mtl_rx_val = sc->rtc;
+ } else {
+ mtl_tx_val = GMAC_MTL_TXQ0_OPERATION_MODE_TSF;
+ mtl_rx_val = GMAC_MTL_RXQ0_OPERATION_MODE_RSF;
+ }
+
WR4(sc, GMAC_MTL_TXQ0_OPERATION_MODE,
- GMAC_MTL_TXQ0_OPERATION_MODE_TSF |
+ mtl_tx_val |
GMAC_MTL_TXQ0_OPERATION_MODE_TXQEN_EN);
WR4(sc, GMAC_MTL_RXQ0_OPERATION_MODE,
- GMAC_MTL_RXQ0_OPERATION_MODE_RSF |
+ mtl_rx_val |
GMAC_MTL_RXQ0_OPERATION_MODE_FEP |
GMAC_MTL_RXQ0_OPERATION_MODE_FUP);
@@ -1112,6 +1125,14 @@
int error;
int n;
+ /* default values */
+ sc->thresh_dma_mode = false;
+ sc->pblx8 = true;
+ sc->txpbl = 0;
+ sc->rxpbl = 0;
+ sc->ttc = 0x10;
+ sc->rtc = 0;
+
/* setup resources */
if (bus_alloc_resources(dev, eqos_spec, sc->res)) {
device_printf(dev, "Could not allocate resources\n");
@@ -1128,7 +1149,7 @@
GMAC_MAC_VERSION_USERVER_SHIFT;
snpsver = ver & GMAC_MAC_VERSION_SNPSVER_MASK;
- if (snpsver != 0x51) {
+ if (snpsver != 0x51 && snpsver != 0x52) {
device_printf(dev, "EQOS version 0x%02x not supported\n",
snpsver);
return (ENXIO);
diff --git a/sys/dev/eqos/if_eqos_reg.h b/sys/dev/eqos/if_eqos_reg.h
--- a/sys/dev/eqos/if_eqos_reg.h
+++ b/sys/dev/eqos/if_eqos_reg.h
@@ -241,6 +241,7 @@
#define GMAC_DMA_CHAN0_RX_END_ADDR 0x1128
#define GMAC_DMA_CHAN0_TX_RING_LEN 0x112C
#define GMAC_DMA_CHAN0_RX_RING_LEN 0x1130
+#define GMAC_DMA_CHAN0_TXRX_PBL_SHIFT 16
#define GMAC_DMA_CHAN0_INTR_ENABLE 0x1134
#define GMAC_DMA_CHAN0_INTR_ENABLE_NIE (1U << 15)
#define GMAC_DMA_CHAN0_INTR_ENABLE_AIE (1U << 14)
diff --git a/sys/dev/eqos/if_eqos_starfive.c b/sys/dev/eqos/if_eqos_starfive.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/eqos/if_eqos_starfive.c
@@ -0,0 +1,219 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2024 Jari Sihvola <jsihv@gmx.com>
+ */
+
+#include "opt_platform.h"
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/systm.h>
+#include <sys/endian.h>
+#include <sys/gpio.h>
+#include <sys/rman.h>
+#include <sys/socket.h>
+#include <machine/bus.h>
+
+#include <net/if.h>
+#include <net/if_media.h>
+#include <dev/mii/mii.h>
+#include <dev/mii/miivar.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+#include <dev/hwreset/hwreset.h>
+#include <dev/regulator/regulator.h>
+
+#include <dev/eqos/if_eqos_var.h>
+
+#include "if_eqos_if.h"
+#include "gpio_if.h"
+
+#include <dev/clk/clk.h>
+
+/* JH7110's board specific code for eqos Ethernet controller driver */
+
+#define JH7110_CSR_FREQ 198000000
+
+#define WR4(sc, o, v) bus_write_4(sc->base.res[EQOS_RES_MEM], (o), (v))
+
+static const struct ofw_compat_data compat_data[] = {
+ {"starfive,jh7110-dwmac", 1},
+ { NULL, 0}
+};
+
+struct if_eqos_starfive_softc {
+ struct eqos_softc base;
+ clk_t gtx;
+ clk_t tx;
+ clk_t stmmaceth;
+ clk_t pclk;
+};
+
+static int
+if_eqos_starfive_set_speed(device_t dev, int speed)
+{
+ struct if_eqos_starfive_softc *sc = device_get_softc(dev);
+ uint64_t freq;
+ int err;
+
+ switch (speed) {
+ case IFM_1000_T:
+ case IFM_1000_SX:
+ freq = 125000000;
+ break;
+ case IFM_100_TX:
+ freq = 25000000;
+ break;
+ case IFM_10_T:
+ freq = 2500000;
+ break;
+ default:
+ device_printf(dev, "unsupported media %u\n", speed);
+ return (-EINVAL);
+ }
+
+ clk_set_freq(sc->gtx, freq, 0);
+ err = clk_enable(sc->gtx);
+ if (err != 0) {
+ device_printf(dev, "Could not enable clock %s\n",
+ clk_get_name(sc->gtx));
+ }
+
+ return (0);
+}
+
+
+
+static int
+if_eqos_starfive_clk_init(device_t dev)
+{
+ struct if_eqos_starfive_softc *sc = device_get_softc(dev);
+ int err;
+
+ if (clk_get_by_ofw_name(dev, 0, "gtx", &sc->gtx) != 0) {
+ device_printf(sc->base.dev, "could not get gtx clock\n");
+ return (ENXIO);
+ }
+
+ if (clk_get_by_ofw_name(dev, 0, "tx", &sc->tx) == 0) {
+ err = clk_enable(sc->tx);
+ if (err != 0) {
+ device_printf(dev, "Could not enable clock %s\n",
+ clk_get_name(sc->tx));
+ }
+ }
+ if (clk_get_by_ofw_name(dev, 0, "stmmaceth", &sc->stmmaceth) == 0) {
+ err = clk_enable(sc->stmmaceth);
+ if (err != 0) {
+ device_printf(dev, "Could not enable clock %s\n",
+ clk_get_name(sc->stmmaceth));
+ }
+ }
+ if (clk_get_by_ofw_name(dev, 0, "pclk", &sc->pclk) == 0) {
+ err = clk_enable(sc->pclk);
+ if (err != 0) {
+ device_printf(dev, "Could not enable clock %s\n",
+ clk_get_name(sc->pclk));
+ }
+ }
+
+ return (0);
+}
+
+static int
+if_eqos_starfive_init(device_t dev)
+{
+ struct if_eqos_starfive_softc *sc = device_get_softc(dev);
+ hwreset_t rst_ahb, rst_stmmaceth;
+ phandle_t node;
+
+ node = ofw_bus_get_node(dev);
+
+ sc->base.ttc = 0x10;
+ sc->base.rtc = 0;
+
+ if (OF_hasprop(node, "snps,force_thresh_dma_mode"))
+ sc->base.thresh_dma_mode = true;
+
+ if (OF_hasprop(node, "snps,no-pbl-x8"))
+ sc->base.pblx8 = false;
+
+ if (OF_hasprop(node, "snps,txpbl")) {
+ OF_getencprop(node, "snps,txpbl", &sc->base.txpbl,
+ sizeof(sc->base.txpbl));
+ }
+ if (OF_hasprop(node, "snps,rxpbl")) {
+ OF_getencprop(node, "snps,rxpbl", &sc->base.rxpbl,
+ sizeof(sc->base.rxpbl));
+ }
+
+ if (hwreset_get_by_ofw_name(dev, 0, "ahb", &rst_ahb)) {
+ device_printf(dev, "Cannot get ahb reset\n");
+ return (ENXIO);
+ }
+ if (hwreset_assert(rst_ahb) != 0) {
+ device_printf(dev, "Cannot assert ahb reset\n");
+ return (ENXIO);
+ }
+
+ if (hwreset_get_by_ofw_name(dev, 0, "stmmaceth", &rst_stmmaceth)) {
+ device_printf(dev, "Cannot get stmmaceth reset\n");
+ return (ENXIO);
+ }
+ if (hwreset_assert(rst_stmmaceth) != 0) {
+ device_printf(dev, "Cannot assert stmmaceth reset\n");
+ return (ENXIO);
+ }
+
+ sc->base.csr_clock = JH7110_CSR_FREQ;
+ sc->base.csr_clock_range = GMAC_MAC_MDIO_ADDRESS_CR_150_250;
+
+ if (if_eqos_starfive_clk_init(dev) != 0) {
+ device_printf(dev, "Clock initialization failed\n");
+ return (ENXIO);
+ }
+ if (hwreset_deassert(rst_ahb) != 0) {
+ device_printf(dev, "Cannot deassert rst_ahb\n");
+ return (ENXIO);
+ }
+ if (hwreset_deassert(rst_stmmaceth) != 0) {
+ device_printf(dev, "Cannot deassert rst_stmmaceth\n");
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+static int
+eqos_starfive_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+ if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0)
+ return (ENXIO);
+
+ device_set_desc(dev, "DesignWare EQOS Gigabit Ethernet for JH7110");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+
+static device_method_t eqos_starfive_methods[] = {
+ /* Device interface */
+ DEVMETHOD(device_probe, eqos_starfive_probe),
+
+ /* EQOS interface */
+ DEVMETHOD(if_eqos_init, if_eqos_starfive_init),
+ DEVMETHOD(if_eqos_set_speed, if_eqos_starfive_set_speed),
+
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_1(eqos, eqos_starfive_driver, eqos_starfive_methods,
+ sizeof(struct if_eqos_starfive_softc), eqos_driver);
+DRIVER_MODULE(eqos_starfive, simplebus, eqos_starfive_driver, 0, 0);
diff --git a/sys/dev/eqos/if_eqos_var.h b/sys/dev/eqos/if_eqos_var.h
--- a/sys/dev/eqos/if_eqos_var.h
+++ b/sys/dev/eqos/if_eqos_var.h
@@ -85,6 +85,13 @@
bool link_up;
int tx_watchdog;
+ bool thresh_dma_mode;
+ bool pblx8;
+ uint32_t txpbl;
+ uint32_t rxpbl;
+ uint32_t ttc;
+ uint32_t rtc;
+
struct ifnet *ifp;
device_t miibus;
struct mtx lock;
diff --git a/sys/riscv/conf/std.starfive b/sys/riscv/conf/std.starfive
--- a/sys/riscv/conf/std.starfive
+++ b/sys/riscv/conf/std.starfive
@@ -4,6 +4,8 @@
device uart_snps # DesignWare Synopsis UART driver
+device eqos
+
# MMC/SD/SDIO Card slot support
device dwmmc
device dwmmc_starfive
diff --git a/sys/riscv/starfive/files.starfive b/sys/riscv/starfive/files.starfive
--- a/sys/riscv/starfive/files.starfive
+++ b/sys/riscv/starfive/files.starfive
@@ -5,4 +5,8 @@
dev/clk/starfive/jh7110_clk_stg.c standard
dev/mmc/host/dwmmc_starfive.c optional dwmmc_starfive fdt
+dev/eqos/if_eqos.c optional eqos
+dev/eqos/if_eqos_if.m optional eqos
+dev/eqos/if_eqos_starfive.c optional eqos
+
riscv/starfive/starfive_syscon.c standard
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Sep 11, 6:17 PM (10 h, 51 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29560567
Default Alt Text
D45600.1789150652.diff (9 KB)
Attached To
Mode
D45600: Add StarFive JH7110's Ethernet (eqos & mcommphy modifications, a new board specific file)
Attached
Detach File
Event Timeline
Log In to Comment