master
c 1,148 lines 32.2 KB
Raw
1 /*
2 * TI OMAP DMA gigacell.
3 *
4 * Copyright (C) 2006-2008 Andrzej Zaborowski <balrog@zabor.org>
5 * Copyright (C) 2007-2008 Lauro Ramos Venancio <lauro.venancio@indt.org.br>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, see <http://www.gnu.org/licenses/>.
19 */
20 #include "qemu/osdep.h"
21 #include "qemu/log.h"
22 #include "qemu/timer.h"
23 #include "hw/arm/omap.h"
24 #include "hw/core/irq.h"
25 #include "hw/dma/soc_dma.h"
26 #include "system/physmem.h"
27
28 struct omap_dma_channel_s {
29 /* transfer data */
30 int burst[2];
31 int pack[2];
32 int endian[2];
33 int endian_lock[2];
34 int translate[2];
35 enum omap_dma_port port[2];
36 hwaddr addr[2];
37 omap_dma_addressing_t mode[2];
38 uint32_t elements;
39 uint16_t frames;
40 int32_t frame_index[2];
41 int16_t element_index[2];
42 int data_type;
43
44 /* transfer type */
45 int transparent_copy;
46 int constant_fill;
47 uint32_t color;
48 int prefetch;
49
50 /* auto init and linked channel data */
51 int end_prog;
52 int repeat;
53 int auto_init;
54 int link_enabled;
55 int link_next_ch;
56
57 /* interruption data */
58 int interrupts;
59 int status;
60 int cstatus;
61
62 /* state data */
63 int active;
64 int enable;
65 int sync;
66 int src_sync;
67 int pending_request;
68 int waiting_end_prog;
69 uint16_t cpc;
70 int set_update;
71
72 /* sync type */
73 int fs;
74 int bs;
75
76 qemu_irq irq;
77 struct omap_dma_channel_s *sibling;
78
79 struct omap_dma_reg_set_s {
80 hwaddr src, dest;
81 int frame;
82 int element;
83 int pck_element;
84 int frame_delta[2];
85 int elem_delta[2];
86 int frames;
87 int elements;
88 int pck_elements;
89 } active_set;
90
91 struct soc_dma_ch_s *dma;
92
93 /* unused parameters */
94 int write_mode;
95 int priority;
96 int interleave_disabled;
97 int type;
98 int suspend;
99 int buf_disable;
100 };
101
102 struct omap_dma_s {
103 struct soc_dma_s *dma;
104 MemoryRegion iomem;
105
106 struct omap_mpu_state_s *mpu;
107 omap_clk clk;
108 qemu_irq irq[4];
109
110 uint32_t gcr;
111 uint32_t ocp;
112 uint32_t caps[5];
113 uint32_t irqen[4];
114 uint32_t irqstat[4];
115
116 int chans;
117 struct omap_dma_channel_s ch[32];
118 struct omap_dma_lcd_channel_s lcd_ch;
119 };
120
121 /* Interrupts */
122 #define TIMEOUT_INTR (1 << 0)
123 #define EVENT_DROP_INTR (1 << 1)
124 #define HALF_FRAME_INTR (1 << 2)
125 #define END_FRAME_INTR (1 << 3)
126 #define LAST_FRAME_INTR (1 << 4)
127 #define END_BLOCK_INTR (1 << 5)
128 #define SYNC (1 << 6)
129 #define END_PKT_INTR (1 << 7)
130 #define TRANS_ERR_INTR (1 << 8)
131 #define MISALIGN_INTR (1 << 11)
132
133 static inline void omap_dma_interrupts_update(struct omap_dma_s *s)
134 {
135 struct omap_dma_channel_s *ch = s->ch;
136
137 /* First three interrupts are shared between two channels each. */
138 if (ch[0].status | ch[6].status) {
139 qemu_irq_raise(ch[0].irq);
140 }
141 if (ch[1].status | ch[7].status) {
142 qemu_irq_raise(ch[1].irq);
143 }
144 if (ch[2].status | ch[8].status) {
145 qemu_irq_raise(ch[2].irq);
146 }
147 if (ch[3].status) {
148 qemu_irq_raise(ch[3].irq);
149 }
150 if (ch[4].status) {
151 qemu_irq_raise(ch[4].irq);
152 }
153 if (ch[5].status) {
154 qemu_irq_raise(ch[5].irq);
155 }
156 }
157
158 static void omap_dma_channel_load(struct omap_dma_channel_s *ch)
159 {
160 struct omap_dma_reg_set_s *a = &ch->active_set;
161 int i, normal;
162
163 /*
164 * TODO: verify address ranges and alignment
165 * TODO: port endianness
166 */
167
168 a->src = ch->addr[0];
169 a->dest = ch->addr[1];
170 a->frames = ch->frames;
171 a->elements = ch->elements;
172 a->pck_elements = ch->frame_index[!ch->src_sync];
173 a->frame = 0;
174 a->element = 0;
175 a->pck_element = 0;
176
177 if (unlikely(!ch->elements || !ch->frames)) {
178 printf("%s: bad DMA request\n", __func__);
179 return;
180 }
181
182 for (i = 0; i < 2; i ++)
183 switch (ch->mode[i]) {
184 case constant:
185 a->elem_delta[i] = 0;
186 a->frame_delta[i] = 0;
187 break;
188 case post_incremented:
189 a->elem_delta[i] = ch->data_type;
190 a->frame_delta[i] = 0;
191 break;
192 case single_index:
193 a->elem_delta[i] = ch->data_type +
194 ch->element_index[0] - 1;
195 a->frame_delta[i] = 0;
196 break;
197 case double_index:
198 a->elem_delta[i] = ch->data_type +
199 ch->element_index[0] - 1;
200 a->frame_delta[i] = ch->frame_index[0] -
201 ch->element_index[0];
202 break;
203 default:
204 break;
205 }
206
207 normal = !ch->transparent_copy && !ch->constant_fill &&
208 /* FIFO is big-endian so either (ch->endian[n] == 1) OR
209 * (ch->endian_lock[n] == 1) mean no endianism conversion. */
210 (ch->endian[0] | ch->endian_lock[0]) ==
211 (ch->endian[1] | ch->endian_lock[1]);
212 for (i = 0; i < 2; i ++) {
213 /* TODO: for a->frame_delta[i] > 0 still use the fast path, just
214 * limit min_elems in omap_dma_transfer_setup to the nearest frame
215 * end. */
216 if (!a->elem_delta[i] && normal &&
217 (a->frames == 1 || !a->frame_delta[i]))
218 ch->dma->type[i] = soc_dma_access_const;
219 else if (a->elem_delta[i] == ch->data_type && normal &&
220 (a->frames == 1 || !a->frame_delta[i]))
221 ch->dma->type[i] = soc_dma_access_linear;
222 else
223 ch->dma->type[i] = soc_dma_access_other;
224
225 ch->dma->vaddr[i] = ch->addr[i];
226 }
227 soc_dma_ch_update(ch->dma);
228 }
229
230 static void omap_dma_activate_channel(struct omap_dma_s *s,
231 struct omap_dma_channel_s *ch)
232 {
233 if (!ch->active) {
234 if (ch->set_update) {
235 /* It's not clear when the active set is supposed to be
236 * loaded from registers. We're already loading it when the
237 * channel is enabled, and for some guests this is not enough
238 * but that may be also because of a race condition (no
239 * delays in qemu) in the guest code, which we're just
240 * working around here. */
241 omap_dma_channel_load(ch);
242 ch->set_update = 0;
243 }
244
245 ch->active = 1;
246 soc_dma_set_request(ch->dma, 1);
247 if (ch->sync)
248 ch->status |= SYNC;
249 }
250 }
251
252 static void omap_dma_deactivate_channel(struct omap_dma_s *s,
253 struct omap_dma_channel_s *ch)
254 {
255 /* Update cpc */
256 ch->cpc = ch->active_set.dest & 0xffff;
257
258 if (ch->pending_request && !ch->waiting_end_prog && ch->enable) {
259 /* Don't deactivate the channel */
260 ch->pending_request = 0;
261 return;
262 }
263
264 /* Don't deactivate the channel if it is synchronized and the DMA request is
265 active */
266 if (ch->sync && ch->enable && (s->dma->drqbmp & (1ULL << ch->sync)))
267 return;
268
269 if (ch->active) {
270 ch->active = 0;
271 ch->status &= ~SYNC;
272 soc_dma_set_request(ch->dma, 0);
273 }
274 }
275
276 static void omap_dma_enable_channel(struct omap_dma_s *s,
277 struct omap_dma_channel_s *ch)
278 {
279 if (!ch->enable) {
280 ch->enable = 1;
281 ch->waiting_end_prog = 0;
282 omap_dma_channel_load(ch);
283 /* TODO: theoretically if ch->sync && ch->prefetch &&
284 * !s->dma->drqbmp[ch->sync], we should also activate and fetch
285 * from source and then stall until signalled. */
286 if ((!ch->sync) || (s->dma->drqbmp & (1ULL << ch->sync))) {
287 omap_dma_activate_channel(s, ch);
288 }
289 }
290 }
291
292 static void omap_dma_disable_channel(struct omap_dma_s *s,
293 struct omap_dma_channel_s *ch)
294 {
295 if (ch->enable) {
296 ch->enable = 0;
297 /* Discard any pending request */
298 ch->pending_request = 0;
299 omap_dma_deactivate_channel(s, ch);
300 }
301 }
302
303 static void omap_dma_channel_end_prog(struct omap_dma_s *s,
304 struct omap_dma_channel_s *ch)
305 {
306 if (ch->waiting_end_prog) {
307 ch->waiting_end_prog = 0;
308 if (!ch->sync || ch->pending_request) {
309 ch->pending_request = 0;
310 omap_dma_activate_channel(s, ch);
311 }
312 }
313 }
314
315 static void omap_dma_process_request(struct omap_dma_s *s, int request)
316 {
317 int channel;
318 int drop_event = 0;
319 struct omap_dma_channel_s *ch = s->ch;
320
321 for (channel = 0; channel < s->chans; channel ++, ch ++) {
322 if (ch->enable && ch->sync == request) {
323 if (!ch->active)
324 omap_dma_activate_channel(s, ch);
325 else if (!ch->pending_request)
326 ch->pending_request = 1;
327 else {
328 /* Request collision */
329 /* Second request received while processing other request */
330 ch->status |= EVENT_DROP_INTR;
331 drop_event = 1;
332 }
333 }
334 }
335
336 if (drop_event)
337 omap_dma_interrupts_update(s);
338 }
339
340 static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
341 {
342 uint8_t value[4];
343 struct omap_dma_channel_s *ch = dma->opaque;
344 struct omap_dma_reg_set_s *a = &ch->active_set;
345 int bytes = dma->bytes;
346
347 do {
348 /* Transfer a single element */
349 /* FIXME: check the endianness */
350 if (!ch->constant_fill)
351 physical_memory_read(a->src, value, ch->data_type);
352 else
353 *(uint32_t *) value = ch->color;
354
355 if (!ch->transparent_copy || *(uint32_t *) value != ch->color)
356 physical_memory_write(a->dest, value, ch->data_type);
357
358 a->src += a->elem_delta[0];
359 a->dest += a->elem_delta[1];
360 a->element ++;
361
362 if (a->element == a->elements) {
363 /* End of Frame */
364 a->element = 0;
365 a->src += a->frame_delta[0];
366 a->dest += a->frame_delta[1];
367 a->frame ++;
368
369 /* If the channel is async, update cpc */
370 if (!ch->sync)
371 ch->cpc = a->dest & 0xffff;
372 }
373 } while ((bytes -= ch->data_type));
374 }
375
376 enum {
377 omap_dma_intr_element_sync,
378 omap_dma_intr_last_frame,
379 omap_dma_intr_half_frame,
380 omap_dma_intr_frame,
381 omap_dma_intr_frame_sync,
382 omap_dma_intr_packet,
383 omap_dma_intr_packet_sync,
384 omap_dma_intr_block,
385 __omap_dma_intr_last,
386 };
387
388 static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
389 {
390 struct omap_dma_port_if_s *src_p, *dest_p;
391 struct omap_dma_reg_set_s *a;
392 struct omap_dma_channel_s *ch = dma->opaque;
393 struct omap_dma_s *s = dma->dma->opaque;
394 uint32_t frames, min_elems, elements[__omap_dma_intr_last];
395
396 a = &ch->active_set;
397
398 src_p = &s->mpu->port[ch->port[0]];
399 dest_p = &s->mpu->port[ch->port[1]];
400 if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
401 (!dest_p->addr_valid(s->mpu, a->dest))) {
402 printf("%s: Bus time-out in DMA%i operation\n",
403 __func__, dma->num);
404 }
405
406 /*
407 * The maximum frame count and maximum element count are both 0xffff,
408 * so our worst case possible number of elements to transfer is
409 * 0xffff * 0xffff == 0xfffe0001. We can therefore keep element
410 * counts in a uint32_t and use UINT_MAX as a sentinel value for
411 * "not set" / "condition does not occur".
412 */
413 min_elems = UINT_MAX;
414
415 /* Check all the conditions that terminate the transfer starting
416 * with those that can occur the soonest. */
417 #define INTR_CHECK(cond, id, nelements) \
418 if (cond) { \
419 elements[id] = nelements; \
420 if (elements[id] < min_elems) \
421 min_elems = elements[id]; \
422 } else \
423 elements[id] = UINT_MAX;
424
425 /* Elements */
426 INTR_CHECK(
427 ch->sync && !ch->fs && !ch->bs,
428 omap_dma_intr_element_sync,
429 1)
430
431 /* Frames */
432 /* TODO: for transfers where entire frames can be read and written
433 * using memcpy() but a->frame_delta is non-zero, try to still do
434 * transfers using soc_dma but limit min_elems to a->elements - ...
435 * See also the TODO in omap_dma_channel_load. */
436 INTR_CHECK(
437 (ch->interrupts & LAST_FRAME_INTR) &&
438 ((a->frame < a->frames - 1) || !a->element),
439 omap_dma_intr_last_frame,
440 (a->frames - a->frame - 2) * a->elements +
441 (a->elements - a->element + 1))
442 INTR_CHECK(
443 ch->interrupts & HALF_FRAME_INTR,
444 omap_dma_intr_half_frame,
445 (a->elements >> 1) +
446 (a->element >= (a->elements >> 1) ? a->elements : 0) -
447 a->element)
448 INTR_CHECK(
449 ch->sync && ch->fs && (ch->interrupts & END_FRAME_INTR),
450 omap_dma_intr_frame,
451 a->elements - a->element)
452 INTR_CHECK(
453 ch->sync && ch->fs && !ch->bs,
454 omap_dma_intr_frame_sync,
455 a->elements - a->element)
456
457 /* Packets */
458 INTR_CHECK(
459 ch->fs && ch->bs &&
460 (ch->interrupts & END_PKT_INTR) && !ch->src_sync,
461 omap_dma_intr_packet,
462 a->pck_elements - a->pck_element)
463 INTR_CHECK(
464 ch->fs && ch->bs && ch->sync,
465 omap_dma_intr_packet_sync,
466 a->pck_elements - a->pck_element)
467
468 /* Blocks */
469 INTR_CHECK(
470 1,
471 omap_dma_intr_block,
472 (a->frames - a->frame - 1) * a->elements +
473 (a->elements - a->element))
474
475 dma->bytes = (uint64_t)min_elems * ch->data_type;
476
477 /* Set appropriate interrupts and/or deactivate channels */
478
479
480 /* If the channel is element synchronized, deactivate it */
481 if (min_elems == elements[omap_dma_intr_element_sync]) {
482 omap_dma_deactivate_channel(s, ch);
483 }
484
485 /* If it is the last frame, set the LAST_FRAME interrupt */
486 if (min_elems == elements[omap_dma_intr_last_frame]) {
487 ch->status |= LAST_FRAME_INTR;
488 }
489
490 /*
491 * If exactly half of the frame was reached, set the HALF_FRAME
492 * interrupt
493 */
494 if (min_elems == elements[omap_dma_intr_half_frame]) {
495 ch->status |= HALF_FRAME_INTR;
496 }
497
498 /* If a full packet has been transferred, set the END_PKT interrupt */
499 if (min_elems == elements[omap_dma_intr_packet]) {
500 ch->status |= END_PKT_INTR;
501 }
502
503 /* If the channel is packet-synchronized, deactivate it */
504 if (min_elems == elements[omap_dma_intr_packet_sync]) {
505 omap_dma_deactivate_channel(s, ch);
506 }
507
508 /* If the channel is frame synchronized, deactivate it */
509 if (min_elems == elements[omap_dma_intr_frame_sync]) {
510 omap_dma_deactivate_channel(s, ch);
511 }
512
513 /* Set the END_FRAME interrupt */
514 if (min_elems == elements[omap_dma_intr_frame]) {
515 ch->status |= END_FRAME_INTR;
516 }
517
518 if (min_elems == elements[omap_dma_intr_block]) {
519 /* End of Block */
520 /* Disable the channel */
521
522 if (!ch->auto_init) {
523 omap_dma_disable_channel(s, ch);
524 } else if (ch->repeat || ch->end_prog) {
525 omap_dma_channel_load(ch);
526 } else {
527 ch->waiting_end_prog = 1;
528 omap_dma_deactivate_channel(s, ch);
529 }
530
531 if (ch->interrupts & END_BLOCK_INTR) {
532 ch->status |= END_BLOCK_INTR;
533 }
534 }
535
536 /* Update packet number */
537 if (ch->fs && ch->bs) {
538 /* Can't overflow: worst case min_elems 0xFFFE0001 + element 0xFFFF */
539 uint32_t new_pck_element = a->pck_element + min_elems;
540 a->pck_element = new_pck_element % a->pck_elements;
541 }
542
543 /*
544 * TODO: check if we really need to update anything here or perhaps we
545 * can skip part of this.
546 */
547 if (dma->update) {
548 /* Can't overflow: worst case min_elems 0xFFFE0001 + element 0xFFFF */
549 uint32_t new_element = a->element + min_elems;
550 a->element += min_elems;
551
552 frames = new_element / a->elements;
553 a->element = new_element % a->elements;
554 a->frame += frames;
555 a->src += (uint64_t)min_elems * a->elem_delta[0] + frames * a->frame_delta[0];
556 a->dest += (uint64_t)min_elems * a->elem_delta[1] + frames * a->frame_delta[1];
557
558 /* If the channel is async, update cpc */
559 if (!ch->sync && frames) {
560 ch->cpc = a->dest & 0xffff;
561 }
562 }
563
564 omap_dma_interrupts_update(s);
565 }
566
567 void omap_dma_reset(struct soc_dma_s *dma)
568 {
569 int i;
570 struct omap_dma_s *s = dma->opaque;
571
572 soc_dma_reset(s->dma);
573 s->gcr = 0x0004;
574 s->ocp = 0x00000000;
575 memset(&s->irqstat, 0, sizeof(s->irqstat));
576 memset(&s->irqen, 0, sizeof(s->irqen));
577 s->lcd_ch.src = emiff;
578 s->lcd_ch.condition = 0;
579 s->lcd_ch.interrupts = 0;
580 s->lcd_ch.dual = 0;
581 for (i = 0; i < s->chans; i ++) {
582 s->ch[i].suspend = 0;
583 s->ch[i].prefetch = 0;
584 s->ch[i].buf_disable = 0;
585 s->ch[i].src_sync = 0;
586 memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));
587 memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));
588 memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));
589 memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));
590 memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));
591 memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian));
592 memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock));
593 memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate));
594 s->ch[i].write_mode = 0;
595 s->ch[i].data_type = 0;
596 s->ch[i].transparent_copy = 0;
597 s->ch[i].constant_fill = 0;
598 s->ch[i].color = 0x00000000;
599 s->ch[i].end_prog = 0;
600 s->ch[i].repeat = 0;
601 s->ch[i].auto_init = 0;
602 s->ch[i].link_enabled = 0;
603 s->ch[i].interrupts = 0x0003;
604 s->ch[i].status = 0;
605 s->ch[i].cstatus = 0;
606 s->ch[i].active = 0;
607 s->ch[i].enable = 0;
608 s->ch[i].sync = 0;
609 s->ch[i].pending_request = 0;
610 s->ch[i].waiting_end_prog = 0;
611 s->ch[i].cpc = 0x0000;
612 s->ch[i].fs = 0;
613 s->ch[i].bs = 0;
614 memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));
615 s->ch[i].priority = 0;
616 s->ch[i].interleave_disabled = 0;
617 s->ch[i].type = 0;
618 }
619 }
620
621 static int omap_dma_ch_reg_read(struct omap_dma_s *s,
622 struct omap_dma_channel_s *ch, int reg, uint16_t *value)
623 {
624 switch (reg) {
625 case 0x00: /* SYS_DMA_CSDP_CH0 */
626 *value = (ch->burst[1] << 14) |
627 (ch->pack[1] << 13) |
628 (ch->port[1] << 9) |
629 (ch->burst[0] << 7) |
630 (ch->pack[0] << 6) |
631 (ch->port[0] << 2) |
632 (ch->data_type >> 1);
633 break;
634
635 case 0x02: /* SYS_DMA_CCR_CH0 */
636 *value = 0 << 10; /* FIFO_FLUSH reads as 0 */
637 *value |= (ch->mode[1] << 14) |
638 (ch->mode[0] << 12) |
639 (ch->end_prog << 11) |
640 (ch->repeat << 9) |
641 (ch->auto_init << 8) |
642 (ch->enable << 7) |
643 (ch->priority << 6) |
644 (ch->fs << 5) | ch->sync;
645 break;
646
647 case 0x04: /* SYS_DMA_CICR_CH0 */
648 *value = ch->interrupts;
649 break;
650
651 case 0x06: /* SYS_DMA_CSR_CH0 */
652 *value = ch->status;
653 ch->status &= SYNC;
654 if (ch->sibling) {
655 *value |= (ch->sibling->status & 0x3f) << 6;
656 ch->sibling->status &= SYNC;
657 }
658 qemu_irq_lower(ch->irq);
659 break;
660
661 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
662 *value = ch->addr[0] & 0x0000ffff;
663 break;
664
665 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
666 *value = ch->addr[0] >> 16;
667 break;
668
669 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
670 *value = ch->addr[1] & 0x0000ffff;
671 break;
672
673 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
674 *value = ch->addr[1] >> 16;
675 break;
676
677 case 0x10: /* SYS_DMA_CEN_CH0 */
678 *value = ch->elements;
679 break;
680
681 case 0x12: /* SYS_DMA_CFN_CH0 */
682 *value = ch->frames;
683 break;
684
685 case 0x14: /* SYS_DMA_CFI_CH0 */
686 *value = ch->frame_index[0];
687 break;
688
689 case 0x16: /* SYS_DMA_CEI_CH0 */
690 *value = ch->element_index[0];
691 break;
692
693 case 0x18: /* SYS_DMA_CPC_CH0 */
694 *value = ch->cpc;
695 break;
696
697 case 0x1a: /* DMA_CDAC */
698 *value = ch->active_set.dest & 0xffff; /* CDAC */
699 break;
700
701 case 0x1c: /* DMA_CDEI */
702 *value = ch->element_index[1];
703 break;
704
705 case 0x1e: /* DMA_CDFI */
706 *value = ch->frame_index[1];
707 break;
708
709 case 0x20: /* DMA_COLOR_L */
710 *value = ch->color & 0xffff;
711 break;
712
713 case 0x22: /* DMA_COLOR_U */
714 *value = ch->color >> 16;
715 break;
716
717 case 0x24: /* DMA_CCR2 */
718 *value = (ch->bs << 2) |
719 (ch->transparent_copy << 1) |
720 ch->constant_fill;
721 break;
722
723 case 0x28: /* DMA_CLNK_CTRL */
724 *value = (ch->link_enabled << 15) |
725 (ch->link_next_ch & 0xf);
726 break;
727
728 case 0x2a: /* DMA_LCH_CTRL */
729 *value = (ch->interleave_disabled << 15) |
730 ch->type;
731 break;
732
733 default:
734 return 1;
735 }
736 return 0;
737 }
738
739 static int omap_dma_ch_reg_write(struct omap_dma_s *s,
740 struct omap_dma_channel_s *ch, int reg, uint16_t value)
741 {
742 switch (reg) {
743 case 0x00: /* SYS_DMA_CSDP_CH0 */
744 ch->burst[1] = (value & 0xc000) >> 14;
745 ch->pack[1] = (value & 0x2000) >> 13;
746 ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
747 ch->burst[0] = (value & 0x0180) >> 7;
748 ch->pack[0] = (value & 0x0040) >> 6;
749 ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
750 if (ch->port[0] >= __omap_dma_port_last) {
751 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
752 __func__, ch->port[0]);
753 }
754 if (ch->port[1] >= __omap_dma_port_last) {
755 qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
756 __func__, ch->port[1]);
757 }
758 ch->data_type = 1 << (value & 3);
759 if ((value & 3) == 3) {
760 qemu_log_mask(LOG_GUEST_ERROR,
761 "%s: bad data_type for DMA channel\n", __func__);
762 ch->data_type >>= 1;
763 }
764 break;
765
766 case 0x02: /* SYS_DMA_CCR_CH0 */
767 ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
768 ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
769 ch->end_prog = (value & 0x0800) >> 11;
770 ch->repeat = (value & 0x0200) >> 9;
771 ch->auto_init = (value & 0x0100) >> 8;
772 ch->priority = (value & 0x0040) >> 6;
773 ch->fs = (value & 0x0020) >> 5;
774 ch->sync = value & 0x001f;
775
776 if (value & 0x0080)
777 omap_dma_enable_channel(s, ch);
778 else
779 omap_dma_disable_channel(s, ch);
780
781 if (ch->end_prog)
782 omap_dma_channel_end_prog(s, ch);
783
784 break;
785
786 case 0x04: /* SYS_DMA_CICR_CH0 */
787 ch->interrupts = value & 0x3f;
788 break;
789
790 case 0x06: /* SYS_DMA_CSR_CH0 */
791 OMAP_RO_REG((hwaddr) reg);
792 break;
793
794 case 0x08: /* SYS_DMA_CSSA_L_CH0 */
795 ch->addr[0] &= 0xffff0000;
796 ch->addr[0] |= value;
797 break;
798
799 case 0x0a: /* SYS_DMA_CSSA_U_CH0 */
800 ch->addr[0] &= 0x0000ffff;
801 ch->addr[0] |= (uint32_t) value << 16;
802 break;
803
804 case 0x0c: /* SYS_DMA_CDSA_L_CH0 */
805 ch->addr[1] &= 0xffff0000;
806 ch->addr[1] |= value;
807 break;
808
809 case 0x0e: /* SYS_DMA_CDSA_U_CH0 */
810 ch->addr[1] &= 0x0000ffff;
811 ch->addr[1] |= (uint32_t) value << 16;
812 break;
813
814 case 0x10: /* SYS_DMA_CEN_CH0 */
815 ch->elements = value;
816 break;
817
818 case 0x12: /* SYS_DMA_CFN_CH0 */
819 ch->frames = value;
820 break;
821
822 case 0x14: /* SYS_DMA_CFI_CH0 */
823 ch->frame_index[0] = (int16_t) value;
824 break;
825
826 case 0x16: /* SYS_DMA_CEI_CH0 */
827 ch->element_index[0] = (int16_t) value;
828 break;
829
830 case 0x18: /* SYS_DMA_CPC_CH0 or DMA_CSAC */
831 OMAP_RO_REG((hwaddr) reg);
832 break;
833
834 case 0x1c: /* DMA_CDEI */
835 ch->element_index[1] = (int16_t) value;
836 break;
837
838 case 0x1e: /* DMA_CDFI */
839 ch->frame_index[1] = (int16_t) value;
840 break;
841
842 case 0x20: /* DMA_COLOR_L */
843 ch->color &= 0xffff0000;
844 ch->color |= value;
845 break;
846
847 case 0x22: /* DMA_COLOR_U */
848 ch->color &= 0xffff;
849 ch->color |= (uint32_t)value << 16;
850 break;
851
852 case 0x24: /* DMA_CCR2 */
853 ch->bs = (value >> 2) & 0x1;
854 ch->transparent_copy = (value >> 1) & 0x1;
855 ch->constant_fill = value & 0x1;
856 break;
857
858 case 0x28: /* DMA_CLNK_CTRL */
859 ch->link_enabled = (value >> 15) & 0x1;
860 if (value & (1 << 14)) { /* Stop_Lnk */
861 ch->link_enabled = 0;
862 omap_dma_disable_channel(s, ch);
863 }
864 ch->link_next_ch = value & 0x1f;
865 break;
866
867 case 0x2a: /* DMA_LCH_CTRL */
868 ch->interleave_disabled = (value >> 15) & 0x1;
869 ch->type = value & 0xf;
870 break;
871
872 default:
873 return 1;
874 }
875 return 0;
876 }
877
878 static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
879 uint16_t value)
880 {
881 switch (offset) {
882 case 0x300: /* SYS_DMA_LCD_CTRL */
883 s->src = (value & 0x40) ? imif : emiff;
884 s->condition = 0;
885 /* Assume no bus errors and thus no BUS_ERROR irq bits. */
886 s->interrupts = (value >> 1) & 1;
887 s->dual = value & 1;
888 break;
889
890 case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
891 s->src_f1_top &= 0xffff0000;
892 s->src_f1_top |= 0x0000ffff & value;
893 break;
894
895 case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
896 s->src_f1_top &= 0x0000ffff;
897 s->src_f1_top |= (uint32_t)value << 16;
898 break;
899
900 case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
901 s->src_f1_bottom &= 0xffff0000;
902 s->src_f1_bottom |= 0x0000ffff & value;
903 break;
904
905 case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
906 s->src_f1_bottom &= 0x0000ffff;
907 s->src_f1_bottom |= (uint32_t)value << 16;
908 break;
909
910 case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
911 s->src_f2_top &= 0xffff0000;
912 s->src_f2_top |= 0x0000ffff & value;
913 break;
914
915 case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
916 s->src_f2_top &= 0x0000ffff;
917 s->src_f2_top |= (uint32_t)value << 16;
918 break;
919
920 case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
921 s->src_f2_bottom &= 0xffff0000;
922 s->src_f2_bottom |= 0x0000ffff & value;
923 break;
924
925 case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
926 s->src_f2_bottom &= 0x0000ffff;
927 s->src_f2_bottom |= (uint32_t)value << 16;
928 break;
929
930 default:
931 return 1;
932 }
933 return 0;
934 }
935
936 static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
937 uint16_t *ret)
938 {
939 int i;
940
941 switch (offset) {
942 case 0x300: /* SYS_DMA_LCD_CTRL */
943 i = s->condition;
944 s->condition = 0;
945 qemu_irq_lower(s->irq);
946 *ret = ((s->src == imif) << 6) | (i << 3) |
947 (s->interrupts << 1) | s->dual;
948 break;
949
950 case 0x302: /* SYS_DMA_LCD_TOP_F1_L */
951 *ret = s->src_f1_top & 0xffff;
952 break;
953
954 case 0x304: /* SYS_DMA_LCD_TOP_F1_U */
955 *ret = s->src_f1_top >> 16;
956 break;
957
958 case 0x306: /* SYS_DMA_LCD_BOT_F1_L */
959 *ret = s->src_f1_bottom & 0xffff;
960 break;
961
962 case 0x308: /* SYS_DMA_LCD_BOT_F1_U */
963 *ret = s->src_f1_bottom >> 16;
964 break;
965
966 case 0x30a: /* SYS_DMA_LCD_TOP_F2_L */
967 *ret = s->src_f2_top & 0xffff;
968 break;
969
970 case 0x30c: /* SYS_DMA_LCD_TOP_F2_U */
971 *ret = s->src_f2_top >> 16;
972 break;
973
974 case 0x30e: /* SYS_DMA_LCD_BOT_F2_L */
975 *ret = s->src_f2_bottom & 0xffff;
976 break;
977
978 case 0x310: /* SYS_DMA_LCD_BOT_F2_U */
979 *ret = s->src_f2_bottom >> 16;
980 break;
981
982 default:
983 return 1;
984 }
985 return 0;
986 }
987
988 static uint64_t omap_dma_read(void *opaque, hwaddr addr, unsigned size)
989 {
990 struct omap_dma_s *s = opaque;
991 int reg, ch;
992 uint16_t ret;
993
994 if (size != 2) {
995 qemu_log_mask(LOG_GUEST_ERROR, "%s: read at offset 0x%" HWADDR_PRIx
996 " with bad width %d\n", __func__, addr, size);
997 return 0;
998 }
999
1000 switch (addr) {
1001 case 0x300 ... 0x3fe:
1002 if (omap_dma_3_1_lcd_read(&s->lcd_ch, addr, &ret)) {
1003 break;
1004 }
1005 return ret;
1006 case 0x000 ... 0x2fe:
1007 reg = addr & 0x3f;
1008 ch = (addr >> 6) & 0x0f;
1009 if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))
1010 break;
1011 return ret;
1012
1013 case 0x404 ... 0x4fe:
1014 break;
1015 case 0x400: /* SYS_DMA_GCR */
1016 return s->gcr;
1017 break;
1018
1019 case 0xb00 ... 0xbfe:
1020 break;
1021 }
1022
1023 OMAP_BAD_REG(addr);
1024 return 0;
1025 }
1026
1027 static void omap_dma_write(void *opaque, hwaddr addr,
1028 uint64_t value, unsigned size)
1029 {
1030 struct omap_dma_s *s = opaque;
1031 int reg, ch;
1032
1033 if (size != 2) {
1034 qemu_log_mask(LOG_GUEST_ERROR, "%s: write at offset 0x%" HWADDR_PRIx
1035 " with bad width %d\n", __func__, addr, size);
1036 return;
1037 }
1038
1039 switch (addr) {
1040 case 0x300 ... 0x3fe:
1041 if (omap_dma_3_1_lcd_write(&s->lcd_ch, addr, value)) {
1042 break;
1043 }
1044 return;
1045 case 0x000 ... 0x2fe:
1046 reg = addr & 0x3f;
1047 ch = (addr >> 6) & 0x0f;
1048 if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))
1049 break;
1050 return;
1051
1052 case 0x404 ... 0x4fe:
1053 break;
1054 case 0x400: /* SYS_DMA_GCR */
1055 s->gcr = value;
1056 return;
1057
1058 case 0xb00 ... 0xbfe:
1059 break;
1060 }
1061
1062 OMAP_BAD_REG(addr);
1063 }
1064
1065 static const MemoryRegionOps omap_dma_ops = {
1066 .read = omap_dma_read,
1067 .write = omap_dma_write,
1068 .endianness = DEVICE_NATIVE_ENDIAN,
1069 };
1070
1071 static void omap_dma_request(void *opaque, int drq, int req)
1072 {
1073 struct omap_dma_s *s = opaque;
1074 /* The request pins are level triggered in QEMU. */
1075 if (req) {
1076 if (~s->dma->drqbmp & (1ULL << drq)) {
1077 s->dma->drqbmp |= 1ULL << drq;
1078 omap_dma_process_request(s, drq);
1079 }
1080 } else
1081 s->dma->drqbmp &= ~(1ULL << drq);
1082 }
1083
1084 /* XXX: this won't be needed once soc_dma knows about clocks. */
1085 static void omap_dma_clk_update(void *opaque, int line, int on)
1086 {
1087 struct omap_dma_s *s = opaque;
1088 int i;
1089
1090 s->dma->freq = omap_clk_getrate(s->clk);
1091
1092 for (i = 0; i < s->chans; i ++)
1093 if (s->ch[i].active)
1094 soc_dma_set_request(s->ch[i].dma, on);
1095 }
1096
1097 struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
1098 MemoryRegion *sysmem,
1099 qemu_irq lcd_irq,
1100 struct omap_mpu_state_s *mpu, omap_clk clk)
1101 {
1102 int num_irqs, memsize, i;
1103 struct omap_dma_s *s = g_new0(struct omap_dma_s, 1);
1104
1105 num_irqs = 6;
1106 memsize = 0x800;
1107 s->mpu = mpu;
1108 s->clk = clk;
1109 s->lcd_ch.irq = lcd_irq;
1110 s->lcd_ch.mpu = mpu;
1111 s->chans = 9;
1112
1113 s->dma = soc_dma_init(9);
1114 s->dma->freq = omap_clk_getrate(clk);
1115 s->dma->transfer_fn = omap_dma_transfer_generic;
1116 s->dma->setup_fn = omap_dma_transfer_setup;
1117 s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1118 s->dma->opaque = s;
1119
1120 while (num_irqs --)
1121 s->ch[num_irqs].irq = irqs[num_irqs];
1122 for (i = 0; i < 3; i ++) {
1123 s->ch[i].sibling = &s->ch[i + 6];
1124 s->ch[i + 6].sibling = &s->ch[i];
1125 }
1126 for (i = 8; i >= 0; i--) {
1127 s->ch[i].dma = &s->dma->ch[i];
1128 s->dma->ch[i].opaque = &s->ch[i];
1129 }
1130
1131 omap_clk_adduser(s->clk, qemu_allocate_irq(omap_dma_clk_update, s, 0));
1132 omap_dma_reset(s->dma);
1133 omap_dma_clk_update(s, 0, 1);
1134
1135 memory_region_init_io(&s->iomem, NULL, &omap_dma_ops, s, "omap.dma", memsize);
1136 memory_region_add_subregion(sysmem, base, &s->iomem);
1137
1138 mpu->drq = s->dma->drq;
1139
1140 return s->dma;
1141 }
1142
1143 struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct soc_dma_s *dma)
1144 {
1145 struct omap_dma_s *s = dma->opaque;
1146
1147 return &s->lcd_ch;
1148 }