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-head mailing list