aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-11-02 10:41:42 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2014-04-03 19:27:47 -0400
commit913a2d0c6952283bc9323cb9152af87f792ff4c4 (patch)
tree57c162dee97649090f7f55750ebed3340f4a78b9
parentb9e97822da374f52aaf99cb502f531ff2184b8f5 (diff)
dmaengine: omap-dma: consolidate writes to DMA registers
There's no need to keep writing registers which don't change value in omap_dma_start_sg(). Move this into omap_dma_start_desc() and merge the register updates together. 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.c123
1 files changed, 48 insertions, 75 deletions
diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index 47a3fa5bc38e..8c5c862f01ed 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -99,40 +99,75 @@ 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
103 if (d->dir == DMA_DEV_TO_MEM) {
104 c->plat->dma_write(sg->addr, CDSA, c->dma_ch);
105 c->plat->dma_write(0, CDEI, c->dma_ch);
106 c->plat->dma_write(0, CDFI, c->dma_ch);
107 } else {
108 c->plat->dma_write(sg->addr, CSSA, c->dma_ch);
109 c->plat->dma_write(0, CSEI, c->dma_ch);
110 c->plat->dma_write(0, CSFI, c->dma_ch);
111 }
112
113 c->plat->dma_write(sg->en, CEN, c->dma_ch);
114 c->plat->dma_write(sg->fn, CFN, c->dma_ch);
115
116 omap_start_dma(c->dma_ch);
117}
118
119static void omap_dma_start_desc(struct omap_chan *c)
120{
121 struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
122 struct omap_desc *d;
102 uint32_t val; 123 uint32_t val;
103 124
125 if (!vd) {
126 c->desc = NULL;
127 return;
128 }
129
130 list_del(&vd->node);
131
132 c->desc = d = to_omap_dma_desc(&vd->tx);
133 c->sgidx = 0;
134
104 if (d->dir == DMA_DEV_TO_MEM) { 135 if (d->dir == DMA_DEV_TO_MEM) {
105 if (dma_omap1()) { 136 if (dma_omap1()) {
106 val = c->plat->dma_read(CSDP, c->dma_ch); 137 val = c->plat->dma_read(CSDP, c->dma_ch);
107 val &= ~(0x1f << 9); 138 val &= ~(0x1f << 9 | 0x1f << 2);
108 val |= OMAP_DMA_PORT_EMIFF << 9; 139 val |= OMAP_DMA_PORT_EMIFF << 9;
140 val |= d->periph_port << 2;
109 c->plat->dma_write(val, CSDP, c->dma_ch); 141 c->plat->dma_write(val, CSDP, c->dma_ch);
110 } 142 }
111 143
112 val = c->plat->dma_read(CCR, c->dma_ch); 144 val = c->plat->dma_read(CCR, c->dma_ch);
113 val &= ~(0x03 << 14); 145 val &= ~(0x03 << 14 | 0x03 << 12);
114 val |= OMAP_DMA_AMODE_POST_INC << 14; 146 val |= OMAP_DMA_AMODE_POST_INC << 14;
147 val |= OMAP_DMA_AMODE_CONSTANT << 12;
115 c->plat->dma_write(val, CCR, c->dma_ch); 148 c->plat->dma_write(val, CCR, c->dma_ch);
116 149
117 c->plat->dma_write(sg->addr, CDSA, c->dma_ch); 150 c->plat->dma_write(d->dev_addr, CSSA, c->dma_ch);
118 c->plat->dma_write(0, CDEI, c->dma_ch); 151 c->plat->dma_write(0, CSEI, c->dma_ch);
119 c->plat->dma_write(0, CDFI, c->dma_ch); 152 c->plat->dma_write(d->fi, CSFI, c->dma_ch);
120 } else { 153 } else {
121 if (dma_omap1()) { 154 if (dma_omap1()) {
122 val = c->plat->dma_read(CSDP, c->dma_ch); 155 val = c->plat->dma_read(CSDP, c->dma_ch);
123 val &= ~(0x1f << 2); 156 val &= ~(0x1f << 9 | 0x1f << 2);
157 val |= d->periph_port << 9;
124 val |= OMAP_DMA_PORT_EMIFF << 2; 158 val |= OMAP_DMA_PORT_EMIFF << 2;
125 c->plat->dma_write(val, CSDP, c->dma_ch); 159 c->plat->dma_write(val, CSDP, c->dma_ch);
126 } 160 }
127 161
128 val = c->plat->dma_read(CCR, c->dma_ch); 162 val = c->plat->dma_read(CCR, c->dma_ch);
129 val &= ~(0x03 << 12); 163 val &= ~(0x03 << 12 | 0x03 << 14);
164 val |= OMAP_DMA_AMODE_CONSTANT << 14;
130 val |= OMAP_DMA_AMODE_POST_INC << 12; 165 val |= OMAP_DMA_AMODE_POST_INC << 12;
131 c->plat->dma_write(val, CCR, c->dma_ch); 166 c->plat->dma_write(val, CCR, c->dma_ch);
132 167
133 c->plat->dma_write(sg->addr, CSSA, c->dma_ch); 168 c->plat->dma_write(d->dev_addr, CDSA, c->dma_ch);
134 c->plat->dma_write(0, CSEI, c->dma_ch); 169 c->plat->dma_write(0, CDEI, c->dma_ch);
135 c->plat->dma_write(0, CSFI, c->dma_ch); 170 c->plat->dma_write(d->fi, CDFI, c->dma_ch);
136 } 171 }
137 172
138 val = c->plat->dma_read(CSDP, c->dma_ch); 173 val = c->plat->dma_read(CSDP, c->dma_ch);
@@ -156,91 +191,29 @@ static void omap_dma_start_sg(struct omap_chan *c, struct omap_desc *d,
156 val = c->plat->dma_read(CCR, c->dma_ch); 191 val = c->plat->dma_read(CCR, c->dma_ch);
157 192
158 /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */ 193 /* DMA_SYNCHRO_CONTROL_UPPER depends on the channel number */
159 val &= ~((1 << 23) | (3 << 19) | 0x1f); 194 val &= ~(1 << 24 | 1 << 23 | 3 << 19 | 1 << 18 | 1 << 5 | 0x1f);
160 val |= (c->dma_sig & ~0x1f) << 14; 195 val |= (c->dma_sig & ~0x1f) << 14;
161 val |= c->dma_sig & 0x1f; 196 val |= c->dma_sig & 0x1f;
162 197
163 if (d->sync_mode & OMAP_DMA_SYNC_FRAME) 198 if (d->sync_mode & OMAP_DMA_SYNC_FRAME)
164 val |= 1 << 5; 199 val |= 1 << 5;
165 else
166 val &= ~(1 << 5);
167 200
168 if (d->sync_mode & OMAP_DMA_SYNC_BLOCK) 201 if (d->sync_mode & OMAP_DMA_SYNC_BLOCK)
169 val |= 1 << 18; 202 val |= 1 << 18;
170 else
171 val &= ~(1 << 18);
172 203
173 switch (d->sync_type) { 204 switch (d->sync_type) {
174 case OMAP_DMA_DST_SYNC_PREFETCH: 205 case OMAP_DMA_DST_SYNC_PREFETCH:/* dest synch */
175 val &= ~(1 << 24); /* dest synch */
176 val |= 1 << 23; /* Prefetch */ 206 val |= 1 << 23; /* Prefetch */
177 break; 207 break;
178 case 0: 208 case 0:
179 val &= ~(1 << 24); /* dest synch */
180 break; 209 break;
181 default: 210 default:
182 val |= 1 << 24; /* source synch */ 211 val |= 1 << 24; /* source synch */
183 break; 212 break;
184 } 213 }
185 c->plat->dma_write(val, CCR, c->dma_ch); 214 c->plat->dma_write(val, CCR, c->dma_ch);
186 } 215 }
187 216
188 c->plat->dma_write(sg->en, CEN, c->dma_ch);
189 c->plat->dma_write(sg->fn, CFN, c->dma_ch);
190
191 omap_start_dma(c->dma_ch);
192}
193
194static void omap_dma_start_desc(struct omap_chan *c)
195{
196 struct virt_dma_desc *vd = vchan_next_desc(&c->vc);
197 struct omap_desc *d;
198 uint32_t val;
199
200 if (!vd) {
201 c->desc = NULL;
202 return;
203 }
204
205 list_del(&vd->node);
206
207 c->desc = d = to_omap_dma_desc(&vd->tx);
208 c->sgidx = 0;
209
210 if (d->dir == DMA_DEV_TO_MEM) {
211 if (dma_omap1()) {
212 val = c->plat->dma_read(CSDP, c->dma_ch);
213 val &= ~(0x1f << 2);
214 val |= d->periph_port << 2;
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 }
243
244 omap_dma_start_sg(c, d, 0); 217 omap_dma_start_sg(c, d, 0);
245} 218}
246 219