diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
commit | 008d0be72b2f160382c6e880765e96b64a050c65 (patch) | |
tree | 36f48a98a3815a408e2ce1693dd182af90f80305 /release/src/linux/linux/arch/mips/sni | |
parent | 611becfb8726c60cb060368541ad98191d4532f5 (diff) | |
download | tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.gz tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.bz2 |
imported original firmware WRT54GL_v4.30.11_11_US
Diffstat (limited to 'release/src/linux/linux/arch/mips/sni')
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/Makefile | 19 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/int-handler.S | 74 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/io.c | 178 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/irq.c | 158 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/pci.c | 187 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/pcimt_scache.c | 37 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/reset.c | 50 | ||||
-rw-r--r-- | release/src/linux/linux/arch/mips/sni/setup.c | 136 |
8 files changed, 839 insertions, 0 deletions
diff --git a/release/src/linux/linux/arch/mips/sni/Makefile b/release/src/linux/linux/arch/mips/sni/Makefile new file mode 100644 index 00000000..d266a836 --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/Makefile @@ -0,0 +1,19 @@ +# +# Makefile for the SNI specific part of the kernel +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). +# + +USE_STANDARD_AS_RULE := true + +all: sni.o int-handler.o + +O_TARGET := sni.o + +obj-y := int-handler.o io.o irq.o pci.o pcimt_scache.o reset.o setup.o + +int-handler.o: int-handler.S + +include $(TOPDIR)/Rules.make diff --git a/release/src/linux/linux/arch/mips/sni/int-handler.S b/release/src/linux/linux/arch/mips/sni/int-handler.S new file mode 100644 index 00000000..76eb463a --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/int-handler.S @@ -0,0 +1,74 @@ +/* + * SNI RM200 PCI specific interrupt handler code. + * + * Copyright (C) 1994, 95, 96, 97, 98, 1999, 2000, 01 by Ralf Baechle + */ +#include <asm/asm.h> +#include <asm/mipsregs.h> +#include <asm/regdef.h> +#include <asm/sni.h> +#include <asm/stackframe.h> + +/* + * The PCI ASIC has the nasty property that it may delay writes if it is busy. + * As a consequence from writes that have not graduated when we exit from the + * interrupt handler we might catch a spurious interrupt. To avoid this we + * force the PCI ASIC to graduate all writes by executing a read from the + * PCI bus. + */ + .set noreorder + .set noat + .align 5 + NESTED(sni_rm200_pci_handle_int, PT_SIZE, sp) + SAVE_ALL + CLI + .set at + + /* Blinken light ... */ + lb t0, led_cache + addiu t0, 1 + sb t0, led_cache + sb t0, PCIMT_CSLED # write only register + .data +led_cache: .byte 0 + .text + + mfc0 t0, CP0_STATUS + mfc0 t1, CP0_CAUSE + and t0, t1 + + andi t1, t0, 0x4a00 # hardware interrupt 1 + bnez t1, _hwint134 + andi t1, t0, 0x1000 # hardware interrupt 2 + bnez t1, _hwint2 + andi t1, t0, 0x8000 # hardware interrupt 5 + bnez t1, _hwint5 + andi t1, t0, 0x0400 # hardware interrupt 0 + bnez t1, _hwint0 + nop + + j ret_from_irq # spurious interrupt + nop + + ############################################################################## + +/* hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug + button interrupts. */ +_hwint0: jal pciasic_hwint0 + move a1, sp + +/* + * hwint 1 deals with EISA and SCSI interrupts, + * hwint 3 should deal with the PCI A - D interrupts, + * hwint 4 is used for only the onboard PCnet 32. + */ +_hwint134: jal pciasic_hwint134 + + +/* This interrupt was used for the com1 console on the first prototypes. */ +_hwint2: jal pciasic_hwint2 + +/* hwint5 is the r4k count / compare interrupt */ +_hwint5: jal pciasic_hwint5 + + END(sni_rm200_pci_handle_int) diff --git a/release/src/linux/linux/arch/mips/sni/io.c b/release/src/linux/linux/arch/mips/sni/io.c new file mode 100644 index 00000000..92d7693f --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/io.c @@ -0,0 +1,178 @@ +/* + * 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. + * + * Low level I/O functions for SNI. + */ +#include <linux/string.h> +#include <linux/spinlock.h> +#include <asm/addrspace.h> +#include <asm/system.h> +#include <asm/sni.h> + +/* + * Urgs... We only can see a 16mb window of the 4gb EISA address space + * at PCIMT_EISA_BASE. Maladia segmentitis ... + * + * To avoid locking and all the related headacke we implement this such + * that accessing the bus address space nests, so we're treating this + * correctly even for interrupts. This is going to suck seriously for + * the SMP members of the RM family. + * + * Making things worse the PCIMT_CSMAPISA register resides on the X bus with + * it's unbeatable 1.4 mb/s transfer rate. + */ + +static inline void eisa_map(unsigned long address) +{ + unsigned char upper; + + upper = address >> 24; + *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper; +} + +#define save_eisa_map() \ + (*(volatile unsigned char *)PCIMT_CSMAPISA) +#define restore_eisa_map(val) \ + do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0) + +static unsigned char sni_readb(unsigned long addr) +{ + unsigned char res; + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + restore_eisa_map(save_map); + + return res; +} + +static unsigned short sni_readw(unsigned long addr) +{ + unsigned short res; + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + restore_eisa_map(save_map); + + return res; +} + +static unsigned int sni_readl(unsigned long addr) +{ + unsigned int res; + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr); + restore_eisa_map(save_map); + + return res; +} + +static void sni_writeb(unsigned char val, unsigned long addr) +{ + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + restore_eisa_map(save_map); +} + +static void sni_writew(unsigned short val, unsigned long addr) +{ + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + restore_eisa_map(save_map); +} + +static void sni_writel(unsigned int val, unsigned long addr) +{ + unsigned int save_map; + + save_map = save_eisa_map(); + eisa_map(addr); + addr &= 0xffffff; + *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val; + restore_eisa_map(save_map); +} + +static void sni_memset_io(unsigned long addr, int val, unsigned long len) +{ + unsigned long waddr; + unsigned int save_map; + + save_map = save_eisa_map(); + waddr = PCIMT_EISA_BASE | (addr & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~addr + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + eisa_map(addr); + memset((char *)waddr, val, fraglen); + addr += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + restore_eisa_map(save_map); +} + +static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + unsigned int save_map; + + save_map = save_eisa_map(); + waddr = PCIMT_EISA_BASE | (from & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~from + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + eisa_map(from); + memcpy((void *)to, (void *)waddr, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + restore_eisa_map(save_map); +} + +static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len) +{ + unsigned long waddr; + unsigned int save_map; + + save_map = save_eisa_map(); + waddr = PCIMT_EISA_BASE | (to & 0xffffff); + while(len) { + unsigned long fraglen; + + fraglen = (~to + 1) & 0xffffff; + fraglen = (fraglen < len) ? fraglen : len; + eisa_map(to); + memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen); + to += fraglen; + from += fraglen; + waddr = waddr + fraglen - 0x1000000; + len -= fraglen; + } + restore_eisa_map(save_map); +} diff --git a/release/src/linux/linux/arch/mips/sni/irq.c b/release/src/linux/linux/arch/mips/sni/irq.c new file mode 100644 index 00000000..d458a1d7 --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/irq.c @@ -0,0 +1,158 @@ +/* + * 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) 1992 Linus Torvalds + * Copyright (C) 1994 - 2000 Ralf Baechle + */ +#include <linux/delay.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/kernel.h> +#include <linux/spinlock.h> + +#include <asm/io.h> +#include <asm/sni.h> + +spinlock_t pciasic_lock = SPIN_LOCK_UNLOCKED; + +extern asmlinkage void sni_rm200_pci_handle_int(void); +extern void do_IRQ(int irq, struct pt_regs *regs); + +static void enable_pciasic_irq(unsigned int irq); + +static unsigned int startup_pciasic_irq(unsigned int irq) +{ + enable_pciasic_irq(irq); + return 0; /* never anything pending */ +} + +#define shutdown_pciasic_irq disable_pciasic_irq + +void disable_pciasic_irq(unsigned int irq) +{ + unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); + unsigned long flags; + + spin_lock_irqsave(&pciasic_lock, flags); + *(volatile u8 *) PCIMT_IRQSEL &= mask; + spin_unlock_irqrestore(&pciasic_lock, flags); +} + +static void enable_pciasic_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); + unsigned long flags; + + spin_lock_irqsave(&pciasic_lock, flags); + *(volatile u8 *) PCIMT_IRQSEL |= mask; + spin_unlock_irqrestore(&pciasic_lock, flags); +} + +#define mask_and_ack_pciasic_irq disable_pciasic_irq + +static void end_pciasic_irq(unsigned int irq) +{ + if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + enable_pciasic_irq(irq); +} + +static struct hw_interrupt_type pciasic_irq_type = { + "PCIASIC", + startup_pciasic_irq, + shutdown_pciasic_irq, + enable_pciasic_irq, + disable_pciasic_irq, + mask_and_ack_pciasic_irq, + end_pciasic_irq, + NULL +}; + +/* + * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug + * button interrupts. Later ... + */ +void pciasic_hwint0(struct pt_regs *regs) +{ + panic("Received int0 but no handler yet ..."); +} + +/* This interrupt was used for the com1 console on the first prototypes. */ +void pciasic_hwint2(struct pt_regs *regs) +{ + /* I think this shouldn't happen on production machines. */ + panic("hwint2 and no handler yet"); +} + +/* hwint5 is the r4k count / compare interrupt */ +void pciasic_hwint5(struct pt_regs *regs) +{ + panic("hwint5 and no handler yet"); +} + +static inline int ls1bit8(unsigned int x) +{ + int b = 8, s; + + x <<= 24; + s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s; + s = 2; if ((x & 0x03) == 0) s = 0; b -= s; x <<= s; + s = 1; if ((x & 0x01) == 0) s = 0; b -= s; + + return b; +} + +/* + * hwint 1 deals with EISA and SCSI interrupts, + * hwint 3 should deal with the PCI A - D interrupts, + * hwint 4 is used for only the onboard PCnet 32. + */ +void pciasic_hwint134(struct pt_regs *regs) +{ + u8 pend = *(volatile char *)PCIMT_CSITPEND; + int irq; + + irq = PCIMT_IRQ_INT2 + ls1bit8(pend); + if (irq == PCIMT_IRQ_EISA) { + pend = *(volatile char *)PCIMT_INT_ACKNOWLEDGE; + if (!(pend ^ 0xff)) + return; + } + do_IRQ(irq, regs); + return; +} + +void __init init_pciasic(void) +{ + unsigned long flags; + + spin_lock_irqsave(&pciasic_lock, flags); + * (volatile u8 *) PCIMT_IRQSEL = + IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD; + spin_unlock_irqrestore(&pciasic_lock, flags); +} + +/* + * On systems with i8259-style interrupt controllers we assume for + * driver compatibility reasons interrupts 0 - 15 to be the i8295 + * interrupts even if the hardware uses a different interrupt numbering. + */ +void __init init_IRQ (void) +{ + int i; + + set_except_vector(0, sni_rm200_pci_handle_int); + + init_generic_irq(); + init_i8259_irqs(); /* Integrated i8259 */ + init_pciasic(); + + /* Actually we've got more interrupts to handle ... */ + for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) { + irq_desc[i].status = IRQ_DISABLED; + irq_desc[i].action = 0; + irq_desc[i].depth = 1; + irq_desc[i].handler = &pciasic_irq_type; + } +} diff --git a/release/src/linux/linux/arch/mips/sni/pci.c b/release/src/linux/linux/arch/mips/sni/pci.c new file mode 100644 index 00000000..8016ffe9 --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/pci.c @@ -0,0 +1,187 @@ +/* + * 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. + * + * SNI specific PCI support for RM200/RM300. + * + * Copyright (C) 1997 - 2000 Ralf Baechle + */ +#include <linux/config.h> +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/pci.h> +#include <linux/types.h> +#include <asm/byteorder.h> +#include <asm/sni.h> + +#ifdef CONFIG_PCI + +#define mkaddr(dev, where) \ +do { \ + if ((dev)->bus->number == 0) \ + return -1; \ + *(volatile u32 *)PCIMT_CONFIG_ADDRESS = \ + ((dev->bus->number & 0xff) << 0x10) | \ + ((dev->devfn & 0xff) << 0x08) | \ + (where & 0xfc); \ +} while(0) + + +/* + * We can't address 8 and 16 bit words directly. Instead we have to + * read/write a 32bit word and mask/modify the data we actually want. + */ +static int pcimt_read_config_byte (struct pci_dev *dev, + int where, unsigned char *val) +{ + u32 res; + + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_word (struct pci_dev *dev, + int where, unsigned short *val) +{ + u32 res; + + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = (le32_to_cpu(res) >> ((where & 3) << 3)) & 0xffff; + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_read_config_dword (struct pci_dev *dev, + int where, unsigned int *val) +{ + u32 res; + + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + res = *(volatile u32 *)PCIMT_CONFIG_DATA; + res = le32_to_cpu(res); + *val = res; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_byte (struct pci_dev *dev, + int where, unsigned char val) +{ + mkaddr(dev, where); + *(volatile u8 *)(PCIMT_CONFIG_DATA + (where & 3)) = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_word (struct pci_dev *dev, + int where, unsigned short val) +{ + if (where & 1) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u16 *)(PCIMT_CONFIG_DATA + (where & 3)) = le16_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +static int pcimt_write_config_dword (struct pci_dev *dev, + int where, unsigned int val) +{ + if (where & 3) + return PCIBIOS_BAD_REGISTER_NUMBER; + mkaddr(dev, where); + *(volatile u32 *)PCIMT_CONFIG_DATA = le32_to_cpu(val); + + return PCIBIOS_SUCCESSFUL; +} + +struct pci_ops sni_pci_ops = { + pcimt_read_config_byte, + pcimt_read_config_word, + pcimt_read_config_dword, + pcimt_write_config_byte, + pcimt_write_config_word, + pcimt_write_config_dword +}; + +void __init +pcibios_fixup_bus(struct pci_bus *b) +{ +} + +void +pcibios_update_resource(struct pci_dev *dev, struct resource *root, + struct resource *res, int resource) +{ + u32 new, check; + int reg; + + new = res->start | (res->flags & PCI_REGION_FLAG_MASK); + if (resource < 6) { + reg = PCI_BASE_ADDRESS_0 + 4*resource; + } else if (resource == PCI_ROM_RESOURCE) { + res->flags |= PCI_ROM_ADDRESS_ENABLE; + new |= PCI_ROM_ADDRESS_ENABLE; + reg = dev->rom_base_reg; + } else { + /* Somebody might have asked allocation of a non-standard resource */ + return; + } + + pci_write_config_dword(dev, reg, new); + pci_read_config_dword(dev, reg, &check); + if ((new ^ check) & ((new & PCI_BASE_ADDRESS_SPACE_IO) ? PCI_BASE_ADDRESS_IO_MASK : PCI_BASE_ADDRESS_MEM_MASK)) { + printk(KERN_ERR "PCI: Error while updating region " + "%s/%d (%08x != %08x)\n", dev->slot_name, resource, + new, check); + } +} + +void __init pcibios_init(void) +{ + struct pci_ops *ops = &sni_pci_ops; + + pci_scan_bus(0, ops, NULL); +} + +int __init pcibios_enable_device(struct pci_dev *dev, int mask) +{ + /* Not needed, since we enable all devices at startup. */ + return 0; +} + +void __init +pcibios_align_resource(void *data, struct resource *res, unsigned long size, + unsigned long align) +{ +} + +unsigned __init int pcibios_assign_all_busses(void) +{ + return 0; +} + +char * __init +pcibios_setup(char *str) +{ + /* Nothing to do for now. */ + + return str; +} + +struct pci_fixup pcibios_fixups[] = { + { 0 } +}; + +#endif /* CONFIG_PCI */ diff --git a/release/src/linux/linux/arch/mips/sni/pcimt_scache.c b/release/src/linux/linux/arch/mips/sni/pcimt_scache.c new file mode 100644 index 00000000..a59d457f --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/pcimt_scache.c @@ -0,0 +1,37 @@ +/* + * arch/mips/sni/pcimt_scache.c + * + * 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) 1997, 1998 by Ralf Baechle + */ +#include <linux/init.h> +#include <linux/kernel.h> +#include <asm/bcache.h> +#include <asm/sni.h> + +#define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF) +#define invspace (*(volatile unsigned int *)PCIMT_INVSPACE) + +void __init sni_pcimt_sc_init(void) +{ + unsigned int scsiz, sc_size; + + scsiz = cacheconf & 7; + if (scsiz == 0) { + printk("Second level cache is deactived.\n"); + return; + } + if (scsiz >= 6) { + printk("Invalid second level cache size configured, " + "deactivating second level cache.\n"); + cacheconf = 0; + return; + } + + sc_size = 128 << scsiz; + printk("%dkb second level cache detected, deactivating.\n", sc_size); + cacheconf = 0; +} diff --git a/release/src/linux/linux/arch/mips/sni/reset.c b/release/src/linux/linux/arch/mips/sni/reset.c new file mode 100644 index 00000000..753cfdbb --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/reset.c @@ -0,0 +1,50 @@ +/* + * linux/arch/mips/sni/process.c + * + * Reset a SNI machine. + */ +#include <asm/io.h> +#include <asm/reboot.h> +#include <asm/system.h> +#include <asm/sni.h> + +/* + * This routine reboots the machine by asking the keyboard + * controller to pulse the reset-line low. We try that for a while, + * and if it doesn't work, we do some other stupid things. + */ +static inline void +kb_wait(void) +{ + int i; + + for (i=0; i<0x10000; i++) + if ((inb_p(0x64) & 0x02) == 0) + break; +} + +void sni_machine_restart(char *command) +{ + int i, j; + + /* This does a normal via the keyboard controller like a PC. + We can do that easier ... */ + sti(); + for (;;) { + for (i=0; i<100; i++) { + kb_wait(); + for(j = 0; j < 100000 ; j++) + /* nothing */; + outb_p(0xfe,0x64); /* pulse reset low */ + } + } +} + +void sni_machine_halt(void) +{ +} + +void sni_machine_power_off(void) +{ + *(volatile unsigned char *)PCIMT_CSWCSM = 0xfd; +} diff --git a/release/src/linux/linux/arch/mips/sni/setup.c b/release/src/linux/linux/arch/mips/sni/setup.c new file mode 100644 index 00000000..2bd841cb --- /dev/null +++ b/release/src/linux/linux/arch/mips/sni/setup.c @@ -0,0 +1,136 @@ +/* + * Setup pointers to hardware-dependent routines. + * + * 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) 1996, 1997, 1998, 2000 by Ralf Baechle + */ +#include <asm/ptrace.h> +#include <linux/config.h> +#include <linux/hdreg.h> +#include <linux/ioport.h> +#include <linux/sched.h> +#include <linux/init.h> +#include <linux/interrupt.h> +#include <linux/timex.h> +#include <linux/pci.h> +#include <linux/mc146818rtc.h> +#include <linux/console.h> +#include <linux/fb.h> +#include <linux/pc_keyb.h> +#include <linux/ide.h> + +#include <asm/bcache.h> +#include <asm/bootinfo.h> +#include <asm/keyboard.h> +#include <asm/io.h> +#include <asm/irq.h> +#include <asm/processor.h> +#include <asm/reboot.h> +#include <asm/sni.h> +#include <asm/time.h> +#include <asm/traps.h> + +extern void sni_machine_restart(char *command); +extern void sni_machine_halt(void); +extern void sni_machine_power_off(void); + +extern struct ide_ops std_ide_ops; +extern struct rtc_ops std_rtc_ops; +extern struct kbd_ops std_kbd_ops; + +static void __init sni_rm200_pci_time_init(struct irqaction *irq) +{ + /* set the clock to 100 Hz */ + outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ + outb_p(LATCH & 0xff , 0x40); /* LSB */ + outb(LATCH >> 8 , 0x40); /* MSB */ + setup_irq(0, irq); +} + + +void __init bus_error_init(void) { /* nothing */ } + + +extern unsigned char sni_map_isa_cache; + +/* + * A bit more gossip about the iron we're running on ... + */ +static inline void sni_pcimt_detect(void) +{ + char boardtype[80]; + unsigned char csmsr; + char *p = boardtype; + unsigned int asic; + + csmsr = *(volatile unsigned char *)PCIMT_CSMSR; + + p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300"); + if ((csmsr & 0x80) == 0) + p += sprintf(p, ", board revision %s", + (csmsr & 0x20) ? "D" : "C"); + asic = csmsr & 0x80; + asic = (csmsr & 0x08) ? asic : !asic; + p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1"); + printk("%s.\n", boardtype); +} + +void __init sni_rm200_pci_setup(void) +{ + sni_pcimt_detect(); + sni_pcimt_sc_init(); + + set_io_port_base(SNI_PORT_BASE); + + /* + * Setup (E)ISA I/O memory access stuff + */ + isa_slot_offset = 0xb0000000; + // sni_map_isa_cache = 0; + EISA_bus = 1; + + request_region(0x00,0x20,"dma1"); + request_region(0x40,0x20,"timer"); + request_region(0x70,0x10,"rtc"); + request_region(0x80,0x10,"dma page reg"); + request_region(0xc0,0x20,"dma2"); + board_time_init = sni_rm200_pci_time_init; + + _machine_restart = sni_machine_restart; + _machine_halt = sni_machine_halt; + _machine_power_off = sni_machine_power_off; + + aux_device_present = 0xaa; + + /* + * Some cluefull person has placed the PCI config data directly in + * the I/O port space ... + */ + request_region(0xcfc,0x04,"PCI config data"); + +#ifdef CONFIG_BLK_DEV_IDE + ide_ops = &std_ide_ops; +#endif + conswitchp = &vga_con; + + screen_info = (struct screen_info) { + 0, 0, /* orig-x, orig-y */ + 0, /* unused */ + 52, /* orig_video_page */ + 3, /* orig_video_mode */ + 80, /* orig_video_cols */ + 4626, 3, 9, /* unused, ega_bx, unused */ + 50, /* orig_video_lines */ + 0x22, /* orig_video_isVGA */ + 16 /* orig_video_points */ + }; + + rtc_ops = &std_rtc_ops; + kbd_ops = &std_kbd_ops; +#ifdef CONFIG_PSMOUSE + aux_device_present = 0xaa; +#endif +} |