This is the patch that includes most of things that I have in IP32-specific parts of my tree. 1. IRQ handling rewrite by me and Vivien. 2. Propper memory detection pathc by Keith. 3. Some other minor fixlets.
Index: arch/mips/sgi-ip32/Makefile =================================================================== RCS file: /home/cvs/linux/arch/mips/sgi-ip32/Makefile,v retrieving revision 1.7 diff -u -r1.7 Makefile --- arch/mips/sgi-ip32/Makefile 13 Jun 2003 13:58:31 -0000 1.7 +++ arch/mips/sgi-ip32/Makefile 30 Jun 2003 00:25:00 -0000 @@ -4,6 +4,6 @@ # obj-y += ip32-berr.o ip32-rtc.o ip32-setup.o ip32-irq.o ip32-irq-glue.o \ - ip32-timer.o crime.o ip32-reset.o + ip32-timer.o crime.o ip32-reset.o ip32-memory.o EXTRA_AFLAGS := $(CFLAGS) Index: arch/mips/sgi-ip32/crime.c =================================================================== RCS file: /home/cvs/linux/arch/mips/sgi-ip32/crime.c,v retrieving revision 1.2 diff -u -r1.2 crime.c --- arch/mips/sgi-ip32/crime.c 6 Aug 2002 00:08:57 -0000 1.2 +++ arch/mips/sgi-ip32/crime.c 30 Jun 2003 00:25:00 -0000 @@ -3,13 +3,17 @@ * License. See the file "COPYING" in the main directory of this archive * for more details. * - * Copyright (C) 2001 Keith M Wesolowski + * Copyright (C) 2001, 2003 Keith M Wesolowski */ +#include <asm/ip32/crime.h> +#include <asm/ptrace.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/mipsregs.h> #include <linux/types.h> #include <linux/init.h> #include <linux/kernel.h> -#include <asm/ip32/crime.h> -#include <asm/ptrace.h> +#include <linux/interrupt.h> void __init crime_init (void) { @@ -18,32 +22,75 @@ id = (id & CRIME_ID_IDBITS) >> 4; - printk ("CRIME id %1lx rev %ld detected at %016lx\n", id, rev, + printk ("CRIME id %1lx rev %ld detected at 0x%016lx\n", id, rev, (unsigned long) CRIME_BASE); } -/* XXX Like on Sun, these give us various useful information to printk. */ -void crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t crime_memerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) { u64 memerr = crime_read_64 (CRIME_MEM_ERROR_STAT); u64 addr = crime_read_64 (CRIME_MEM_ERROR_ADDR); + int fatal = 0; + memerr &= CRIME_MEM_ERROR_STAT_MASK; + addr &= CRIME_MEM_ERROR_ADDR_MASK; + + printk("CRIME memory error at 0x%08lx ST 0x%08lx<", addr, memerr); - printk ("CRIME memory error at physaddr 0x%08lx status %08lx\n", - addr << 2, memerr); + if (memerr & CRIME_MEM_ERROR_INV) + printk("INV,"); + if (memerr & CRIME_MEM_ERROR_ECC) { + u64 ecc_syn = crime_read_64(CRIME_MEM_ERROR_ECC_SYN); + u64 ecc_gen = crime_read_64(CRIME_MEM_ERROR_ECC_CHK); + + ecc_syn &= CRIME_MEM_ERROR_ECC_SYN_MASK; + ecc_gen &= CRIME_MEM_ERROR_ECC_CHK_MASK; + + printk("ECC,SYN=0x%08lx,GEN=0x%08lx,", ecc_syn, ecc_gen); + } + if (memerr & CRIME_MEM_ERROR_MULTIPLE) { + fatal = 1; + printk("MULTIPLE,"); + } + if (memerr & CRIME_MEM_ERROR_HARD_ERR) { + fatal = 1; + printk("HARD,"); + } + if (memerr & CRIME_MEM_ERROR_SOFT_ERR) + printk("SOFT,"); + if (memerr & CRIME_MEM_ERROR_CPU_ACCESS) + printk("CPU,"); + if (memerr & CRIME_MEM_ERROR_VICE_ACCESS) + printk("VICE,"); + if (memerr & CRIME_MEM_ERROR_GBE_ACCESS) + printk("GBE,"); + if (memerr & CRIME_MEM_ERROR_RE_ACCESS) + printk("RE,REID=0x%02lx,", (memerr & CRIME_MEM_ERROR_RE_ID)>>8); + if (memerr & CRIME_MEM_ERROR_MACE_ACCESS) + printk("MACE,MACEID=0x%02lx,", memerr & CRIME_MEM_ERROR_MACE_ID); crime_write_64 (CRIME_MEM_ERROR_STAT, 0); + + if (fatal) { + printk("FATAL>\n"); + panic("Fatal memory error detected, halting\n"); + } else { + printk("NONFATAL>\n"); + } + + return IRQ_HANDLED; } -void crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) +irqreturn_t crime_cpuerr_intr (unsigned int irq, void *dev_id, struct pt_regs *regs) { u64 cpuerr = crime_read_64 (CRIME_CPU_ERROR_STAT); u64 addr = crime_read_64 (CRIME_CPU_ERROR_ADDR); cpuerr &= CRIME_CPU_ERROR_MASK; addr <<= 2UL; - printk ("CRIME CPU interface error detected at %09lx status %08lx\n", + printk ("CRIME CPU error detected at 0x%09lx status 0x%08lx\n", addr, cpuerr); crime_write_64 (CRIME_CPU_ERROR_STAT, 0); + return IRQ_HANDLED; } Index: arch/mips/sgi-ip32/ip32-berr.c =================================================================== RCS file: /home/cvs/linux/arch/mips/sgi-ip32/ip32-berr.c,v retrieving revision 1.4 diff -u -r1.4 ip32-berr.c --- arch/mips/sgi-ip32/ip32-berr.c 14 Apr 2003 16:33:24 -0000 1.4 +++ arch/mips/sgi-ip32/ip32-berr.c 30 Jun 2003 00:25:00 -0000 @@ -9,6 +9,7 @@ */ #include <linux/init.h> #include <linux/kernel.h> +#include <linux/sched.h> #include <asm/traps.h> #include <asm/uaccess.h> #include <asm/addrspace.h> Index: arch/mips/sgi-ip32/ip32-irq.c =================================================================== RCS file: /home/cvs/linux/arch/mips/sgi-ip32/ip32-irq.c,v retrieving revision 1.5 diff -u -r1.5 ip32-irq.c --- arch/mips/sgi-ip32/ip32-irq.c 16 Apr 2003 13:02:43 -0000 1.5 +++ arch/mips/sgi-ip32/ip32-irq.c 30 Jun 2003 00:25:00 -0000 @@ -28,6 +28,10 @@ #include <asm/ip32/mace.h> #include <asm/signal.h> +/* issue a PIO read to make sure no PIO writes are pending */ +#define flush_crime_bus() crime_read_64(CRIME_CONTROL); +#define flush_mace_bus() mace_read_64(MACEISA_FLASH_NIC_REG); + #undef DEBUG_IRQ #ifdef DEBUG_IRQ #define DBG(x...) printk(x) @@ -103,9 +107,9 @@ */ /* Some initial interrupts to set up */ -extern void crime_memerr_intr (unsigned int irq, void *dev_id, +extern irqreturn_t crime_memerr_intr (int irq, void *dev_id, struct pt_regs *regs); -extern void crime_cpuerr_intr (unsigned int irq, void *dev_id, +extern irqreturn_t crime_cpuerr_intr (int irq, void *dev_id, struct pt_regs *regs); struct irqaction memerr_irq = { crime_memerr_intr, SA_INTERRUPT, @@ -163,13 +167,13 @@ * We get to split the register in half and do faster lookups. */ +static u64 crime_mask=0; + static void enable_crime_irq(unsigned int irq) { - u64 crime_mask; unsigned long flags; local_irq_save(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); crime_mask |= 1 << (irq - 1); crime_write_64(CRIME_INT_MASK, crime_mask); local_irq_restore(flags); @@ -177,35 +181,35 @@ static unsigned int startup_crime_irq(unsigned int irq) { + crime_mask = crime_read_64(CRIME_INT_MASK); enable_crime_irq(irq); return 0; /* This is probably not right; we could have pending irqs */ } static void disable_crime_irq(unsigned int irq) { - u64 crime_mask; unsigned long flags; local_irq_save(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); crime_mask &= ~(1 << (irq - 1)); crime_write_64(CRIME_INT_MASK, crime_mask); + flush_crime_bus(); local_irq_restore(flags); } static void mask_and_ack_crime_irq (unsigned int irq) { - u64 crime_mask; unsigned long flags; /* Edge triggered interrupts must be cleared. */ if ((irq >= CRIME_GBE0_IRQ && irq <= CRIME_GBE3_IRQ) || (irq >= CRIME_RE_EMPTY_E_IRQ && irq <= CRIME_RE_IDLE_E_IRQ) || (irq >= CRIME_SOFT0_IRQ && irq <= CRIME_SOFT2_IRQ)) { + u64 crime_int; local_irq_save(flags); - crime_mask = crime_read_64(CRIME_HARD_INT); - crime_mask &= ~(1 << (irq - 1)); - crime_write_64(CRIME_HARD_INT, crime_mask); + crime_int = crime_read_64(CRIME_HARD_INT); + crime_int &= ~(1 << (irq - 1)); + crime_write_64(CRIME_HARD_INT, crime_int); local_irq_restore(flags); } disable_crime_irq(irq); @@ -236,42 +240,39 @@ * next chunk of the CRIME register in one piece. */ +static u32 macepci_mask; + static void enable_macepci_irq(unsigned int irq) { - u32 mace_mask; - u64 crime_mask; unsigned long flags; local_irq_save(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask |= MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); - /* - * In case the CRIME interrupt isn't enabled, we must enable it; - * however, we never disable interrupts at that level. - */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_mask |= 1 << (irq - 1); - crime_write_64(CRIME_INT_MASK, crime_mask); + macepci_mask |= MACEPCI_CONTROL_INT(irq - 9); + mace_write_32(MACEPCI_CONTROL, macepci_mask); + crime_mask |= 1 << (irq - 1); + crime_write_64(CRIME_INT_MASK, crime_mask); local_irq_restore(flags); } static unsigned int startup_macepci_irq(unsigned int irq) { - enable_macepci_irq (irq); - - return 0; /* XXX */ + crime_mask = crime_read_64 (CRIME_INT_MASK); + macepci_mask = mace_read_32(MACEPCI_CONTROL); + enable_macepci_irq (irq); + return 0; } static void disable_macepci_irq(unsigned int irq) { - u32 mace_mask; unsigned long flags; local_irq_save(flags); - mace_mask = mace_read_32(MACEPCI_CONTROL); - mace_mask &= ~MACEPCI_CONTROL_INT(irq - 9); - mace_write_32(MACEPCI_CONTROL, mace_mask); + crime_mask &= ~(1 << (irq - 1)); + crime_write_64(CRIME_INT_MASK, crime_mask); + flush_crime_bus(); + macepci_mask &= ~MACEPCI_CONTROL_INT(irq - 9); + mace_write_32(MACEPCI_CONTROL, macepci_mask); + flush_mace_bus(); local_irq_restore(flags); } @@ -299,10 +300,10 @@ * CRIME register. */ +u32 maceisa_mask = 0; + static void enable_maceisa_irq (unsigned int irq) { - u64 crime_mask; - u32 mace_mask; unsigned int crime_int = 0; unsigned long flags; @@ -321,46 +322,56 @@ } DBG ("crime_int %016lx enabled\n", crime_int); local_irq_save(flags); - crime_mask = crime_read_64(CRIME_INT_MASK); crime_mask |= crime_int; crime_write_64(CRIME_INT_MASK, crime_mask); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask |= 1 << (irq - 33); - mace_write_32(MACEISA_INT_MASK, mace_mask); + maceisa_mask |= 1 << (irq - 33); + mace_write_32(MACEISA_INT_MASK, maceisa_mask); local_irq_restore(flags); } static unsigned int startup_maceisa_irq (unsigned int irq) { + crime_mask = crime_read_64 (CRIME_INT_MASK); + maceisa_mask = mace_read_32(MACEISA_INT_MASK); enable_maceisa_irq(irq); return 0; } static void disable_maceisa_irq(unsigned int irq) { - u32 mace_mask; + unsigned int crime_int = 0; unsigned long flags; local_irq_save(flags); - mace_mask = mace_read_32(MACEISA_INT_MASK); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_MASK, mace_mask); + maceisa_mask &= ~(1 << (irq - 33)); + if(!(maceisa_mask & MACEISA_AUDIO_INT)) + crime_int |= MACE_AUDIO_INT; + if(!(maceisa_mask & MACEISA_MISC_INT)) + crime_int |= MACE_MISC_INT; + if(!(maceisa_mask & MACEISA_SUPERIO_INT)) + crime_int |= MACE_SUPERIO_INT; + crime_mask &= ~crime_int; + crime_write_64(CRIME_INT_MASK, crime_mask); + flush_crime_bus(); + mace_write_32(MACEISA_INT_MASK, maceisa_mask); + flush_mace_bus(); local_irq_restore(flags); } static void mask_and_ack_maceisa_irq(unsigned int irq) { - u32 mace_mask; + u32 mace_int; unsigned long flags; switch (irq) { case MACEISA_PARALLEL_IRQ: case MACEISA_SERIAL1_TDMAPR_IRQ: case MACEISA_SERIAL2_TDMAPR_IRQ: + /* edge triggered */ local_irq_save(flags); - mace_mask = mace_read_32(MACEISA_INT_STAT); - mace_mask &= ~(1 << (irq - 33)); - mace_write_32(MACEISA_INT_STAT, mace_mask); + mace_int = mace_read_32(MACEISA_INT_STAT); + mace_int &= ~(1 << (irq - 33)); + mace_write_32(MACEISA_INT_STAT, mace_int); local_irq_restore(flags); break; } @@ -392,11 +403,9 @@ static void enable_mace_irq(unsigned int irq) { - u64 crime_mask; unsigned long flags; local_irq_save(flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); crime_mask |= 1 << (irq - 1); crime_write_64 (CRIME_INT_MASK, crime_mask); local_irq_restore (flags); @@ -404,19 +413,19 @@ static unsigned int startup_mace_irq(unsigned int irq) { + crime_mask = crime_read_64 (CRIME_INT_MASK); enable_mace_irq(irq); return 0; } static void disable_mace_irq(unsigned int irq) { - u64 crime_mask; unsigned long flags; local_irq_save(flags); - crime_mask = crime_read_64 (CRIME_INT_MASK); crime_mask &= ~(1 << (irq - 1)); crime_write_64 (CRIME_INT_MASK, crime_mask); + flush_crime_bus(); local_irq_restore(flags); } @@ -446,9 +455,12 @@ u32 mace; printk ("Unknown interrupt occurred!\n"); - printk ("cp0_status: %08x\tcp0_cause: %08x\n", - read_c0_status(), - read_c0_cause()); + printk ("cp0_status: %08x\n", + read_c0_status ()); + printk ("cp0_cause: %08x\n", + read_c0_cause ()); +// printk ("badvaddr: %08x\n", +// read_32bit_cp0_register (CP0_BADVADDR)); crime = crime_read_64 (CRIME_INT_MASK); printk ("CRIME interrupt mask: %016lx\n", crime); crime = crime_read_64 (CRIME_INT_STAT); @@ -465,7 +477,7 @@ printk("Register dump:\n"); show_regs(regs); - printk("Please mail this report to linux-mips@oss.sgi.com\n"); + printk("Please mail this report to linux-mips@linux-mips.org\n"); printk("Spinning..."); while(1) ; } @@ -474,43 +486,18 @@ void ip32_irq0(struct pt_regs *regs) { u64 crime_int; - u64 crime_mask; int irq = 0; - unsigned long flags; - local_irq_save(flags); - /* disable crime interrupts */ - crime_mask = crime_read_64(CRIME_INT_MASK); - crime_write_64(CRIME_INT_MASK, 0); - - crime_int = crime_read_64(CRIME_INT_STAT); - - if (crime_int & CRIME_MACE_INT_MASK) { - crime_int &= CRIME_MACE_INT_MASK; - irq = ffs (crime_int); - } else if (crime_int & CRIME_MACEISA_INT_MASK) { - u32 mace_int; - mace_int = mace_read_32 (MACEISA_INT_STAT); - if (mace_int == 0) - irq = 0; - else - irq = ffs (mace_int) + 32; - } else if (crime_int & CRIME_MACEPCI_INT_MASK) { - crime_int &= CRIME_MACEPCI_INT_MASK; - crime_int >>= 8; - irq = ffs (crime_int) + 8; - } else if (crime_int & 0xffff0000) { - crime_int >>= 16; - irq = ffs (crime_int) + 16; + crime_int = crime_read_64(CRIME_INT_STAT) & crime_mask; + irq = ffs(crime_int); + crime_int = 1ULL << (irq - 1); + + if (crime_int & CRIME_MACEISA_INT_MASK) { + u32 mace_int = mace_read_32 (MACEISA_INT_STAT) & maceisa_mask; + irq = ffs (mace_int) + 32; } - if (irq == 0) - ip32_unknown_interrupt(regs); DBG("*irq %u*\n", irq); do_IRQ(irq, regs); - - /* enable crime interrupts */ - crime_write_64(CRIME_INT_MASK, crime_mask); - local_irq_restore (flags); } void ip32_irq1(struct pt_regs *regs) Index: arch/mips/sgi-ip32/ip32-setup.c =================================================================== RCS file: /home/cvs/linux/arch/mips/sgi-ip32/ip32-setup.c,v retrieving revision 1.4 diff -u -r1.4 ip32-setup.c --- arch/mips/sgi-ip32/ip32-setup.c 14 Apr 2003 16:33:24 -0000 1.4 +++ arch/mips/sgi-ip32/ip32-setup.c 30 Jun 2003 00:25:00 -0000 @@ -13,6 +13,8 @@ #include <linux/mc146818rtc.h> #include <linux/param.h> #include <linux/init.h> +#include <linux/console.h> +#include <linux/bootmem.h> #include <asm/time.h> #include <asm/mipsregs.h> @@ -28,7 +30,6 @@ extern u32 cc_interval; #ifdef CONFIG_SGI_O2MACE_ETH - /* * This is taken care of in here 'cause they say using Arc later on is * problematic @@ -59,19 +60,41 @@ } #endif +#ifdef CONFIG_FB_SGIO2 +#include "../../../drivers/video/sgio2fb.h" +void *sgio2fb_mem; +#endif + +void __init ip32_devsetup(void) +{ +#ifdef CONFIG_FB_SGIO2 + sgio2fb_mem=__alloc_bootmem(TILE_PTR_SIZE<<TILE_SHIFT, TILE_SIZE,__pa(MAX_DMA_ADDRESS)); +#endif +#ifdef CONFIG_SGI_O2MACE_ETH + { + char *mac=ArcGetEnvironmentVariable("eaddr"); + str2eaddr(o2meth_eaddr, mac); + } +#endif +} + extern void ip32_time_init(void); -extern void ip32_reboot_setup(void); +extern void ip32_be_init(void); void __init ip32_setup(void) { -#ifdef CONFIG_SERIAL_CONSOLE +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_MACE_SGIO2) char *ctype; #endif TLBMISS_HANDLER_SETUP (); mips_io_port_base = UNCACHEDADDR(MACEPCI_HI_IO);; -#ifdef CONFIG_SERIAL_CONSOLE +#ifdef CONFIG_SERIAL_MACE_SGIO2 +#warning O2MACECONSOLE compiled in + o2serial_console_init(); +#endif +#if defined(CONFIG_SERIAL_CONSOLE) || defined(CONFIG_SERIAL_MACE_SGIO2) ctype = ArcGetEnvironmentVariable("console"); if (*ctype == 'd') { if (ctype[1] == '2') @@ -80,26 +103,16 @@ console_setup ("ttyS0"); } #endif -#ifdef CONFIG_SGI_O2MACE_ETH - { - char *mac=ArcGetEnvironmentVariable("eaddr"); - str2eaddr(o2meth_eaddr, mac); - } -#endif - + ip32_devsetup(); #ifdef CONFIG_VT +# ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; +# endif #endif - rtc_ops = &ip32_rtc_ops; board_be_init = ip32_be_init; board_time_init = ip32_time_init; + board_timer_setup = NULL; crime_init (); -} - -int __init page_is_ram (unsigned long pagenr) -{ - /* XXX: to do? */ - return 1; } Index: include/asm-mips64/ip32/crime.h =================================================================== RCS file: /home/cvs/linux/include/asm-mips64/ip32/crime.h,v retrieving revision 1.3 diff -u -r1.3 crime.h --- include/asm-mips64/ip32/crime.h 27 Jun 2002 14:27:11 -0000 1.3 +++ include/asm-mips64/ip32/crime.h 30 Jun 2003 00:25:06 -0000 @@ -11,7 +11,9 @@ #ifndef __ASM_CRIME_H__ #define __ASM_CRIME_H__ +#include <asm/types.h> #include <asm/addrspace.h> +#include <asm/io64.h> /* * Address map @@ -23,12 +25,8 @@ #endif #ifndef __ASSEMBLY__ -static inline u64 crime_read_64 (unsigned long __offset) { - return *((volatile u64 *) (CRIME_BASE + __offset)); -} -static inline void crime_write_64 (unsigned long __offset, u64 __val) { - *((volatile u64 *) (CRIME_BASE + __offset)) = __val; -} +#define crime_read_64(__offset) __in64(CRIME_BASE+(__offset)) +#define crime_write_64(__offset,__val) __out64(__val,CRIME_BASE+(__offset)) #endif #undef BIT @@ -179,11 +177,9 @@ * macros for CRIME memory bank control registers. */ #define CRIME_MEM_BANK_CONTROL(__bank) (0x00000208 + ((__bank) << 3)) -#define CRIME_MEM_BANK_CONTROL_MSK 0x11f /* 9 bits 7:5 reserved */ +#define CRIME_MEM_BANK_CONTROL_MASK 0x11f /* 9 bits 7:5 reserved */ #define CRIME_MEM_BANK_CONTROL_ADDR 0x01f #define CRIME_MEM_BANK_CONTROL_SDRAM_SIZE 0x100 -#define CRIME_MEM_BANK_CONTROL_BANK_TO_ADDR(__bank) \ - (((__bank) & CRIME_MEM_BANK_CONTROL_ADDR) << 25) #define CRIME_MEM_REFRESH_COUNTER (0x00000248) #define CRIME_MEM_REFRESH_COUNTER_MASK 0x7ff /* 11-bit register */ @@ -206,8 +202,10 @@ #define CRIME_MEM_ERROR_SOFT_ERR 0x00100000 #define CRIME_MEM_ERROR_HARD_ERR 0x00200000 #define CRIME_MEM_ERROR_MULTIPLE 0x00400000 +#define CRIME_MEM_ERROR_ECC 0x01800000 #define CRIME_MEM_ERROR_MEM_ECC_RD 0x00800000 #define CRIME_MEM_ERROR_MEM_ECC_RMW 0x01000000 +#define CRIME_MEM_ERROR_INV 0x0e000000 #define CRIME_MEM_ERROR_INV_MEM_ADDR_RD 0x02000000 #define CRIME_MEM_ERROR_INV_MEM_ADDR_WR 0x04000000 #define CRIME_MEM_ERROR_INV_MEM_ADDR_RMW 0x08000000 Index: include/asm-mips64/ip32/mace.h =================================================================== RCS file: /home/cvs/linux/include/asm-mips64/ip32/mace.h,v retrieving revision 1.6 diff -u -r1.6 mace.h --- include/asm-mips64/ip32/mace.h 7 Apr 2003 02:28:45 -0000 1.6 +++ include/asm-mips64/ip32/mace.h 30 Jun 2003 00:25:06 -0000 @@ -12,7 +12,8 @@ #define __ASM_MACE_H__ #include <asm/addrspace.h> - +#include <asm/system.h> +#include <asm/io64.h> /* * Address map */ @@ -50,8 +51,7 @@ #define MACEPCI_SWAPPED_VIEW 0 #define MACEPCI_NATIVE_VIEW 0x40000000 #define MACEPCI_IO 0x80000000 -/*#define MACEPCI_HI_MEMORY 0x0000000280000000UL * This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ -#define MACEPCI_HI_MEMORY 0x0000000200000000UL /* This mipght be just 0x0000000200000000UL 2G more :) (or maybe it is different between 1.1 & 1.5 */ +#define MACEPCI_HI_MEMORY 0x0000000200000000UL #define MACEPCI_HI_IO 0x0000000100000000UL /* @@ -130,7 +130,9 @@ #define MACEISA_EPP_BASE (MACE_ISA_EXT ) #define MACEISA_ECP_BASE (MACE_ISA_EXT + 0x00008000) #define MACEISA_SER1_BASE (MACE_ISA_EXT + 0x00010000) +#define MACEISA_SER1_REGS (MACE_ISA_BASE + 0x00020000) #define MACEISA_SER2_BASE (MACE_ISA_EXT + 0x00018000) +#define MACEISA_SER2_REGS (MACE_ISA_BASE + 0x00030000) #define MACEISA_RTC_BASE (MACE_ISA_EXT + 0x00020000) #define MACEISA_GAME_BASE (MACE_ISA_EXT + 0x00030000) @@ -138,6 +140,8 @@ * Ringbase address and reset register - 64 bits */ #define MACEISA_RINGBASE MACE_ISA_BASE +/* Ring buffers occupy 8 4K buffers */ +#define MACEISA_RINGBUFFERS_SIZE 8*4*1024 /* * Flash-ROM/LED/DP-RAM/NIC Controller Register - 64 bits (?) @@ -197,6 +201,61 @@ #define MACEISA_SERIAL2_RDMAT_INT BIT (30) #define MACEISA_SERIAL2_RDMAOR_INT BIT (31) +#define MACEI2C_CONFIG MACE_I2C_BASE +#define MACEI2C_CONTROL (MACE_I2C_BASE|0x10) +#define MACEI2C_DATA (MACE_I2C_BASE|0x18) + +/* Bits for I2C_CONFIG */ +#define MACEI2C_RESET BIT(0) +#define MACEI2C_FAST BIT(1) +#define MACEI2C_DATA_OVERRIDE BIT(2) +#define MACEI2C_CLOCK_OVERRIDE BIT(3) +#define MACEI2C_DATA_STATUS BIT(4) +#define MACEI2C_CLOCK_STATUS BIT(5) + +/* Bits for I2C_CONTROL */ +#define MACEI2C_NOT_IDLE BIT(0) /* write: 0=force idle + * read: 0=idle 1=not idle */ +#define MACEI2C_DIR BIT(1) /* 0=write 1=read */ +#define MACEI2C_MORE_BYTES BIT(2) /* 0=last byte 1=more bytes */ +#define MACEI2C_TRANS_BUSY BIT(4) /* 0=trans done 1=trans busy */ +#define MACEI2C_NACK BIT(5) /* 0=ack received 1=ack not */ +#define MACEI2C_BUS_ERROR BIT(7) /* 0=no bus err 1=bus err */ + + +#define MACEISA_AUDIO_INT (MACEISA_AUDIO_SW_INT | \ + MACEISA_AUDIO_SC_INT | \ + MACEISA_AUDIO1_DMAT_INT | \ + MACEISA_AUDIO1_OF_INT | \ + MACEISA_AUDIO2_DMAT_INT | \ + MACEISA_AUDIO2_MERR_INT | \ + MACEISA_AUDIO3_DMAT_INT | \ + MACEISA_AUDIO3_MERR_INT) +#define MACEISA_MISC_INT (MACEISA_RTC_INT | \ + MACEISA_KEYB_INT | \ + MACEISA_KEYB_POLL_INT | \ + MACEISA_MOUSE_INT | \ + MACEISA_MOUSE_POLL_INT | \ + MACEISA_TIMER0_INT | \ + MACEISA_TIMER1_INT | \ + MACEISA_TIMER2_INT) +#define MACEISA_SUPERIO_INT (MACEISA_PARALLEL_INT | \ + MACEISA_PAR_CTXA_INT | \ + MACEISA_PAR_CTXB_INT | \ + MACEISA_PAR_MERR_INT | \ + MACEISA_SERIAL1_INT | \ + MACEISA_SERIAL1_TDMAT_INT | \ + MACEISA_SERIAL1_TDMAPR_INT | \ + MACEISA_SERIAL1_TDMAME_INT | \ + MACEISA_SERIAL1_RDMAT_INT | \ + MACEISA_SERIAL1_RDMAOR_INT | \ + MACEISA_SERIAL2_INT | \ + MACEISA_SERIAL2_TDMAT_INT | \ + MACEISA_SERIAL2_TDMAPR_INT | \ + MACEISA_SERIAL2_TDMAME_INT | \ + MACEISA_SERIAL2_RDMAT_INT | \ + MACEISA_SERIAL2_RDMAOR_INT) + #ifndef __ASSEMBLY__ #include <asm/types.h> @@ -220,7 +279,7 @@ static inline u64 mace_read_64 (unsigned long __offset) { - return *((volatile u64 *) (MACE_BASE + __offset)); + return __in64 (MACE_BASE + __offset); } static inline void mace_write_8 (unsigned long __offset, u8 __val) @@ -240,7 +299,7 @@ static inline void mace_write_64 (unsigned long __offset, u64 __val) { - *((volatile u64 *) (MACE_BASE + __offset)) = __val; + __out64 (__val, MACE_BASE + __offset); } /* Call it whenever device needs to read data from main memory coherently */ @@ -248,6 +307,17 @@ { /* mace_write_32(MACEPCI_WFLUSH,0xffffffff);*/ } + +/* MACE ISA ring buffers access */ +void maceisa_init(void); +void* maceisa_audio_input_ring(void); +/* num - audio channel number: 0 or 1 */ +void* maceisa_audio_output_ring(int num); +void* maceisa_scratch_ring(void); +/* num - number of serial port: 0 or 1 */ +void* maceisa_serial_tx_ring(int num); +void* maceisa_serial_rx_ring(int num); + #endif /* !__ASSEMBLY__ */ --- /dev/null Sun Jul 17 16:46:18 1994 +++ include/asm-mips64/io64.h Sun Jun 15 10:35:18 2003 @@ -0,0 +1,99 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2002 Ralf Baechle + * Copyright (C) 2003 Keith M Wesolowski + */ + +#ifndef __ASM_IO64_H +#define __ASM_IO64_H + +#include <linux/types.h> + +/* Generic 64-bit I/O register reads and writes. This does no byte-swapping + * as it makes little sense and no platform that needs this is insane enough + * to require it. + */ + +#ifndef __ASSEMBLY__ +#if _MIPS_SZLONG >= 64 +static inline u64 __in64(unsigned long addr) +{ + return *(volatile u64 *)addr; +} + +static inline void __out64(u64 val, unsigned long addr) +{ + *(volatile u64 *)addr = val; +} + +#define in64(a) __in64(a) +#define out64(v,a) __out64(v,a) + +#else /* _MIPS_SZLONG < 64 */ + +#include <asm/system.h> + +static inline u64 __in64(unsigned long addr) +{ + u64 res; + + asm volatile ( + " .set mips3 \n" + " ld %L0, (%1) # __in64 \n" + " dsra %M0, %L0, 32 \n" + " sll %L0, 0 \n" + " .set mips0 \n" + : "=r" (res) + : "r" (addr) + ); + + return res; +} + +static inline u64 in64(unsigned long addr) +{ + unsigned long flags; + u64 res; + + local_irq_save(flags); + res = __in64(addr); + local_irq_restore(flags); + + return res; +} + +static inline void __out64(u64 val, unsigned long addr) +{ + u64 tmp; + + asm volatile ( + " .set mips3 \n" + " dsll %L0, 32 # __out64 \n" + " dsll %M0, 32 \n" + " dsrl %L0, 32 \n" + " or %L0, %M0 \n" + " sd %L0, (%2) \n" + " .set mips0 \n" + : "=&r" (tmp) + : "0" (val), "r" (addr) + : "memory" + ); +} + +static inline void out64(u64 val, unsigned long addr) +{ + unsigned long flags; + + local_irq_save(flags); + __out64(val, addr); + local_irq_restore(flags); +} +#endif /* _MIPS_SZLONG */ +#endif /* !__ASSEMBLY__ */ + + +#endif /* __ASM_IO64_H */ --- /dev/null Sun Jul 17 16:46:18 1994 +++ include/asm-mips/io64.h Sun Jun 15 10:35:18 2003 @@ -0,0 +1,99 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2000, 2001 Broadcom Corporation + * Copyright (C) 2002 Ralf Baechle + * Copyright (C) 2003 Keith M Wesolowski + */ + +#ifndef __ASM_IO64_H +#define __ASM_IO64_H + +#include <linux/types.h> + +/* Generic 64-bit I/O register reads and writes. This does no byte-swapping + * as it makes little sense and no platform that needs this is insane enough + * to require it. + */ + +#ifndef __ASSEMBLY__ +#if _MIPS_SZLONG >= 64 +static inline u64 __in64(unsigned long addr) +{ + return *(volatile u64 *)addr; +} + +static inline void __out64(u64 val, unsigned long addr) +{ + *(volatile u64 *)addr = val; +} + +#define in64(a) __in64(a) +#define out64(v,a) __out64(v,a) + +#else /* _MIPS_SZLONG < 64 */ + +#include <asm/system.h> + +static inline u64 __in64(unsigned long addr) +{ + u64 res; + + asm volatile ( + " .set mips3 \n" + " ld %L0, (%1) # __in64 \n" + " dsra %M0, %L0, 32 \n" + " sll %L0, 0 \n" + " .set mips0 \n" + : "=r" (res) + : "r" (addr) + ); + + return res; +} + +static inline u64 in64(unsigned long addr) +{ + unsigned long flags; + u64 res; + + local_irq_save(flags); + res = __in64(addr); + local_irq_restore(flags); + + return res; +} + +static inline void __out64(u64 val, unsigned long addr) +{ + u64 tmp; + + asm volatile ( + " .set mips3 \n" + " dsll %L0, 32 # __out64 \n" + " dsll %M0, 32 \n" + " dsrl %L0, 32 \n" + " or %L0, %M0 \n" + " sd %L0, (%2) \n" + " .set mips0 \n" + : "=&r" (tmp) + : "0" (val), "r" (addr) + : "memory" + ); +} + +static inline void out64(u64 val, unsigned long addr) +{ + unsigned long flags; + + local_irq_save(flags); + __out64(val, addr); + local_irq_restore(flags); +} +#endif /* _MIPS_SZLONG */ +#endif /* !__ASSEMBLY__ */ + + +#endif /* __ASM_IO64_H */ --- /dev/null Sun Jul 17 16:46:18 1994 +++ arch/mips/sgi-ip32/ip32-memory.c Sun Jun 1 18:55:04 2003 @@ -0,0 +1,37 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 2003 Keith M Wesolowski + */ +#include <asm/ip32/crime.h> +#include <asm/bootinfo.h> +#include <asm/page.h> +#include <asm/pgtable.h> +#include <asm/pgalloc.h> +#include <linux/types.h> +#include <linux/init.h> +#include <linux/kernel.h> + +void __init prom_meminit (void) +{ + u64 base, size; + int bank; + + for (bank=0; bank < CRIME_MAXBANKS; bank++) { + u64 bankctl = crime_read_64(CRIME_MEM_BANK_CONTROL(bank)); + base = (bankctl & CRIME_MEM_BANK_CONTROL_ADDR) << 25; + if (bank != 0 && base == 0) + continue; + size = (bankctl & CRIME_MEM_BANK_CONTROL_SDRAM_SIZE) ? 128 : 32; + printk("CRIME MC: bank %d base 0x%016lx size %luMB\n", + bank, base, size); + size <<= 20; + if (base + size > (256 << 20)) + continue; + add_memory_region (base, size, BOOT_MEM_RAM); + } +} + +void __init prom_free_prom_memory (void) { }