aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/xilinx
diff options
context:
space:
mode:
authorRuslan Bukin <br@FreeBSD.org>2020-02-07 14:36:28 +0000
committerRuslan Bukin <br@FreeBSD.org>2020-02-07 14:36:28 +0000
commita8692c16c962027f141facc357ee28578ccf04b7 (patch)
tree0457fa9ab94616ffc04853c23607e71de3f8b455 /sys/dev/xilinx
parent79208b1025f3a99aea828109b5423a62be3f87b0 (diff)
Notes
Diffstat (limited to 'sys/dev/xilinx')
-rw-r--r--sys/dev/xilinx/axidma.c18
-rw-r--r--sys/dev/xilinx/axidma.h16
-rw-r--r--sys/dev/xilinx/if_xae.c79
3 files changed, 89 insertions, 24 deletions
diff --git a/sys/dev/xilinx/axidma.c b/sys/dev/xilinx/axidma.c
index 3c9b1b5c6dc70..32683de787d35 100644
--- a/sys/dev/xilinx/axidma.c
+++ b/sys/dev/xilinx/axidma.c
@@ -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,17 +79,8 @@ __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;
xdma_channel_t *xchan;
diff --git a/sys/dev/xilinx/axidma.h b/sys/dev/xilinx/axidma.h
index 8e5d83874eee9..addacb463d2a4 100644
--- a/sys/dev/xilinx/axidma.h
+++ b/sys/dev/xilinx/axidma.h
@@ -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;
@@ -93,4 +89,8 @@ struct axidma_desc {
uint32_t reserved[3];
};
+struct axidma_fdt_data {
+ int id;
+};
+
#endif /* !_DEV_XILINX_AXIDMA_H_ */
diff --git a/sys/dev/xilinx/if_xae.c b/sys/dev/xilinx/if_xae.c
index bde6470c43763..e6dbb15de75e0 100644
--- a/sys/dev/xilinx/if_xae.c
+++ b/sys/dev/xilinx/if_xae.c
@@ -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);
}