diff options
author | Vinod Koul <vinod.koul@intel.com> | 2015-10-30 22:07:05 -0400 |
---|---|---|
committer | Vinod Koul <vinod.koul@intel.com> | 2015-10-30 22:07:05 -0400 |
commit | 3638691c64728bad2714a7d4908516997319c481 (patch) | |
tree | a28b97b74af872e4cf5ed2ab2e004848e9252ab5 | |
parent | 7d9d43ace29be375d3d1654b688b94029308a1be (diff) | |
parent | 97c37accd38f6136fa0abbdef01b5f864e91e6c7 (diff) |
Merge branch 'topic/idma' into for-linus
-rw-r--r-- | drivers/dma/Kconfig | 2 | ||||
-rw-r--r-- | drivers/dma/Makefile | 2 | ||||
-rw-r--r-- | drivers/dma/idma64.c | 22 | ||||
-rw-r--r-- | drivers/dma/idma64.h | 14 |
4 files changed, 19 insertions, 21 deletions
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index 6a388a7c6429..e6cd1a32025a 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig | |||
@@ -229,7 +229,7 @@ config IMX_SDMA | |||
229 | Support the i.MX SDMA engine. This engine is integrated into | 229 | Support the i.MX SDMA engine. This engine is integrated into |
230 | Freescale i.MX25/31/35/51/53/6 chips. | 230 | Freescale i.MX25/31/35/51/53/6 chips. |
231 | 231 | ||
232 | config IDMA64 | 232 | config INTEL_IDMA64 |
233 | tristate "Intel integrated DMA 64-bit support" | 233 | tristate "Intel integrated DMA 64-bit support" |
234 | select DMA_ENGINE | 234 | select DMA_ENGINE |
235 | select DMA_VIRTUAL_CHANNELS | 235 | select DMA_VIRTUAL_CHANNELS |
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 7711a7180726..ef9c099bd2b6 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile | |||
@@ -34,7 +34,7 @@ obj-$(CONFIG_HSU_DMA) += hsu/ | |||
34 | obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o | 34 | obj-$(CONFIG_IMG_MDC_DMA) += img-mdc-dma.o |
35 | obj-$(CONFIG_IMX_DMA) += imx-dma.o | 35 | obj-$(CONFIG_IMX_DMA) += imx-dma.o |
36 | obj-$(CONFIG_IMX_SDMA) += imx-sdma.o | 36 | obj-$(CONFIG_IMX_SDMA) += imx-sdma.o |
37 | obj-$(CONFIG_IDMA64) += idma64.o | 37 | obj-$(CONFIG_INTEL_IDMA64) += idma64.o |
38 | obj-$(CONFIG_INTEL_IOATDMA) += ioat/ | 38 | obj-$(CONFIG_INTEL_IOATDMA) += ioat/ |
39 | obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o | 39 | obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o |
40 | obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o | 40 | obj-$(CONFIG_INTEL_MIC_X100_DMA) += mic_x100_dma.o |
diff --git a/drivers/dma/idma64.c b/drivers/dma/idma64.c index 18c14e1f1414..39e6ab1d01fb 100644 --- a/drivers/dma/idma64.c +++ b/drivers/dma/idma64.c | |||
@@ -65,9 +65,6 @@ static void idma64_chan_init(struct idma64 *idma64, struct idma64_chan *idma64c) | |||
65 | u32 cfghi = IDMA64C_CFGH_SRC_PER(1) | IDMA64C_CFGH_DST_PER(0); | 65 | u32 cfghi = IDMA64C_CFGH_SRC_PER(1) | IDMA64C_CFGH_DST_PER(0); |
66 | u32 cfglo = 0; | 66 | u32 cfglo = 0; |
67 | 67 | ||
68 | /* Enforce FIFO drain when channel is suspended */ | ||
69 | cfglo |= IDMA64C_CFGL_CH_DRAIN; | ||
70 | |||
71 | /* Set default burst alignment */ | 68 | /* Set default burst alignment */ |
72 | cfglo |= IDMA64C_CFGL_DST_BURST_ALIGN | IDMA64C_CFGL_SRC_BURST_ALIGN; | 69 | cfglo |= IDMA64C_CFGL_DST_BURST_ALIGN | IDMA64C_CFGL_SRC_BURST_ALIGN; |
73 | 70 | ||
@@ -257,15 +254,15 @@ static u64 idma64_hw_desc_fill(struct idma64_hw_desc *hw, | |||
257 | dar = config->dst_addr; | 254 | dar = config->dst_addr; |
258 | ctllo |= IDMA64C_CTLL_DST_FIX | IDMA64C_CTLL_SRC_INC | | 255 | ctllo |= IDMA64C_CTLL_DST_FIX | IDMA64C_CTLL_SRC_INC | |
259 | IDMA64C_CTLL_FC_M2P; | 256 | IDMA64C_CTLL_FC_M2P; |
260 | src_width = min_t(u32, 2, __fls(sar | hw->len)); | 257 | src_width = __ffs(sar | hw->len | 4); |
261 | dst_width = __fls(config->dst_addr_width); | 258 | dst_width = __ffs(config->dst_addr_width); |
262 | } else { /* DMA_DEV_TO_MEM */ | 259 | } else { /* DMA_DEV_TO_MEM */ |
263 | sar = config->src_addr; | 260 | sar = config->src_addr; |
264 | dar = hw->phys; | 261 | dar = hw->phys; |
265 | ctllo |= IDMA64C_CTLL_DST_INC | IDMA64C_CTLL_SRC_FIX | | 262 | ctllo |= IDMA64C_CTLL_DST_INC | IDMA64C_CTLL_SRC_FIX | |
266 | IDMA64C_CTLL_FC_P2M; | 263 | IDMA64C_CTLL_FC_P2M; |
267 | src_width = __fls(config->src_addr_width); | 264 | src_width = __ffs(config->src_addr_width); |
268 | dst_width = min_t(u32, 2, __fls(dar | hw->len)); | 265 | dst_width = __ffs(dar | hw->len | 4); |
269 | } | 266 | } |
270 | 267 | ||
271 | lli->sar = sar; | 268 | lli->sar = sar; |
@@ -428,12 +425,17 @@ static int idma64_slave_config(struct dma_chan *chan, | |||
428 | return 0; | 425 | return 0; |
429 | } | 426 | } |
430 | 427 | ||
431 | static void idma64_chan_deactivate(struct idma64_chan *idma64c) | 428 | static void idma64_chan_deactivate(struct idma64_chan *idma64c, bool drain) |
432 | { | 429 | { |
433 | unsigned short count = 100; | 430 | unsigned short count = 100; |
434 | u32 cfglo; | 431 | u32 cfglo; |
435 | 432 | ||
436 | cfglo = channel_readl(idma64c, CFG_LO); | 433 | cfglo = channel_readl(idma64c, CFG_LO); |
434 | if (drain) | ||
435 | cfglo |= IDMA64C_CFGL_CH_DRAIN; | ||
436 | else | ||
437 | cfglo &= ~IDMA64C_CFGL_CH_DRAIN; | ||
438 | |||
437 | channel_writel(idma64c, CFG_LO, cfglo | IDMA64C_CFGL_CH_SUSP); | 439 | channel_writel(idma64c, CFG_LO, cfglo | IDMA64C_CFGL_CH_SUSP); |
438 | do { | 440 | do { |
439 | udelay(1); | 441 | udelay(1); |
@@ -456,7 +458,7 @@ static int idma64_pause(struct dma_chan *chan) | |||
456 | 458 | ||
457 | spin_lock_irqsave(&idma64c->vchan.lock, flags); | 459 | spin_lock_irqsave(&idma64c->vchan.lock, flags); |
458 | if (idma64c->desc && idma64c->desc->status == DMA_IN_PROGRESS) { | 460 | if (idma64c->desc && idma64c->desc->status == DMA_IN_PROGRESS) { |
459 | idma64_chan_deactivate(idma64c); | 461 | idma64_chan_deactivate(idma64c, false); |
460 | idma64c->desc->status = DMA_PAUSED; | 462 | idma64c->desc->status = DMA_PAUSED; |
461 | } | 463 | } |
462 | spin_unlock_irqrestore(&idma64c->vchan.lock, flags); | 464 | spin_unlock_irqrestore(&idma64c->vchan.lock, flags); |
@@ -486,7 +488,7 @@ static int idma64_terminate_all(struct dma_chan *chan) | |||
486 | LIST_HEAD(head); | 488 | LIST_HEAD(head); |
487 | 489 | ||
488 | spin_lock_irqsave(&idma64c->vchan.lock, flags); | 490 | spin_lock_irqsave(&idma64c->vchan.lock, flags); |
489 | idma64_chan_deactivate(idma64c); | 491 | idma64_chan_deactivate(idma64c, true); |
490 | idma64_stop_transfer(idma64c); | 492 | idma64_stop_transfer(idma64c); |
491 | if (idma64c->desc) { | 493 | if (idma64c->desc) { |
492 | idma64_vdesc_free(&idma64c->desc->vdesc); | 494 | idma64_vdesc_free(&idma64c->desc->vdesc); |
diff --git a/drivers/dma/idma64.h b/drivers/dma/idma64.h index a4d99685a7c4..f6aeff0af8a5 100644 --- a/drivers/dma/idma64.h +++ b/drivers/dma/idma64.h | |||
@@ -16,6 +16,8 @@ | |||
16 | #include <linux/spinlock.h> | 16 | #include <linux/spinlock.h> |
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | 18 | ||
19 | #include <asm-generic/io-64-nonatomic-lo-hi.h> | ||
20 | |||
19 | #include "virt-dma.h" | 21 | #include "virt-dma.h" |
20 | 22 | ||
21 | /* Channel registers */ | 23 | /* Channel registers */ |
@@ -166,19 +168,13 @@ static inline void idma64c_writel(struct idma64_chan *idma64c, int offset, | |||
166 | 168 | ||
167 | static inline u64 idma64c_readq(struct idma64_chan *idma64c, int offset) | 169 | static inline u64 idma64c_readq(struct idma64_chan *idma64c, int offset) |
168 | { | 170 | { |
169 | u64 l, h; | 171 | return lo_hi_readq(idma64c->regs + offset); |
170 | |||
171 | l = idma64c_readl(idma64c, offset); | ||
172 | h = idma64c_readl(idma64c, offset + 4); | ||
173 | |||
174 | return l | (h << 32); | ||
175 | } | 172 | } |
176 | 173 | ||
177 | static inline void idma64c_writeq(struct idma64_chan *idma64c, int offset, | 174 | static inline void idma64c_writeq(struct idma64_chan *idma64c, int offset, |
178 | u64 value) | 175 | u64 value) |
179 | { | 176 | { |
180 | idma64c_writel(idma64c, offset, value); | 177 | lo_hi_writeq(value, idma64c->regs + offset); |
181 | idma64c_writel(idma64c, offset + 4, value >> 32); | ||
182 | } | 178 | } |
183 | 179 | ||
184 | #define channel_readq(idma64c, reg) \ | 180 | #define channel_readq(idma64c, reg) \ |
@@ -217,7 +213,7 @@ static inline void idma64_writel(struct idma64 *idma64, int offset, u32 value) | |||
217 | idma64_writel(idma64, IDMA64_##reg, (value)) | 213 | idma64_writel(idma64, IDMA64_##reg, (value)) |
218 | 214 | ||
219 | /** | 215 | /** |
220 | * struct idma64_chip - representation of DesignWare DMA controller hardware | 216 | * struct idma64_chip - representation of iDMA 64-bit controller hardware |
221 | * @dev: struct device of the DMA controller | 217 | * @dev: struct device of the DMA controller |
222 | * @irq: irq line | 218 | * @irq: irq line |
223 | * @regs: memory mapped I/O space | 219 | * @regs: memory mapped I/O space |