summaryrefslogtreecommitdiffstats
path: root/include/asm-alpha/dma.h
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1995-11-14 08:00:00 +0000
committer <ralf@linux-mips.org>1995-11-14 08:00:00 +0000
commite7c2a72e2680827d6a733931273a93461c0d8d1b (patch)
treec9abeda78ef7504062bb2e816bcf3e3c9d680112 /include/asm-alpha/dma.h
parentec6044459060a8c9ce7f64405c465d141898548c (diff)
Import of Linux/MIPS 1.3.0
Diffstat (limited to 'include/asm-alpha/dma.h')
-rw-r--r--include/asm-alpha/dma.h53
1 files changed, 41 insertions, 12 deletions
diff --git a/include/asm-alpha/dma.h b/include/asm-alpha/dma.h
index caf437f30..4b327266d 100644
--- a/include/asm-alpha/dma.h
+++ b/include/asm-alpha/dma.h
@@ -1,11 +1,11 @@
/*
* include/asm-alpha/dma.h
*
- * This is essentially the same as the i386 DMA stuff, as
- * the AlphaPC uses normal EISA dma (but the DMA controller
- * is not on the EISA bus, but on the local VL82c106 bus).
- *
- * These DMA-functions don't know about EISA DMA yet..
+ * This is essentially the same as the i386 DMA stuff, as the AlphaPCs
+ * use ISA-compatible dma. The only extension is support for high-page
+ * registers that allow to set the top 8 bits of a 32-bit DMA address.
+ * This register should be written last when setting up a DMA address
+ * as this will also enable DMA across 64 KB boundaries.
*/
/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
@@ -20,8 +20,8 @@
#include <asm/io.h> /* need byte IO */
-#define dma_outb outb_local
-#define dma_inb inb_local
+#define dma_outb outb
+#define dma_inb inb
/*
* NOTES about DMA transfers:
@@ -73,6 +73,9 @@
#define MAX_DMA_CHANNELS 8
+/* The maximum address that we can perform a DMA transfer to on this platform */
+#define MAX_DMA_ADDRESS 0x1000000
+
/* 8237 DMA controllers */
#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */
#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */
@@ -88,6 +91,7 @@
#define DMA1_RESET_REG 0x0D /* Master Clear (w) */
#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */
#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */
+#define DMA1_EXT_MODE_REG (0x400 | DMA1_MODE_REG)
#define DMA2_CMD_REG 0xD0 /* command register (w) */
#define DMA2_STAT_REG 0xD0 /* status register (r) */
@@ -99,6 +103,7 @@
#define DMA2_RESET_REG 0xDA /* Master Clear (w) */
#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */
#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */
+#define DMA2_EXT_MODE_REG (0x400 | DMA2_MODE_REG)
#define DMA_ADDR_0 0x00 /* DMA address registers */
#define DMA_ADDR_1 0x02
@@ -126,6 +131,15 @@
#define DMA_PAGE_6 0x89
#define DMA_PAGE_7 0x8A
+#define DMA_HIPAGE_0 (0x400 | DMA_PAGE_0)
+#define DMA_HIPAGE_1 (0x400 | DMA_PAGE_1)
+#define DMA_HIPAGE_2 (0x400 | DMA_PAGE_2)
+#define DMA_HIPAGE_3 (0x400 | DMA_PAGE_3)
+#define DMA_HIPAGE_4 (0x400 | DMA_PAGE_4)
+#define DMA_HIPAGE_5 (0x400 | DMA_PAGE_5)
+#define DMA_HIPAGE_6 (0x400 | DMA_PAGE_6)
+#define DMA_HIPAGE_7 (0x400 | DMA_PAGE_7)
+
#define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */
#define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */
#define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */
@@ -171,34 +185,49 @@ static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
dma_outb(mode | (dmanr&3), DMA2_MODE_REG);
}
+/* set extended mode for a specific DMA channel */
+static __inline__ void set_dma_ext_mode(unsigned int dmanr, char ext_mode)
+{
+ if (dmanr<=3)
+ dma_outb(ext_mode | dmanr, DMA1_EXT_MODE_REG);
+ else
+ dma_outb(ext_mode | (dmanr&3), DMA2_EXT_MODE_REG);
+}
+
/* Set only the page register bits of the transfer address.
* This is used for successive transfers when we know the contents of
- * the lower 16 bits of the DMA current address register, but a 64k boundary
- * may have been crossed.
+ * the lower 16 bits of the DMA current address register.
*/
-static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+static __inline__ void set_dma_page(unsigned int dmanr, unsigned int pagenr)
{
switch(dmanr) {
case 0:
dma_outb(pagenr, DMA_PAGE_0);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_0);
break;
case 1:
dma_outb(pagenr, DMA_PAGE_1);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_1);
break;
case 2:
dma_outb(pagenr, DMA_PAGE_2);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_2);
break;
case 3:
dma_outb(pagenr, DMA_PAGE_3);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_3);
break;
case 5:
dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_5);
break;
case 6:
dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_6);
break;
case 7:
dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+ dma_outb((pagenr >> 8), DMA_HIPAGE_7);
break;
}
}
@@ -209,7 +238,6 @@ static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
*/
static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
{
- set_dma_page(dmanr, a>>16);
if (dmanr <= 3) {
dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
@@ -217,6 +245,7 @@ static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
}
+ set_dma_page(dmanr, a>>16); /* set hipage last to enable 32-bit mode */
}
@@ -265,7 +294,7 @@ static __inline__ int get_dma_residue(unsigned int dmanr)
/* These are in kernel/dma.c: */
-extern int request_dma(unsigned int dmanr, char * deviceID); /* reserve a DMA channel */
+extern int request_dma(unsigned int dmanr, char * device_id); /* reserve a DMA channel */
extern void free_dma(unsigned int dmanr); /* release it again */