aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Mundt <lethal@linux-sh.org>2011-06-21 04:59:05 -0400
committerPaul Mundt <lethal@linux-sh.org>2011-06-21 04:59:05 -0400
commitf448e9c9dad6fb919ec74cd1b2c189efe952886f (patch)
treeebc7eafdef4ed53eec1679f6607ef825c08bf201
parent9dd056e9eba106ef622795b566f769a9ab0a49a8 (diff)
parent260bf2c5f69f419b04b6861ca91565b5fb16ce48 (diff)
Merge branch 'common/dma' into sh-latest
-rw-r--r--drivers/dma/shdma.c66
-rw-r--r--drivers/dma/shdma.h2
-rw-r--r--include/linux/sh_dma.h8
3 files changed, 64 insertions, 12 deletions
diff --git a/drivers/dma/shdma.c b/drivers/dma/shdma.c
index 707d30ce3354..7f49235d14b9 100644
--- a/drivers/dma/shdma.c
+++ b/drivers/dma/shdma.c
@@ -70,12 +70,36 @@ static u32 sh_dmae_readl(struct sh_dmae_chan *sh_dc, u32 reg)
70 70
71static u16 dmaor_read(struct sh_dmae_device *shdev) 71static u16 dmaor_read(struct sh_dmae_device *shdev)
72{ 72{
73 return __raw_readw(shdev->chan_reg + DMAOR / sizeof(u32)); 73 u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32);
74
75 if (shdev->pdata->dmaor_is_32bit)
76 return __raw_readl(addr);
77 else
78 return __raw_readw(addr);
74} 79}
75 80
76static void dmaor_write(struct sh_dmae_device *shdev, u16 data) 81static void dmaor_write(struct sh_dmae_device *shdev, u16 data)
77{ 82{
78 __raw_writew(data, shdev->chan_reg + DMAOR / sizeof(u32)); 83 u32 __iomem *addr = shdev->chan_reg + DMAOR / sizeof(u32);
84
85 if (shdev->pdata->dmaor_is_32bit)
86 __raw_writel(data, addr);
87 else
88 __raw_writew(data, addr);
89}
90
91static void chcr_write(struct sh_dmae_chan *sh_dc, u32 data)
92{
93 struct sh_dmae_device *shdev = to_sh_dev(sh_dc);
94
95 __raw_writel(data, sh_dc->base + shdev->chcr_offset / sizeof(u32));
96}
97
98static u32 chcr_read(struct sh_dmae_chan *sh_dc)
99{
100 struct sh_dmae_device *shdev = to_sh_dev(sh_dc);
101
102 return __raw_readl(sh_dc->base + shdev->chcr_offset / sizeof(u32));
79} 103}
80 104
81/* 105/*
@@ -120,7 +144,7 @@ static int sh_dmae_rst(struct sh_dmae_device *shdev)
120 144
121static bool dmae_is_busy(struct sh_dmae_chan *sh_chan) 145static bool dmae_is_busy(struct sh_dmae_chan *sh_chan)
122{ 146{
123 u32 chcr = sh_dmae_readl(sh_chan, CHCR); 147 u32 chcr = chcr_read(sh_chan);
124 148
125 if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE) 149 if ((chcr & (CHCR_DE | CHCR_TE)) == CHCR_DE)
126 return true; /* working */ 150 return true; /* working */
@@ -167,18 +191,23 @@ static void dmae_set_reg(struct sh_dmae_chan *sh_chan, struct sh_dmae_regs *hw)
167 191
168static void dmae_start(struct sh_dmae_chan *sh_chan) 192static void dmae_start(struct sh_dmae_chan *sh_chan)
169{ 193{
170 u32 chcr = sh_dmae_readl(sh_chan, CHCR); 194 struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
195 u32 chcr = chcr_read(sh_chan);
171 196
172 chcr |= CHCR_DE | CHCR_IE; 197 if (shdev->pdata->needs_tend_set)
173 sh_dmae_writel(sh_chan, chcr & ~CHCR_TE, CHCR); 198 sh_dmae_writel(sh_chan, 0xFFFFFFFF, TEND);
199
200 chcr |= CHCR_DE | shdev->chcr_ie_bit;
201 chcr_write(sh_chan, chcr & ~CHCR_TE);
174} 202}
175 203
176static void dmae_halt(struct sh_dmae_chan *sh_chan) 204static void dmae_halt(struct sh_dmae_chan *sh_chan)
177{ 205{
178 u32 chcr = sh_dmae_readl(sh_chan, CHCR); 206 struct sh_dmae_device *shdev = to_sh_dev(sh_chan);
207 u32 chcr = chcr_read(sh_chan);
179 208
180 chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); 209 chcr &= ~(CHCR_DE | CHCR_TE | shdev->chcr_ie_bit);
181 sh_dmae_writel(sh_chan, chcr, CHCR); 210 chcr_write(sh_chan, chcr);
182} 211}
183 212
184static void dmae_init(struct sh_dmae_chan *sh_chan) 213static void dmae_init(struct sh_dmae_chan *sh_chan)
@@ -190,7 +219,7 @@ static void dmae_init(struct sh_dmae_chan *sh_chan)
190 u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan, 219 u32 chcr = DM_INC | SM_INC | 0x400 | log2size_to_chcr(sh_chan,
191 LOG2_DEFAULT_XFER_SIZE); 220 LOG2_DEFAULT_XFER_SIZE);
192 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr); 221 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, chcr);
193 sh_dmae_writel(sh_chan, chcr, CHCR); 222 chcr_write(sh_chan, chcr);
194} 223}
195 224
196static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val) 225static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
@@ -200,7 +229,7 @@ static int dmae_set_chcr(struct sh_dmae_chan *sh_chan, u32 val)
200 return -EBUSY; 229 return -EBUSY;
201 230
202 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val); 231 sh_chan->xmit_shift = calc_xmit_shift(sh_chan, val);
203 sh_dmae_writel(sh_chan, val, CHCR); 232 chcr_write(sh_chan, val);
204 233
205 return 0; 234 return 0;
206} 235}
@@ -216,6 +245,9 @@ static int dmae_set_dmars(struct sh_dmae_chan *sh_chan, u16 val)
216 if (dmae_is_busy(sh_chan)) 245 if (dmae_is_busy(sh_chan))
217 return -EBUSY; 246 return -EBUSY;
218 247
248 if (pdata->no_dmars)
249 return 0;
250
219 /* in the case of a missing DMARS resource use first memory window */ 251 /* in the case of a missing DMARS resource use first memory window */
220 if (!addr) 252 if (!addr)
221 addr = (u16 __iomem *)shdev->chan_reg; 253 addr = (u16 __iomem *)shdev->chan_reg;
@@ -840,7 +872,7 @@ static irqreturn_t sh_dmae_interrupt(int irq, void *data)
840 872
841 spin_lock(&sh_chan->desc_lock); 873 spin_lock(&sh_chan->desc_lock);
842 874
843 chcr = sh_dmae_readl(sh_chan, CHCR); 875 chcr = chcr_read(sh_chan);
844 876
845 if (chcr & CHCR_TE) { 877 if (chcr & CHCR_TE) {
846 /* DMA stop */ 878 /* DMA stop */
@@ -1138,6 +1170,16 @@ static int __init sh_dmae_probe(struct platform_device *pdev)
1138 /* platform data */ 1170 /* platform data */
1139 shdev->pdata = pdata; 1171 shdev->pdata = pdata;
1140 1172
1173 if (pdata->chcr_offset)
1174 shdev->chcr_offset = pdata->chcr_offset;
1175 else
1176 shdev->chcr_offset = CHCR;
1177
1178 if (pdata->chcr_ie_bit)
1179 shdev->chcr_ie_bit = pdata->chcr_ie_bit;
1180 else
1181 shdev->chcr_ie_bit = CHCR_IE;
1182
1141 platform_set_drvdata(pdev, shdev); 1183 platform_set_drvdata(pdev, shdev);
1142 1184
1143 pm_runtime_enable(&pdev->dev); 1185 pm_runtime_enable(&pdev->dev);
diff --git a/drivers/dma/shdma.h b/drivers/dma/shdma.h
index 6c73b654a5c3..dc56576f9fdb 100644
--- a/drivers/dma/shdma.h
+++ b/drivers/dma/shdma.h
@@ -47,6 +47,8 @@ struct sh_dmae_device {
47 struct list_head node; 47 struct list_head node;
48 u32 __iomem *chan_reg; 48 u32 __iomem *chan_reg;
49 u16 __iomem *dmars; 49 u16 __iomem *dmars;
50 unsigned int chcr_offset;
51 u32 chcr_ie_bit;
50}; 52};
51 53
52#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common) 54#define to_sh_chan(chan) container_of(chan, struct sh_dmae_chan, common)
diff --git a/include/linux/sh_dma.h b/include/linux/sh_dma.h
index b08cd4efa15c..cb2dd118cc0f 100644
--- a/include/linux/sh_dma.h
+++ b/include/linux/sh_dma.h
@@ -62,6 +62,12 @@ struct sh_dmae_pdata {
62 const unsigned int *ts_shift; 62 const unsigned int *ts_shift;
63 int ts_shift_num; 63 int ts_shift_num;
64 u16 dmaor_init; 64 u16 dmaor_init;
65 unsigned int chcr_offset;
66 u32 chcr_ie_bit;
67
68 unsigned int dmaor_is_32bit:1;
69 unsigned int needs_tend_set:1;
70 unsigned int no_dmars:1;
65}; 71};
66 72
67/* DMA register */ 73/* DMA register */
@@ -71,6 +77,8 @@ struct sh_dmae_pdata {
71#define CHCR 0x0C 77#define CHCR 0x0C
72#define DMAOR 0x40 78#define DMAOR 0x40
73 79
80#define TEND 0x18 /* USB-DMAC */
81
74/* DMAOR definitions */ 82/* DMAOR definitions */
75#define DMAOR_AE 0x00000004 83#define DMAOR_AE 0x00000004
76#define DMAOR_NMIF 0x00000002 84#define DMAOR_NMIF 0x00000002