#include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "../port/error.h" #include "sa1110dma.h" static int debug = 1; /* * DMA helper routines */ enum { NDMA = 6, /* Number of DMA channels */ DMAREGS = 0xb0000000, /* DMA registers, physical */ }; enum { /* Device Address Register, DDAR */ RW = 0, E = 1, BS = 2, DW = 3, DS = 4, /* bits 4 - 7 */ DA = 8 /* bits 8 - 31 */ }; enum { /* Device Control & Status Register, DCSR */ RUN = 0, IE = 1, ERROR = 2, DONEA = 3, STRTA = 4, DONEB = 5, STRTB = 6, BIU = 7 }; typedef struct DMAchan { int inuse; Rendez r; void (*intr)(void*, ulong); void *param; } DMAchan; struct { Lock; DMAchan chan[6]; } dma; struct dmaregs { ulong ddar; ulong dcsr_set; ulong dcsr_clr; ulong dcsr_rd; void* dstrtA; ulong dxcntA; void* dstrtB; ulong dxcntB; } *dmaregs; static void dmaintr(Ureg*, void *); void dmainit(void) { int i; /* map the lcd regs into the kernel's virtual space */ dmaregs = (struct dmaregs*)mapspecial(DMAREGS, NDMA*sizeof(struct dmaregs));; for (i = 0; i < NDMA; i++) { intrenable(IRQdma0+i, dmaintr, &dmaregs[i], "DMA"); } } int dmaalloc(int rd, int bigendian, int burstsize, int datumsize, int device, ulong port, void (*intr)(void*, ulong), void *param) { int i; if (debug) print("dma: dmaalloc\n"); lock(&dma); for (i = 0; i < NDMA; i++) { if (dma.chan[i].inuse) continue; dma.chan[i].inuse++; unlock(&dma); dmaregs[i].ddar = (rd?1:0)<dcsr_rd) & (1<