aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/dma
diff options
context:
space:
mode:
authorGuennadi Liakhovetski <g.liakhovetski@gmx.de>2010-02-11 11:50:14 -0500
committerPaul Mundt <lethal@linux-sh.org>2010-03-01 21:09:04 -0500
commit8b1935e6a36b0967efc593d67ed3aebbfbc1f5b1 (patch)
tree811ebd670e9704790625137b4a824e548bded00b /drivers/dma
parent027811b9b81a6b3ae5aa20c3302897bee9dcf09e (diff)
dmaengine: shdma: separate DMA headers.
Separate SH DMA headers into ones, commonly used by both drivers, and ones, specific to each of them. This will make the future development of the dmaengine driver easier. Signed-off-by: Guennadi Liakhovetski <g.liakhovetski@gmx.de> Acked-by: Mark Brown <broonie@opensource.wolfsonmicro.com> Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/dma')
-rw-r--r--drivers/dma/shdma.c79
-rw-r--r--drivers/dma/shdma.h4
2 files changed, 52 insertions, 31 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index ab12fa5a1296..b419afaa2389 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -24,8 +24,7 @@
24#include <linux/delay.h> 24#include <linux/delay.h>
25#include <linux/dma-mapping.h> 25#include <linux/dma-mapping.h>
26#include <linux/platform_device.h> 26#include <linux/platform_device.h>
27#include <cpu/dma.h> 27#include <asm/dmaengine.h>
28#include <asm/dma-sh.h>
29#include "shdma.h" 28#include "shdma.h"
30 29
31/* DMA descriptor control */ 30/* DMA descriptor control */
@@ -38,15 +37,8 @@ enum sh_dmae_desc_status {
38}; 37};
39 38
40#define NR_DESCS_PER_CHANNEL 32 39#define NR_DESCS_PER_CHANNEL 32
41/* 40/* Default MEMCPY transfer size = 2^2 = 4 bytes */
42 * Define the default configuration for dual address memory-memory transfer. 41#define LOG2_DEFAULT_XFER_SIZE 2
43 * The 0x400 value represents auto-request, external->external.
44 *
45 * And this driver set 4byte burst mode.
46 * If you want to change mode, you need to change RS_DEFAULT of value.
47 * (ex 1byte burst mode -> (RS_DUAL & ~TS_32)
48 */
49#define RS_DEFAULT (RS_DUAL)
50 42
51/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */ 43/* A bitmask with bits enough for enum sh_dmae_slave_chan_id */
52static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)]; 44static unsigned long sh_dmae_slave_used[BITS_TO_LONGS(SHDMA_SLAVE_NUMBER)];
@@ -90,7 +82,7 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev)
90 unsigned short dmaor; 82 unsigned short dmaor;
91 83
92 sh_dmae_ctl_stop(shdev); 84 sh_dmae_ctl_stop(shdev);
93 dmaor = dmaor_read(shdev) | DMAOR_INIT; 85 dmaor = dmaor_read(shdev) | shdev->pdata->dmaor_init;
94 86
95 dmaor_write(shdev, dmaor); 87 dmaor_write(shdev, dmaor);
96 if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) { 88 if (dmaor_read(shdev) & (DMAOR_AE | DMAOR_NMIF)) {
@@ -110,13 +102,36 @@ static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
110 return false; /* waiting */ 102 return false; /* waiting */
111} 103}
112 104
113static unsigned int ts_shift[] = TS_SHIFT; 105static unsigned int calc_xmit_shift(struct sh_dmae_chan *sh_chan, u32 chcr)
114static inline unsigned int calc_xmit_shift(u32 chcr)
115{ 106{
116 int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) | 107 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
117 ((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); 108 struct sh_dmae_device, common);
109 struct sh_dmae_pdata *pdata = shdev->pdata;
110 int cnt = ((chcr & pdata->ts_low_mask) >> pdata->ts_low_shift) |
111 ((chcr & pdata->ts_high_mask) >> pdata->ts_high_shift);
112
113 if (cnt >= pdata->ts_shift_num)
114 cnt = 0;
118 115
119 return ts_shift[cnt]; 116 return pdata->ts_shift[cnt];
117}
118
119static u32 log2size_to_chcr(struct sh_dmae_chan *sh_chan, int l2size)
120{
121 struct sh_dmae_device *shdev = container_of(sh_chan->common.device,
122 struct sh_dmae_device, common);
123 struct sh_dmae_pdata *pdata = shdev->pdata;
124 int i;
125
126 for (i = 0; i < pdata->ts_shift_num; i++)
127 if (pdata->ts_shift[i] == l2size)
128 break;
129
130 if (i == pdata->ts_shift_num)
131 i = 0;
132
133 return ((i << pdata->ts_low_shift) & pdata->ts_low_mask) |
134 ((i << pdata->ts_high_shift) & pdata->ts_high_mask);
120} 135}
121 136
122static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw) 137static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
@@ -144,8 +159,13 @@ static void dmae_halt(struct sh_dmae_chan *sh_chan)
144 159
145static void dmae_init(struct sh_dmae_chan *sh_chan) 160static void dmae_init(struct sh_dmae_chan *sh_chan)
146{ 161{
147 u32 chcr = RS_DEFAULT; /* default is DUAL mode */ 162 /*
148 sh_chan->xmit_shift = calc_xmit_shift(chcr); 163 * Default configuration for dual address memory-memory transfer.
164 * 0x400 represents auto-request.
165 */
166 u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
167 LOG2_DEFAULT_XFER_SIZE);
168 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
149 sh_dmae_writel(sh_chan, chcr, CHCR); 169 sh_dmae_writel(sh_chan, chcr, CHCR);
150} 170}
151 171
@@ -155,7 +175,7 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
155 if (dmae_is_busy(sh_chan)) 175 if (dmae_is_busy(sh_chan))
156 return -EBUSY; 176 return -EBUSY;
157 177
158 sh_chan->xmit_shift = calc_xmit_shift(val); 178 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
159 sh_dmae_writel(sh_chan, val, CHCR); 179 sh_dmae_writel(sh_chan, val, CHCR);
160 180
161 return 0; 181 return 0;
@@ -285,9 +305,8 @@ static int sh_dmae_alloc_chan_resources(struct dma_chan *chan)
285 305
286 dmae_set_dmars(sh_chan, cfg->mid_rid); 306 dmae_set_dmars(sh_chan, cfg->mid_rid);
287 dmae_set_chcr(sh_chan, cfg->chcr); 307 dmae_set_chcr(sh_chan, cfg->chcr);
288 } else { 308 } else if ((sh_dmae_readl(sh_chan, CHCR) & 0xf00) != 0x400) {
289 if ((sh_dmae_readl(sh_chan, CHCR) & 0x700) != 0x400) 309 dmae_init(sh_chan);
290 dmae_set_chcr(sh_chan, RS_DEFAULT);
291 } 310 }
292 311
293 spin_lock_bh(&sh_chan->desc_lock); 312 spin_lock_bh(&sh_chan->desc_lock);
@@ -757,7 +776,7 @@ static irqreturn_t sh_dmae_err(int irq, void *data)
757 sh_dmae_ctl_stop(shdev); 776 sh_dmae_ctl_stop(shdev);
758 777
759 /* We cannot detect, which channel caused the error, have to reset all */ 778 /* We cannot detect, which channel caused the error, have to reset all */
760 for (i = 0; i < MAX_DMA_CHANNELS; i++) { 779 for (i = 0; i < SH_DMAC_MAX_CHANNELS; i++) {
761 struct sh_dmae_chan *sh_chan = shdev->chan[i]; 780 struct sh_dmae_chan *sh_chan = shdev->chan[i];
762 if (sh_chan) { 781 if (sh_chan) {
763 struct sh_desc *desc; 782 struct sh_desc *desc;
@@ -822,6 +841,9 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
822 return -ENOMEM; 841 return -ENOMEM;
823 } 842 }
824 843
844 /* copy struct dma_device */
845 new_sh_chan->common.device = &shdev->common;
846
825 new_sh_chan->dev = shdev->common.dev; 847 new_sh_chan->dev = shdev->common.dev;
826 new_sh_chan->id = id; 848 new_sh_chan->id = id;
827 new_sh_chan->irq = irq; 849 new_sh_chan->irq = irq;
@@ -840,9 +862,6 @@ static int __devinit sh_dmae_chan_probe(struct sh_dmae_device *shdev, int id,
840 INIT_LIST_HEAD(&new_sh_chan->ld_queue); 862 INIT_LIST_HEAD(&new_sh_chan->ld_queue);
841 INIT_LIST_HEAD(&new_sh_chan->ld_free); 863 INIT_LIST_HEAD(&new_sh_chan->ld_free);
842 864
843 /* copy struct dma_device */
844 new_sh_chan->common.device = &shdev->common;
845
846 /* Add the channel to DMA device channel list */ 865 /* Add the channel to DMA device channel list */
847 list_add_tail(&new_sh_chan->common.device_node, 866 list_add_tail(&new_sh_chan->common.device_node,
848 &shdev->common.channels); 867 &shdev->common.channels);
@@ -896,8 +915,8 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
896{ 915{
897 struct sh_dmae_pdata *pdata = pdev->dev.platform_data; 916 struct sh_dmae_pdata *pdata = pdev->dev.platform_data;
898 unsigned long irqflags = IRQF_DISABLED, 917 unsigned long irqflags = IRQF_DISABLED,
899 chan_flag[MAX_DMA_CHANNELS] = {}; 918 chan_flag[SH_DMAC_MAX_CHANNELS] = {};
900 int errirq, chan_irq[MAX_DMA_CHANNELS]; 919 int errirq, chan_irq[SH_DMAC_MAX_CHANNELS];
901 int err, i, irq_cnt = 0, irqres = 0; 920 int err, i, irq_cnt = 0, irqres = 0;
902 struct sh_dmae_device *shdev; 921 struct sh_dmae_device *shdev;
903 struct resource *chan, *dmars, *errirq_res, *chanirq_res; 922 struct resource *chan, *dmars, *errirq_res, *chanirq_res;
@@ -983,7 +1002,7 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
983 1002
984 shdev->common.dev = &pdev->dev; 1003 shdev->common.dev = &pdev->dev;
985 /* Default transfer size of 32 bytes requires 32-byte alignment */ 1004 /* Default transfer size of 32 bytes requires 32-byte alignment */
986 shdev->common.copy_align = 5; 1005 shdev->common.copy_align = LOG2_DEFAULT_XFER_SIZE;
987 1006
988#if defined(CONFIG_CPU_SH4) 1007#if defined(CONFIG_CPU_SH4)
989 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1); 1008 chanirq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 800fd884be83..9f0897f7fe34 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -17,6 +17,8 @@
17#include <linux/interrupt.h> 17#include <linux/interrupt.h>
18#include <linux/list.h> 18#include <linux/list.h>
19 19
20#include <asm/dmaengine.h>
21
20#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */ 22#define SH_DMA_TCR_MAX 0x00FFFFFF /* 16MB */
21 23
22struct sh_dmae_regs { 24struct sh_dmae_regs {
@@ -55,7 +57,7 @@ struct sh_dmae_chan {
55 57
56struct sh_dmae_device { 58struct sh_dmae_device {
57 struct dma_device common; 59 struct dma_device common;
58 struct sh_dmae_chan *chan[MAX_DMA_CHANNELS]; 60 struct sh_dmae_chan *chan[SH_DMAC_MAX_CHANNELS];
59 struct sh_dmae_pdata *pdata; 61 struct sh_dmae_pdata *pdata;
60 u32 __iomem *chan_reg; 62 u32 __iomem *chan_reg;
61 u16 __iomem *dmars; 63 u16 __iomem *dmars;