]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
dmaengine: ioatdma: add descriptor pre-fetch support for v3.4
authorDave Jiang <dave.jiang@intel.com>
Fri, 22 Feb 2019 17:00:05 +0000 (10:00 -0700)
committerVinod Koul <vkoul@kernel.org>
Mon, 25 Feb 2019 06:48:38 +0000 (12:18 +0530)
Adding support for new feature on ioatdma 3.4 hardware that provides
descriptor pre-fetching in order to reduce small DMA latencies.

Signed-off-by: Dave Jiang <dave.jiang@intel.com>
Signed-off-by: Vinod Koul <vkoul@kernel.org>
drivers/dma/ioat/dma.c
drivers/dma/ioat/init.c
drivers/dma/ioat/registers.h

index 23fb2fa040002daeb3e248036efa261b63b3769e..f373a139e0c37b175dbce3a1c2a9658ef7a1bb05 100644 (file)
@@ -372,6 +372,7 @@ struct ioat_ring_ent **
 ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags)
 {
        struct ioatdma_chan *ioat_chan = to_ioat_chan(c);
+       struct ioatdma_device *ioat_dma = ioat_chan->ioat_dma;
        struct ioat_ring_ent **ring;
        int total_descs = 1 << order;
        int i, chunks;
@@ -437,6 +438,17 @@ ioat_alloc_ring(struct dma_chan *c, int order, gfp_t flags)
        }
        ring[i]->hw->next = ring[0]->txd.phys;
 
+       /* setup descriptor pre-fetching for v3.4 */
+       if (ioat_dma->cap & IOAT_CAP_DPS) {
+               u16 drsctl = IOAT_CHAN_DRSZ_2MB | IOAT_CHAN_DRS_EN;
+
+               if (chunks == 1)
+                       drsctl |= IOAT_CHAN_DRS_AUTOWRAP;
+
+               writew(drsctl, ioat_chan->reg_base + IOAT_CHAN_DRSCTL_OFFSET);
+
+       }
+
        return ring;
 }
 
index 58dd1bfd3eddaec5b1e6b2f15fc5e4766c6dfab8..020bcdecb3fb800f19142704eae29f04e80c68b6 100644 (file)
@@ -138,10 +138,10 @@ static int ioat3_dma_self_test(struct ioatdma_device *ioat_dma);
 static int ioat_dca_enabled = 1;
 module_param(ioat_dca_enabled, int, 0644);
 MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
-int ioat_pending_level = 4;
+int ioat_pending_level = 7;
 module_param(ioat_pending_level, int, 0644);
 MODULE_PARM_DESC(ioat_pending_level,
-                "high-water mark for pushing ioat descriptors (default: 4)");
+                "high-water mark for pushing ioat descriptors (default: 7)");
 static char ioat_interrupt_style[32] = "msix";
 module_param_string(ioat_interrupt_style, ioat_interrupt_style,
                    sizeof(ioat_interrupt_style), 0644);
@@ -1188,6 +1188,10 @@ static int ioat3_dma_probe(struct ioatdma_device *ioat_dma, int dca)
        if (err)
                return err;
 
+       if (ioat_dma->cap & IOAT_CAP_DPS)
+               writeb(ioat_pending_level + 1,
+                      ioat_dma->reg_base + IOAT_PREFETCH_LIMIT_OFFSET);
+
        return 0;
 }
 
index 2f3bbc88ff2a0faca2bed832525c7a6fd1c475b3..2b517d6db5fd37cf8a43dd8d68fe85736a0f3b9f 100644 (file)
@@ -84,6 +84,9 @@
 #define IOAT_CAP_PQ                            0x00000200
 #define IOAT_CAP_DWBES                         0x00002000
 #define IOAT_CAP_RAID16SS                      0x00020000
+#define IOAT_CAP_DPS                           0x00800000
+
+#define IOAT_PREFETCH_LIMIT_OFFSET             0x4C    /* CHWPREFLMT */
 
 #define IOAT_CHANNEL_MMIO_SIZE                 0x80    /* Each Channel MMIO space is this size */
 
 
 #define IOAT_CHANERR_MASK_OFFSET               0x2C    /* 32-bit Channel Error Register */
 
+#define IOAT_CHAN_DRSCTL_OFFSET                        0xB6
+#define IOAT_CHAN_DRSZ_4KB                     0x0000
+#define IOAT_CHAN_DRSZ_8KB                     0x0001
+#define IOAT_CHAN_DRSZ_2MB                     0x0009
+#define IOAT_CHAN_DRS_EN                       0x0100
+#define IOAT_CHAN_DRS_AUTOWRAP                 0x0200
+
 #endif /* _IOAT_REGISTERS_H_ */