xref: /openbmc/qemu/hw/dma/omap_dma.c (revision 062cfce8d4c077800d252b84c65da8a2dd03fd6f)
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/irq.h"
25  #include "hw/arm/soc_dma.h"
26  
27  struct omap_dma_channel_s {
28      /* transfer data */
29      int burst[2];
30      int pack[2];
31      int endian[2];
32      int endian_lock[2];
33      int translate[2];
34      enum omap_dma_port port[2];
35      hwaddr addr[2];
36      omap_dma_addressing_t mode[2];
37      uint32_t elements;
38      uint16_t frames;
39      int32_t frame_index[2];
40      int16_t element_index[2];
41      int data_type;
42  
43      /* transfer type */
44      int transparent_copy;
45      int constant_fill;
46      uint32_t color;
47      int prefetch;
48  
49      /* auto init and linked channel data */
50      int end_prog;
51      int repeat;
52      int auto_init;
53      int link_enabled;
54      int link_next_ch;
55  
56      /* interruption data */
57      int interrupts;
58      int status;
59      int cstatus;
60  
61      /* state data */
62      int active;
63      int enable;
64      int sync;
65      int src_sync;
66      int pending_request;
67      int waiting_end_prog;
68      uint16_t cpc;
69      int set_update;
70  
71      /* sync type */
72      int fs;
73      int bs;
74  
75      /* compatibility */
76      int omap_3_1_compatible_disable;
77  
78      qemu_irq irq;
79      struct omap_dma_channel_s *sibling;
80  
81      struct omap_dma_reg_set_s {
82          hwaddr src, dest;
83          int frame;
84          int element;
85          int pck_element;
86          int frame_delta[2];
87          int elem_delta[2];
88          int frames;
89          int elements;
90          int pck_elements;
91      } active_set;
92  
93      struct soc_dma_ch_s *dma;
94  
95      /* unused parameters */
96      int write_mode;
97      int priority;
98      int interleave_disabled;
99      int type;
100      int suspend;
101      int buf_disable;
102  };
103  
104  struct omap_dma_s {
105      struct soc_dma_s *dma;
106      MemoryRegion iomem;
107  
108      struct omap_mpu_state_s *mpu;
109      omap_clk clk;
110      qemu_irq irq[4];
111      void (*intr_update)(struct omap_dma_s *s);
112      enum omap_dma_model model;
113      int omap_3_1_mapping_disabled;
114  
115      uint32_t gcr;
116      uint32_t ocp;
117      uint32_t caps[5];
118      uint32_t irqen[4];
119      uint32_t irqstat[4];
120  
121      int chans;
122      struct omap_dma_channel_s ch[32];
123      struct omap_dma_lcd_channel_s lcd_ch;
124  };
125  
126  /* Interrupts */
127  #define TIMEOUT_INTR    (1 << 0)
128  #define EVENT_DROP_INTR (1 << 1)
129  #define HALF_FRAME_INTR (1 << 2)
130  #define END_FRAME_INTR  (1 << 3)
131  #define LAST_FRAME_INTR (1 << 4)
132  #define END_BLOCK_INTR  (1 << 5)
133  #define SYNC            (1 << 6)
134  #define END_PKT_INTR	(1 << 7)
135  #define TRANS_ERR_INTR	(1 << 8)
136  #define MISALIGN_INTR	(1 << 11)
137  
omap_dma_interrupts_update(struct omap_dma_s * s)138  static inline void omap_dma_interrupts_update(struct omap_dma_s *s)
139  {
140      s->intr_update(s);
141  }
142  
omap_dma_channel_load(struct omap_dma_channel_s * ch)143  static void omap_dma_channel_load(struct omap_dma_channel_s *ch)
144  {
145      struct omap_dma_reg_set_s *a = &ch->active_set;
146      int i, normal;
147      int omap_3_1 = !ch->omap_3_1_compatible_disable;
148  
149      /*
150       * TODO: verify address ranges and alignment
151       * TODO: port endianness
152       */
153  
154      a->src = ch->addr[0];
155      a->dest = ch->addr[1];
156      a->frames = ch->frames;
157      a->elements = ch->elements;
158      a->pck_elements = ch->frame_index[!ch->src_sync];
159      a->frame = 0;
160      a->element = 0;
161      a->pck_element = 0;
162  
163      if (unlikely(!ch->elements || !ch->frames)) {
164          printf("%s: bad DMA request\n", __func__);
165          return;
166      }
167  
168      for (i = 0; i < 2; i ++)
169          switch (ch->mode[i]) {
170          case constant:
171              a->elem_delta[i] = 0;
172              a->frame_delta[i] = 0;
173              break;
174          case post_incremented:
175              a->elem_delta[i] = ch->data_type;
176              a->frame_delta[i] = 0;
177              break;
178          case single_index:
179              a->elem_delta[i] = ch->data_type +
180                      ch->element_index[omap_3_1 ? 0 : i] - 1;
181              a->frame_delta[i] = 0;
182              break;
183          case double_index:
184              a->elem_delta[i] = ch->data_type +
185                      ch->element_index[omap_3_1 ? 0 : i] - 1;
186              a->frame_delta[i] = ch->frame_index[omap_3_1 ? 0 : i] -
187                      ch->element_index[omap_3_1 ? 0 : i];
188              break;
189          default:
190              break;
191          }
192  
193      normal = !ch->transparent_copy && !ch->constant_fill &&
194              /* FIFO is big-endian so either (ch->endian[n] == 1) OR
195               * (ch->endian_lock[n] == 1) mean no endianism conversion.  */
196              (ch->endian[0] | ch->endian_lock[0]) ==
197              (ch->endian[1] | ch->endian_lock[1]);
198      for (i = 0; i < 2; i ++) {
199          /* TODO: for a->frame_delta[i] > 0 still use the fast path, just
200           * limit min_elems in omap_dma_transfer_setup to the nearest frame
201           * end.  */
202          if (!a->elem_delta[i] && normal &&
203                          (a->frames == 1 || !a->frame_delta[i]))
204              ch->dma->type[i] = soc_dma_access_const;
205          else if (a->elem_delta[i] == ch->data_type && normal &&
206                          (a->frames == 1 || !a->frame_delta[i]))
207              ch->dma->type[i] = soc_dma_access_linear;
208          else
209              ch->dma->type[i] = soc_dma_access_other;
210  
211          ch->dma->vaddr[i] = ch->addr[i];
212      }
213      soc_dma_ch_update(ch->dma);
214  }
215  
omap_dma_activate_channel(struct omap_dma_s * s,struct omap_dma_channel_s * ch)216  static void omap_dma_activate_channel(struct omap_dma_s *s,
217                  struct omap_dma_channel_s *ch)
218  {
219      if (!ch->active) {
220          if (ch->set_update) {
221              /* It's not clear when the active set is supposed to be
222               * loaded from registers.  We're already loading it when the
223               * channel is enabled, and for some guests this is not enough
224               * but that may be also because of a race condition (no
225               * delays in qemu) in the guest code, which we're just
226               * working around here.  */
227              omap_dma_channel_load(ch);
228              ch->set_update = 0;
229          }
230  
231          ch->active = 1;
232          soc_dma_set_request(ch->dma, 1);
233          if (ch->sync)
234              ch->status |= SYNC;
235      }
236  }
237  
omap_dma_deactivate_channel(struct omap_dma_s * s,struct omap_dma_channel_s * ch)238  static void omap_dma_deactivate_channel(struct omap_dma_s *s,
239                  struct omap_dma_channel_s *ch)
240  {
241      /* Update cpc */
242      ch->cpc = ch->active_set.dest & 0xffff;
243  
244      if (ch->pending_request && !ch->waiting_end_prog && ch->enable) {
245          /* Don't deactivate the channel */
246          ch->pending_request = 0;
247          return;
248      }
249  
250      /* Don't deactivate the channel if it is synchronized and the DMA request is
251         active */
252      if (ch->sync && ch->enable && (s->dma->drqbmp & (1ULL << ch->sync)))
253          return;
254  
255      if (ch->active) {
256          ch->active = 0;
257          ch->status &= ~SYNC;
258          soc_dma_set_request(ch->dma, 0);
259      }
260  }
261  
omap_dma_enable_channel(struct omap_dma_s * s,struct omap_dma_channel_s * ch)262  static void omap_dma_enable_channel(struct omap_dma_s *s,
263                  struct omap_dma_channel_s *ch)
264  {
265      if (!ch->enable) {
266          ch->enable = 1;
267          ch->waiting_end_prog = 0;
268          omap_dma_channel_load(ch);
269          /* TODO: theoretically if ch->sync && ch->prefetch &&
270           * !s->dma->drqbmp[ch->sync], we should also activate and fetch
271           * from source and then stall until signalled.  */
272          if ((!ch->sync) || (s->dma->drqbmp & (1ULL << ch->sync))) {
273              omap_dma_activate_channel(s, ch);
274          }
275      }
276  }
277  
omap_dma_disable_channel(struct omap_dma_s * s,struct omap_dma_channel_s * ch)278  static void omap_dma_disable_channel(struct omap_dma_s *s,
279                  struct omap_dma_channel_s *ch)
280  {
281      if (ch->enable) {
282          ch->enable = 0;
283          /* Discard any pending request */
284          ch->pending_request = 0;
285          omap_dma_deactivate_channel(s, ch);
286      }
287  }
288  
omap_dma_channel_end_prog(struct omap_dma_s * s,struct omap_dma_channel_s * ch)289  static void omap_dma_channel_end_prog(struct omap_dma_s *s,
290                  struct omap_dma_channel_s *ch)
291  {
292      if (ch->waiting_end_prog) {
293          ch->waiting_end_prog = 0;
294          if (!ch->sync || ch->pending_request) {
295              ch->pending_request = 0;
296              omap_dma_activate_channel(s, ch);
297          }
298      }
299  }
300  
omap_dma_interrupts_3_1_update(struct omap_dma_s * s)301  static void omap_dma_interrupts_3_1_update(struct omap_dma_s *s)
302  {
303      struct omap_dma_channel_s *ch = s->ch;
304  
305      /* First three interrupts are shared between two channels each. */
306      if (ch[0].status | ch[6].status)
307          qemu_irq_raise(ch[0].irq);
308      if (ch[1].status | ch[7].status)
309          qemu_irq_raise(ch[1].irq);
310      if (ch[2].status | ch[8].status)
311          qemu_irq_raise(ch[2].irq);
312      if (ch[3].status)
313          qemu_irq_raise(ch[3].irq);
314      if (ch[4].status)
315          qemu_irq_raise(ch[4].irq);
316      if (ch[5].status)
317          qemu_irq_raise(ch[5].irq);
318  }
319  
omap_dma_interrupts_3_2_update(struct omap_dma_s * s)320  static void omap_dma_interrupts_3_2_update(struct omap_dma_s *s)
321  {
322      struct omap_dma_channel_s *ch = s->ch;
323      int i;
324  
325      for (i = s->chans; i; ch ++, i --)
326          if (ch->status)
327              qemu_irq_raise(ch->irq);
328  }
329  
omap_dma_enable_3_1_mapping(struct omap_dma_s * s)330  static void omap_dma_enable_3_1_mapping(struct omap_dma_s *s)
331  {
332      s->omap_3_1_mapping_disabled = 0;
333      s->chans = 9;
334      s->intr_update = omap_dma_interrupts_3_1_update;
335  }
336  
omap_dma_disable_3_1_mapping(struct omap_dma_s * s)337  static void omap_dma_disable_3_1_mapping(struct omap_dma_s *s)
338  {
339      s->omap_3_1_mapping_disabled = 1;
340      s->chans = 16;
341      s->intr_update = omap_dma_interrupts_3_2_update;
342  }
343  
omap_dma_process_request(struct omap_dma_s * s,int request)344  static void omap_dma_process_request(struct omap_dma_s *s, int request)
345  {
346      int channel;
347      int drop_event = 0;
348      struct omap_dma_channel_s *ch = s->ch;
349  
350      for (channel = 0; channel < s->chans; channel ++, ch ++) {
351          if (ch->enable && ch->sync == request) {
352              if (!ch->active)
353                  omap_dma_activate_channel(s, ch);
354              else if (!ch->pending_request)
355                  ch->pending_request = 1;
356              else {
357                  /* Request collision */
358                  /* Second request received while processing other request */
359                  ch->status |= EVENT_DROP_INTR;
360                  drop_event = 1;
361              }
362          }
363      }
364  
365      if (drop_event)
366          omap_dma_interrupts_update(s);
367  }
368  
omap_dma_transfer_generic(struct soc_dma_ch_s * dma)369  static void omap_dma_transfer_generic(struct soc_dma_ch_s *dma)
370  {
371      uint8_t value[4];
372      struct omap_dma_channel_s *ch = dma->opaque;
373      struct omap_dma_reg_set_s *a = &ch->active_set;
374      int bytes = dma->bytes;
375  #ifdef MULTI_REQ
376      uint16_t status = ch->status;
377  #endif
378  
379      do {
380          /* Transfer a single element */
381          /* FIXME: check the endianness */
382          if (!ch->constant_fill)
383              cpu_physical_memory_read(a->src, value, ch->data_type);
384          else
385              *(uint32_t *) value = ch->color;
386  
387          if (!ch->transparent_copy || *(uint32_t *) value != ch->color)
388              cpu_physical_memory_write(a->dest, value, ch->data_type);
389  
390          a->src += a->elem_delta[0];
391          a->dest += a->elem_delta[1];
392          a->element ++;
393  
394  #ifndef MULTI_REQ
395          if (a->element == a->elements) {
396              /* End of Frame */
397              a->element = 0;
398              a->src += a->frame_delta[0];
399              a->dest += a->frame_delta[1];
400              a->frame ++;
401  
402              /* If the channel is async, update cpc */
403              if (!ch->sync)
404                  ch->cpc = a->dest & 0xffff;
405          }
406      } while ((bytes -= ch->data_type));
407  #else
408          /* If the channel is element synchronized, deactivate it */
409          if (ch->sync && !ch->fs && !ch->bs)
410              omap_dma_deactivate_channel(s, ch);
411  
412          /* If it is the last frame, set the LAST_FRAME interrupt */
413          if (a->element == 1 && a->frame == a->frames - 1)
414              if (ch->interrupts & LAST_FRAME_INTR)
415                  ch->status |= LAST_FRAME_INTR;
416  
417          /* If the half of the frame was reached, set the HALF_FRAME
418             interrupt */
419          if (a->element == (a->elements >> 1))
420              if (ch->interrupts & HALF_FRAME_INTR)
421                  ch->status |= HALF_FRAME_INTR;
422  
423          if (ch->fs && ch->bs) {
424              a->pck_element ++;
425              /* Check if a full packet has been transferred.  */
426              if (a->pck_element == a->pck_elements) {
427                  a->pck_element = 0;
428  
429                  /* Set the END_PKT interrupt */
430                  if ((ch->interrupts & END_PKT_INTR) && !ch->src_sync)
431                      ch->status |= END_PKT_INTR;
432  
433                  /* If the channel is packet-synchronized, deactivate it */
434                  if (ch->sync)
435                      omap_dma_deactivate_channel(s, ch);
436              }
437          }
438  
439          if (a->element == a->elements) {
440              /* End of Frame */
441              a->element = 0;
442              a->src += a->frame_delta[0];
443              a->dest += a->frame_delta[1];
444              a->frame ++;
445  
446              /* If the channel is frame synchronized, deactivate it */
447              if (ch->sync && ch->fs && !ch->bs)
448                  omap_dma_deactivate_channel(s, ch);
449  
450              /* If the channel is async, update cpc */
451              if (!ch->sync)
452                  ch->cpc = a->dest & 0xffff;
453  
454              /* Set the END_FRAME interrupt */
455              if (ch->interrupts & END_FRAME_INTR)
456                  ch->status |= END_FRAME_INTR;
457  
458              if (a->frame == a->frames) {
459                  /* End of Block */
460                  /* Disable the channel */
461  
462                  if (ch->omap_3_1_compatible_disable) {
463                      omap_dma_disable_channel(s, ch);
464                      if (ch->link_enabled)
465                          omap_dma_enable_channel(s,
466                                          &s->ch[ch->link_next_ch]);
467                  } else {
468                      if (!ch->auto_init)
469                          omap_dma_disable_channel(s, ch);
470                      else if (ch->repeat || ch->end_prog)
471                          omap_dma_channel_load(ch);
472                      else {
473                          ch->waiting_end_prog = 1;
474                          omap_dma_deactivate_channel(s, ch);
475                      }
476                  }
477  
478                  if (ch->interrupts & END_BLOCK_INTR)
479                      ch->status |= END_BLOCK_INTR;
480              }
481          }
482      } while (status == ch->status && ch->active);
483  
484      omap_dma_interrupts_update(s);
485  #endif
486  }
487  
488  enum {
489      omap_dma_intr_element_sync,
490      omap_dma_intr_last_frame,
491      omap_dma_intr_half_frame,
492      omap_dma_intr_frame,
493      omap_dma_intr_frame_sync,
494      omap_dma_intr_packet,
495      omap_dma_intr_packet_sync,
496      omap_dma_intr_block,
497      __omap_dma_intr_last,
498  };
499  
500  static void omap_dma_transfer_setup(struct soc_dma_ch_s *dma)
501  {
502      struct omap_dma_port_if_s *src_p, *dest_p;
503      struct omap_dma_reg_set_s *a;
504      struct omap_dma_channel_s *ch = dma->opaque;
505      struct omap_dma_s *s = dma->dma->opaque;
506      int frames, min_elems, elements[__omap_dma_intr_last];
507  
508      a = &ch->active_set;
509  
510      src_p = &s->mpu->port[ch->port[0]];
511      dest_p = &s->mpu->port[ch->port[1]];
512      if ((!ch->constant_fill && !src_p->addr_valid(s->mpu, a->src)) ||
513                      (!dest_p->addr_valid(s->mpu, a->dest))) {
514  #if 0
515          /* Bus time-out */
516          if (ch->interrupts & TIMEOUT_INTR)
517              ch->status |= TIMEOUT_INTR;
518          omap_dma_deactivate_channel(s, ch);
519          continue;
520  #endif
521          printf("%s: Bus time-out in DMA%i operation\n",
522                          __func__, dma->num);
523      }
524  
525      min_elems = INT_MAX;
526  
527      /* Check all the conditions that terminate the transfer starting
528       * with those that can occur the soonest.  */
529  #define INTR_CHECK(cond, id, nelements)	\
530      if (cond) {			\
531          elements[id] = nelements;	\
532          if (elements[id] < min_elems)	\
533              min_elems = elements[id];	\
534      } else				\
535          elements[id] = INT_MAX;
536  
537      /* Elements */
538      INTR_CHECK(
539                      ch->sync && !ch->fs && !ch->bs,
540                      omap_dma_intr_element_sync,
541                      1)
542  
543      /* Frames */
544      /* TODO: for transfers where entire frames can be read and written
545       * using memcpy() but a->frame_delta is non-zero, try to still do
546       * transfers using soc_dma but limit min_elems to a->elements - ...
547       * See also the TODO in omap_dma_channel_load.  */
548      INTR_CHECK(
549                      (ch->interrupts & LAST_FRAME_INTR) &&
550                      ((a->frame < a->frames - 1) || !a->element),
551                      omap_dma_intr_last_frame,
552                      (a->frames - a->frame - 2) * a->elements +
553                      (a->elements - a->element + 1))
554      INTR_CHECK(
555                      ch->interrupts & HALF_FRAME_INTR,
556                      omap_dma_intr_half_frame,
557                      (a->elements >> 1) +
558                      (a->element >= (a->elements >> 1) ? a->elements : 0) -
559                      a->element)
560      INTR_CHECK(
561                      ch->sync && ch->fs && (ch->interrupts & END_FRAME_INTR),
562                      omap_dma_intr_frame,
563                      a->elements - a->element)
564      INTR_CHECK(
565                      ch->sync && ch->fs && !ch->bs,
566                      omap_dma_intr_frame_sync,
567                      a->elements - a->element)
568  
569      /* Packets */
570      INTR_CHECK(
571                      ch->fs && ch->bs &&
572                      (ch->interrupts & END_PKT_INTR) && !ch->src_sync,
573                      omap_dma_intr_packet,
574                      a->pck_elements - a->pck_element)
575      INTR_CHECK(
576                      ch->fs && ch->bs && ch->sync,
577                      omap_dma_intr_packet_sync,
578                      a->pck_elements - a->pck_element)
579  
580      /* Blocks */
581      INTR_CHECK(
582                      1,
583                      omap_dma_intr_block,
584                      (a->frames - a->frame - 1) * a->elements +
585                      (a->elements - a->element))
586  
587      dma->bytes = min_elems * ch->data_type;
588  
589      /* Set appropriate interrupts and/or deactivate channels */
590  
591  #ifdef MULTI_REQ
592      /* TODO: should all of this only be done if dma->update, and otherwise
593       * inside omap_dma_transfer_generic below - check what's faster.  */
594      if (dma->update) {
595  #endif
596  
597          /* If the channel is element synchronized, deactivate it */
598          if (min_elems == elements[omap_dma_intr_element_sync])
599              omap_dma_deactivate_channel(s, ch);
600  
601          /* If it is the last frame, set the LAST_FRAME interrupt */
602          if (min_elems == elements[omap_dma_intr_last_frame])
603              ch->status |= LAST_FRAME_INTR;
604  
605          /* If exactly half of the frame was reached, set the HALF_FRAME
606             interrupt */
607          if (min_elems == elements[omap_dma_intr_half_frame])
608              ch->status |= HALF_FRAME_INTR;
609  
610          /* If a full packet has been transferred, set the END_PKT interrupt */
611          if (min_elems == elements[omap_dma_intr_packet])
612              ch->status |= END_PKT_INTR;
613  
614          /* If the channel is packet-synchronized, deactivate it */
615          if (min_elems == elements[omap_dma_intr_packet_sync])
616              omap_dma_deactivate_channel(s, ch);
617  
618          /* If the channel is frame synchronized, deactivate it */
619          if (min_elems == elements[omap_dma_intr_frame_sync])
620              omap_dma_deactivate_channel(s, ch);
621  
622          /* Set the END_FRAME interrupt */
623          if (min_elems == elements[omap_dma_intr_frame])
624              ch->status |= END_FRAME_INTR;
625  
626          if (min_elems == elements[omap_dma_intr_block]) {
627              /* End of Block */
628              /* Disable the channel */
629  
630              if (ch->omap_3_1_compatible_disable) {
631                  omap_dma_disable_channel(s, ch);
632                  if (ch->link_enabled)
633                      omap_dma_enable_channel(s, &s->ch[ch->link_next_ch]);
634              } else {
635                  if (!ch->auto_init)
636                      omap_dma_disable_channel(s, ch);
637                  else if (ch->repeat || ch->end_prog)
638                      omap_dma_channel_load(ch);
639                  else {
640                      ch->waiting_end_prog = 1;
641                      omap_dma_deactivate_channel(s, ch);
642                  }
643              }
644  
645              if (ch->interrupts & END_BLOCK_INTR)
646                  ch->status |= END_BLOCK_INTR;
647          }
648  
649          /* Update packet number */
650          if (ch->fs && ch->bs) {
651              a->pck_element += min_elems;
652              a->pck_element %= a->pck_elements;
653          }
654  
655          /* TODO: check if we really need to update anything here or perhaps we
656           * can skip part of this.  */
657  #ifndef MULTI_REQ
658          if (dma->update) {
659  #endif
660              a->element += min_elems;
661  
662              frames = a->element / a->elements;
663              a->element = a->element % a->elements;
664              a->frame += frames;
665              a->src += min_elems * a->elem_delta[0] + frames * a->frame_delta[0];
666              a->dest += min_elems * a->elem_delta[1] + frames * a->frame_delta[1];
667  
668              /* If the channel is async, update cpc */
669              if (!ch->sync && frames)
670                  ch->cpc = a->dest & 0xffff;
671  
672              /* TODO: if the destination port is IMIF or EMIFF, set the dirty
673               * bits on it.  */
674  #ifndef MULTI_REQ
675          }
676  #else
677      }
678  #endif
679  
680      omap_dma_interrupts_update(s);
681  }
682  
683  void omap_dma_reset(struct soc_dma_s *dma)
684  {
685      int i;
686      struct omap_dma_s *s = dma->opaque;
687  
688      soc_dma_reset(s->dma);
689      s->gcr = 0x0004;
690      s->ocp = 0x00000000;
691      memset(&s->irqstat, 0, sizeof(s->irqstat));
692      memset(&s->irqen, 0, sizeof(s->irqen));
693      s->lcd_ch.src = emiff;
694      s->lcd_ch.condition = 0;
695      s->lcd_ch.interrupts = 0;
696      s->lcd_ch.dual = 0;
697      omap_dma_enable_3_1_mapping(s);
698      for (i = 0; i < s->chans; i ++) {
699          s->ch[i].suspend = 0;
700          s->ch[i].prefetch = 0;
701          s->ch[i].buf_disable = 0;
702          s->ch[i].src_sync = 0;
703          memset(&s->ch[i].burst, 0, sizeof(s->ch[i].burst));
704          memset(&s->ch[i].port, 0, sizeof(s->ch[i].port));
705          memset(&s->ch[i].mode, 0, sizeof(s->ch[i].mode));
706          memset(&s->ch[i].frame_index, 0, sizeof(s->ch[i].frame_index));
707          memset(&s->ch[i].element_index, 0, sizeof(s->ch[i].element_index));
708          memset(&s->ch[i].endian, 0, sizeof(s->ch[i].endian));
709          memset(&s->ch[i].endian_lock, 0, sizeof(s->ch[i].endian_lock));
710          memset(&s->ch[i].translate, 0, sizeof(s->ch[i].translate));
711          s->ch[i].write_mode = 0;
712          s->ch[i].data_type = 0;
713          s->ch[i].transparent_copy = 0;
714          s->ch[i].constant_fill = 0;
715          s->ch[i].color = 0x00000000;
716          s->ch[i].end_prog = 0;
717          s->ch[i].repeat = 0;
718          s->ch[i].auto_init = 0;
719          s->ch[i].link_enabled = 0;
720          s->ch[i].interrupts = 0x0003;
721          s->ch[i].status = 0;
722          s->ch[i].cstatus = 0;
723          s->ch[i].active = 0;
724          s->ch[i].enable = 0;
725          s->ch[i].sync = 0;
726          s->ch[i].pending_request = 0;
727          s->ch[i].waiting_end_prog = 0;
728          s->ch[i].cpc = 0x0000;
729          s->ch[i].fs = 0;
730          s->ch[i].bs = 0;
731          s->ch[i].omap_3_1_compatible_disable = 0;
732          memset(&s->ch[i].active_set, 0, sizeof(s->ch[i].active_set));
733          s->ch[i].priority = 0;
734          s->ch[i].interleave_disabled = 0;
735          s->ch[i].type = 0;
736      }
737  }
738  
739  static int omap_dma_ch_reg_read(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          *value = (ch->burst[1] << 14) |
745                  (ch->pack[1] << 13) |
746                  (ch->port[1] << 9) |
747                  (ch->burst[0] << 7) |
748                  (ch->pack[0] << 6) |
749                  (ch->port[0] << 2) |
750                  (ch->data_type >> 1);
751          break;
752  
753      case 0x02:	/* SYS_DMA_CCR_CH0 */
754          if (s->model <= omap_dma_3_1)
755              *value = 0 << 10;			/* FIFO_FLUSH reads as 0 */
756          else
757              *value = ch->omap_3_1_compatible_disable << 10;
758          *value |= (ch->mode[1] << 14) |
759                  (ch->mode[0] << 12) |
760                  (ch->end_prog << 11) |
761                  (ch->repeat << 9) |
762                  (ch->auto_init << 8) |
763                  (ch->enable << 7) |
764                  (ch->priority << 6) |
765                  (ch->fs << 5) | ch->sync;
766          break;
767  
768      case 0x04:	/* SYS_DMA_CICR_CH0 */
769          *value = ch->interrupts;
770          break;
771  
772      case 0x06:	/* SYS_DMA_CSR_CH0 */
773          *value = ch->status;
774          ch->status &= SYNC;
775          if (!ch->omap_3_1_compatible_disable && ch->sibling) {
776              *value |= (ch->sibling->status & 0x3f) << 6;
777              ch->sibling->status &= SYNC;
778          }
779          qemu_irq_lower(ch->irq);
780          break;
781  
782      case 0x08:	/* SYS_DMA_CSSA_L_CH0 */
783          *value = ch->addr[0] & 0x0000ffff;
784          break;
785  
786      case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */
787          *value = ch->addr[0] >> 16;
788          break;
789  
790      case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */
791          *value = ch->addr[1] & 0x0000ffff;
792          break;
793  
794      case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */
795          *value = ch->addr[1] >> 16;
796          break;
797  
798      case 0x10:	/* SYS_DMA_CEN_CH0 */
799          *value = ch->elements;
800          break;
801  
802      case 0x12:	/* SYS_DMA_CFN_CH0 */
803          *value = ch->frames;
804          break;
805  
806      case 0x14:	/* SYS_DMA_CFI_CH0 */
807          *value = ch->frame_index[0];
808          break;
809  
810      case 0x16:	/* SYS_DMA_CEI_CH0 */
811          *value = ch->element_index[0];
812          break;
813  
814      case 0x18:	/* SYS_DMA_CPC_CH0 or DMA_CSAC */
815          if (ch->omap_3_1_compatible_disable)
816              *value = ch->active_set.src & 0xffff;	/* CSAC */
817          else
818              *value = ch->cpc;
819          break;
820  
821      case 0x1a:	/* DMA_CDAC */
822          *value = ch->active_set.dest & 0xffff;	/* CDAC */
823          break;
824  
825      case 0x1c:	/* DMA_CDEI */
826          *value = ch->element_index[1];
827          break;
828  
829      case 0x1e:	/* DMA_CDFI */
830          *value = ch->frame_index[1];
831          break;
832  
833      case 0x20:	/* DMA_COLOR_L */
834          *value = ch->color & 0xffff;
835          break;
836  
837      case 0x22:	/* DMA_COLOR_U */
838          *value = ch->color >> 16;
839          break;
840  
841      case 0x24:	/* DMA_CCR2 */
842          *value = (ch->bs << 2) |
843                  (ch->transparent_copy << 1) |
844                  ch->constant_fill;
845          break;
846  
847      case 0x28:	/* DMA_CLNK_CTRL */
848          *value = (ch->link_enabled << 15) |
849                  (ch->link_next_ch & 0xf);
850          break;
851  
852      case 0x2a:	/* DMA_LCH_CTRL */
853          *value = (ch->interleave_disabled << 15) |
854                  ch->type;
855          break;
856  
857      default:
858          return 1;
859      }
860      return 0;
861  }
862  
863  static int omap_dma_ch_reg_write(struct omap_dma_s *s,
864                  struct omap_dma_channel_s *ch, int reg, uint16_t value)
865  {
866      switch (reg) {
867      case 0x00:	/* SYS_DMA_CSDP_CH0 */
868          ch->burst[1] = (value & 0xc000) >> 14;
869          ch->pack[1] = (value & 0x2000) >> 13;
870          ch->port[1] = (enum omap_dma_port) ((value & 0x1e00) >> 9);
871          ch->burst[0] = (value & 0x0180) >> 7;
872          ch->pack[0] = (value & 0x0040) >> 6;
873          ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
874          if (ch->port[0] >= __omap_dma_port_last) {
875              qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
876                            __func__, ch->port[0]);
877          }
878          if (ch->port[1] >= __omap_dma_port_last) {
879              qemu_log_mask(LOG_GUEST_ERROR, "%s: invalid DMA port %i\n",
880                            __func__, ch->port[1]);
881          }
882          ch->data_type = 1 << (value & 3);
883          if ((value & 3) == 3) {
884              qemu_log_mask(LOG_GUEST_ERROR,
885                            "%s: bad data_type for DMA channel\n", __func__);
886              ch->data_type >>= 1;
887          }
888          break;
889  
890      case 0x02:	/* SYS_DMA_CCR_CH0 */
891          ch->mode[1] = (omap_dma_addressing_t) ((value & 0xc000) >> 14);
892          ch->mode[0] = (omap_dma_addressing_t) ((value & 0x3000) >> 12);
893          ch->end_prog = (value & 0x0800) >> 11;
894          if (s->model >= omap_dma_3_2)
895              ch->omap_3_1_compatible_disable  = (value >> 10) & 0x1;
896          ch->repeat = (value & 0x0200) >> 9;
897          ch->auto_init = (value & 0x0100) >> 8;
898          ch->priority = (value & 0x0040) >> 6;
899          ch->fs = (value & 0x0020) >> 5;
900          ch->sync = value & 0x001f;
901  
902          if (value & 0x0080)
903              omap_dma_enable_channel(s, ch);
904          else
905              omap_dma_disable_channel(s, ch);
906  
907          if (ch->end_prog)
908              omap_dma_channel_end_prog(s, ch);
909  
910          break;
911  
912      case 0x04:	/* SYS_DMA_CICR_CH0 */
913          ch->interrupts = value & 0x3f;
914          break;
915  
916      case 0x06:	/* SYS_DMA_CSR_CH0 */
917          OMAP_RO_REG((hwaddr) reg);
918          break;
919  
920      case 0x08:	/* SYS_DMA_CSSA_L_CH0 */
921          ch->addr[0] &= 0xffff0000;
922          ch->addr[0] |= value;
923          break;
924  
925      case 0x0a:	/* SYS_DMA_CSSA_U_CH0 */
926          ch->addr[0] &= 0x0000ffff;
927          ch->addr[0] |= (uint32_t) value << 16;
928          break;
929  
930      case 0x0c:	/* SYS_DMA_CDSA_L_CH0 */
931          ch->addr[1] &= 0xffff0000;
932          ch->addr[1] |= value;
933          break;
934  
935      case 0x0e:	/* SYS_DMA_CDSA_U_CH0 */
936          ch->addr[1] &= 0x0000ffff;
937          ch->addr[1] |= (uint32_t) value << 16;
938          break;
939  
940      case 0x10:	/* SYS_DMA_CEN_CH0 */
941          ch->elements = value;
942          break;
943  
944      case 0x12:	/* SYS_DMA_CFN_CH0 */
945          ch->frames = value;
946          break;
947  
948      case 0x14:	/* SYS_DMA_CFI_CH0 */
949          ch->frame_index[0] = (int16_t) value;
950          break;
951  
952      case 0x16:	/* SYS_DMA_CEI_CH0 */
953          ch->element_index[0] = (int16_t) value;
954          break;
955  
956      case 0x18:	/* SYS_DMA_CPC_CH0 or DMA_CSAC */
957          OMAP_RO_REG((hwaddr) reg);
958          break;
959  
960      case 0x1c:	/* DMA_CDEI */
961          ch->element_index[1] = (int16_t) value;
962          break;
963  
964      case 0x1e:	/* DMA_CDFI */
965          ch->frame_index[1] = (int16_t) value;
966          break;
967  
968      case 0x20:	/* DMA_COLOR_L */
969          ch->color &= 0xffff0000;
970          ch->color |= value;
971          break;
972  
973      case 0x22:	/* DMA_COLOR_U */
974          ch->color &= 0xffff;
975          ch->color |= (uint32_t)value << 16;
976          break;
977  
978      case 0x24:	/* DMA_CCR2 */
979          ch->bs = (value >> 2) & 0x1;
980          ch->transparent_copy = (value >> 1) & 0x1;
981          ch->constant_fill = value & 0x1;
982          break;
983  
984      case 0x28:	/* DMA_CLNK_CTRL */
985          ch->link_enabled = (value >> 15) & 0x1;
986          if (value & (1 << 14)) {			/* Stop_Lnk */
987              ch->link_enabled = 0;
988              omap_dma_disable_channel(s, ch);
989          }
990          ch->link_next_ch = value & 0x1f;
991          break;
992  
993      case 0x2a:	/* DMA_LCH_CTRL */
994          ch->interleave_disabled = (value >> 15) & 0x1;
995          ch->type = value & 0xf;
996          break;
997  
998      default:
999          return 1;
1000      }
1001      return 0;
1002  }
1003  
1004  static int omap_dma_3_2_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
1005                  uint16_t value)
1006  {
1007      switch (offset) {
1008      case 0xbc0:	/* DMA_LCD_CSDP */
1009          s->brust_f2 = (value >> 14) & 0x3;
1010          s->pack_f2 = (value >> 13) & 0x1;
1011          s->data_type_f2 = (1 << ((value >> 11) & 0x3));
1012          s->brust_f1 = (value >> 7) & 0x3;
1013          s->pack_f1 = (value >> 6) & 0x1;
1014          s->data_type_f1 = (1 << ((value >> 0) & 0x3));
1015          break;
1016  
1017      case 0xbc2:	/* DMA_LCD_CCR */
1018          s->mode_f2 = (value >> 14) & 0x3;
1019          s->mode_f1 = (value >> 12) & 0x3;
1020          s->end_prog = (value >> 11) & 0x1;
1021          s->omap_3_1_compatible_disable = (value >> 10) & 0x1;
1022          s->repeat = (value >> 9) & 0x1;
1023          s->auto_init = (value >> 8) & 0x1;
1024          s->running = (value >> 7) & 0x1;
1025          s->priority = (value >> 6) & 0x1;
1026          s->bs = (value >> 4) & 0x1;
1027          break;
1028  
1029      case 0xbc4:	/* DMA_LCD_CTRL */
1030          s->dst = (value >> 8) & 0x1;
1031          s->src = ((value >> 6) & 0x3) << 1;
1032          s->condition = 0;
1033          /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1034          s->interrupts = (value >> 1) & 1;
1035          s->dual = value & 1;
1036          break;
1037  
1038      case 0xbc8:	/* TOP_B1_L */
1039          s->src_f1_top &= 0xffff0000;
1040          s->src_f1_top |= 0x0000ffff & value;
1041          break;
1042  
1043      case 0xbca:	/* TOP_B1_U */
1044          s->src_f1_top &= 0x0000ffff;
1045          s->src_f1_top |= (uint32_t)value << 16;
1046          break;
1047  
1048      case 0xbcc:	/* BOT_B1_L */
1049          s->src_f1_bottom &= 0xffff0000;
1050          s->src_f1_bottom |= 0x0000ffff & value;
1051          break;
1052  
1053      case 0xbce:	/* BOT_B1_U */
1054          s->src_f1_bottom &= 0x0000ffff;
1055          s->src_f1_bottom |= (uint32_t) value << 16;
1056          break;
1057  
1058      case 0xbd0:	/* TOP_B2_L */
1059          s->src_f2_top &= 0xffff0000;
1060          s->src_f2_top |= 0x0000ffff & value;
1061          break;
1062  
1063      case 0xbd2:	/* TOP_B2_U */
1064          s->src_f2_top &= 0x0000ffff;
1065          s->src_f2_top |= (uint32_t) value << 16;
1066          break;
1067  
1068      case 0xbd4:	/* BOT_B2_L */
1069          s->src_f2_bottom &= 0xffff0000;
1070          s->src_f2_bottom |= 0x0000ffff & value;
1071          break;
1072  
1073      case 0xbd6:	/* BOT_B2_U */
1074          s->src_f2_bottom &= 0x0000ffff;
1075          s->src_f2_bottom |= (uint32_t) value << 16;
1076          break;
1077  
1078      case 0xbd8:	/* DMA_LCD_SRC_EI_B1 */
1079          s->element_index_f1 = value;
1080          break;
1081  
1082      case 0xbda:	/* DMA_LCD_SRC_FI_B1_L */
1083          s->frame_index_f1 &= 0xffff0000;
1084          s->frame_index_f1 |= 0x0000ffff & value;
1085          break;
1086  
1087      case 0xbf4:	/* DMA_LCD_SRC_FI_B1_U */
1088          s->frame_index_f1 &= 0x0000ffff;
1089          s->frame_index_f1 |= (uint32_t) value << 16;
1090          break;
1091  
1092      case 0xbdc:	/* DMA_LCD_SRC_EI_B2 */
1093          s->element_index_f2 = value;
1094          break;
1095  
1096      case 0xbde:	/* DMA_LCD_SRC_FI_B2_L */
1097          s->frame_index_f2 &= 0xffff0000;
1098          s->frame_index_f2 |= 0x0000ffff & value;
1099          break;
1100  
1101      case 0xbf6:	/* DMA_LCD_SRC_FI_B2_U */
1102          s->frame_index_f2 &= 0x0000ffff;
1103          s->frame_index_f2 |= (uint32_t) value << 16;
1104          break;
1105  
1106      case 0xbe0:	/* DMA_LCD_SRC_EN_B1 */
1107          s->elements_f1 = value;
1108          break;
1109  
1110      case 0xbe4:	/* DMA_LCD_SRC_FN_B1 */
1111          s->frames_f1 = value;
1112          break;
1113  
1114      case 0xbe2:	/* DMA_LCD_SRC_EN_B2 */
1115          s->elements_f2 = value;
1116          break;
1117  
1118      case 0xbe6:	/* DMA_LCD_SRC_FN_B2 */
1119          s->frames_f2 = value;
1120          break;
1121  
1122      case 0xbea:	/* DMA_LCD_LCH_CTRL */
1123          s->lch_type = value & 0xf;
1124          break;
1125  
1126      default:
1127          return 1;
1128      }
1129      return 0;
1130  }
1131  
1132  static int omap_dma_3_2_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
1133                  uint16_t *ret)
1134  {
1135      switch (offset) {
1136      case 0xbc0:	/* DMA_LCD_CSDP */
1137          *ret = (s->brust_f2 << 14) |
1138              (s->pack_f2 << 13) |
1139              ((s->data_type_f2 >> 1) << 11) |
1140              (s->brust_f1 << 7) |
1141              (s->pack_f1 << 6) |
1142              ((s->data_type_f1 >> 1) << 0);
1143          break;
1144  
1145      case 0xbc2:	/* DMA_LCD_CCR */
1146          *ret = (s->mode_f2 << 14) |
1147              (s->mode_f1 << 12) |
1148              (s->end_prog << 11) |
1149              (s->omap_3_1_compatible_disable << 10) |
1150              (s->repeat << 9) |
1151              (s->auto_init << 8) |
1152              (s->running << 7) |
1153              (s->priority << 6) |
1154              (s->bs << 4);
1155          break;
1156  
1157      case 0xbc4:	/* DMA_LCD_CTRL */
1158          qemu_irq_lower(s->irq);
1159          *ret = (s->dst << 8) |
1160              ((s->src & 0x6) << 5) |
1161              (s->condition << 3) |
1162              (s->interrupts << 1) |
1163              s->dual;
1164          break;
1165  
1166      case 0xbc8:	/* TOP_B1_L */
1167          *ret = s->src_f1_top & 0xffff;
1168          break;
1169  
1170      case 0xbca:	/* TOP_B1_U */
1171          *ret = s->src_f1_top >> 16;
1172          break;
1173  
1174      case 0xbcc:	/* BOT_B1_L */
1175          *ret = s->src_f1_bottom & 0xffff;
1176          break;
1177  
1178      case 0xbce:	/* BOT_B1_U */
1179          *ret = s->src_f1_bottom >> 16;
1180          break;
1181  
1182      case 0xbd0:	/* TOP_B2_L */
1183          *ret = s->src_f2_top & 0xffff;
1184          break;
1185  
1186      case 0xbd2:	/* TOP_B2_U */
1187          *ret = s->src_f2_top >> 16;
1188          break;
1189  
1190      case 0xbd4:	/* BOT_B2_L */
1191          *ret = s->src_f2_bottom & 0xffff;
1192          break;
1193  
1194      case 0xbd6:	/* BOT_B2_U */
1195          *ret = s->src_f2_bottom >> 16;
1196          break;
1197  
1198      case 0xbd8:	/* DMA_LCD_SRC_EI_B1 */
1199          *ret = s->element_index_f1;
1200          break;
1201  
1202      case 0xbda:	/* DMA_LCD_SRC_FI_B1_L */
1203          *ret = s->frame_index_f1 & 0xffff;
1204          break;
1205  
1206      case 0xbf4:	/* DMA_LCD_SRC_FI_B1_U */
1207          *ret = s->frame_index_f1 >> 16;
1208          break;
1209  
1210      case 0xbdc:	/* DMA_LCD_SRC_EI_B2 */
1211          *ret = s->element_index_f2;
1212          break;
1213  
1214      case 0xbde:	/* DMA_LCD_SRC_FI_B2_L */
1215          *ret = s->frame_index_f2 & 0xffff;
1216          break;
1217  
1218      case 0xbf6:	/* DMA_LCD_SRC_FI_B2_U */
1219          *ret = s->frame_index_f2 >> 16;
1220          break;
1221  
1222      case 0xbe0:	/* DMA_LCD_SRC_EN_B1 */
1223          *ret = s->elements_f1;
1224          break;
1225  
1226      case 0xbe4:	/* DMA_LCD_SRC_FN_B1 */
1227          *ret = s->frames_f1;
1228          break;
1229  
1230      case 0xbe2:	/* DMA_LCD_SRC_EN_B2 */
1231          *ret = s->elements_f2;
1232          break;
1233  
1234      case 0xbe6:	/* DMA_LCD_SRC_FN_B2 */
1235          *ret = s->frames_f2;
1236          break;
1237  
1238      case 0xbea:	/* DMA_LCD_LCH_CTRL */
1239          *ret = s->lch_type;
1240          break;
1241  
1242      default:
1243          return 1;
1244      }
1245      return 0;
1246  }
1247  
1248  static int omap_dma_3_1_lcd_write(struct omap_dma_lcd_channel_s *s, int offset,
1249                  uint16_t value)
1250  {
1251      switch (offset) {
1252      case 0x300:	/* SYS_DMA_LCD_CTRL */
1253          s->src = (value & 0x40) ? imif : emiff;
1254          s->condition = 0;
1255          /* Assume no bus errors and thus no BUS_ERROR irq bits.  */
1256          s->interrupts = (value >> 1) & 1;
1257          s->dual = value & 1;
1258          break;
1259  
1260      case 0x302:	/* SYS_DMA_LCD_TOP_F1_L */
1261          s->src_f1_top &= 0xffff0000;
1262          s->src_f1_top |= 0x0000ffff & value;
1263          break;
1264  
1265      case 0x304:	/* SYS_DMA_LCD_TOP_F1_U */
1266          s->src_f1_top &= 0x0000ffff;
1267          s->src_f1_top |= (uint32_t)value << 16;
1268          break;
1269  
1270      case 0x306:	/* SYS_DMA_LCD_BOT_F1_L */
1271          s->src_f1_bottom &= 0xffff0000;
1272          s->src_f1_bottom |= 0x0000ffff & value;
1273          break;
1274  
1275      case 0x308:	/* SYS_DMA_LCD_BOT_F1_U */
1276          s->src_f1_bottom &= 0x0000ffff;
1277          s->src_f1_bottom |= (uint32_t)value << 16;
1278          break;
1279  
1280      case 0x30a:	/* SYS_DMA_LCD_TOP_F2_L */
1281          s->src_f2_top &= 0xffff0000;
1282          s->src_f2_top |= 0x0000ffff & value;
1283          break;
1284  
1285      case 0x30c:	/* SYS_DMA_LCD_TOP_F2_U */
1286          s->src_f2_top &= 0x0000ffff;
1287          s->src_f2_top |= (uint32_t)value << 16;
1288          break;
1289  
1290      case 0x30e:	/* SYS_DMA_LCD_BOT_F2_L */
1291          s->src_f2_bottom &= 0xffff0000;
1292          s->src_f2_bottom |= 0x0000ffff & value;
1293          break;
1294  
1295      case 0x310:	/* SYS_DMA_LCD_BOT_F2_U */
1296          s->src_f2_bottom &= 0x0000ffff;
1297          s->src_f2_bottom |= (uint32_t)value << 16;
1298          break;
1299  
1300      default:
1301          return 1;
1302      }
1303      return 0;
1304  }
1305  
1306  static int omap_dma_3_1_lcd_read(struct omap_dma_lcd_channel_s *s, int offset,
1307                  uint16_t *ret)
1308  {
1309      int i;
1310  
1311      switch (offset) {
1312      case 0x300:	/* SYS_DMA_LCD_CTRL */
1313          i = s->condition;
1314          s->condition = 0;
1315          qemu_irq_lower(s->irq);
1316          *ret = ((s->src == imif) << 6) | (i << 3) |
1317                  (s->interrupts << 1) | s->dual;
1318          break;
1319  
1320      case 0x302:	/* SYS_DMA_LCD_TOP_F1_L */
1321          *ret = s->src_f1_top & 0xffff;
1322          break;
1323  
1324      case 0x304:	/* SYS_DMA_LCD_TOP_F1_U */
1325          *ret = s->src_f1_top >> 16;
1326          break;
1327  
1328      case 0x306:	/* SYS_DMA_LCD_BOT_F1_L */
1329          *ret = s->src_f1_bottom & 0xffff;
1330          break;
1331  
1332      case 0x308:	/* SYS_DMA_LCD_BOT_F1_U */
1333          *ret = s->src_f1_bottom >> 16;
1334          break;
1335  
1336      case 0x30a:	/* SYS_DMA_LCD_TOP_F2_L */
1337          *ret = s->src_f2_top & 0xffff;
1338          break;
1339  
1340      case 0x30c:	/* SYS_DMA_LCD_TOP_F2_U */
1341          *ret = s->src_f2_top >> 16;
1342          break;
1343  
1344      case 0x30e:	/* SYS_DMA_LCD_BOT_F2_L */
1345          *ret = s->src_f2_bottom & 0xffff;
1346          break;
1347  
1348      case 0x310:	/* SYS_DMA_LCD_BOT_F2_U */
1349          *ret = s->src_f2_bottom >> 16;
1350          break;
1351  
1352      default:
1353          return 1;
1354      }
1355      return 0;
1356  }
1357  
1358  static int omap_dma_sys_write(struct omap_dma_s *s, int offset, uint16_t value)
1359  {
1360      switch (offset) {
1361      case 0x400:	/* SYS_DMA_GCR */
1362          s->gcr = value;
1363          break;
1364  
1365      case 0x404:	/* DMA_GSCR */
1366          if (value & 0x8)
1367              omap_dma_disable_3_1_mapping(s);
1368          else
1369              omap_dma_enable_3_1_mapping(s);
1370          break;
1371  
1372      case 0x408:	/* DMA_GRST */
1373          if (value & 0x1)
1374              omap_dma_reset(s->dma);
1375          break;
1376  
1377      default:
1378          return 1;
1379      }
1380      return 0;
1381  }
1382  
1383  static int omap_dma_sys_read(struct omap_dma_s *s, int offset,
1384                  uint16_t *ret)
1385  {
1386      switch (offset) {
1387      case 0x400:	/* SYS_DMA_GCR */
1388          *ret = s->gcr;
1389          break;
1390  
1391      case 0x404:	/* DMA_GSCR */
1392          *ret = s->omap_3_1_mapping_disabled << 3;
1393          break;
1394  
1395      case 0x408:	/* DMA_GRST */
1396          *ret = 0;
1397          break;
1398  
1399      case 0x442:	/* DMA_HW_ID */
1400      case 0x444:	/* DMA_PCh2_ID */
1401      case 0x446:	/* DMA_PCh0_ID */
1402      case 0x448:	/* DMA_PCh1_ID */
1403      case 0x44a:	/* DMA_PChG_ID */
1404      case 0x44c:	/* DMA_PChD_ID */
1405          *ret = 1;
1406          break;
1407  
1408      case 0x44e:	/* DMA_CAPS_0_U */
1409          *ret = (s->caps[0] >> 16) & 0xffff;
1410          break;
1411      case 0x450:	/* DMA_CAPS_0_L */
1412          *ret = (s->caps[0] >>  0) & 0xffff;
1413          break;
1414  
1415      case 0x452:	/* DMA_CAPS_1_U */
1416          *ret = (s->caps[1] >> 16) & 0xffff;
1417          break;
1418      case 0x454:	/* DMA_CAPS_1_L */
1419          *ret = (s->caps[1] >>  0) & 0xffff;
1420          break;
1421  
1422      case 0x456:	/* DMA_CAPS_2 */
1423          *ret = s->caps[2];
1424          break;
1425  
1426      case 0x458:	/* DMA_CAPS_3 */
1427          *ret = s->caps[3];
1428          break;
1429  
1430      case 0x45a:	/* DMA_CAPS_4 */
1431          *ret = s->caps[4];
1432          break;
1433  
1434      case 0x460:	/* DMA_PCh2_SR */
1435      case 0x480:	/* DMA_PCh0_SR */
1436      case 0x482:	/* DMA_PCh1_SR */
1437      case 0x4c0:	/* DMA_PChD_SR_0 */
1438          qemu_log_mask(LOG_UNIMP,
1439                        "%s: Physical Channel Status Registers not implemented\n",
1440                        __func__);
1441          *ret = 0xff;
1442          break;
1443  
1444      default:
1445          return 1;
1446      }
1447      return 0;
1448  }
1449  
1450  static uint64_t omap_dma_read(void *opaque, hwaddr addr, unsigned size)
1451  {
1452      struct omap_dma_s *s = opaque;
1453      int reg, ch;
1454      uint16_t ret;
1455  
1456      if (size != 2) {
1457          return omap_badwidth_read16(opaque, addr);
1458      }
1459  
1460      switch (addr) {
1461      case 0x300 ... 0x3fe:
1462          if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1463              if (omap_dma_3_1_lcd_read(&s->lcd_ch, addr, &ret))
1464                  break;
1465              return ret;
1466          }
1467          /* Fall through. */
1468      case 0x000 ... 0x2fe:
1469          reg = addr & 0x3f;
1470          ch = (addr >> 6) & 0x0f;
1471          if (omap_dma_ch_reg_read(s, &s->ch[ch], reg, &ret))
1472              break;
1473          return ret;
1474  
1475      case 0x404 ... 0x4fe:
1476          if (s->model <= omap_dma_3_1)
1477              break;
1478          /* Fall through. */
1479      case 0x400:
1480          if (omap_dma_sys_read(s, addr, &ret))
1481              break;
1482          return ret;
1483  
1484      case 0xb00 ... 0xbfe:
1485          if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1486              if (omap_dma_3_2_lcd_read(&s->lcd_ch, addr, &ret))
1487                  break;
1488              return ret;
1489          }
1490          break;
1491      }
1492  
1493      OMAP_BAD_REG(addr);
1494      return 0;
1495  }
1496  
1497  static void omap_dma_write(void *opaque, hwaddr addr,
1498                             uint64_t value, unsigned size)
1499  {
1500      struct omap_dma_s *s = opaque;
1501      int reg, ch;
1502  
1503      if (size != 2) {
1504          omap_badwidth_write16(opaque, addr, value);
1505          return;
1506      }
1507  
1508      switch (addr) {
1509      case 0x300 ... 0x3fe:
1510          if (s->model <= omap_dma_3_1 || !s->omap_3_1_mapping_disabled) {
1511              if (omap_dma_3_1_lcd_write(&s->lcd_ch, addr, value))
1512                  break;
1513              return;
1514          }
1515          /* Fall through.  */
1516      case 0x000 ... 0x2fe:
1517          reg = addr & 0x3f;
1518          ch = (addr >> 6) & 0x0f;
1519          if (omap_dma_ch_reg_write(s, &s->ch[ch], reg, value))
1520              break;
1521          return;
1522  
1523      case 0x404 ... 0x4fe:
1524          if (s->model <= omap_dma_3_1)
1525              break;
1526          /* fall through */
1527      case 0x400:
1528          if (omap_dma_sys_write(s, addr, value))
1529              break;
1530          return;
1531  
1532      case 0xb00 ... 0xbfe:
1533          if (s->model == omap_dma_3_2 && s->omap_3_1_mapping_disabled) {
1534              if (omap_dma_3_2_lcd_write(&s->lcd_ch, addr, value))
1535                  break;
1536              return;
1537          }
1538          break;
1539      }
1540  
1541      OMAP_BAD_REG(addr);
1542  }
1543  
1544  static const MemoryRegionOps omap_dma_ops = {
1545      .read = omap_dma_read,
1546      .write = omap_dma_write,
1547      .endianness = DEVICE_NATIVE_ENDIAN,
1548  };
1549  
1550  static void omap_dma_request(void *opaque, int drq, int req)
1551  {
1552      struct omap_dma_s *s = opaque;
1553      /* The request pins are level triggered in QEMU.  */
1554      if (req) {
1555          if (~s->dma->drqbmp & (1ULL << drq)) {
1556              s->dma->drqbmp |= 1ULL << drq;
1557              omap_dma_process_request(s, drq);
1558          }
1559      } else
1560          s->dma->drqbmp &= ~(1ULL << drq);
1561  }
1562  
1563  /* XXX: this won't be needed once soc_dma knows about clocks.  */
1564  static void omap_dma_clk_update(void *opaque, int line, int on)
1565  {
1566      struct omap_dma_s *s = opaque;
1567      int i;
1568  
1569      s->dma->freq = omap_clk_getrate(s->clk);
1570  
1571      for (i = 0; i < s->chans; i ++)
1572          if (s->ch[i].active)
1573              soc_dma_set_request(s->ch[i].dma, on);
1574  }
1575  
1576  static void omap_dma_setcaps(struct omap_dma_s *s)
1577  {
1578      switch (s->model) {
1579      default:
1580      case omap_dma_3_1:
1581          break;
1582      case omap_dma_3_2:
1583          /* XXX Only available for sDMA */
1584          s->caps[0] =
1585                  (1 << 19) |	/* Constant Fill Capability */
1586                  (1 << 18);	/* Transparent BLT Capability */
1587          s->caps[1] =
1588                  (1 << 1);	/* 1-bit palettized capability (DMA 3.2 only) */
1589          s->caps[2] =
1590                  (1 << 8) |	/* SEPARATE_SRC_AND_DST_INDEX_CPBLTY */
1591                  (1 << 7) |	/* DST_DOUBLE_INDEX_ADRS_CPBLTY */
1592                  (1 << 6) |	/* DST_SINGLE_INDEX_ADRS_CPBLTY */
1593                  (1 << 5) |	/* DST_POST_INCRMNT_ADRS_CPBLTY */
1594                  (1 << 4) |	/* DST_CONST_ADRS_CPBLTY */
1595                  (1 << 3) |	/* SRC_DOUBLE_INDEX_ADRS_CPBLTY */
1596                  (1 << 2) |	/* SRC_SINGLE_INDEX_ADRS_CPBLTY */
1597                  (1 << 1) |	/* SRC_POST_INCRMNT_ADRS_CPBLTY */
1598                  (1 << 0);	/* SRC_CONST_ADRS_CPBLTY */
1599          s->caps[3] =
1600                  (1 << 6) |	/* BLOCK_SYNCHR_CPBLTY (DMA 4 only) */
1601                  (1 << 7) |	/* PKT_SYNCHR_CPBLTY (DMA 4 only) */
1602                  (1 << 5) |	/* CHANNEL_CHAINING_CPBLTY */
1603                  (1 << 4) |	/* LCh_INTERLEAVE_CPBLTY */
1604                  (1 << 3) |	/* AUTOINIT_REPEAT_CPBLTY (DMA 3.2 only) */
1605                  (1 << 2) |	/* AUTOINIT_ENDPROG_CPBLTY (DMA 3.2 only) */
1606                  (1 << 1) |	/* FRAME_SYNCHR_CPBLTY */
1607                  (1 << 0);	/* ELMNT_SYNCHR_CPBLTY */
1608          s->caps[4] =
1609                  (1 << 7) |	/* PKT_INTERRUPT_CPBLTY (DMA 4 only) */
1610                  (1 << 6) |	/* SYNC_STATUS_CPBLTY */
1611                  (1 << 5) |	/* BLOCK_INTERRUPT_CPBLTY */
1612                  (1 << 4) |	/* LAST_FRAME_INTERRUPT_CPBLTY */
1613                  (1 << 3) |	/* FRAME_INTERRUPT_CPBLTY */
1614                  (1 << 2) |	/* HALF_FRAME_INTERRUPT_CPBLTY */
1615                  (1 << 1) |	/* EVENT_DROP_INTERRUPT_CPBLTY */
1616                  (1 << 0);	/* TIMEOUT_INTERRUPT_CPBLTY (DMA 3.2 only) */
1617          break;
1618      }
1619  }
1620  
1621  struct soc_dma_s *omap_dma_init(hwaddr base, qemu_irq *irqs,
1622                  MemoryRegion *sysmem,
1623                  qemu_irq lcd_irq, struct omap_mpu_state_s *mpu, omap_clk clk,
1624                  enum omap_dma_model model)
1625  {
1626      int num_irqs, memsize, i;
1627      struct omap_dma_s *s = g_new0(struct omap_dma_s, 1);
1628  
1629      if (model <= omap_dma_3_1) {
1630          num_irqs = 6;
1631          memsize = 0x800;
1632      } else {
1633          num_irqs = 16;
1634          memsize = 0xc00;
1635      }
1636      s->model = model;
1637      s->mpu = mpu;
1638      s->clk = clk;
1639      s->lcd_ch.irq = lcd_irq;
1640      s->lcd_ch.mpu = mpu;
1641  
1642      s->dma = soc_dma_init((model <= omap_dma_3_1) ? 9 : 16);
1643      s->dma->freq = omap_clk_getrate(clk);
1644      s->dma->transfer_fn = omap_dma_transfer_generic;
1645      s->dma->setup_fn = omap_dma_transfer_setup;
1646      s->dma->drq = qemu_allocate_irqs(omap_dma_request, s, 32);
1647      s->dma->opaque = s;
1648  
1649      while (num_irqs --)
1650          s->ch[num_irqs].irq = irqs[num_irqs];
1651      for (i = 0; i < 3; i ++) {
1652          s->ch[i].sibling = &s->ch[i + 6];
1653          s->ch[i + 6].sibling = &s->ch[i];
1654      }
1655      for (i = (model <= omap_dma_3_1) ? 8 : 15; i >= 0; i --) {
1656          s->ch[i].dma = &s->dma->ch[i];
1657          s->dma->ch[i].opaque = &s->ch[i];
1658      }
1659  
1660      omap_dma_setcaps(s);
1661      omap_clk_adduser(s->clk, qemu_allocate_irq(omap_dma_clk_update, s, 0));
1662      omap_dma_reset(s->dma);
1663      omap_dma_clk_update(s, 0, 1);
1664  
1665      memory_region_init_io(&s->iomem, NULL, &omap_dma_ops, s, "omap.dma", memsize);
1666      memory_region_add_subregion(sysmem, base, &s->iomem);
1667  
1668      mpu->drq = s->dma->drq;
1669  
1670      return s->dma;
1671  }
1672  
1673  struct omap_dma_lcd_channel_s *omap_dma_get_lcdch(struct soc_dma_s *dma)
1674  {
1675      struct omap_dma_s *s = dma->opaque;
1676  
1677      return &s->lcd_ch;
1678  }
1679