symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/pxa2xx_dma.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * Intel XScale PXA255/270 DMA controller.
       
     3  *
       
     4  * Copyright (c) 2006 Openedhand Ltd.
       
     5  * Copyright (c) 2006 Thorsten Zitterell
       
     6  * Written by Andrzej Zaborowski <balrog@zabor.org>
       
     7  *
       
     8  * This code is licenced under the GPL.
       
     9  */
       
    10 
       
    11 #include "hw.h"
       
    12 #include "pxa.h"
       
    13 
       
    14 struct pxa2xx_dma_channel_s {
       
    15     target_phys_addr_t descr;
       
    16     target_phys_addr_t src;
       
    17     target_phys_addr_t dest;
       
    18     uint32_t cmd;
       
    19     uint32_t state;
       
    20     int request;
       
    21 };
       
    22 
       
    23 /* Allow the DMA to be used as a PIC.  */
       
    24 typedef void (*pxa2xx_dma_handler_t)(void *opaque, int irq, int level);
       
    25 
       
    26 struct pxa2xx_dma_state_s {
       
    27     pxa2xx_dma_handler_t handler;
       
    28     qemu_irq irq;
       
    29 
       
    30     uint32_t stopintr;
       
    31     uint32_t eorintr;
       
    32     uint32_t rasintr;
       
    33     uint32_t startintr;
       
    34     uint32_t endintr;
       
    35 
       
    36     uint32_t align;
       
    37     uint32_t pio;
       
    38 
       
    39     int channels;
       
    40     struct pxa2xx_dma_channel_s *chan;
       
    41 
       
    42     uint8_t *req;
       
    43 
       
    44     /* Flag to avoid recursive DMA invocations.  */
       
    45     int running;
       
    46 };
       
    47 
       
    48 #define PXA255_DMA_NUM_CHANNELS	16
       
    49 #define PXA27X_DMA_NUM_CHANNELS	32
       
    50 
       
    51 #define PXA2XX_DMA_NUM_REQUESTS	75
       
    52 
       
    53 #define DCSR0	0x0000	/* DMA Control / Status register for Channel 0 */
       
    54 #define DCSR31	0x007c	/* DMA Control / Status register for Channel 31 */
       
    55 #define DALGN	0x00a0	/* DMA Alignment register */
       
    56 #define DPCSR	0x00a4	/* DMA Programmed I/O Control Status register */
       
    57 #define DRQSR0	0x00e0	/* DMA DREQ<0> Status register */
       
    58 #define DRQSR1	0x00e4	/* DMA DREQ<1> Status register */
       
    59 #define DRQSR2	0x00e8	/* DMA DREQ<2> Status register */
       
    60 #define DINT	0x00f0	/* DMA Interrupt register */
       
    61 #define DRCMR0	0x0100	/* Request to Channel Map register 0 */
       
    62 #define DRCMR63	0x01fc	/* Request to Channel Map register 63 */
       
    63 #define D_CH0	0x0200	/* Channel 0 Descriptor start */
       
    64 #define DRCMR64	0x1100	/* Request to Channel Map register 64 */
       
    65 #define DRCMR74	0x1128	/* Request to Channel Map register 74 */
       
    66 
       
    67 /* Per-channel register */
       
    68 #define DDADR	0x00
       
    69 #define DSADR	0x01
       
    70 #define DTADR	0x02
       
    71 #define DCMD	0x03
       
    72 
       
    73 /* Bit-field masks */
       
    74 #define DRCMR_CHLNUM		0x1f
       
    75 #define DRCMR_MAPVLD		(1 << 7)
       
    76 #define DDADR_STOP		(1 << 0)
       
    77 #define DDADR_BREN		(1 << 1)
       
    78 #define DCMD_LEN		0x1fff
       
    79 #define DCMD_WIDTH(x)		(1 << ((((x) >> 14) & 3) - 1))
       
    80 #define DCMD_SIZE(x)		(4 << (((x) >> 16) & 3))
       
    81 #define DCMD_FLYBYT		(1 << 19)
       
    82 #define DCMD_FLYBYS		(1 << 20)
       
    83 #define DCMD_ENDIRQEN		(1 << 21)
       
    84 #define DCMD_STARTIRQEN		(1 << 22)
       
    85 #define DCMD_CMPEN		(1 << 25)
       
    86 #define DCMD_FLOWTRG		(1 << 28)
       
    87 #define DCMD_FLOWSRC		(1 << 29)
       
    88 #define DCMD_INCTRGADDR		(1 << 30)
       
    89 #define DCMD_INCSRCADDR		(1 << 31)
       
    90 #define DCSR_BUSERRINTR		(1 << 0)
       
    91 #define DCSR_STARTINTR		(1 << 1)
       
    92 #define DCSR_ENDINTR		(1 << 2)
       
    93 #define DCSR_STOPINTR		(1 << 3)
       
    94 #define DCSR_RASINTR		(1 << 4)
       
    95 #define DCSR_REQPEND		(1 << 8)
       
    96 #define DCSR_EORINT		(1 << 9)
       
    97 #define DCSR_CMPST		(1 << 10)
       
    98 #define DCSR_MASKRUN		(1 << 22)
       
    99 #define DCSR_RASIRQEN		(1 << 23)
       
   100 #define DCSR_CLRCMPST		(1 << 24)
       
   101 #define DCSR_SETCMPST		(1 << 25)
       
   102 #define DCSR_EORSTOPEN		(1 << 26)
       
   103 #define DCSR_EORJMPEN		(1 << 27)
       
   104 #define DCSR_EORIRQEN		(1 << 28)
       
   105 #define DCSR_STOPIRQEN		(1 << 29)
       
   106 #define DCSR_NODESCFETCH	(1 << 30)
       
   107 #define DCSR_RUN		(1 << 31)
       
   108 
       
   109 static inline void pxa2xx_dma_update(struct pxa2xx_dma_state_s *s, int ch)
       
   110 {
       
   111     if (ch >= 0) {
       
   112         if ((s->chan[ch].state & DCSR_STOPIRQEN) &&
       
   113                 (s->chan[ch].state & DCSR_STOPINTR))
       
   114             s->stopintr |= 1 << ch;
       
   115         else
       
   116             s->stopintr &= ~(1 << ch);
       
   117 
       
   118         if ((s->chan[ch].state & DCSR_EORIRQEN) &&
       
   119                 (s->chan[ch].state & DCSR_EORINT))
       
   120             s->eorintr |= 1 << ch;
       
   121         else
       
   122             s->eorintr &= ~(1 << ch);
       
   123 
       
   124         if ((s->chan[ch].state & DCSR_RASIRQEN) &&
       
   125                 (s->chan[ch].state & DCSR_RASINTR))
       
   126             s->rasintr |= 1 << ch;
       
   127         else
       
   128             s->rasintr &= ~(1 << ch);
       
   129 
       
   130         if (s->chan[ch].state & DCSR_STARTINTR)
       
   131             s->startintr |= 1 << ch;
       
   132         else
       
   133             s->startintr &= ~(1 << ch);
       
   134 
       
   135         if (s->chan[ch].state & DCSR_ENDINTR)
       
   136             s->endintr |= 1 << ch;
       
   137         else
       
   138             s->endintr &= ~(1 << ch);
       
   139     }
       
   140 
       
   141     if (s->stopintr | s->eorintr | s->rasintr | s->startintr | s->endintr)
       
   142         qemu_irq_raise(s->irq);
       
   143     else
       
   144         qemu_irq_lower(s->irq);
       
   145 }
       
   146 
       
   147 static inline void pxa2xx_dma_descriptor_fetch(
       
   148                 struct pxa2xx_dma_state_s *s, int ch)
       
   149 {
       
   150     uint32_t desc[4];
       
   151     target_phys_addr_t daddr = s->chan[ch].descr & ~0xf;
       
   152     if ((s->chan[ch].descr & DDADR_BREN) && (s->chan[ch].state & DCSR_CMPST))
       
   153         daddr += 32;
       
   154 
       
   155     cpu_physical_memory_read(daddr, (uint8_t *) desc, 16);
       
   156     s->chan[ch].descr = desc[DDADR];
       
   157     s->chan[ch].src = desc[DSADR];
       
   158     s->chan[ch].dest = desc[DTADR];
       
   159     s->chan[ch].cmd = desc[DCMD];
       
   160 
       
   161     if (s->chan[ch].cmd & DCMD_FLOWSRC)
       
   162         s->chan[ch].src &= ~3;
       
   163     if (s->chan[ch].cmd & DCMD_FLOWTRG)
       
   164         s->chan[ch].dest &= ~3;
       
   165 
       
   166     if (s->chan[ch].cmd & (DCMD_CMPEN | DCMD_FLYBYS | DCMD_FLYBYT))
       
   167         printf("%s: unsupported mode in channel %i\n", __FUNCTION__, ch);
       
   168 
       
   169     if (s->chan[ch].cmd & DCMD_STARTIRQEN)
       
   170         s->chan[ch].state |= DCSR_STARTINTR;
       
   171 }
       
   172 
       
   173 static void pxa2xx_dma_run(struct pxa2xx_dma_state_s *s)
       
   174 {
       
   175     int c, srcinc, destinc;
       
   176     uint32_t n, size;
       
   177     uint32_t width;
       
   178     uint32_t length;
       
   179     uint8_t buffer[32];
       
   180     struct pxa2xx_dma_channel_s *ch;
       
   181 
       
   182     if (s->running ++)
       
   183         return;
       
   184 
       
   185     while (s->running) {
       
   186         s->running = 1;
       
   187         for (c = 0; c < s->channels; c ++) {
       
   188             ch = &s->chan[c];
       
   189 
       
   190             while ((ch->state & DCSR_RUN) && !(ch->state & DCSR_STOPINTR)) {
       
   191                 /* Test for pending requests */
       
   192                 if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) && !ch->request)
       
   193                     break;
       
   194 
       
   195                 length = ch->cmd & DCMD_LEN;
       
   196                 size = DCMD_SIZE(ch->cmd);
       
   197                 width = DCMD_WIDTH(ch->cmd);
       
   198 
       
   199                 srcinc = (ch->cmd & DCMD_INCSRCADDR) ? width : 0;
       
   200                 destinc = (ch->cmd & DCMD_INCTRGADDR) ? width : 0;
       
   201 
       
   202                 while (length) {
       
   203                     size = MIN(length, size);
       
   204 
       
   205                     for (n = 0; n < size; n += width) {
       
   206                         cpu_physical_memory_read(ch->src, buffer + n, width);
       
   207                         ch->src += srcinc;
       
   208                     }
       
   209 
       
   210                     for (n = 0; n < size; n += width) {
       
   211                         cpu_physical_memory_write(ch->dest, buffer + n, width);
       
   212                         ch->dest += destinc;
       
   213                     }
       
   214 
       
   215                     length -= size;
       
   216 
       
   217                     if ((ch->cmd & (DCMD_FLOWSRC | DCMD_FLOWTRG)) &&
       
   218                             !ch->request) {
       
   219                         ch->state |= DCSR_EORINT;
       
   220                         if (ch->state & DCSR_EORSTOPEN)
       
   221                             ch->state |= DCSR_STOPINTR;
       
   222                         if ((ch->state & DCSR_EORJMPEN) &&
       
   223                                         !(ch->state & DCSR_NODESCFETCH))
       
   224                             pxa2xx_dma_descriptor_fetch(s, c);
       
   225                         break;
       
   226 		    }
       
   227                 }
       
   228 
       
   229                 ch->cmd = (ch->cmd & ~DCMD_LEN) | length;
       
   230 
       
   231                 /* Is the transfer complete now? */
       
   232                 if (!length) {
       
   233                     if (ch->cmd & DCMD_ENDIRQEN)
       
   234                         ch->state |= DCSR_ENDINTR;
       
   235 
       
   236                     if ((ch->state & DCSR_NODESCFETCH) ||
       
   237                                 (ch->descr & DDADR_STOP) ||
       
   238                                 (ch->state & DCSR_EORSTOPEN)) {
       
   239                         ch->state |= DCSR_STOPINTR;
       
   240                         ch->state &= ~DCSR_RUN;
       
   241 
       
   242                         break;
       
   243                     }
       
   244 
       
   245                     ch->state |= DCSR_STOPINTR;
       
   246                     break;
       
   247                 }
       
   248             }
       
   249         }
       
   250 
       
   251         s->running --;
       
   252     }
       
   253 }
       
   254 
       
   255 static uint32_t pxa2xx_dma_read(void *opaque, target_phys_addr_t offset)
       
   256 {
       
   257     struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
       
   258     unsigned int channel;
       
   259 
       
   260     switch (offset) {
       
   261     case DRCMR64 ... DRCMR74:
       
   262         offset -= DRCMR64 - DRCMR0 - (64 << 2);
       
   263         /* Fall through */
       
   264     case DRCMR0 ... DRCMR63:
       
   265         channel = (offset - DRCMR0) >> 2;
       
   266         return s->req[channel];
       
   267 
       
   268     case DRQSR0:
       
   269     case DRQSR1:
       
   270     case DRQSR2:
       
   271         return 0;
       
   272 
       
   273     case DCSR0 ... DCSR31:
       
   274         channel = offset >> 2;
       
   275 	if (s->chan[channel].request)
       
   276             return s->chan[channel].state | DCSR_REQPEND;
       
   277         return s->chan[channel].state;
       
   278 
       
   279     case DINT:
       
   280         return s->stopintr | s->eorintr | s->rasintr |
       
   281                 s->startintr | s->endintr;
       
   282 
       
   283     case DALGN:
       
   284         return s->align;
       
   285 
       
   286     case DPCSR:
       
   287         return s->pio;
       
   288     }
       
   289 
       
   290     if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
       
   291         channel = (offset - D_CH0) >> 4;
       
   292         switch ((offset & 0x0f) >> 2) {
       
   293         case DDADR:
       
   294             return s->chan[channel].descr;
       
   295         case DSADR:
       
   296             return s->chan[channel].src;
       
   297         case DTADR:
       
   298             return s->chan[channel].dest;
       
   299         case DCMD:
       
   300             return s->chan[channel].cmd;
       
   301         }
       
   302     }
       
   303 
       
   304     cpu_abort(cpu_single_env,
       
   305                     "%s: Bad offset 0x" TARGET_FMT_plx "\n", __FUNCTION__, offset);
       
   306     return 7;
       
   307 }
       
   308 
       
   309 static void pxa2xx_dma_write(void *opaque,
       
   310                  target_phys_addr_t offset, uint32_t value)
       
   311 {
       
   312     struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
       
   313     unsigned int channel;
       
   314 
       
   315     switch (offset) {
       
   316     case DRCMR64 ... DRCMR74:
       
   317         offset -= DRCMR64 - DRCMR0 - (64 << 2);
       
   318         /* Fall through */
       
   319     case DRCMR0 ... DRCMR63:
       
   320         channel = (offset - DRCMR0) >> 2;
       
   321 
       
   322         if (value & DRCMR_MAPVLD)
       
   323             if ((value & DRCMR_CHLNUM) > s->channels)
       
   324                 cpu_abort(cpu_single_env, "%s: Bad DMA channel %i\n",
       
   325                         __FUNCTION__, value & DRCMR_CHLNUM);
       
   326 
       
   327         s->req[channel] = value;
       
   328         break;
       
   329 
       
   330     case DRQSR0:
       
   331     case DRQSR1:
       
   332     case DRQSR2:
       
   333         /* Nothing to do */
       
   334         break;
       
   335 
       
   336     case DCSR0 ... DCSR31:
       
   337         channel = offset >> 2;
       
   338         s->chan[channel].state &= 0x0000071f & ~(value &
       
   339                         (DCSR_EORINT | DCSR_ENDINTR |
       
   340                          DCSR_STARTINTR | DCSR_BUSERRINTR));
       
   341         s->chan[channel].state |= value & 0xfc800000;
       
   342 
       
   343         if (s->chan[channel].state & DCSR_STOPIRQEN)
       
   344             s->chan[channel].state &= ~DCSR_STOPINTR;
       
   345 
       
   346         if (value & DCSR_NODESCFETCH) {
       
   347             /* No-descriptor-fetch mode */
       
   348             if (value & DCSR_RUN) {
       
   349                 s->chan[channel].state &= ~DCSR_STOPINTR;
       
   350                 pxa2xx_dma_run(s);
       
   351             }
       
   352         } else {
       
   353             /* Descriptor-fetch mode */
       
   354             if (value & DCSR_RUN) {
       
   355                 s->chan[channel].state &= ~DCSR_STOPINTR;
       
   356                 pxa2xx_dma_descriptor_fetch(s, channel);
       
   357                 pxa2xx_dma_run(s);
       
   358             }
       
   359         }
       
   360 
       
   361         /* Shouldn't matter as our DMA is synchronous.  */
       
   362         if (!(value & (DCSR_RUN | DCSR_MASKRUN)))
       
   363             s->chan[channel].state |= DCSR_STOPINTR;
       
   364 
       
   365         if (value & DCSR_CLRCMPST)
       
   366             s->chan[channel].state &= ~DCSR_CMPST;
       
   367         if (value & DCSR_SETCMPST)
       
   368             s->chan[channel].state |= DCSR_CMPST;
       
   369 
       
   370         pxa2xx_dma_update(s, channel);
       
   371         break;
       
   372 
       
   373     case DALGN:
       
   374         s->align = value;
       
   375         break;
       
   376 
       
   377     case DPCSR:
       
   378         s->pio = value & 0x80000001;
       
   379         break;
       
   380 
       
   381     default:
       
   382         if (offset >= D_CH0 && offset < D_CH0 + (s->channels << 4)) {
       
   383             channel = (offset - D_CH0) >> 4;
       
   384             switch ((offset & 0x0f) >> 2) {
       
   385             case DDADR:
       
   386                 s->chan[channel].descr = value;
       
   387                 break;
       
   388             case DSADR:
       
   389                 s->chan[channel].src = value;
       
   390                 break;
       
   391             case DTADR:
       
   392                 s->chan[channel].dest = value;
       
   393                 break;
       
   394             case DCMD:
       
   395                 s->chan[channel].cmd = value;
       
   396                 break;
       
   397             default:
       
   398                 goto fail;
       
   399             }
       
   400 
       
   401             break;
       
   402         }
       
   403     fail:
       
   404         cpu_abort(cpu_single_env, "%s: Bad offset " TARGET_FMT_plx "\n",
       
   405                 __FUNCTION__, offset);
       
   406     }
       
   407 }
       
   408 
       
   409 static uint32_t pxa2xx_dma_readbad(void *opaque, target_phys_addr_t offset)
       
   410 {
       
   411     cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__);
       
   412     return 5;
       
   413 }
       
   414 
       
   415 static void pxa2xx_dma_writebad(void *opaque,
       
   416                  target_phys_addr_t offset, uint32_t value)
       
   417 {
       
   418     cpu_abort(cpu_single_env, "%s: Bad access width\n", __FUNCTION__);
       
   419 }
       
   420 
       
   421 static CPUReadMemoryFunc *pxa2xx_dma_readfn[] = {
       
   422     pxa2xx_dma_readbad,
       
   423     pxa2xx_dma_readbad,
       
   424     pxa2xx_dma_read
       
   425 };
       
   426 
       
   427 static CPUWriteMemoryFunc *pxa2xx_dma_writefn[] = {
       
   428     pxa2xx_dma_writebad,
       
   429     pxa2xx_dma_writebad,
       
   430     pxa2xx_dma_write
       
   431 };
       
   432 
       
   433 static void pxa2xx_dma_save(QEMUFile *f, void *opaque)
       
   434 {
       
   435     struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
       
   436     int i;
       
   437 
       
   438     qemu_put_be32(f, s->channels);
       
   439 
       
   440     qemu_put_be32s(f, &s->stopintr);
       
   441     qemu_put_be32s(f, &s->eorintr);
       
   442     qemu_put_be32s(f, &s->rasintr);
       
   443     qemu_put_be32s(f, &s->startintr);
       
   444     qemu_put_be32s(f, &s->endintr);
       
   445     qemu_put_be32s(f, &s->align);
       
   446     qemu_put_be32s(f, &s->pio);
       
   447 
       
   448     qemu_put_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
       
   449     for (i = 0; i < s->channels; i ++) {
       
   450         qemu_put_betl(f, s->chan[i].descr);
       
   451         qemu_put_betl(f, s->chan[i].src);
       
   452         qemu_put_betl(f, s->chan[i].dest);
       
   453         qemu_put_be32s(f, &s->chan[i].cmd);
       
   454         qemu_put_be32s(f, &s->chan[i].state);
       
   455         qemu_put_be32(f, s->chan[i].request);
       
   456     };
       
   457 }
       
   458 
       
   459 static int pxa2xx_dma_load(QEMUFile *f, void *opaque, int version_id)
       
   460 {
       
   461     struct pxa2xx_dma_state_s *s = (struct pxa2xx_dma_state_s *) opaque;
       
   462     int i;
       
   463 
       
   464     if (qemu_get_be32(f) != s->channels)
       
   465         return -EINVAL;
       
   466 
       
   467     qemu_get_be32s(f, &s->stopintr);
       
   468     qemu_get_be32s(f, &s->eorintr);
       
   469     qemu_get_be32s(f, &s->rasintr);
       
   470     qemu_get_be32s(f, &s->startintr);
       
   471     qemu_get_be32s(f, &s->endintr);
       
   472     qemu_get_be32s(f, &s->align);
       
   473     qemu_get_be32s(f, &s->pio);
       
   474 
       
   475     qemu_get_buffer(f, s->req, PXA2XX_DMA_NUM_REQUESTS);
       
   476     for (i = 0; i < s->channels; i ++) {
       
   477         s->chan[i].descr = qemu_get_betl(f);
       
   478         s->chan[i].src = qemu_get_betl(f);
       
   479         s->chan[i].dest = qemu_get_betl(f);
       
   480         qemu_get_be32s(f, &s->chan[i].cmd);
       
   481         qemu_get_be32s(f, &s->chan[i].state);
       
   482         s->chan[i].request = qemu_get_be32(f);
       
   483     };
       
   484 
       
   485     return 0;
       
   486 }
       
   487 
       
   488 static struct pxa2xx_dma_state_s *pxa2xx_dma_init(target_phys_addr_t base,
       
   489                 qemu_irq irq, int channels)
       
   490 {
       
   491     int i, iomemtype;
       
   492     struct pxa2xx_dma_state_s *s;
       
   493     s = (struct pxa2xx_dma_state_s *)
       
   494             qemu_mallocz(sizeof(struct pxa2xx_dma_state_s));
       
   495 
       
   496     s->channels = channels;
       
   497     s->chan = qemu_mallocz(sizeof(struct pxa2xx_dma_channel_s) * s->channels);
       
   498     s->irq = irq;
       
   499     s->handler = (pxa2xx_dma_handler_t) pxa2xx_dma_request;
       
   500     s->req = qemu_mallocz(sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
       
   501 
       
   502     memset(s->chan, 0, sizeof(struct pxa2xx_dma_channel_s) * s->channels);
       
   503     for (i = 0; i < s->channels; i ++)
       
   504         s->chan[i].state = DCSR_STOPINTR;
       
   505 
       
   506     memset(s->req, 0, sizeof(uint8_t) * PXA2XX_DMA_NUM_REQUESTS);
       
   507 
       
   508     iomemtype = cpu_register_io_memory(0, pxa2xx_dma_readfn,
       
   509                     pxa2xx_dma_writefn, s);
       
   510     cpu_register_physical_memory(base, 0x00010000, iomemtype);
       
   511 
       
   512     register_savevm("pxa2xx_dma", 0, 0, pxa2xx_dma_save, pxa2xx_dma_load, s);
       
   513 
       
   514     return s;
       
   515 }
       
   516 
       
   517 struct pxa2xx_dma_state_s *pxa27x_dma_init(target_phys_addr_t base,
       
   518                 qemu_irq irq)
       
   519 {
       
   520     return pxa2xx_dma_init(base, irq, PXA27X_DMA_NUM_CHANNELS);
       
   521 }
       
   522 
       
   523 struct pxa2xx_dma_state_s *pxa255_dma_init(target_phys_addr_t base,
       
   524                 qemu_irq irq)
       
   525 {
       
   526     return pxa2xx_dma_init(base, irq, PXA255_DMA_NUM_CHANNELS);
       
   527 }
       
   528 
       
   529 void pxa2xx_dma_request(struct pxa2xx_dma_state_s *s, int req_num, int on)
       
   530 {
       
   531     int ch;
       
   532     if (req_num < 0 || req_num >= PXA2XX_DMA_NUM_REQUESTS)
       
   533         cpu_abort(cpu_single_env,
       
   534               "%s: Bad DMA request %i\n", __FUNCTION__, req_num);
       
   535 
       
   536     if (!(s->req[req_num] & DRCMR_MAPVLD))
       
   537         return;
       
   538     ch = s->req[req_num] & DRCMR_CHLNUM;
       
   539 
       
   540     if (!s->chan[ch].request && on)
       
   541         s->chan[ch].state |= DCSR_RASINTR;
       
   542     else
       
   543         s->chan[ch].state &= ~DCSR_RASINTR;
       
   544     if (s->chan[ch].request && !on)
       
   545         s->chan[ch].state |= DCSR_EORINT;
       
   546 
       
   547     s->chan[ch].request = on;
       
   548     if (on) {
       
   549         pxa2xx_dma_run(s);
       
   550         pxa2xx_dma_update(s, ch);
       
   551     }
       
   552 }