aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-11-02 09:26:57 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-04-03 19:27:43 -0400
commitb9e97822da374f52aaf99cb502f531ff2184b8f5 (patch)
treede5205a5f5b51cfdf268d9c774b9240d8bd8fbe9
parent1b416c4b41351c3eb8fc42dbb4cd8eba463c0813 (diff)
dmaengine: omap-dma: program hardware directly
Program the transfer parameters directly into the hardware, rather than using the functions in arch/arm/plat-omap/dma.c. Acked-by: Tony Lindgren <tony@atomide.com> Acked-by: Vinod Koul <vinod.koul@intel.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
-rw-r--r--drivers/dma/omap-dma.c142
-rw-r--r--include/linux/omap-dma.h6
2 files changed, 130 insertions, 18 deletions
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 4ac26bf0ad30..47a3fa5bc38e 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -99,16 +99,94 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
99 unsigned idx) 99 unsigned idx)
100{ 100{
101 struct omap_sg *sg = d->sg + idx; 101 struct omap_sg *sg = d->sg + idx;
102 uint32_t val;
103
104 if (d->dir == DMA_DEV_TO_MEM) {
105 if (dma_omap1()) {
106 val = c->plat->dma_read(CSDP, c->dma_ch);
107 val &= ~(0x1f << 9);
108 val |= OMAP_DMA_PORT_EMIFF << 9;
109 c->plat->dma_write(val, CSDP, c->dma_ch);
110 }
102 111
103 if (d->dir == DMA_DEV_TO_MEM) 112 val = c->plat->dma_read(CCR, c->dma_ch);
104 omap_set_dma_dest_params(c->dma_ch, OMAP_DMA_PORT_EMIFF, 113 val &= ~(0x03 << 14);
105 OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0); 114 val |= OMAP_DMA_AMODE_POST_INC << 14;
106 else 115 c->plat->dma_write(val, CCR, c->dma_ch);
107 omap_set_dma_src_params(c->dma_ch, OMAP_DMA_PORT_EMIFF, 116
108 OMAP_DMA_AMODE_POST_INC, sg->addr, 0, 0); 117 c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
118 c->plat->dma_write(0, CDEI, c->dma_ch);
119 c->plat->dma_write(0, CDFI, c->dma_ch);
120 } else {
121 if (dma_omap1()) {
122 val = c->plat->dma_read(CSDP, c->dma_ch);
123 val &= ~(0x1f << 2);
124 val |= OMAP_DMA_PORT_EMIFF << 2;
125 c->plat->dma_write(val, CSDP, c->dma_ch);
126 }
127
128 val = c->plat->dma_read(CCR, c->dma_ch);
129 val &= ~(0x03 << 12);
130 val |= OMAP_DMA_AMODE_POST_INC << 12;
131 c->plat->dma_write(val, CCR, c->dma_ch);
132
133 c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
134 c->plat->dma_write(0, CSEI, c->dma_ch);
135 c->plat->dma_write(0, CSFI, c->dma_ch);
136 }
137
138 val = c->plat->dma_read(CSDP, c->dma_ch);
139 val &= ~0x03;
140 val |= d->es;
141 c->plat->dma_write(val, CSDP, c->dma_ch);
142
143 if (dma_omap1()) {
144 val = c->plat->dma_read(CCR, c->dma_ch);
145 val &= ~(1 << 5);
146 if (d->sync_mode == OMAP_DMA_SYNC_FRAME)
147 val |= 1 << 5;
148 c->plat->dma_write(val, CCR, c->dma_ch);
149
150 val = c->plat->dma_read(CCR2, c->dma_ch);
151 val &= ~(1 << 2);
152 if (d->sync_mode == OMAP_DMA_SYNC_BLOCK)
153 val |= 1 << 2;
154 c->plat->dma_write(val, CCR2, c->dma_ch);
155 } else if (c->dma_sig) {
156 val = c->plat->dma_read(CCR, c->dma_ch);
157
158 /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
159 val &= ~((1 << 23) | (3 << 19) | 0x1f);
160 val |= (c->dma_sig & ~0x1f) << 14;
161 val |= c->dma_sig & 0x1f;
162
163 if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
164 val |= 1 << 5;
165 else
166 val &= ~(1 << 5);
167
168 if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
169 val |= 1 << 18;
170 else
171 val &= ~(1 << 18);
172
173 switch (d->sync_type) {
174 case OMAP_DMA_DST_SYNC_PREFETCH:
175 val &= ~(1 << 24); /* dest synch */
176 val |= 1 << 23; /* Prefetch */
177 break;
178 case 0:
179 val &= ~(1 << 24); /* dest synch */
180 break;
181 default:
182 val |= 1 << 24; /* source synch */
183 break;
184 }
185 c->plat->dma_write(val, CCR, c->dma_ch);
186 }
109 187
110 omap_set_dma_transfer_params(c->dma_ch, d->es, sg->en, sg->fn, 188 c->plat->dma_write(sg->en, CEN, c->dma_ch);
111 d->sync_mode, c->dma_sig, d->sync_type); 189 c->plat->dma_write(sg->fn, CFN, c->dma_ch);
112 190
113 omap_start_dma(c->dma_ch); 191 omap_start_dma(c->dma_ch);
114} 192}
@@ -117,6 +195,7 @@ static void omap_dma_start_desc(struct omap_chan *c)
117{ 195{
118 struct virt_dma_desc *vd = vchan_next_desc(&c->vc); 196 struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
119 struct omap_desc *d; 197 struct omap_desc *d;
198 uint32_t val;
120 199
121 if (!vd) { 200 if (!vd) {
122 c->desc = NULL; 201 c->desc = NULL;
@@ -128,12 +207,39 @@ static void omap_dma_start_desc(struct omap_chan *c)
128 c->desc = d = to_omap_dma_desc(&vd->tx); 207 c->desc = d = to_omap_dma_desc(&vd->tx);
129 c->sgidx = 0; 208 c->sgidx = 0;
130 209
131 if (d->dir == DMA_DEV_TO_MEM) 210 if (d->dir == DMA_DEV_TO_MEM) {
132 omap_set_dma_src_params(c->dma_ch, d->periph_port, 211 if (dma_omap1()) {
133 OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi); 212 val = c->plat->dma_read(CSDP, c->dma_ch);
134 else 213 val &= ~(0x1f << 2);
135 omap_set_dma_dest_params(c->dma_ch, d->periph_port, 214 val |= d->periph_port << 2;
136 OMAP_DMA_AMODE_CONSTANT, d->dev_addr, 0, d->fi); 215 c->plat->dma_write(val, CSDP, c->dma_ch);
216 }
217
218 val = c->plat->dma_read(CCR, c->dma_ch);
219 val &= ~(0x03 << 12);
220 val |= OMAP_DMA_AMODE_CONSTANT << 12;
221 c->plat->dma_write(val, CCR, c->dma_ch);
222
223 c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
224 c->plat->dma_write(0, CSEI, c->dma_ch);
225 c->plat->dma_write(d->fi, CSFI, c->dma_ch);
226 } else {
227 if (dma_omap1()) {
228 val = c->plat->dma_read(CSDP, c->dma_ch);
229 val &= ~(0x1f << 9);
230 val |= d->periph_port << 9;
231 c->plat->dma_write(val, CSDP, c->dma_ch);
232 }
233
234 val = c->plat->dma_read(CCR, c->dma_ch);
235 val &= ~(0x03 << 14);
236 val |= OMAP_DMA_AMODE_CONSTANT << 14;
237 c->plat->dma_write(val, CCR, c->dma_ch);
238
239 c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
240 c->plat->dma_write(0, CDEI, c->dma_ch);
241 c->plat->dma_write(d->fi, CDFI, c->dma_ch);
242 }
137 243
138 omap_dma_start_sg(c, d, 0); 244 omap_dma_start_sg(c, d, 0);
139} 245}
@@ -452,8 +558,12 @@ static struct dma_async_tx_descriptor *omap_dma_prep_dma_cyclic(
452 } 558 }
453 559
454 if (dma_omap2plus()) { 560 if (dma_omap2plus()) {
455 omap_set_dma_src_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); 561 uint32_t val;
456 omap_set_dma_dest_burst_mode(c->dma_ch, OMAP_DMA_DATA_BURST_16); 562
563 val = c->plat->dma_read(CSDP, c->dma_ch);
564 val |= 0x03 << 7; /* src burst mode 16 */
565 val |= 0x03 << 14; /* dst burst mode 16 */
566 c->plat->dma_write(val, CSDP, c->dma_ch);
457 } 567 }
458 568
459 return vchan_tx_prep(&c->vc, &d->vd, flags); 569 return vchan_tx_prep(&c->vc, &d->vd, flags);
diff --git a/include/linux/omap-dma.h b/include/linux/omap-dma.h
index 14742fc2aefe..d631658e2237 100644
--- a/include/linux/omap-dma.h
+++ b/include/linux/omap-dma.h
@@ -289,8 +289,10 @@ struct omap_system_dma_plat_info {
289#define dma_omap2plus() 0 289#define dma_omap2plus() 0
290#endif 290#endif
291#define dma_omap1() (!dma_omap2plus()) 291#define dma_omap1() (!dma_omap2plus())
292#define dma_omap15xx() ((dma_omap1() && (d->dev_caps & ENABLE_1510_MODE))) 292#define __dma_omap15xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_1510_MODE)
293#define dma_omap16xx() ((dma_omap1() && (d->dev_caps & ENABLE_16XX_MODE))) 293#define __dma_omap16xx(d) (dma_omap1() && (d)->dev_caps & ENABLE_16XX_MODE)
294#define dma_omap15xx() __dma_omap15xx(d)
295#define dma_omap16xx() __dma_omap16xx(d)
294 296
295extern struct omap_system_dma_plat_info *omap_get_plat_info(void); 297extern struct omap_system_dma_plat_info *omap_get_plat_info(void);
296 298