patch-2.4.20 linux-2.4.20/include/asm-mips/au1000_dma.h
Next file: linux-2.4.20/include/asm-mips/au1000_gpio.h
Previous file: linux-2.4.20/include/asm-mips/au1000.h
Back to the patch index
Back to the overall index
- Lines: 179
- Date:
Thu Nov 28 15:53:15 2002
- Orig file:
linux-2.4.19/include/asm-mips/au1000_dma.h
- Orig date:
Fri Aug 2 17:39:45 2002
diff -urN linux-2.4.19/include/asm-mips/au1000_dma.h linux-2.4.20/include/asm-mips/au1000_dma.h
@@ -44,6 +44,7 @@
/* DMA Channel Register Offsets */
#define DMA_MODE_SET 0x00000000
+#define DMA_MODE_READ DMA_MODE_SET
#define DMA_MODE_CLEAR 0x00000004
/* DMA Mode register bits follow */
#define DMA_DAH_MASK (0x0f << 20)
@@ -101,15 +102,21 @@
struct dma_chan {
int dev_id; // this channel is allocated if >=0, free otherwise
unsigned int io;
- int irq;
const char *dev_str;
+ int irq;
+ void *irq_dev;
unsigned int fifo_addr;
unsigned int mode;
};
/* These are in arch/mips/au1000/common/dma.c */
extern struct dma_chan au1000_dma_table[];
-extern int request_au1000_dma(int dev_id, const char *dev_str);
+extern int request_au1000_dma(int dev_id,
+ const char *dev_str,
+ void (*irqhandler)(int, void *,
+ struct pt_regs *),
+ unsigned long irqflags,
+ void *irq_dev_id);
extern void free_au1000_dma(unsigned int dmanr);
extern int au1000_dma_read_proc(char *buf, char **start, off_t fpos,
int length, int *eof, void *data);
@@ -162,45 +169,75 @@
au_writel(DMA_BE0 | DMA_BE1, chan->io + DMA_MODE_SET);
}
-/* enable/disable a specific DMA channel */
-static __inline__ void enable_dma(unsigned int dmanr)
+static __inline__ void start_dma(unsigned int dmanr)
{
struct dma_chan *chan = get_dma_chan(dmanr);
if (!chan)
return;
- // set device FIFO address
- au_writel(virt_to_phys((void *) chan->fifo_addr),
- chan->io + DMA_PERIPHERAL_ADDR);
-
- au_writel(chan->
- mode | (chan->dev_id << DMA_DID_BIT) | DMA_IE | DMA_GO,
- chan->io + DMA_MODE_SET);
+ au_writel(DMA_GO, chan->io + DMA_MODE_SET);
}
#define DMA_HALT_POLL 0x5000
-static __inline__ void disable_dma(unsigned int dmanr)
+static __inline__ void halt_dma(unsigned int dmanr)
{
- int i;
struct dma_chan *chan = get_dma_chan(dmanr);
+ int i;
if (!chan)
return;
- au_writel(DMA_D1 | DMA_D0 | DMA_GO, chan->io + DMA_MODE_CLEAR);
-
+ au_writel(DMA_GO, chan->io + DMA_MODE_CLEAR);
// poll the halt bit
for (i = 0; i < DMA_HALT_POLL; i++)
- if (au_readl(chan->io + DMA_MODE_SET) & DMA_HALT)
+ if (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT)
break;
- if (i == DMA_HALT_POLL) {
- printk(KERN_INFO "disable_dma: HALT poll expired!\n");
- } else {
+ if (i == DMA_HALT_POLL)
+ printk(KERN_INFO "halt_dma: HALT poll expired!\n");
+}
+
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return;
+
+ halt_dma(dmanr);
+
// now we can disable the buffers
au_writel(~DMA_GO, chan->io + DMA_MODE_CLEAR);
- }
}
+static __inline__ int dma_halted(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 1;
+ return (au_readl(chan->io + DMA_MODE_READ) & DMA_HALT) ? 1 : 0;
+}
+
+/* initialize a DMA channel */
+static __inline__ void init_dma(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ u32 mode;
+ if (!chan)
+ return;
+
+ disable_dma(dmanr);
+
+ // set device FIFO address
+ au_writel(virt_to_phys((void *) chan->fifo_addr),
+ chan->io + DMA_PERIPHERAL_ADDR);
+
+ mode = chan->mode | (chan->dev_id << DMA_DID_BIT);
+ if (chan->irq)
+ mode |= DMA_IE;
+
+ au_writel(~mode, chan->io + DMA_MODE_CLEAR);
+ au_writel(mode, chan->io + DMA_MODE_SET);
+}
/*
* set mode for a specific DMA channel
@@ -211,12 +248,21 @@
if (!chan)
return;
/*
- * chan->mode only holds endianess, direction, transfer size, device
- * FIFO width, and cacheability info for the channel. Make sure
- * anything else is masked off.
+ * set_dma_mode is only allowed to change endianess, direction,
+ * transfer size, device FIFO width, and coherency settings.
+ * Make sure anything else is masked off.
*/
mode &= (DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
- chan->mode = mode;
+ chan->mode &= ~(DMA_BE | DMA_DR | DMA_TS8 | DMA_DW_MASK | DMA_NC);
+ chan->mode |= mode;
+}
+
+static __inline__ unsigned int get_dma_mode(unsigned int dmanr)
+{
+ struct dma_chan *chan = get_dma_chan(dmanr);
+ if (!chan)
+ return 0;
+ return chan->mode;
}
static __inline__ int get_dma_active_buffer(unsigned int dmanr)
@@ -224,7 +270,7 @@
struct dma_chan *chan = get_dma_chan(dmanr);
if (!chan)
return -1;
- return (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ? 1 : 0;
+ return (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ? 1 : 0;
}
@@ -345,7 +391,7 @@
if (!chan)
return 0;
- return au_readl(chan->io + DMA_MODE_SET) & (DMA_D0 | DMA_D1);
+ return au_readl(chan->io + DMA_MODE_READ) & (DMA_D0 | DMA_D1);
}
@@ -371,7 +417,7 @@
if (!chan)
return 0;
- curBufCntReg = (au_readl(chan->io + DMA_MODE_SET) & DMA_AB) ?
+ curBufCntReg = (au_readl(chan->io + DMA_MODE_READ) & DMA_AB) ?
DMA_BUFFER1_COUNT : DMA_BUFFER0_COUNT;
count = au_readl(chan->io + curBufCntReg) & DMA_COUNT_MASK;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)