]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
dmaengine: ioatdma: support latency tolerance report (LTR) for v3.4
authorDave Jiang <dave.jiang@intel.com>
Fri, 22 Feb 2019 17:00:10 +0000 (10:00 -0700)
committerVinod Koul <vkoul@kernel.org>
Mon, 25 Feb 2019 06:48:38 +0000 (12:18 +0530)
IOATDMA 3.4 supports PCIe LTR mechanism. The registers are non-standard
PCIe LTR support. This needs to be setup in order to not suffer performance
impact and provide proper power management. The channel is set to active
when it is allocated, and to passive when it's freed.

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

index 020bcdecb3fb800f19142704eae29f04e80c68b6..d41dc9a9ff68da6e82ccf69e982c252ee56fc88b 100644 (file)
@@ -638,6 +638,11 @@ static void ioat_free_chan_resources(struct dma_chan *c)
        ioat_stop(ioat_chan);
        ioat_reset_hw(ioat_chan);
 
+       /* Put LTR to idle */
+       if (ioat_dma->version >= IOAT_VER_3_4)
+               writeb(IOAT_CHAN_LTR_SWSEL_IDLE,
+                       ioat_chan->reg_base + IOAT_CHAN_LTR_SWSEL_OFFSET);
+
        spin_lock_bh(&ioat_chan->cleanup_lock);
        spin_lock_bh(&ioat_chan->prep_lock);
        descs = ioat_ring_space(ioat_chan);
@@ -727,6 +732,28 @@ static int ioat_alloc_chan_resources(struct dma_chan *c)
        spin_unlock_bh(&ioat_chan->prep_lock);
        spin_unlock_bh(&ioat_chan->cleanup_lock);
 
+       /* Setting up LTR values for 3.4 or later */
+       if (ioat_chan->ioat_dma->version >= IOAT_VER_3_4) {
+               u32 lat_val;
+
+               lat_val = IOAT_CHAN_LTR_ACTIVE_SNVAL |
+                       IOAT_CHAN_LTR_ACTIVE_SNLATSCALE |
+                       IOAT_CHAN_LTR_ACTIVE_SNREQMNT;
+               writel(lat_val, ioat_chan->reg_base +
+                               IOAT_CHAN_LTR_ACTIVE_OFFSET);
+
+               lat_val = IOAT_CHAN_LTR_IDLE_SNVAL |
+                         IOAT_CHAN_LTR_IDLE_SNLATSCALE |
+                         IOAT_CHAN_LTR_IDLE_SNREQMNT;
+               writel(lat_val, ioat_chan->reg_base +
+                               IOAT_CHAN_LTR_IDLE_OFFSET);
+
+               /* Select to active */
+               writeb(IOAT_CHAN_LTR_SWSEL_ACTIVE,
+                      ioat_chan->reg_base +
+                      IOAT_CHAN_LTR_SWSEL_OFFSET);
+       }
+
        ioat_start_null_desc(ioat_chan);
 
        /* check that we got off the ground */
index 2b517d6db5fd37cf8a43dd8d68fe85736a0f3b9f..99c1c24d465dade2e2a7093a9c2eb2ba9a420d37 100644 (file)
 #define IOAT_CHAN_DRS_EN                       0x0100
 #define IOAT_CHAN_DRS_AUTOWRAP                 0x0200
 
+#define IOAT_CHAN_LTR_SWSEL_OFFSET             0xBC
+#define IOAT_CHAN_LTR_SWSEL_ACTIVE             0x0
+#define IOAT_CHAN_LTR_SWSEL_IDLE               0x1
+
+#define IOAT_CHAN_LTR_ACTIVE_OFFSET            0xC0
+#define IOAT_CHAN_LTR_ACTIVE_SNVAL             0x0000  /* 0 us */
+#define IOAT_CHAN_LTR_ACTIVE_SNLATSCALE                0x0800  /* 1us scale */
+#define IOAT_CHAN_LTR_ACTIVE_SNREQMNT          0x8000  /* snoop req enable */
+
+#define IOAT_CHAN_LTR_IDLE_OFFSET              0xC4
+#define IOAT_CHAN_LTR_IDLE_SNVAL               0x0258  /* 600 us */
+#define IOAT_CHAN_LTR_IDLE_SNLATSCALE          0x0800  /* 1us scale */
+#define IOAT_CHAN_LTR_IDLE_SNREQMNT            0x8000  /* snoop req enable */
+
 #endif /* _IOAT_REGISTERS_H_ */