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 <jrt...@jrtc27.com>
  Reviewed by:  James Clarke <jrt...@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);
        }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to