summaryrefslogtreecommitdiffstats
path: root/include/asm-alpha/pyxis.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/asm-alpha/pyxis.h')
-rw-r--r--include/asm-alpha/pyxis.h356
1 files changed, 317 insertions, 39 deletions
diff --git a/include/asm-alpha/pyxis.h b/include/asm-alpha/pyxis.h
index 9d3d49595..d10408bde 100644
--- a/include/asm-alpha/pyxis.h
+++ b/include/asm-alpha/pyxis.h
@@ -1,11 +1,11 @@
#ifndef __ALPHA_PYXIS__H__
#define __ALPHA_PYXIS__H__
-#include <linux/config.h> /* CONFIG_ALPHA_RUFFIAN. */
+#include <linux/config.h>
#include <linux/types.h>
/*
- * PYXIS is the internal name for a cor logic chipset which provides
+ * PYXIS is the internal name for a core logic chipset which provides
* memory controller and PCI access for the 21164A chip based systems.
*
* This file is based on:
@@ -71,11 +71,23 @@
#define BYTE_ENABLE_SHIFT 5
#define TRANSFER_LENGTH_SHIFT 3
-#define MEM_SP1_MASK 0x1fffffff /* Mem sparse space 1 mask is 29 bits */
+#define MEM_R1_MASK 0x1fffffff /* SPARSE Mem region 1 mask is 29 bits */
+#define MEM_R2_MASK 0x07ffffff /* SPARSE Mem region 2 mask is 27 bits */
+#define MEM_R3_MASK 0x03ffffff /* SPARSE Mem region 3 mask is 26 bits */
-#define PYXIS_DMA_WIN_BASE (1024UL*1024UL*1024UL)
+#ifdef CONFIG_ALPHA_SRM_SETUP
+/* if we are using the SRM PCI setup, we'll need to use variables instead */
+#define PYXIS_DMA_WIN_BASE_DEFAULT (1024*1024*1024)
+#define PYXIS_DMA_WIN_SIZE_DEFAULT (1024*1024*1024)
+
+extern unsigned int PYXIS_DMA_WIN_BASE;
+extern unsigned int PYXIS_DMA_WIN_SIZE;
+
+#else /* SRM_SETUP */
+#define PYXIS_DMA_WIN_BASE (1024*1024*1024)
#define PYXIS_DMA_WIN_SIZE (1024*1024*1024)
+#endif /* SRM_SETUP */
/*
* General Registers
@@ -97,13 +109,13 @@
#define PYXIS_DIAG_CHECK (IDENT_ADDR + 0x8740003000UL)
/*
- * Performance Monitor registers (p4-3)
+ * Performance Monitor registers
*/
#define PYXIS_PERF_MONITOR (IDENT_ADDR + 0x8740004000UL)
#define PYXIS_PERF_CONTROL (IDENT_ADDR + 0x8740004040UL)
/*
- * 21171-CA Error registers (p4-3)
+ * Error registers
*/
#define PYXIS_ERR (IDENT_ADDR + 0x8740008200UL)
#define PYXIS_STAT (IDENT_ADDR + 0x8740008240UL)
@@ -118,18 +130,25 @@
#define PYXIS_PCI_ERR2 (IDENT_ADDR + 0x8740008880UL)
/*
- * PCI Address Translation Registers. I've only defined
- * the first window fully as that's the only one that we're currently using.
- * The other window bases are needed to disable the windows.
+ * PCI Address Translation Registers.
*/
#define PYXIS_TBIA (IDENT_ADDR + 0x8760000100UL)
+
#define PYXIS_W0_BASE (IDENT_ADDR + 0x8760000400UL)
#define PYXIS_W0_MASK (IDENT_ADDR + 0x8760000440UL)
#define PYXIS_T0_BASE (IDENT_ADDR + 0x8760000480UL)
#define PYXIS_W1_BASE (IDENT_ADDR + 0x8760000500UL)
+#define PYXIS_W1_MASK (IDENT_ADDR + 0x8760000540UL)
+#define PYXIS_T1_BASE (IDENT_ADDR + 0x8760000580UL)
+
#define PYXIS_W2_BASE (IDENT_ADDR + 0x8760000600UL)
+#define PYXIS_W2_MASK (IDENT_ADDR + 0x8760000640UL)
+#define PYXIS_T2_BASE (IDENT_ADDR + 0x8760000680UL)
+
#define PYXIS_W3_BASE (IDENT_ADDR + 0x8760000700UL)
+#define PYXIS_W3_MASK (IDENT_ADDR + 0x8760000740UL)
+#define PYXIS_T3_BASE (IDENT_ADDR + 0x8760000780UL)
/*
* Memory Control registers
@@ -143,9 +162,19 @@
#define PYXIS_CONF (IDENT_ADDR + 0x8700000000UL)
#define PYXIS_IO (IDENT_ADDR + 0x8580000000UL)
#define PYXIS_SPARSE_MEM (IDENT_ADDR + 0x8000000000UL)
+#define PYXIS_SPARSE_MEM_R2 (IDENT_ADDR + 0x8400000000UL)
+#define PYXIS_SPARSE_MEM_R3 (IDENT_ADDR + 0x8500000000UL)
#define PYXIS_DENSE_MEM (IDENT_ADDR + 0x8600000000UL)
/*
+ * Byte/Word PCI Memory Spaces:
+ */
+#define PYXIS_BW_MEM (IDENT_ADDR + 0x8800000000UL)
+#define PYXIS_BW_IO (IDENT_ADDR + 0x8900000000UL)
+#define PYXIS_BW_CFG_0 (IDENT_ADDR + 0x8a00000000UL)
+#define PYXIS_BW_CFG_1 (IDENT_ADDR + 0x8b00000000UL)
+
+/*
* Interrupt Control registers
*/
#define PYXIS_INT_REQ (IDENT_ADDR + 0x87A0000000UL)
@@ -179,9 +208,8 @@
* Translate physical memory address as seen on (PCI) bus into
* a kernel virtual address and vv.
*/
-
#if defined(CONFIG_ALPHA_RUFFIAN)
-/* Ruffian doesn't do 1G PCI window. */
+/* Ruffian doesn't do 1G PCI window */
extern inline unsigned long virt_to_bus(void * address)
{
@@ -192,7 +220,7 @@ extern inline void * bus_to_virt(unsigned long address)
{
return phys_to_virt(address);
}
-#else
+#else /* RUFFIAN */
extern inline unsigned long virt_to_bus(void * address)
{
return virt_to_phys(address) + PYXIS_DMA_WIN_BASE;
@@ -207,13 +235,86 @@ extern inline void * bus_to_virt(unsigned long address)
/*
* I/O functions:
*
- * PYXIS (the 2117x PCI/memory support chipset for the EV5 (21164)
- * series of processors uses a sparse address mapping scheme to
+ * PYXIS, the 21174 PCI/memory support chipset for the EV56 (21164A)
+ * and PCA56 (21164PC) processors, can use either a sparse address
+ * mapping scheme, or the so-called byte-word PCI address space, to
* get at PCI memory and I/O.
*/
#define vuip volatile unsigned int *
+#ifdef BWIO_ENABLED
+
+extern inline unsigned int __inb(unsigned long addr)
+{
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldbu %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned char *)(addr+PYXIS_BW_IO)));
+
+ return result;
+}
+
+extern inline void __outb(unsigned char b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stb %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned char *)(addr+PYXIS_BW_IO)), "r" (b));
+}
+
+extern inline unsigned int __inw(unsigned long addr)
+{
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldwu %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned short *)(addr+PYXIS_BW_IO)));
+
+ return result;
+}
+
+extern inline void __outw(unsigned short b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stw %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned short *)(addr+PYXIS_BW_IO)), "r" (b));
+}
+
+extern inline unsigned int __inl(unsigned long addr)
+{
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldl %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned int *)(addr+PYXIS_BW_IO)));
+
+ return result;
+}
+
+extern inline void __outl(unsigned int b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stl %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned int *)(addr+PYXIS_BW_IO)), "r" (b));
+}
+
+#define inb(port) __inb((port))
+#define inw(port) __inw((port))
+#define inl(port) __inl((port))
+
+#define outb(x, port) __outb((x),(port))
+#define outw(x, port) __outw((x),(port))
+#define outl(x, port) __outl((x),(port))
+
+#else /* BWIO_ENABLED */
+
extern inline unsigned int __inb(unsigned long addr)
{
long result = *(vuip) ((addr << 5) + PYXIS_IO + 0x00);
@@ -257,6 +358,14 @@ extern inline void __outl(unsigned int b, unsigned long addr)
mb();
}
+#define inb(port) \
+(__builtin_constant_p((port))?__inb(port):_inb(port))
+
+#define outb(x, port) \
+(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+
+#endif /* BWIO_ENABLED */
+
/*
* Memory functions. 64-bit and 32-bit accesses are done through
@@ -290,25 +399,197 @@ extern inline void __outl(unsigned int b, unsigned long addr)
*
*/
-extern inline void pyxis_set_hae(unsigned long new_hae)
+#ifdef BWIO_ENABLED
+
+extern inline unsigned long __readb(unsigned long addr)
+{
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldbu %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned char *)(addr+PYXIS_BW_MEM)));
+
+ return result;
+}
+
+extern inline unsigned long __readw(unsigned long addr)
{
- unsigned long ipl = swpipl(7);
- hae.cache = new_hae;
- *hae.reg = new_hae;
- mb();
- new_hae = *hae.reg; /* read it to be sure it got out */
- setipl(ipl);
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldwu %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned short *)(addr+PYXIS_BW_MEM)));
+
+ return result;
}
+extern inline unsigned long __readl(unsigned long addr)
+{
+ register unsigned long result;
+
+ __asm__ __volatile__ (
+ "ldl %0,%1"
+ : "=r" (result)
+ : "m" (*(unsigned int *)(addr+PYXIS_BW_MEM)));
+
+ return result;
+}
+
+extern inline void __writeb(unsigned char b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stb %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned char *)(addr+PYXIS_BW_MEM)), "r" (b));
+}
+
+extern inline void __writew(unsigned short b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stw %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned short *)(addr+PYXIS_BW_MEM)), "r" (b));
+}
+
+extern inline void __writel(unsigned int b, unsigned long addr)
+{
+ __asm__ __volatile__ (
+ "stl %1,%0\n\t"
+ "mb"
+ : : "m" (*(unsigned int *)(addr+PYXIS_BW_MEM)), "r" (b));
+}
+
+#define readb(addr) __readb((addr))
+#define readw(addr) __readw((addr))
+
+#define writeb(b, addr) __writeb((b),(addr))
+#define writew(b, addr) __writew((b),(addr))
+
+#else /* BWIO_ENABLED */
+
+#ifdef CONFIG_ALPHA_SRM_SETUP
+
+extern unsigned long pyxis_sm_base_r1, pyxis_sm_base_r2, pyxis_sm_base_r3;
+
+extern inline unsigned long __readb(unsigned long addr)
+{
+ unsigned long result, shift, work;
+
+ if ((addr >= pyxis_sm_base_r1) &&
+ (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
+ work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r2) &&
+ (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
+ work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r3) &&
+ (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
+ work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
+ else
+ {
+#if 0
+ printk("__readb: address 0x%lx not covered by HAE\n", addr);
+#endif
+ return 0x0ffUL;
+ }
+ shift = (addr & 0x3) << 3;
+ result = *(vuip) work;
+ result >>= shift;
+ return 0x0ffUL & result;
+}
+
+extern inline unsigned long __readw(unsigned long addr)
+{
+ unsigned long result, shift, work;
+
+ if ((addr >= pyxis_sm_base_r1) &&
+ (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
+ work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x08);
+ else
+ if ((addr >= pyxis_sm_base_r2) &&
+ (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
+ work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x08);
+ else
+ if ((addr >= pyxis_sm_base_r3) &&
+ (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
+ work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x08);
+ else
+ {
+#if 0
+ printk("__readw: address 0x%lx not covered by HAE\n", addr);
+#endif
+ return 0x0ffffUL;
+ }
+ shift = (addr & 0x3) << 3;
+ result = *(vuip) work;
+ result >>= shift;
+ return 0x0ffffUL & result;
+}
+
+extern inline void __writeb(unsigned char b, unsigned long addr)
+{
+ unsigned long work;
+
+ if ((addr >= pyxis_sm_base_r1) &&
+ (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
+ work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r2) &&
+ (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
+ work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r3) &&
+ (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
+ work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
+ else
+ {
+#if 0
+ printk("__writeb: address 0x%lx not covered by HAE\n", addr);
+#endif
+ return;
+ }
+ *(vuip) work = b * 0x01010101;
+}
+
+extern inline void __writew(unsigned short b, unsigned long addr)
+{
+ unsigned long work;
+
+ if ((addr >= pyxis_sm_base_r1) &&
+ (addr <= (pyxis_sm_base_r1 + MEM_R1_MASK)))
+ work = (((addr & MEM_R1_MASK) << 5) + PYXIS_SPARSE_MEM + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r2) &&
+ (addr <= (pyxis_sm_base_r2 + MEM_R2_MASK)))
+ work = (((addr & MEM_R2_MASK) << 5) + PYXIS_SPARSE_MEM_R2 + 0x00);
+ else
+ if ((addr >= pyxis_sm_base_r3) &&
+ (addr <= (pyxis_sm_base_r3 + MEM_R3_MASK)))
+ work = (((addr & MEM_R3_MASK) << 5) + PYXIS_SPARSE_MEM_R3 + 0x00);
+ else
+ {
+#if 0
+ printk("__writew: address 0x%lx not covered by HAE\n", addr);
+#endif
+ return;
+ }
+ *(vuip) work = b * 0x00010001;
+}
+
+#else /* SRM_SETUP */
+
extern inline unsigned long __readb(unsigned long addr)
{
unsigned long result, shift, msb, work, temp;
shift = (addr & 0x3) << 3;
msb = addr & 0xE0000000UL;
- temp = addr & MEM_SP1_MASK ;
+ temp = addr & MEM_R1_MASK ;
if (msb != hae.cache) {
- pyxis_set_hae(msb);
+ set_hae(msb);
}
work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x00);
result = *(vuip) work;
@@ -322,9 +603,9 @@ extern inline unsigned long __readw(unsigned long addr)
shift = (addr & 0x3) << 3;
msb = addr & 0xE0000000UL;
- temp = addr & MEM_SP1_MASK ;
+ temp = addr & MEM_R1_MASK ;
if (msb != hae.cache) {
- pyxis_set_hae(msb);
+ set_hae(msb);
}
work = ((temp << 5) + PYXIS_SPARSE_MEM + 0x08);
result = *(vuip) work;
@@ -332,19 +613,14 @@ extern inline unsigned long __readw(unsigned long addr)
return 0x0ffffUL & result;
}
-extern inline unsigned long __readl(unsigned long addr)
-{
- return *(vuip) (addr + PYXIS_DENSE_MEM);
-}
-
extern inline void __writeb(unsigned char b, unsigned long addr)
{
unsigned long msb ;
msb = addr & 0xE0000000 ;
- addr &= MEM_SP1_MASK ;
+ addr &= MEM_R1_MASK ;
if (msb != hae.cache) {
- pyxis_set_hae(msb);
+ set_hae(msb);
}
*(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x00) = b * 0x01010101;
}
@@ -354,23 +630,25 @@ extern inline void __writew(unsigned short b, unsigned long addr)
unsigned long msb ;
msb = addr & 0xE0000000 ;
- addr &= MEM_SP1_MASK ;
+ addr &= MEM_R1_MASK ;
if (msb != hae.cache) {
- pyxis_set_hae(msb);
+ set_hae(msb);
}
*(vuip) ((addr << 5) + PYXIS_SPARSE_MEM + 0x08) = b * 0x00010001;
}
+#endif /* SRM_SETUP */
+
+extern inline unsigned long __readl(unsigned long addr)
+{
+ return *(vuip) (addr + PYXIS_DENSE_MEM);
+}
extern inline void __writel(unsigned int b, unsigned long addr)
{
*(vuip) (addr + PYXIS_DENSE_MEM) = b;
}
-#define inb(port) \
-(__builtin_constant_p((port))?__inb(port):_inb(port))
-
-#define outb(x, port) \
-(__builtin_constant_p((port))?__outb((x),(port)):_outb((x),(port)))
+#endif /* BWIO_ENABLED */
#define readl(a) __readl((unsigned long)(a))
#define writel(v,a) __writel((v),(unsigned long)(a))