svn commit: r357653 - in head/sys/dev: xdma xilinx
Ruslan Bukin
br at FreeBSD.org
Fri Feb 7 14:36:30 UTC 2020
Author: br
Date: Fri Feb 7 14:36:28 2020
New Revision: 357653
URL: https://svnweb.freebsd.org/changeset/base/357653
Log:
Fix xae(4) driver attachement on the Government Furnished Equipment (GFE)
riscv cores.
GFE cores come with standard DTS file that lacks standard 'dmas ='
property, which means xae(4) could not find a DMA controller to use.
The 'dmas' property could not be added to the DTS file because the
ethernet controller and DMA engine parts in Linux are implemented
in a single driver.
Instead of 'dmas' property the standard Xilinx 'axistream-connected'
property is provided, so fallback to use it instead.
Suggested by: James Clarke <jrtc27 at jrtc27.com>
Reviewed by: James Clarke <jrtc27 at jrtc27.com>
Sponsored by: DARPA, AFRL
Modified:
head/sys/dev/xdma/xdma.c
head/sys/dev/xdma/xdma.h
head/sys/dev/xilinx/axidma.c
head/sys/dev/xilinx/axidma.h
head/sys/dev/xilinx/if_xae.c
Modified: head/sys/dev/xdma/xdma.c
==============================================================================
--- head/sys/dev/xdma/xdma.c Fri Feb 7 12:26:38 2020 (r357652)
+++ head/sys/dev/xdma/xdma.c Fri Feb 7 14:36:28 2020 (r357653)
@@ -511,6 +511,24 @@ xdma_ofw_get(device_t dev, const char *prop)
#endif
/*
+ * Allocate xdma controller.
+ */
+xdma_controller_t *
+xdma_get(device_t dev, device_t dma_dev)
+{
+ xdma_controller_t *xdma;
+
+ xdma = malloc(sizeof(struct xdma_controller),
+ M_XDMA, M_WAITOK | M_ZERO);
+ xdma->dev = dev;
+ xdma->dma_dev = dma_dev;
+
+ TAILQ_INIT(&xdma->channels);
+
+ return (xdma);
+}
+
+/*
* Free xDMA controller object.
*/
int
Modified: head/sys/dev/xdma/xdma.h
==============================================================================
--- head/sys/dev/xdma/xdma.h Fri Feb 7 12:26:38 2020 (r357652)
+++ head/sys/dev/xdma/xdma.h Fri Feb 7 14:36:28 2020 (r357653)
@@ -231,6 +231,7 @@ static MALLOC_DEFINE(M_XDMA, "xdma", "xDMA framework")
/* xDMA controller ops */
xdma_controller_t *xdma_ofw_get(device_t dev, const char *prop);
+xdma_controller_t *xdma_get(device_t dev, device_t dma_dev);
int xdma_put(xdma_controller_t *xdma);
vmem_t * xdma_get_memory(device_t dev);
void xdma_put_memory(vmem_t *vmem);
Modified: head/sys/dev/xilinx/axidma.c
==============================================================================
--- head/sys/dev/xilinx/axidma.c Fri Feb 7 12:26:38 2020 (r357652)
+++ head/sys/dev/xilinx/axidma.c Fri Feb 7 14:36:28 2020 (r357653)
@@ -61,6 +61,15 @@ __FBSDID("$FreeBSD$");
#include "xdma_if.h"
+#define READ4(_sc, _reg) \
+ bus_space_read_4(_sc->bst, _sc->bsh, _reg)
+#define WRITE4(_sc, _reg, _val) \
+ bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
+#define READ8(_sc, _reg) \
+ bus_space_read_8(_sc->bst, _sc->bsh, _reg)
+#define WRITE8(_sc, _reg, _val) \
+ bus_space_write_8(_sc->bst, _sc->bsh, _reg, _val)
+
#define AXIDMA_DEBUG
#undef AXIDMA_DEBUG
@@ -70,16 +79,7 @@ __FBSDID("$FreeBSD$");
#define dprintf(fmt, ...)
#endif
-#define AXIDMA_NCHANNELS 2
-#define AXIDMA_DESCS_NUM 512
-#define AXIDMA_TX_CHAN 0
-#define AXIDMA_RX_CHAN 1
-
extern struct bus_space memmap_bus;
-
-struct axidma_fdt_data {
- int id;
-};
struct axidma_channel {
struct axidma_softc *sc;
Modified: head/sys/dev/xilinx/axidma.h
==============================================================================
--- head/sys/dev/xilinx/axidma.h Fri Feb 7 12:26:38 2020 (r357652)
+++ head/sys/dev/xilinx/axidma.h Fri Feb 7 14:36:28 2020 (r357653)
@@ -60,14 +60,10 @@
#define AXI_TAILDESC_MSB(n) (0x14 + 0x30 * (n)) /* Tail Descriptor Pointer. Upper 32 bits of address. */
#define AXI_SG_CTL 0x2C /* Scatter/Gather User and Cache */
-#define READ4(_sc, _reg) \
- bus_space_read_4(_sc->bst, _sc->bsh, _reg)
-#define WRITE4(_sc, _reg, _val) \
- bus_space_write_4(_sc->bst, _sc->bsh, _reg, _val)
-#define READ8(_sc, _reg) \
- bus_space_read_8(_sc->bst, _sc->bsh, _reg)
-#define WRITE8(_sc, _reg, _val) \
- bus_space_write_8(_sc->bst, _sc->bsh, _reg, _val)
+#define AXIDMA_NCHANNELS 2
+#define AXIDMA_DESCS_NUM 512
+#define AXIDMA_TX_CHAN 0
+#define AXIDMA_RX_CHAN 1
struct axidma_desc {
uint32_t next;
@@ -91,6 +87,10 @@ struct axidma_desc {
uint32_t app3;
uint32_t app4;
uint32_t reserved[3];
+};
+
+struct axidma_fdt_data {
+ int id;
};
#endif /* !_DEV_XILINX_AXIDMA_H_ */
Modified: head/sys/dev/xilinx/if_xae.c
==============================================================================
--- head/sys/dev/xilinx/if_xae.c Fri Feb 7 12:26:38 2020 (r357652)
+++ head/sys/dev/xilinx/if_xae.c Fri Feb 7 14:36:28 2020 (r357653)
@@ -64,6 +64,8 @@ __FBSDID("$FreeBSD$");
#include <dev/xilinx/if_xaereg.h>
#include <dev/xilinx/if_xaevar.h>
+#include <dev/xilinx/axidma.h>
+
#include "miibus_if.h"
#define READ4(_sc, _reg) \
@@ -775,6 +777,68 @@ xae_phy_fixup(struct xae_softc *sc)
}
static int
+get_xdma_std(struct xae_softc *sc)
+{
+
+ sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
+ if (sc->xdma_tx == NULL)
+ return (ENXIO);
+
+ sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
+ if (sc->xdma_rx == NULL) {
+ xdma_put(sc->xdma_tx);
+ return (ENXIO);
+ }
+
+ return (0);
+}
+
+static int
+get_xdma_axistream(struct xae_softc *sc)
+{
+ struct axidma_fdt_data *data;
+ device_t dma_dev;
+ phandle_t node;
+ pcell_t prop;
+ size_t len;
+
+ node = ofw_bus_get_node(sc->dev);
+ len = OF_getencprop(node, "axistream-connected", &prop, sizeof(prop));
+ if (len != sizeof(prop)) {
+ device_printf(sc->dev,
+ "%s: Couldn't get axistream-connected prop.\n", __func__);
+ return (ENXIO);
+ }
+ dma_dev = OF_device_from_xref(prop);
+ if (dma_dev == NULL) {
+ device_printf(sc->dev, "Could not get DMA device by xref.\n");
+ return (ENXIO);
+ }
+
+ sc->xdma_tx = xdma_get(sc->dev, dma_dev);
+ if (sc->xdma_tx == NULL) {
+ device_printf(sc->dev, "Could not find DMA controller.\n");
+ return (ENXIO);
+ }
+ data = malloc(sizeof(struct axidma_fdt_data),
+ M_DEVBUF, (M_WAITOK | M_ZERO));
+ data->id = AXIDMA_TX_CHAN;
+ sc->xdma_tx->data = data;
+
+ sc->xdma_rx = xdma_get(sc->dev, dma_dev);
+ if (sc->xdma_rx == NULL) {
+ device_printf(sc->dev, "Could not find DMA controller.\n");
+ return (ENXIO);
+ }
+ data = malloc(sizeof(struct axidma_fdt_data),
+ M_DEVBUF, (M_WAITOK | M_ZERO));
+ data->id = AXIDMA_RX_CHAN;
+ sc->xdma_rx->data = data;
+
+ return (0);
+}
+
+static int
setup_xdma(struct xae_softc *sc)
{
device_t dev;
@@ -784,15 +848,16 @@ setup_xdma(struct xae_softc *sc)
dev = sc->dev;
/* Get xDMA controller */
- sc->xdma_tx = xdma_ofw_get(sc->dev, "tx");
- if (sc->xdma_tx == NULL) {
- device_printf(dev, "Could not find DMA controller.\n");
- return (ENXIO);
+ error = get_xdma_std(sc);
+
+ if (error) {
+ device_printf(sc->dev,
+ "Fallback to axistream-connected property\n");
+ error = get_xdma_axistream(sc);
}
- sc->xdma_rx = xdma_ofw_get(sc->dev, "rx");
- if (sc->xdma_rx == NULL) {
- device_printf(dev, "Could not find DMA controller.\n");
+ if (error) {
+ device_printf(dev, "Could not find xDMA controllers.\n");
return (ENXIO);
}
More information about the svn-src-all
mailing list