diff options
| -rw-r--r-- | arch/mips/Kconfig | 5 | ||||
| -rw-r--r-- | arch/mips/pci/fixup-sni.c | 66 | ||||
| -rw-r--r-- | arch/mips/pci/ops-sni.c | 77 | ||||
| -rw-r--r-- | arch/mips/sni/Makefile | 2 | ||||
| -rw-r--r-- | arch/mips/sni/a20r.c | 227 | ||||
| -rw-r--r-- | arch/mips/sni/ds1216.c | 81 | ||||
| -rw-r--r-- | arch/mips/sni/irq.c | 188 | ||||
| -rw-r--r-- | arch/mips/sni/pcimt.c | 390 | ||||
| -rw-r--r-- | arch/mips/sni/pcit.c | 351 | ||||
| -rw-r--r-- | arch/mips/sni/reset.c | 9 | ||||
| -rw-r--r-- | arch/mips/sni/rm200.c | 186 | ||||
| -rw-r--r-- | arch/mips/sni/setup.c | 242 | ||||
| -rw-r--r-- | arch/mips/sni/sniprom.c | 129 | ||||
| -rw-r--r-- | arch/mips/sni/time.c | 148 | ||||
| -rw-r--r-- | include/asm-mips/ds1216.h | 31 | ||||
| -rw-r--r-- | include/asm-mips/mach-rm/cpu-feature-overrides.h | 5 | ||||
| -rw-r--r-- | include/asm-mips/sni.h | 132 |
17 files changed, 1874 insertions, 395 deletions
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index a92ce6bd7cf1..46fa5ca9f5ac 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
| @@ -726,15 +726,16 @@ config SNI_RM | |||
| 726 | select BOOT_ELF32 | 726 | select BOOT_ELF32 |
| 727 | select DMA_NONCOHERENT | 727 | select DMA_NONCOHERENT |
| 728 | select GENERIC_ISA_DMA | 728 | select GENERIC_ISA_DMA |
| 729 | select HAVE_STD_PC_SERIAL_PORT | ||
| 730 | select HW_HAS_EISA | 729 | select HW_HAS_EISA |
| 731 | select HW_HAS_PCI | 730 | select HW_HAS_PCI |
| 731 | select IRQ_CPU | ||
| 732 | select I8253 | 732 | select I8253 |
| 733 | select I8259 | 733 | select I8259 |
| 734 | select ISA | 734 | select ISA |
| 735 | select SWAP_IO_SPACE if CPU_BIG_ENDIAN | 735 | select SWAP_IO_SPACE if CPU_BIG_ENDIAN |
| 736 | select SYS_HAS_CPU_R4X00 | 736 | select SYS_HAS_CPU_R4X00 |
| 737 | select SYS_HAS_CPU_R5000 | 737 | select SYS_HAS_CPU_R5000 |
| 738 | select SYS_HAS_CPU_R10000 | ||
| 738 | select R5000_CPU_SCACHE | 739 | select R5000_CPU_SCACHE |
| 739 | select SYS_SUPPORTS_32BIT_KERNEL | 740 | select SYS_SUPPORTS_32BIT_KERNEL |
| 740 | select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL | 741 | select SYS_SUPPORTS_64BIT_KERNEL if EXPERIMENTAL |
| @@ -1066,7 +1067,7 @@ config BOOT_ELF32 | |||
| 1066 | 1067 | ||
| 1067 | config MIPS_L1_CACHE_SHIFT | 1068 | config MIPS_L1_CACHE_SHIFT |
| 1068 | int | 1069 | int |
| 1069 | default "4" if MACH_DECSTATION | 1070 | default "4" if MACH_DECSTATION || SNI_RM |
| 1070 | default "7" if SGI_IP27 | 1071 | default "7" if SGI_IP27 |
| 1071 | default "5" | 1072 | default "5" |
| 1072 | 1073 | ||
diff --git a/arch/mips/pci/fixup-sni.c b/arch/mips/pci/fixup-sni.c index a176f2ca8656..0c9a4732d455 100644 --- a/arch/mips/pci/fixup-sni.c +++ b/arch/mips/pci/fixup-sni.c | |||
| @@ -15,7 +15,7 @@ | |||
| 15 | #include <asm/sni.h> | 15 | #include <asm/sni.h> |
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | * Shortcuts ... | 18 | * PCIMT Shortcuts ... |
| 19 | */ | 19 | */ |
| 20 | #define SCSI PCIMT_IRQ_SCSI | 20 | #define SCSI PCIMT_IRQ_SCSI |
| 21 | #define ETH PCIMT_IRQ_ETHERNET | 21 | #define ETH PCIMT_IRQ_ETHERNET |
| @@ -67,6 +67,50 @@ static char irq_tab_rm300d[8][5] __initdata = { | |||
| 67 | { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ | 67 | { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ |
| 68 | }; | 68 | }; |
| 69 | 69 | ||
| 70 | static char irq_tab_rm300e[5][5] __initdata = { | ||
| 71 | /* INTA INTB INTC INTD */ | ||
| 72 | { 0, 0, 0, 0, 0 }, /* HOST bridge */ | ||
| 73 | { SCSI, SCSI, SCSI, SCSI, SCSI }, /* SCSI */ | ||
| 74 | { 0, INTC, INTD, INTA, INTB }, /* Bridge/i960 */ | ||
| 75 | { 0, INTD, INTA, INTB, INTC }, /* Slot 1 */ | ||
| 76 | { 0, INTA, INTB, INTC, INTD }, /* Slot 2 */ | ||
| 77 | }; | ||
| 78 | #undef SCSI | ||
| 79 | #undef ETH | ||
| 80 | #undef INTA | ||
| 81 | #undef INTB | ||
| 82 | #undef INTC | ||
| 83 | #undef INTD | ||
| 84 | |||
| 85 | |||
| 86 | /* | ||
| 87 | * PCIT Shortcuts ... | ||
| 88 | */ | ||
| 89 | #define SCSI0 PCIT_IRQ_SCSI0 | ||
| 90 | #define SCSI1 PCIT_IRQ_SCSI1 | ||
| 91 | #define ETH PCIT_IRQ_ETHERNET | ||
| 92 | #define INTA PCIT_IRQ_INTA | ||
| 93 | #define INTB PCIT_IRQ_INTB | ||
| 94 | #define INTC PCIT_IRQ_INTC | ||
| 95 | #define INTD PCIT_IRQ_INTD | ||
| 96 | |||
| 97 | static char irq_tab_pcit[13][5] __initdata = { | ||
| 98 | /* INTA INTB INTC INTD */ | ||
| 99 | { 0, 0, 0, 0, 0 }, /* HOST bridge */ | ||
| 100 | { SCSI0, SCSI0, SCSI0, SCSI0, SCSI0 }, /* SCSI */ | ||
| 101 | { SCSI1, SCSI1, SCSI1, SCSI1, SCSI1 }, /* SCSI */ | ||
| 102 | { ETH, ETH, ETH, ETH, ETH }, /* Ethernet */ | ||
| 103 | { 0, INTA, INTB, INTC, INTD }, /* PCI-PCI bridge */ | ||
| 104 | { 0, 0, 0, 0, 0 }, /* Unused */ | ||
| 105 | { 0, 0, 0, 0, 0 }, /* Unused */ | ||
| 106 | { 0, 0, 0, 0, 0 }, /* Unused */ | ||
| 107 | { 0, INTA, INTB, INTC, INTD }, /* Slot 1 */ | ||
| 108 | { 0, INTB, INTC, INTD, INTA }, /* Slot 2 */ | ||
| 109 | { 0, INTC, INTD, INTA, INTB }, /* Slot 3 */ | ||
| 110 | { 0, INTD, INTA, INTB, INTC }, /* Slot 4 */ | ||
| 111 | { 0, INTA, INTB, INTC, INTD }, /* Slot 5 */ | ||
| 112 | }; | ||
| 113 | |||
| 70 | static inline int is_rm300_revd(void) | 114 | static inline int is_rm300_revd(void) |
| 71 | { | 115 | { |
| 72 | unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR; | 116 | unsigned char csmsr = *(volatile unsigned char *)PCIMT_CSMSR; |
| @@ -76,10 +120,24 @@ static inline int is_rm300_revd(void) | |||
| 76 | 120 | ||
| 77 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) | 121 | int __init pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) |
| 78 | { | 122 | { |
| 79 | if (is_rm300_revd()) | 123 | switch (sni_brd_type) { |
| 80 | return irq_tab_rm300d[slot][pin]; | 124 | case SNI_BRD_PCI_TOWER: |
| 125 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 126 | return irq_tab_pcit[slot][pin]; | ||
| 127 | |||
| 128 | case SNI_BRD_PCI_MTOWER: | ||
| 129 | if (is_rm300_revd()) | ||
| 130 | return irq_tab_rm300d[slot][pin]; | ||
| 131 | /* fall through */ | ||
| 81 | 132 | ||
| 82 | return irq_tab_rm200[slot][pin]; | 133 | case SNI_BRD_PCI_DESKTOP: |
| 134 | return irq_tab_rm200[slot][pin]; | ||
| 135 | |||
| 136 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 137 | return irq_tab_rm300e[slot][pin]; | ||
| 138 | } | ||
| 139 | |||
| 140 | return 0; | ||
| 83 | } | 141 | } |
| 84 | 142 | ||
| 85 | /* Do platform specific device initialization at pci_enable_device() time */ | 143 | /* Do platform specific device initialization at pci_enable_device() time */ |
diff --git a/arch/mips/pci/ops-sni.c b/arch/mips/pci/ops-sni.c index 2b0ccd6d9dcd..fa2d2c60f797 100644 --- a/arch/mips/pci/ops-sni.c +++ b/arch/mips/pci/ops-sni.c | |||
| @@ -83,7 +83,82 @@ static int pcimt_write(struct pci_bus *bus, unsigned int devfn, int reg, | |||
| 83 | return 0; | 83 | return 0; |
| 84 | } | 84 | } |
| 85 | 85 | ||
| 86 | struct pci_ops sni_pci_ops = { | 86 | struct pci_ops sni_pcimt_ops = { |
| 87 | .read = pcimt_read, | 87 | .read = pcimt_read, |
| 88 | .write = pcimt_write, | 88 | .write = pcimt_write, |
| 89 | }; | 89 | }; |
| 90 | |||
| 91 | static int pcit_set_config_address(unsigned int busno, unsigned int devfn, int reg) | ||
| 92 | { | ||
| 93 | if ((devfn > 255) || (reg > 255) || (busno > 255)) | ||
| 94 | return PCIBIOS_BAD_REGISTER_NUMBER; | ||
| 95 | |||
| 96 | outl ((1 << 31) | ((busno & 0xff) << 16) | ((devfn & 0xff) << 8) | (reg & 0xfc), 0xcf8); | ||
| 97 | return PCIBIOS_SUCCESSFUL; | ||
| 98 | } | ||
| 99 | |||
| 100 | static int pcit_read(struct pci_bus *bus, unsigned int devfn, int reg, | ||
| 101 | int size, u32 * val) | ||
| 102 | { | ||
| 103 | int res; | ||
| 104 | |||
| 105 | /* | ||
| 106 | * on bus 0 we need to check, whether there is a device answering | ||
| 107 | * for the devfn by doing a config write and checking the result. If | ||
| 108 | * we don't do it, we will get a data bus error | ||
| 109 | */ | ||
| 110 | if (bus->number == 0) { | ||
| 111 | pcit_set_config_address (0, 0, 0x68); | ||
| 112 | outl (inl (0xcfc) | 0xc0000000, 0xcfc); | ||
| 113 | if ((res = pcit_set_config_address(0, devfn, 0))) | ||
| 114 | return res; | ||
| 115 | outl (0xffffffff, 0xcfc); | ||
| 116 | pcit_set_config_address (0, 0, 0x68); | ||
| 117 | if (inl(0xcfc) & 0x100000) | ||
| 118 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 119 | } | ||
| 120 | if ((res = pcit_set_config_address(bus->number, devfn, reg))) | ||
| 121 | return res; | ||
| 122 | |||
| 123 | switch (size) { | ||
| 124 | case 1: | ||
| 125 | *val = inb(PCIMT_CONFIG_DATA + (reg & 3)); | ||
| 126 | break; | ||
| 127 | case 2: | ||
| 128 | *val = inw(PCIMT_CONFIG_DATA + (reg & 2)); | ||
| 129 | break; | ||
| 130 | case 4: | ||
| 131 | *val = inl(PCIMT_CONFIG_DATA); | ||
| 132 | break; | ||
| 133 | } | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | |||
| 137 | static int pcit_write(struct pci_bus *bus, unsigned int devfn, int reg, | ||
| 138 | int size, u32 val) | ||
| 139 | { | ||
| 140 | int res; | ||
| 141 | |||
| 142 | if ((res = pcit_set_config_address(bus->number, devfn, reg))) | ||
| 143 | return res; | ||
| 144 | |||
| 145 | switch (size) { | ||
| 146 | case 1: | ||
| 147 | outb (val, PCIMT_CONFIG_DATA + (reg & 3)); | ||
| 148 | break; | ||
| 149 | case 2: | ||
| 150 | outw (val, PCIMT_CONFIG_DATA + (reg & 2)); | ||
| 151 | break; | ||
| 152 | case 4: | ||
| 153 | outl (val, PCIMT_CONFIG_DATA); | ||
| 154 | break; | ||
| 155 | } | ||
| 156 | |||
| 157 | return 0; | ||
| 158 | } | ||
| 159 | |||
| 160 | |||
| 161 | struct pci_ops sni_pcit_ops = { | ||
| 162 | .read = pcit_read, | ||
| 163 | .write = pcit_write, | ||
| 164 | }; | ||
diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index a5eb0adb87c7..e30809a92151 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile | |||
| @@ -2,7 +2,7 @@ | |||
| 2 | # Makefile for the SNI specific part of the kernel | 2 | # Makefile for the SNI specific part of the kernel |
| 3 | # | 3 | # |
| 4 | 4 | ||
| 5 | obj-y += irq.o pcimt_scache.o reset.o setup.o | 5 | obj-y += irq.o reset.o setup.o ds1216.o a20r.o rm200.o pcimt.o pcit.o time.o |
| 6 | obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o | 6 | obj-$(CONFIG_CPU_BIG_ENDIAN) += sniprom.o |
| 7 | 7 | ||
| 8 | EXTRA_AFLAGS := $(CFLAGS) | 8 | EXTRA_AFLAGS := $(CFLAGS) |
diff --git a/arch/mips/sni/a20r.c b/arch/mips/sni/a20r.c new file mode 100644 index 000000000000..31ab80f1befa --- /dev/null +++ b/arch/mips/sni/a20r.c | |||
| @@ -0,0 +1,227 @@ | |||
| 1 | /* | ||
| 2 | * A20R specific code | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/serial_8250.h> | ||
| 15 | |||
| 16 | #include <asm/sni.h> | ||
| 17 | #include <asm/time.h> | ||
| 18 | #include <asm/ds1216.h> | ||
| 19 | |||
| 20 | #define PORT(_base,_irq) \ | ||
| 21 | { \ | ||
| 22 | .iobase = _base, \ | ||
| 23 | .irq = _irq, \ | ||
| 24 | .uartclk = 1843200, \ | ||
| 25 | .iotype = UPIO_PORT, \ | ||
| 26 | .flags = UPF_BOOT_AUTOCONF, \ | ||
| 27 | } | ||
| 28 | |||
| 29 | static struct plat_serial8250_port a20r_data[] = { | ||
| 30 | PORT(0x3f8, 4), | ||
| 31 | PORT(0x2f8, 3), | ||
| 32 | { }, | ||
| 33 | }; | ||
| 34 | |||
| 35 | static struct platform_device a20r_serial8250_device = { | ||
| 36 | .name = "serial8250", | ||
| 37 | .id = PLAT8250_DEV_PLATFORM, | ||
| 38 | .dev = { | ||
| 39 | .platform_data = a20r_data, | ||
| 40 | }, | ||
| 41 | }; | ||
| 42 | |||
| 43 | static struct resource snirm_82596_rsrc[] = { | ||
| 44 | { | ||
| 45 | .start = 0xb8000000, | ||
| 46 | .end = 0xb8000004, | ||
| 47 | .flags = IORESOURCE_MEM | ||
| 48 | }, | ||
| 49 | { | ||
| 50 | .start = 0xb8010000, | ||
| 51 | .end = 0xb8010004, | ||
| 52 | .flags = IORESOURCE_MEM | ||
| 53 | }, | ||
| 54 | { | ||
| 55 | .start = 0xbff00000, | ||
| 56 | .end = 0xbff00020, | ||
| 57 | .flags = IORESOURCE_MEM | ||
| 58 | }, | ||
| 59 | { | ||
| 60 | .start = 22, | ||
| 61 | .end = 22, | ||
| 62 | .flags = IORESOURCE_IRQ | ||
| 63 | }, | ||
| 64 | { | ||
| 65 | .flags = 0x01 /* 16bit mpu port access */ | ||
| 66 | } | ||
| 67 | }; | ||
| 68 | |||
| 69 | static struct platform_device snirm_82596_pdev = { | ||
| 70 | .name = "snirm_82596", | ||
| 71 | .num_resources = ARRAY_SIZE(snirm_82596_rsrc), | ||
| 72 | .resource = snirm_82596_rsrc | ||
| 73 | }; | ||
| 74 | |||
| 75 | static struct resource snirm_53c710_rsrc[] = { | ||
| 76 | { | ||
| 77 | .start = 0xb9000000, | ||
| 78 | .end = 0xb90fffff, | ||
| 79 | .flags = IORESOURCE_MEM | ||
| 80 | }, | ||
| 81 | { | ||
| 82 | .start = 19, | ||
| 83 | .end = 19, | ||
| 84 | .flags = IORESOURCE_IRQ | ||
| 85 | } | ||
| 86 | }; | ||
| 87 | |||
| 88 | static struct platform_device snirm_53c710_pdev = { | ||
| 89 | .name = "snirm_53c710", | ||
| 90 | .num_resources = ARRAY_SIZE(snirm_53c710_rsrc), | ||
| 91 | .resource = snirm_53c710_rsrc | ||
| 92 | }; | ||
| 93 | |||
| 94 | static struct resource sc26xx_rsrc[] = { | ||
| 95 | { | ||
| 96 | .start = 0xbc070000, | ||
| 97 | .end = 0xbc0700ff, | ||
| 98 | .flags = IORESOURCE_MEM | ||
| 99 | }, | ||
| 100 | { | ||
| 101 | .start = 20, | ||
| 102 | .end = 20, | ||
| 103 | .flags = IORESOURCE_IRQ | ||
| 104 | } | ||
| 105 | }; | ||
| 106 | |||
| 107 | static struct platform_device sc26xx_pdev = { | ||
| 108 | .name = "SC26xx", | ||
| 109 | .num_resources = ARRAY_SIZE(sc26xx_rsrc), | ||
| 110 | .resource = sc26xx_rsrc | ||
| 111 | }; | ||
| 112 | |||
| 113 | static u32 a20r_ack_hwint(void) | ||
| 114 | { | ||
| 115 | u32 status = read_c0_status(); | ||
| 116 | |||
| 117 | write_c0_status (status | 0x00010000); | ||
| 118 | asm volatile( | ||
| 119 | " .set push \n" | ||
| 120 | " .set noat \n" | ||
| 121 | " .set noreorder \n" | ||
| 122 | " lw $1, 0(%0) \n" | ||
| 123 | " sb $0, 0(%1) \n" | ||
| 124 | " sync \n" | ||
| 125 | " lb %1, 0(%1) \n" | ||
| 126 | " b 1f \n" | ||
| 127 | " ori %1, $1, 2 \n" | ||
| 128 | " .align 8 \n" | ||
| 129 | "1: \n" | ||
| 130 | " nop \n" | ||
| 131 | " sw %1, 0(%0) \n" | ||
| 132 | " sync \n" | ||
| 133 | " li %1, 0x20 \n" | ||
| 134 | "2: \n" | ||
| 135 | " nop \n" | ||
| 136 | " bnez %1,2b \n" | ||
| 137 | " addiu %1, -1 \n" | ||
| 138 | " sw $1, 0(%0) \n" | ||
| 139 | " sync \n" | ||
| 140 | ".set pop \n" | ||
| 141 | : | ||
| 142 | : "Jr" (PCIMT_UCONF), "Jr" (0xbc000000)); | ||
| 143 | write_c0_status(status); | ||
| 144 | |||
| 145 | return status; | ||
| 146 | } | ||
| 147 | |||
| 148 | static inline void unmask_a20r_irq(unsigned int irq) | ||
| 149 | { | ||
| 150 | set_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); | ||
| 151 | irq_enable_hazard(); | ||
| 152 | } | ||
| 153 | |||
| 154 | static inline void mask_a20r_irq(unsigned int irq) | ||
| 155 | { | ||
| 156 | clear_c0_status(0x100 << (irq - SNI_A20R_IRQ_BASE)); | ||
| 157 | irq_disable_hazard(); | ||
| 158 | } | ||
| 159 | |||
| 160 | static void end_a20r_irq(unsigned int irq) | ||
| 161 | { | ||
| 162 | if (!(irq_desc[irq].status & (IRQ_DISABLED | IRQ_INPROGRESS))) { | ||
| 163 | a20r_ack_hwint(); | ||
| 164 | unmask_a20r_irq(irq); | ||
| 165 | } | ||
| 166 | } | ||
| 167 | |||
| 168 | static struct irq_chip a20r_irq_type = { | ||
| 169 | .typename = "A20R", | ||
| 170 | .ack = mask_a20r_irq, | ||
| 171 | .mask = mask_a20r_irq, | ||
| 172 | .mask_ack = mask_a20r_irq, | ||
| 173 | .unmask = unmask_a20r_irq, | ||
| 174 | .end = end_a20r_irq, | ||
| 175 | }; | ||
| 176 | |||
| 177 | /* | ||
| 178 | * hwint 0 receive all interrupts | ||
| 179 | */ | ||
| 180 | static void a20r_hwint(void) | ||
| 181 | { | ||
| 182 | u32 cause, status; | ||
| 183 | int irq; | ||
| 184 | |||
| 185 | clear_c0_status (IE_IRQ0); | ||
| 186 | status = a20r_ack_hwint(); | ||
| 187 | cause = read_c0_cause(); | ||
| 188 | |||
| 189 | irq = ffs(((cause & status) >> 8) & 0xf8); | ||
| 190 | if (likely(irq > 0)) | ||
| 191 | do_IRQ(SNI_A20R_IRQ_BASE + irq - 1); | ||
| 192 | set_c0_status(IE_IRQ0); | ||
| 193 | } | ||
| 194 | |||
| 195 | void __init sni_a20r_irq_init(void) | ||
| 196 | { | ||
| 197 | int i; | ||
| 198 | |||
| 199 | for (i = SNI_A20R_IRQ_BASE + 2 ; i < SNI_A20R_IRQ_BASE + 8; i++) | ||
| 200 | set_irq_chip(i, &a20r_irq_type); | ||
| 201 | sni_hwint = a20r_hwint; | ||
| 202 | change_c0_status(ST0_IM, IE_IRQ0); | ||
| 203 | setup_irq (SNI_A20R_IRQ_BASE + 3, &sni_isa_irq); | ||
| 204 | } | ||
| 205 | |||
| 206 | void sni_a20r_init(void) | ||
| 207 | { | ||
| 208 | ds1216_base = (volatile unsigned char *) SNI_DS1216_A20R_BASE; | ||
| 209 | rtc_mips_get_time = ds1216_get_cmos_time; | ||
| 210 | } | ||
| 211 | |||
| 212 | static int __init snirm_a20r_setup_devinit(void) | ||
| 213 | { | ||
| 214 | switch (sni_brd_type) { | ||
| 215 | case SNI_BRD_TOWER_OASIC: | ||
| 216 | case SNI_BRD_MINITOWER: | ||
| 217 | platform_device_register(&snirm_82596_pdev); | ||
| 218 | platform_device_register(&snirm_53c710_pdev); | ||
| 219 | platform_device_register(&sc26xx_pdev); | ||
| 220 | platform_device_register(&a20r_serial8250_device); | ||
| 221 | break; | ||
| 222 | } | ||
| 223 | |||
| 224 | return 0; | ||
| 225 | } | ||
| 226 | |||
| 227 | device_initcall(snirm_a20r_setup_devinit); | ||
diff --git a/arch/mips/sni/ds1216.c b/arch/mips/sni/ds1216.c new file mode 100644 index 000000000000..1d92732c14f1 --- /dev/null +++ b/arch/mips/sni/ds1216.c | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | |||
| 2 | #include <linux/bcd.h> | ||
| 3 | #include <linux/time.h> | ||
| 4 | |||
| 5 | #include <asm/ds1216.h> | ||
| 6 | |||
| 7 | volatile unsigned char *ds1216_base; | ||
| 8 | |||
| 9 | /* | ||
| 10 | * Read the 64 bit we'd like to have - It a series | ||
| 11 | * of 64 bits showing up in the LSB of the base register. | ||
| 12 | * | ||
| 13 | */ | ||
| 14 | static unsigned char *ds1216_read(void) | ||
| 15 | { | ||
| 16 | static unsigned char rdbuf[8]; | ||
| 17 | unsigned char c; | ||
| 18 | int i, j; | ||
| 19 | |||
| 20 | for (i = 0; i < 8; i++) { | ||
| 21 | c = 0x0; | ||
| 22 | for (j = 0; j < 8; j++) { | ||
| 23 | c |= (*ds1216_base & 0x1) << j; | ||
| 24 | } | ||
| 25 | rdbuf[i] = c; | ||
| 26 | } | ||
| 27 | |||
| 28 | return rdbuf; | ||
| 29 | } | ||
| 30 | |||
| 31 | static void ds1216_switch_ds_to_clock(void) | ||
| 32 | { | ||
| 33 | unsigned char magic[] = { | ||
| 34 | 0xc5, 0x3a, 0xa3, 0x5c, 0xc5, 0x3a, 0xa3, 0x5c | ||
| 35 | }; | ||
| 36 | int i,j,c; | ||
| 37 | |||
| 38 | /* Reset magic pointer */ | ||
| 39 | c = *ds1216_base; | ||
| 40 | |||
| 41 | /* Write 64 bit magic to DS1216 */ | ||
| 42 | for (i = 0; i < 8; i++) { | ||
| 43 | c = magic[i]; | ||
| 44 | for (j = 0; j < 8; j++) { | ||
| 45 | *ds1216_base = c; | ||
| 46 | c = c >> 1; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | unsigned long ds1216_get_cmos_time(void) | ||
| 52 | { | ||
| 53 | unsigned char *rdbuf; | ||
| 54 | unsigned int year, month, date, hour, min, sec; | ||
| 55 | |||
| 56 | ds1216_switch_ds_to_clock(); | ||
| 57 | rdbuf = ds1216_read(); | ||
| 58 | |||
| 59 | sec = BCD2BIN(DS1216_SEC(rdbuf)); | ||
| 60 | min = BCD2BIN(DS1216_MIN(rdbuf)); | ||
| 61 | hour = BCD2BIN(DS1216_HOUR(rdbuf)); | ||
| 62 | date = BCD2BIN(DS1216_DATE(rdbuf)); | ||
| 63 | month = BCD2BIN(DS1216_MONTH(rdbuf)); | ||
| 64 | year = BCD2BIN(DS1216_YEAR(rdbuf)); | ||
| 65 | |||
| 66 | if (DS1216_1224(rdbuf) && DS1216_AMPM(rdbuf)) | ||
| 67 | hour+=12; | ||
| 68 | |||
| 69 | if (year < 70) | ||
| 70 | year += 2000; | ||
| 71 | else | ||
| 72 | year += 1900; | ||
| 73 | |||
| 74 | return mktime(year, month, date, hour, min, sec); | ||
| 75 | } | ||
| 76 | |||
| 77 | int ds1216_set_rtc_mmss(unsigned long nowtime) | ||
| 78 | { | ||
| 79 | printk("ds1216_set_rtc_mmss called but not implemented\n"); | ||
| 80 | return -1; | ||
| 81 | } | ||
diff --git a/arch/mips/sni/irq.c b/arch/mips/sni/irq.c index 039e8e540508..ad5fc471a004 100644 --- a/arch/mips/sni/irq.c +++ b/arch/mips/sni/irq.c | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | * | 5 | * |
| 6 | * Copyright (C) 1992 Linus Torvalds | 6 | * Copyright (C) 1992 Linus Torvalds |
| 7 | * Copyright (C) 1994 - 2000 Ralf Baechle | 7 | * Copyright (C) 1994 - 2000 Ralf Baechle |
| 8 | * Copyright (C) 2006 Thomas Bogendoerfer | ||
| 8 | */ | 9 | */ |
| 9 | #include <linux/delay.h> | 10 | #include <linux/delay.h> |
| 10 | #include <linux/init.h> | 11 | #include <linux/init.h> |
| @@ -15,152 +16,34 @@ | |||
| 15 | #include <asm/i8259.h> | 16 | #include <asm/i8259.h> |
| 16 | #include <asm/io.h> | 17 | #include <asm/io.h> |
| 17 | #include <asm/sni.h> | 18 | #include <asm/sni.h> |
| 19 | #include <asm/irq.h> | ||
| 20 | #include <asm/irq_cpu.h> | ||
| 18 | 21 | ||
| 19 | static void enable_pciasic_irq(unsigned int irq) | 22 | void (*sni_hwint)(void); |
| 20 | { | ||
| 21 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); | ||
| 22 | |||
| 23 | *(volatile u8 *) PCIMT_IRQSEL |= mask; | ||
| 24 | } | ||
| 25 | |||
| 26 | void disable_pciasic_irq(unsigned int irq) | ||
| 27 | { | ||
| 28 | unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); | ||
| 29 | |||
| 30 | *(volatile u8 *) PCIMT_IRQSEL &= mask; | ||
| 31 | } | ||
| 32 | 23 | ||
| 33 | static void end_pciasic_irq(unsigned int irq) | 24 | asmlinkage void plat_irq_dispatch(void) |
| 34 | { | ||
| 35 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 36 | enable_pciasic_irq(irq); | ||
| 37 | } | ||
| 38 | |||
| 39 | static struct irq_chip pciasic_irq_type = { | ||
| 40 | .name = "ASIC-PCI", | ||
| 41 | .ack = disable_pciasic_irq, | ||
| 42 | .mask = disable_pciasic_irq, | ||
| 43 | .mask_ack = disable_pciasic_irq, | ||
| 44 | .unmask = enable_pciasic_irq, | ||
| 45 | .end = end_pciasic_irq, | ||
| 46 | }; | ||
| 47 | |||
| 48 | /* | ||
| 49 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | ||
| 50 | * button interrupts. Later ... | ||
| 51 | */ | ||
| 52 | static void pciasic_hwint0(void) | ||
| 53 | { | ||
| 54 | panic("Received int0 but no handler yet ..."); | ||
| 55 | } | ||
| 56 | |||
| 57 | /* This interrupt was used for the com1 console on the first prototypes. */ | ||
| 58 | static void pciasic_hwint2(void) | ||
| 59 | { | ||
| 60 | /* I think this shouldn't happen on production machines. */ | ||
| 61 | panic("hwint2 and no handler yet"); | ||
| 62 | } | ||
| 63 | |||
| 64 | /* hwint5 is the r4k count / compare interrupt */ | ||
| 65 | static void pciasic_hwint5(void) | ||
| 66 | { | ||
| 67 | panic("hwint5 and no handler yet"); | ||
| 68 | } | ||
| 69 | |||
| 70 | static unsigned int ls1bit8(unsigned int x) | ||
| 71 | { | ||
| 72 | int b = 7, s; | ||
| 73 | |||
| 74 | s = 4; if ((x & 0x0f) == 0) s = 0; b -= s; x <<= s; | ||
| 75 | s = 2; if ((x & 0x30) == 0) s = 0; b -= s; x <<= s; | ||
| 76 | s = 1; if ((x & 0x40) == 0) s = 0; b -= s; | ||
| 77 | |||
| 78 | return b; | ||
| 79 | } | ||
| 80 | |||
| 81 | /* | ||
| 82 | * hwint 1 deals with EISA and SCSI interrupts, | ||
| 83 | * | ||
| 84 | * The EISA_INT bit in CSITPEND is high active, all others are low active. | ||
| 85 | */ | ||
| 86 | static void pciasic_hwint1(void) | ||
| 87 | { | 25 | { |
| 88 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | 26 | sni_hwint(); |
| 89 | unsigned long flags; | ||
| 90 | |||
| 91 | if (pend & IT_EISA) { | ||
| 92 | int irq; | ||
| 93 | /* | ||
| 94 | * Note: ASIC PCI's builtin interrupt achknowledge feature is | ||
| 95 | * broken. Using it may result in loss of some or all i8259 | ||
| 96 | * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ... | ||
| 97 | */ | ||
| 98 | irq = i8259_irq(); | ||
| 99 | if (unlikely(irq < 0)) | ||
| 100 | return; | ||
| 101 | |||
| 102 | do_IRQ(irq); | ||
| 103 | } | ||
| 104 | |||
| 105 | if (!(pend & IT_SCSI)) { | ||
| 106 | flags = read_c0_status(); | ||
| 107 | clear_c0_status(ST0_IM); | ||
| 108 | do_IRQ(PCIMT_IRQ_SCSI); | ||
| 109 | write_c0_status(flags); | ||
| 110 | } | ||
| 111 | } | 27 | } |
| 112 | 28 | ||
| 113 | /* | 29 | /* ISA irq handler */ |
| 114 | * hwint 3 should deal with the PCI A - D interrupts, | 30 | static irqreturn_t sni_isa_irq_handler(int dummy, void *p) |
| 115 | */ | ||
| 116 | static void pciasic_hwint3(void) | ||
| 117 | { | 31 | { |
| 118 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | ||
| 119 | int irq; | 32 | int irq; |
| 120 | 33 | ||
| 121 | pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); | 34 | irq = i8259_irq(); |
| 122 | clear_c0_status(IE_IRQ3); | 35 | if (unlikely(irq < 0)) |
| 123 | irq = PCIMT_IRQ_INT2 + ls1bit8(pend); | 36 | return IRQ_NONE; |
| 124 | do_IRQ(irq); | ||
| 125 | set_c0_status(IE_IRQ3); | ||
| 126 | } | ||
| 127 | 37 | ||
| 128 | /* | 38 | do_IRQ(irq); |
| 129 | * hwint 4 is used for only the onboard PCnet 32. | 39 | return IRQ_HANDLED; |
| 130 | */ | ||
| 131 | static void pciasic_hwint4(void) | ||
| 132 | { | ||
| 133 | clear_c0_status(IE_IRQ4); | ||
| 134 | do_IRQ(PCIMT_IRQ_ETHERNET); | ||
| 135 | set_c0_status(IE_IRQ4); | ||
| 136 | } | ||
| 137 | |||
| 138 | asmlinkage void plat_irq_dispatch(void) | ||
| 139 | { | ||
| 140 | unsigned int pending = read_c0_status() & read_c0_cause(); | ||
| 141 | static unsigned char led_cache; | ||
| 142 | |||
| 143 | *(volatile unsigned char *) PCIMT_CSLED = ++led_cache; | ||
| 144 | |||
| 145 | if (pending & 0x0800) | ||
| 146 | pciasic_hwint1(); | ||
| 147 | else if (pending & 0x4000) | ||
| 148 | pciasic_hwint4(); | ||
| 149 | else if (pending & 0x2000) | ||
| 150 | pciasic_hwint3(); | ||
| 151 | else if (pending & 0x1000) | ||
| 152 | pciasic_hwint2(); | ||
| 153 | else if (pending & 0x8000) | ||
| 154 | pciasic_hwint5(); | ||
| 155 | else if (pending & 0x0400) | ||
| 156 | pciasic_hwint0(); | ||
| 157 | } | 40 | } |
| 158 | 41 | ||
| 159 | void __init init_pciasic(void) | 42 | struct irqaction sni_isa_irq = { |
| 160 | { | 43 | .handler = sni_isa_irq_handler, |
| 161 | * (volatile u8 *) PCIMT_IRQSEL = | 44 | .name = "ISA", |
| 162 | IT_EISA | IT_INTA | IT_INTB | IT_INTC | IT_INTD; | 45 | .flags = SA_SHIRQ |
| 163 | } | 46 | }; |
| 164 | 47 | ||
| 165 | /* | 48 | /* |
| 166 | * On systems with i8259-style interrupt controllers we assume for | 49 | * On systems with i8259-style interrupt controllers we assume for |
| @@ -169,14 +52,31 @@ void __init init_pciasic(void) | |||
| 169 | */ | 52 | */ |
| 170 | void __init arch_init_irq(void) | 53 | void __init arch_init_irq(void) |
| 171 | { | 54 | { |
| 172 | int i; | ||
| 173 | |||
| 174 | init_i8259_irqs(); /* Integrated i8259 */ | 55 | init_i8259_irqs(); /* Integrated i8259 */ |
| 175 | init_pciasic(); | 56 | switch (sni_brd_type) { |
| 176 | 57 | case SNI_BRD_10: | |
| 177 | /* Actually we've got more interrupts to handle ... */ | 58 | case SNI_BRD_10NEW: |
| 178 | for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_ETHERNET; i++) | 59 | case SNI_BRD_TOWER_OASIC: |
| 179 | set_irq_chip(i, &pciasic_irq_type); | 60 | case SNI_BRD_MINITOWER: |
| 180 | 61 | sni_a20r_irq_init(); | |
| 181 | change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); | 62 | break; |
| 63 | |||
| 64 | case SNI_BRD_PCI_TOWER: | ||
| 65 | sni_pcit_irq_init(); | ||
| 66 | break; | ||
| 67 | |||
| 68 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 69 | sni_pcit_cplus_irq_init(); | ||
| 70 | break; | ||
| 71 | |||
| 72 | case SNI_BRD_RM200: | ||
| 73 | sni_rm200_irq_init(); | ||
| 74 | break; | ||
| 75 | |||
| 76 | case SNI_BRD_PCI_MTOWER: | ||
| 77 | case SNI_BRD_PCI_DESKTOP: | ||
| 78 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 79 | sni_pcimt_irq_init(); | ||
| 80 | break; | ||
| 81 | } | ||
| 182 | } | 82 | } |
diff --git a/arch/mips/sni/pcimt.c b/arch/mips/sni/pcimt.c new file mode 100644 index 000000000000..6c0dad7cbf4e --- /dev/null +++ b/arch/mips/sni/pcimt.c | |||
| @@ -0,0 +1,390 @@ | |||
| 1 | /* | ||
| 2 | * PCIMT specific code | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | ||
| 9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 10 | */ | ||
| 11 | |||
| 12 | #include <linux/init.h> | ||
| 13 | #include <linux/interrupt.h> | ||
| 14 | #include <linux/pci.h> | ||
| 15 | #include <linux/serial_8250.h> | ||
| 16 | |||
| 17 | #include <asm/mc146818-time.h> | ||
| 18 | #include <asm/sni.h> | ||
| 19 | #include <asm/time.h> | ||
| 20 | #include <asm/i8259.h> | ||
| 21 | #include <asm/irq_cpu.h> | ||
| 22 | |||
| 23 | #define cacheconf (*(volatile unsigned int *)PCIMT_CACHECONF) | ||
| 24 | #define invspace (*(volatile unsigned int *)PCIMT_INVSPACE) | ||
| 25 | |||
| 26 | static void __init sni_pcimt_sc_init(void) | ||
| 27 | { | ||
| 28 | unsigned int scsiz, sc_size; | ||
| 29 | |||
| 30 | scsiz = cacheconf & 7; | ||
| 31 | if (scsiz == 0) { | ||
| 32 | printk("Second level cache is deactived.\n"); | ||
| 33 | return; | ||
| 34 | } | ||
| 35 | if (scsiz >= 6) { | ||
| 36 | printk("Invalid second level cache size configured, " | ||
| 37 | "deactivating second level cache.\n"); | ||
| 38 | cacheconf = 0; | ||
| 39 | return; | ||
| 40 | } | ||
| 41 | |||
| 42 | sc_size = 128 << scsiz; | ||
| 43 | printk("%dkb second level cache detected, deactivating.\n", sc_size); | ||
| 44 | cacheconf = 0; | ||
| 45 | } | ||
| 46 | |||
| 47 | |||
| 48 | /* | ||
| 49 | * A bit more gossip about the iron we're running on ... | ||
| 50 | */ | ||
| 51 | static inline void sni_pcimt_detect(void) | ||
| 52 | { | ||
| 53 | char boardtype[80]; | ||
| 54 | unsigned char csmsr; | ||
| 55 | char *p = boardtype; | ||
| 56 | unsigned int asic; | ||
| 57 | |||
| 58 | csmsr = *(volatile unsigned char *)PCIMT_CSMSR; | ||
| 59 | |||
| 60 | p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300"); | ||
| 61 | if ((csmsr & 0x80) == 0) | ||
| 62 | p += sprintf(p, ", board revision %s", | ||
| 63 | (csmsr & 0x20) ? "D" : "C"); | ||
| 64 | asic = csmsr & 0x80; | ||
| 65 | asic = (csmsr & 0x08) ? asic : !asic; | ||
| 66 | p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1"); | ||
| 67 | printk("%s.\n", boardtype); | ||
| 68 | } | ||
| 69 | |||
| 70 | #define PORT(_base,_irq) \ | ||
| 71 | { \ | ||
| 72 | .iobase = _base, \ | ||
| 73 | .irq = _irq, \ | ||
| 74 | .uartclk = 1843200, \ | ||
| 75 | .iotype = UPIO_PORT, \ | ||
| 76 | .flags = UPF_BOOT_AUTOCONF, \ | ||
| 77 | } | ||
| 78 | |||
| 79 | static struct plat_serial8250_port pcimt_data[] = { | ||
| 80 | PORT(0x3f8, 4), | ||
| 81 | PORT(0x2f8, 3), | ||
| 82 | { }, | ||
| 83 | }; | ||
| 84 | |||
| 85 | static struct platform_device pcimt_serial8250_device = { | ||
| 86 | .name = "serial8250", | ||
| 87 | .id = PLAT8250_DEV_PLATFORM, | ||
| 88 | .dev = { | ||
| 89 | .platform_data = pcimt_data, | ||
| 90 | }, | ||
| 91 | }; | ||
| 92 | |||
| 93 | static struct resource sni_io_resource = { | ||
| 94 | .start = 0x00001000UL, | ||
| 95 | .end = 0x03bfffffUL, | ||
| 96 | .name = "PCIMT IO MEM", | ||
| 97 | .flags = IORESOURCE_IO, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct resource pcimt_io_resources[] = { | ||
| 101 | { | ||
| 102 | .start = 0x00, | ||
| 103 | .end = 0x1f, | ||
| 104 | .name = "dma1", | ||
| 105 | .flags = IORESOURCE_BUSY | ||
| 106 | }, { | ||
| 107 | .start = 0x40, | ||
| 108 | .end = 0x5f, | ||
| 109 | .name = "timer", | ||
| 110 | .flags = IORESOURCE_BUSY | ||
| 111 | }, { | ||
| 112 | .start = 0x60, | ||
| 113 | .end = 0x6f, | ||
| 114 | .name = "keyboard", | ||
| 115 | .flags = IORESOURCE_BUSY | ||
| 116 | }, { | ||
| 117 | .start = 0x80, | ||
| 118 | .end = 0x8f, | ||
| 119 | .name = "dma page reg", | ||
| 120 | .flags = IORESOURCE_BUSY | ||
| 121 | }, { | ||
| 122 | .start = 0xc0, | ||
| 123 | .end = 0xdf, | ||
| 124 | .name = "dma2", | ||
| 125 | .flags = IORESOURCE_BUSY | ||
| 126 | }, { | ||
| 127 | .start = 0xcfc, | ||
| 128 | .end = 0xcff, | ||
| 129 | .name = "PCI config data", | ||
| 130 | .flags = IORESOURCE_BUSY | ||
| 131 | } | ||
| 132 | }; | ||
| 133 | |||
| 134 | static struct resource sni_mem_resource = { | ||
| 135 | .start = 0x10000000UL, | ||
| 136 | .end = 0xffffffffUL, | ||
| 137 | .name = "PCIMT PCI MEM", | ||
| 138 | .flags = IORESOURCE_MEM | ||
| 139 | }; | ||
| 140 | |||
| 141 | /* | ||
| 142 | * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used | ||
| 143 | * for other purposes. Be paranoid and allocate all of the before the PCI | ||
| 144 | * code gets a chance to to map anything else there ... | ||
| 145 | * | ||
| 146 | * This leaves the following areas available: | ||
| 147 | * | ||
| 148 | * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory | ||
| 149 | * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory | ||
| 150 | * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory | ||
| 151 | * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory | ||
| 152 | * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory | ||
| 153 | */ | ||
| 154 | static struct resource pcimt_mem_resources[] = { | ||
| 155 | { | ||
| 156 | .start = 0x100a0000, | ||
| 157 | .end = 0x100bffff, | ||
| 158 | .name = "Video RAM area", | ||
| 159 | .flags = IORESOURCE_BUSY | ||
| 160 | }, { | ||
| 161 | .start = 0x100c0000, | ||
| 162 | .end = 0x100fffff, | ||
| 163 | .name = "ISA Reserved", | ||
| 164 | .flags = IORESOURCE_BUSY | ||
| 165 | }, { | ||
| 166 | .start = 0x14000000, | ||
| 167 | .end = 0x17bfffff, | ||
| 168 | .name = "PCI IO", | ||
| 169 | .flags = IORESOURCE_BUSY | ||
| 170 | }, { | ||
| 171 | .start = 0x17c00000, | ||
| 172 | .end = 0x17ffffff, | ||
| 173 | .name = "Cache Replacement Area", | ||
| 174 | .flags = IORESOURCE_BUSY | ||
| 175 | }, { | ||
| 176 | .start = 0x1a000000, | ||
| 177 | .end = 0x1a000003, | ||
| 178 | .name = "PCI INT Acknowledge", | ||
| 179 | .flags = IORESOURCE_BUSY | ||
| 180 | }, { | ||
| 181 | .start = 0x1fc00000, | ||
| 182 | .end = 0x1fc7ffff, | ||
| 183 | .name = "Boot PROM", | ||
| 184 | .flags = IORESOURCE_BUSY | ||
| 185 | }, { | ||
| 186 | .start = 0x1fc80000, | ||
| 187 | .end = 0x1fcfffff, | ||
| 188 | .name = "Diag PROM", | ||
| 189 | .flags = IORESOURCE_BUSY | ||
| 190 | }, { | ||
| 191 | .start = 0x1fd00000, | ||
| 192 | .end = 0x1fdfffff, | ||
| 193 | .name = "X-Bus", | ||
| 194 | .flags = IORESOURCE_BUSY | ||
| 195 | }, { | ||
| 196 | .start = 0x1fe00000, | ||
| 197 | .end = 0x1fefffff, | ||
| 198 | .name = "BIOS map", | ||
| 199 | .flags = IORESOURCE_BUSY | ||
| 200 | }, { | ||
| 201 | .start = 0x1ff00000, | ||
| 202 | .end = 0x1ff7ffff, | ||
| 203 | .name = "NVRAM / EEPROM", | ||
| 204 | .flags = IORESOURCE_BUSY | ||
| 205 | }, { | ||
| 206 | .start = 0x1fff0000, | ||
| 207 | .end = 0x1fffefff, | ||
| 208 | .name = "ASIC PCI", | ||
| 209 | .flags = IORESOURCE_BUSY | ||
| 210 | }, { | ||
| 211 | .start = 0x1ffff000, | ||
| 212 | .end = 0x1fffffff, | ||
| 213 | .name = "MP Agent", | ||
| 214 | .flags = IORESOURCE_BUSY | ||
| 215 | }, { | ||
| 216 | .start = 0x20000000, | ||
| 217 | .end = 0x9fffffff, | ||
| 218 | .name = "Main Memory", | ||
| 219 | .flags = IORESOURCE_BUSY | ||
| 220 | } | ||
| 221 | }; | ||
| 222 | |||
| 223 | static void __init sni_pcimt_resource_init(void) | ||
| 224 | { | ||
| 225 | int i; | ||
| 226 | |||
| 227 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
| 228 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) | ||
| 229 | request_resource(&ioport_resource, pcimt_io_resources + i); | ||
| 230 | |||
| 231 | /* request mem space for pcimt-specific devices */ | ||
| 232 | for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) | ||
| 233 | request_resource(&sni_mem_resource, pcimt_mem_resources + i); | ||
| 234 | |||
| 235 | ioport_resource.end = sni_io_resource.end; | ||
| 236 | } | ||
| 237 | |||
| 238 | extern struct pci_ops sni_pcimt_ops; | ||
| 239 | |||
| 240 | static struct pci_controller sni_controller = { | ||
| 241 | .pci_ops = &sni_pcimt_ops, | ||
| 242 | .mem_resource = &sni_mem_resource, | ||
| 243 | .mem_offset = 0x10000000UL, | ||
| 244 | .io_resource = &sni_io_resource, | ||
| 245 | .io_offset = 0x00000000UL | ||
| 246 | }; | ||
| 247 | |||
| 248 | static void enable_pcimt_irq(unsigned int irq) | ||
| 249 | { | ||
| 250 | unsigned int mask = 1 << (irq - PCIMT_IRQ_INT2); | ||
| 251 | |||
| 252 | *(volatile u8 *) PCIMT_IRQSEL |= mask; | ||
| 253 | } | ||
| 254 | |||
| 255 | void disable_pcimt_irq(unsigned int irq) | ||
| 256 | { | ||
| 257 | unsigned int mask = ~(1 << (irq - PCIMT_IRQ_INT2)); | ||
| 258 | |||
| 259 | *(volatile u8 *) PCIMT_IRQSEL &= mask; | ||
| 260 | } | ||
| 261 | |||
| 262 | static void end_pcimt_irq(unsigned int irq) | ||
| 263 | { | ||
| 264 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 265 | enable_pcimt_irq(irq); | ||
| 266 | } | ||
| 267 | |||
| 268 | static struct irq_chip pcimt_irq_type = { | ||
| 269 | .typename = "PCIMT", | ||
| 270 | .ack = disable_pcimt_irq, | ||
| 271 | .mask = disable_pcimt_irq, | ||
| 272 | .mask_ack = disable_pcimt_irq, | ||
| 273 | .unmask = enable_pcimt_irq, | ||
| 274 | .end = end_pcimt_irq, | ||
| 275 | }; | ||
| 276 | |||
| 277 | /* | ||
| 278 | * hwint0 should deal with MP agent, ASIC PCI, EISA NMI and debug | ||
| 279 | * button interrupts. Later ... | ||
| 280 | */ | ||
| 281 | static void pcimt_hwint0(void) | ||
| 282 | { | ||
| 283 | panic("Received int0 but no handler yet ..."); | ||
| 284 | } | ||
| 285 | |||
| 286 | /* | ||
| 287 | * hwint 1 deals with EISA and SCSI interrupts, | ||
| 288 | * | ||
| 289 | * The EISA_INT bit in CSITPEND is high active, all others are low active. | ||
| 290 | */ | ||
| 291 | static void pcimt_hwint1(void) | ||
| 292 | { | ||
| 293 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | ||
| 294 | unsigned long flags; | ||
| 295 | |||
| 296 | if (pend & IT_EISA) { | ||
| 297 | int irq; | ||
| 298 | /* | ||
| 299 | * Note: ASIC PCI's builtin interrupt achknowledge feature is | ||
| 300 | * broken. Using it may result in loss of some or all i8259 | ||
| 301 | * interupts, so don't use PCIMT_INT_ACKNOWLEDGE ... | ||
| 302 | */ | ||
| 303 | irq = i8259_irq(); | ||
| 304 | if (unlikely(irq < 0)) | ||
| 305 | return; | ||
| 306 | |||
| 307 | do_IRQ(irq); | ||
| 308 | } | ||
| 309 | |||
| 310 | if (!(pend & IT_SCSI)) { | ||
| 311 | flags = read_c0_status(); | ||
| 312 | clear_c0_status(ST0_IM); | ||
| 313 | do_IRQ(PCIMT_IRQ_SCSI); | ||
| 314 | write_c0_status(flags); | ||
| 315 | } | ||
| 316 | } | ||
| 317 | |||
| 318 | /* | ||
| 319 | * hwint 3 should deal with the PCI A - D interrupts, | ||
| 320 | */ | ||
| 321 | static void pcimt_hwint3(void) | ||
| 322 | { | ||
| 323 | u8 pend = *(volatile char *)PCIMT_CSITPEND; | ||
| 324 | int irq; | ||
| 325 | |||
| 326 | pend &= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); | ||
| 327 | pend ^= (IT_INTA | IT_INTB | IT_INTC | IT_INTD); | ||
| 328 | clear_c0_status(IE_IRQ3); | ||
| 329 | irq = PCIMT_IRQ_INT2 + ffs(pend) - 1; | ||
| 330 | do_IRQ(irq); | ||
| 331 | set_c0_status(IE_IRQ3); | ||
| 332 | } | ||
| 333 | |||
| 334 | static void sni_pcimt_hwint(void) | ||
| 335 | { | ||
| 336 | u32 pending = (read_c0_cause() & read_c0_status()); | ||
| 337 | |||
| 338 | if (pending & C_IRQ5) | ||
| 339 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7); | ||
| 340 | else if (pending & C_IRQ4) | ||
| 341 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 6); | ||
| 342 | else if (pending & C_IRQ3) | ||
| 343 | pcimt_hwint3(); | ||
| 344 | else if (pending & C_IRQ1) | ||
| 345 | pcimt_hwint1(); | ||
| 346 | else if (pending & C_IRQ0) { | ||
| 347 | pcimt_hwint0(); | ||
| 348 | } | ||
| 349 | } | ||
| 350 | |||
| 351 | void __init sni_pcimt_irq_init(void) | ||
| 352 | { | ||
| 353 | int i; | ||
| 354 | |||
| 355 | *(volatile u8 *) PCIMT_IRQSEL = IT_ETH | IT_EISA; | ||
| 356 | mips_cpu_irq_init(); | ||
| 357 | /* Actually we've got more interrupts to handle ... */ | ||
| 358 | for (i = PCIMT_IRQ_INT2; i <= PCIMT_IRQ_SCSI; i++) | ||
| 359 | set_irq_chip(i, &pcimt_irq_type); | ||
| 360 | sni_hwint = sni_pcimt_hwint; | ||
| 361 | change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ3); | ||
| 362 | } | ||
| 363 | |||
| 364 | void sni_pcimt_init(void) | ||
| 365 | { | ||
| 366 | sni_pcimt_resource_init(); | ||
| 367 | sni_pcimt_detect(); | ||
| 368 | sni_pcimt_sc_init(); | ||
| 369 | rtc_mips_get_time = mc146818_get_cmos_time; | ||
| 370 | rtc_mips_set_time = mc146818_set_rtc_mmss; | ||
| 371 | board_time_init = sni_cpu_time_init; | ||
| 372 | #ifdef CONFIG_PCI | ||
| 373 | register_pci_controller(&sni_controller); | ||
| 374 | #endif | ||
| 375 | } | ||
| 376 | |||
| 377 | static int __init snirm_pcimt_setup_devinit(void) | ||
| 378 | { | ||
| 379 | switch (sni_brd_type) { | ||
| 380 | case SNI_BRD_PCI_MTOWER: | ||
| 381 | case SNI_BRD_PCI_DESKTOP: | ||
| 382 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 383 | platform_device_register(&pcimt_serial8250_device); | ||
| 384 | break; | ||
| 385 | } | ||
| 386 | |||
| 387 | return 0; | ||
| 388 | } | ||
| 389 | |||
| 390 | device_initcall(snirm_pcimt_setup_devinit); | ||
diff --git a/arch/mips/sni/pcit.c b/arch/mips/sni/pcit.c new file mode 100644 index 000000000000..3921096023c3 --- /dev/null +++ b/arch/mips/sni/pcit.c | |||
| @@ -0,0 +1,351 @@ | |||
| 1 | /* | ||
| 2 | * PCI Tower specific code | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/pci.h> | ||
| 14 | #include <linux/serial_8250.h> | ||
| 15 | |||
| 16 | #include <asm/mc146818-time.h> | ||
| 17 | #include <asm/sni.h> | ||
| 18 | #include <asm/time.h> | ||
| 19 | #include <asm/irq_cpu.h> | ||
| 20 | |||
| 21 | |||
| 22 | #define PORT(_base,_irq) \ | ||
| 23 | { \ | ||
| 24 | .iobase = _base, \ | ||
| 25 | .irq = _irq, \ | ||
| 26 | .uartclk = 1843200, \ | ||
| 27 | .iotype = UPIO_PORT, \ | ||
| 28 | .flags = UPF_BOOT_AUTOCONF, \ | ||
| 29 | } | ||
| 30 | |||
| 31 | static struct plat_serial8250_port pcit_data[] = { | ||
| 32 | PORT(0x3f8, 0), | ||
| 33 | PORT(0x2f8, 3), | ||
| 34 | { }, | ||
| 35 | }; | ||
| 36 | |||
| 37 | static struct platform_device pcit_serial8250_device = { | ||
| 38 | .name = "serial8250", | ||
| 39 | .id = PLAT8250_DEV_PLATFORM, | ||
| 40 | .dev = { | ||
| 41 | .platform_data = pcit_data, | ||
| 42 | }, | ||
| 43 | }; | ||
| 44 | |||
| 45 | static struct plat_serial8250_port pcit_cplus_data[] = { | ||
| 46 | PORT(0x3f8, 4), | ||
| 47 | PORT(0x2f8, 3), | ||
| 48 | PORT(0x3e8, 4), | ||
| 49 | PORT(0x2e8, 3), | ||
| 50 | { }, | ||
| 51 | }; | ||
| 52 | |||
| 53 | static struct platform_device pcit_cplus_serial8250_device = { | ||
| 54 | .name = "serial8250", | ||
| 55 | .id = PLAT8250_DEV_PLATFORM, | ||
| 56 | .dev = { | ||
| 57 | .platform_data = pcit_cplus_data, | ||
| 58 | }, | ||
| 59 | }; | ||
| 60 | |||
| 61 | static struct resource sni_io_resource = { | ||
| 62 | .start = 0x00001000UL, | ||
| 63 | .end = 0x03bfffffUL, | ||
| 64 | .name = "PCIT IO MEM", | ||
| 65 | .flags = IORESOURCE_IO, | ||
| 66 | }; | ||
| 67 | |||
| 68 | static struct resource pcit_io_resources[] = { | ||
| 69 | { | ||
| 70 | .start = 0x00, | ||
| 71 | .end = 0x1f, | ||
| 72 | .name = "dma1", | ||
| 73 | .flags = IORESOURCE_BUSY | ||
| 74 | }, { | ||
| 75 | .start = 0x40, | ||
| 76 | .end = 0x5f, | ||
| 77 | .name = "timer", | ||
| 78 | .flags = IORESOURCE_BUSY | ||
| 79 | }, { | ||
| 80 | .start = 0x60, | ||
| 81 | .end = 0x6f, | ||
| 82 | .name = "keyboard", | ||
| 83 | .flags = IORESOURCE_BUSY | ||
| 84 | }, { | ||
| 85 | .start = 0x80, | ||
| 86 | .end = 0x8f, | ||
| 87 | .name = "dma page reg", | ||
| 88 | .flags = IORESOURCE_BUSY | ||
| 89 | }, { | ||
| 90 | .start = 0xc0, | ||
| 91 | .end = 0xdf, | ||
| 92 | .name = "dma2", | ||
| 93 | .flags = IORESOURCE_BUSY | ||
| 94 | }, { | ||
| 95 | .start = 0xcfc, | ||
| 96 | .end = 0xcff, | ||
| 97 | .name = "PCI config data", | ||
| 98 | .flags = IORESOURCE_BUSY | ||
| 99 | } | ||
| 100 | }; | ||
| 101 | |||
| 102 | static struct resource sni_mem_resource = { | ||
| 103 | .start = 0x10000000UL, | ||
| 104 | .end = 0xffffffffUL, | ||
| 105 | .name = "PCIT PCI MEM", | ||
| 106 | .flags = IORESOURCE_MEM | ||
| 107 | }; | ||
| 108 | |||
| 109 | /* | ||
| 110 | * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used | ||
| 111 | * for other purposes. Be paranoid and allocate all of the before the PCI | ||
| 112 | * code gets a chance to to map anything else there ... | ||
| 113 | * | ||
| 114 | * This leaves the following areas available: | ||
| 115 | * | ||
| 116 | * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory | ||
| 117 | * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory | ||
| 118 | * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory | ||
| 119 | * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory | ||
| 120 | * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory | ||
| 121 | */ | ||
| 122 | static struct resource pcit_mem_resources[] = { | ||
| 123 | { | ||
| 124 | .start = 0x14000000, | ||
| 125 | .end = 0x17bfffff, | ||
| 126 | .name = "PCI IO", | ||
| 127 | .flags = IORESOURCE_BUSY | ||
| 128 | }, { | ||
| 129 | .start = 0x17c00000, | ||
| 130 | .end = 0x17ffffff, | ||
| 131 | .name = "Cache Replacement Area", | ||
| 132 | .flags = IORESOURCE_BUSY | ||
| 133 | }, { | ||
| 134 | .start = 0x180a0000, | ||
| 135 | .end = 0x180bffff, | ||
| 136 | .name = "Video RAM area", | ||
| 137 | .flags = IORESOURCE_BUSY | ||
| 138 | }, { | ||
| 139 | .start = 0x180c0000, | ||
| 140 | .end = 0x180fffff, | ||
| 141 | .name = "ISA Reserved", | ||
| 142 | .flags = IORESOURCE_BUSY | ||
| 143 | }, { | ||
| 144 | .start = 0x19000000, | ||
| 145 | .end = 0x1fbfffff, | ||
| 146 | .name = "PCI MEM", | ||
| 147 | .flags = IORESOURCE_BUSY | ||
| 148 | }, { | ||
| 149 | .start = 0x1fc00000, | ||
| 150 | .end = 0x1fc7ffff, | ||
| 151 | .name = "Boot PROM", | ||
| 152 | .flags = IORESOURCE_BUSY | ||
| 153 | }, { | ||
| 154 | .start = 0x1fc80000, | ||
| 155 | .end = 0x1fcfffff, | ||
| 156 | .name = "Diag PROM", | ||
| 157 | .flags = IORESOURCE_BUSY | ||
| 158 | }, { | ||
| 159 | .start = 0x1fd00000, | ||
| 160 | .end = 0x1fdfffff, | ||
| 161 | .name = "X-Bus", | ||
| 162 | .flags = IORESOURCE_BUSY | ||
| 163 | }, { | ||
| 164 | .start = 0x1fe00000, | ||
| 165 | .end = 0x1fefffff, | ||
| 166 | .name = "BIOS map", | ||
| 167 | .flags = IORESOURCE_BUSY | ||
| 168 | }, { | ||
| 169 | .start = 0x1ff00000, | ||
| 170 | .end = 0x1ff7ffff, | ||
| 171 | .name = "NVRAM / EEPROM", | ||
| 172 | .flags = IORESOURCE_BUSY | ||
| 173 | }, { | ||
| 174 | .start = 0x1fff0000, | ||
| 175 | .end = 0x1fffefff, | ||
| 176 | .name = "MAUI ASIC", | ||
| 177 | .flags = IORESOURCE_BUSY | ||
| 178 | }, { | ||
| 179 | .start = 0x1ffff000, | ||
| 180 | .end = 0x1fffffff, | ||
| 181 | .name = "MP Agent", | ||
| 182 | .flags = IORESOURCE_BUSY | ||
| 183 | }, { | ||
| 184 | .start = 0x20000000, | ||
| 185 | .end = 0x9fffffff, | ||
| 186 | .name = "Main Memory", | ||
| 187 | .flags = IORESOURCE_BUSY | ||
| 188 | } | ||
| 189 | }; | ||
| 190 | |||
| 191 | static void __init sni_pcit_resource_init(void) | ||
| 192 | { | ||
| 193 | int i; | ||
| 194 | |||
| 195 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
| 196 | for (i = 0; i < ARRAY_SIZE(pcit_io_resources); i++) | ||
| 197 | request_resource(&ioport_resource, pcit_io_resources + i); | ||
| 198 | |||
| 199 | /* request mem space for pcimt-specific devices */ | ||
| 200 | for (i = 0; i < ARRAY_SIZE(pcit_mem_resources); i++) | ||
| 201 | request_resource(&sni_mem_resource, pcit_mem_resources + i); | ||
| 202 | |||
| 203 | ioport_resource.end = sni_io_resource.end; | ||
| 204 | } | ||
| 205 | |||
| 206 | |||
| 207 | extern struct pci_ops sni_pcit_ops; | ||
| 208 | |||
| 209 | static struct pci_controller sni_pcit_controller = { | ||
| 210 | .pci_ops = &sni_pcit_ops, | ||
| 211 | .mem_resource = &sni_mem_resource, | ||
| 212 | .mem_offset = 0x10000000UL, | ||
| 213 | .io_resource = &sni_io_resource, | ||
| 214 | .io_offset = 0x00000000UL | ||
| 215 | }; | ||
| 216 | |||
| 217 | static void enable_pcit_irq(unsigned int irq) | ||
| 218 | { | ||
| 219 | u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); | ||
| 220 | |||
| 221 | *(volatile u32 *)SNI_PCIT_INT_REG |= mask; | ||
| 222 | } | ||
| 223 | |||
| 224 | void disable_pcit_irq(unsigned int irq) | ||
| 225 | { | ||
| 226 | u32 mask = 1 << (irq - SNI_PCIT_INT_START + 24); | ||
| 227 | |||
| 228 | *(volatile u32 *)SNI_PCIT_INT_REG &= ~mask; | ||
| 229 | } | ||
| 230 | |||
| 231 | void end_pcit_irq(unsigned int irq) | ||
| 232 | { | ||
| 233 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 234 | enable_pcit_irq(irq); | ||
| 235 | } | ||
| 236 | |||
| 237 | static struct irq_chip pcit_irq_type = { | ||
| 238 | .typename = "PCIT", | ||
| 239 | .ack = disable_pcit_irq, | ||
| 240 | .mask = disable_pcit_irq, | ||
| 241 | .mask_ack = disable_pcit_irq, | ||
| 242 | .unmask = enable_pcit_irq, | ||
| 243 | .end = end_pcit_irq, | ||
| 244 | }; | ||
| 245 | |||
| 246 | static void pcit_hwint1(void) | ||
| 247 | { | ||
| 248 | u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG; | ||
| 249 | int irq; | ||
| 250 | |||
| 251 | clear_c0_status(IE_IRQ1); | ||
| 252 | irq = ffs((pending >> 16) & 0x7f); | ||
| 253 | |||
| 254 | if (likely(irq > 0)) | ||
| 255 | do_IRQ (irq + SNI_PCIT_INT_START - 1); | ||
| 256 | set_c0_status (IE_IRQ1); | ||
| 257 | } | ||
| 258 | |||
| 259 | static void pcit_hwint0(void) | ||
| 260 | { | ||
| 261 | u32 pending = *(volatile u32 *)SNI_PCIT_INT_REG; | ||
| 262 | int irq; | ||
| 263 | |||
| 264 | clear_c0_status(IE_IRQ0); | ||
| 265 | irq = ffs((pending >> 16) & 0x7f); | ||
| 266 | |||
| 267 | if (likely(irq > 0)) | ||
| 268 | do_IRQ (irq + SNI_PCIT_INT_START - 1); | ||
| 269 | set_c0_status (IE_IRQ0); | ||
| 270 | } | ||
| 271 | |||
| 272 | static void sni_pcit_hwint(void) | ||
| 273 | { | ||
| 274 | u32 pending = (read_c0_cause() & read_c0_status()); | ||
| 275 | |||
| 276 | if (pending & C_IRQ1) | ||
| 277 | pcit_hwint1(); | ||
| 278 | else if (pending & C_IRQ2) | ||
| 279 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4); | ||
| 280 | else if (pending & C_IRQ3) | ||
| 281 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5); | ||
| 282 | else if (pending & C_IRQ5) | ||
| 283 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7); | ||
| 284 | } | ||
| 285 | |||
| 286 | static void sni_pcit_hwint_cplus(void) | ||
| 287 | { | ||
| 288 | u32 pending = (read_c0_cause() & read_c0_status()); | ||
| 289 | |||
| 290 | if (pending & C_IRQ0) | ||
| 291 | pcit_hwint0(); | ||
| 292 | else if (pending & C_IRQ2) | ||
| 293 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 4); | ||
| 294 | else if (pending & C_IRQ3) | ||
| 295 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 5); | ||
| 296 | else if (pending & C_IRQ5) | ||
| 297 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7); | ||
| 298 | } | ||
| 299 | |||
| 300 | void __init sni_pcit_irq_init(void) | ||
| 301 | { | ||
| 302 | int i; | ||
| 303 | |||
| 304 | mips_cpu_irq_init(); | ||
| 305 | for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) | ||
| 306 | set_irq_chip(i, &pcit_irq_type); | ||
| 307 | *(volatile u32 *)SNI_PCIT_INT_REG = 0; | ||
| 308 | sni_hwint = sni_pcit_hwint; | ||
| 309 | change_c0_status(ST0_IM, IE_IRQ1); | ||
| 310 | setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq); | ||
| 311 | } | ||
| 312 | |||
| 313 | void __init sni_pcit_cplus_irq_init(void) | ||
| 314 | { | ||
| 315 | int i; | ||
| 316 | |||
| 317 | mips_cpu_irq_init(); | ||
| 318 | for (i = SNI_PCIT_INT_START; i <= SNI_PCIT_INT_END; i++) | ||
| 319 | set_irq_chip(i, &pcit_irq_type); | ||
| 320 | *(volatile u32 *)SNI_PCIT_INT_REG = 0; | ||
| 321 | sni_hwint = sni_pcit_hwint_cplus; | ||
| 322 | change_c0_status(ST0_IM, IE_IRQ0); | ||
| 323 | setup_irq (SNI_PCIT_INT_START + 6, &sni_isa_irq); | ||
| 324 | } | ||
| 325 | |||
| 326 | void sni_pcit_init(void) | ||
| 327 | { | ||
| 328 | sni_pcit_resource_init(); | ||
| 329 | rtc_mips_get_time = mc146818_get_cmos_time; | ||
| 330 | rtc_mips_set_time = mc146818_set_rtc_mmss; | ||
| 331 | board_time_init = sni_cpu_time_init; | ||
| 332 | #ifdef CONFIG_PCI | ||
| 333 | register_pci_controller(&sni_pcit_controller); | ||
| 334 | #endif | ||
| 335 | } | ||
| 336 | |||
| 337 | static int __init snirm_pcit_setup_devinit(void) | ||
| 338 | { | ||
| 339 | switch (sni_brd_type) { | ||
| 340 | case SNI_BRD_PCI_TOWER: | ||
| 341 | platform_device_register(&pcit_serial8250_device); | ||
| 342 | break; | ||
| 343 | |||
| 344 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 345 | platform_device_register(&pcit_cplus_serial8250_device); | ||
| 346 | break; | ||
| 347 | } | ||
| 348 | return 0; | ||
| 349 | } | ||
| 350 | |||
| 351 | device_initcall(snirm_pcit_setup_devinit); | ||
diff --git a/arch/mips/sni/reset.c b/arch/mips/sni/reset.c index be85bec002e1..2eada8aea682 100644 --- a/arch/mips/sni/reset.c +++ b/arch/mips/sni/reset.c | |||
| @@ -13,12 +13,11 @@ | |||
| 13 | * controller to pulse the reset-line low. We try that for a while, | 13 | * controller to pulse the reset-line low. We try that for a while, |
| 14 | * and if it doesn't work, we do some other stupid things. | 14 | * and if it doesn't work, we do some other stupid things. |
| 15 | */ | 15 | */ |
| 16 | static inline void | 16 | static inline void kb_wait(void) |
| 17 | kb_wait(void) | ||
| 18 | { | 17 | { |
| 19 | int i; | 18 | int i; |
| 20 | 19 | ||
| 21 | for (i=0; i<0x10000; i++) | 20 | for (i = 0; i < 0x10000; i++) |
| 22 | if ((inb_p(0x64) & 0x02) == 0) | 21 | if ((inb_p(0x64) & 0x02) == 0) |
| 23 | break; | 22 | break; |
| 24 | } | 23 | } |
| @@ -32,9 +31,9 @@ void sni_machine_restart(char *command) | |||
| 32 | We can do that easier ... */ | 31 | We can do that easier ... */ |
| 33 | local_irq_disable(); | 32 | local_irq_disable(); |
| 34 | for (;;) { | 33 | for (;;) { |
| 35 | for (i=0; i<100; i++) { | 34 | for (i = 0; i < 100; i++) { |
| 36 | kb_wait(); | 35 | kb_wait(); |
| 37 | for(j = 0; j < 100000 ; j++) | 36 | for (j = 0; j < 100000 ; j++) |
| 38 | /* nothing */; | 37 | /* nothing */; |
| 39 | outb_p(0xfe,0x64); /* pulse reset low */ | 38 | outb_p(0xfe,0x64); /* pulse reset low */ |
| 40 | } | 39 | } |
diff --git a/arch/mips/sni/rm200.c b/arch/mips/sni/rm200.c new file mode 100644 index 000000000000..517dc698c083 --- /dev/null +++ b/arch/mips/sni/rm200.c | |||
| @@ -0,0 +1,186 @@ | |||
| 1 | /* | ||
| 2 | * RM200 specific code | ||
| 3 | * | ||
| 4 | * This file is subject to the terms and conditions of the GNU General Public | ||
| 5 | * License. See the file "COPYING" in the main directory of this archive | ||
| 6 | * for more details. | ||
| 7 | * | ||
| 8 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 9 | */ | ||
| 10 | |||
| 11 | #include <linux/init.h> | ||
| 12 | #include <linux/interrupt.h> | ||
| 13 | #include <linux/platform_device.h> | ||
| 14 | #include <linux/serial_8250.h> | ||
| 15 | |||
| 16 | #include <asm/sni.h> | ||
| 17 | #include <asm/time.h> | ||
| 18 | #include <asm/ds1216.h> | ||
| 19 | #include <asm/irq_cpu.h> | ||
| 20 | |||
| 21 | #define PORT(_base,_irq) \ | ||
| 22 | { \ | ||
| 23 | .iobase = _base, \ | ||
| 24 | .irq = _irq, \ | ||
| 25 | .uartclk = 1843200, \ | ||
| 26 | .iotype = UPIO_PORT, \ | ||
| 27 | .flags = UPF_BOOT_AUTOCONF, \ | ||
| 28 | } | ||
| 29 | |||
| 30 | static struct plat_serial8250_port rm200_data[] = { | ||
| 31 | PORT(0x3f8, 4), | ||
| 32 | PORT(0x2f8, 3), | ||
| 33 | { }, | ||
| 34 | }; | ||
| 35 | |||
| 36 | static struct platform_device rm200_serial8250_device = { | ||
| 37 | .name = "serial8250", | ||
| 38 | .id = PLAT8250_DEV_PLATFORM, | ||
| 39 | .dev = { | ||
| 40 | .platform_data = rm200_data, | ||
| 41 | }, | ||
| 42 | }; | ||
| 43 | |||
| 44 | static struct resource snirm_82596_rm200_rsrc[] = { | ||
| 45 | { | ||
| 46 | .start = 0xb8000000, | ||
| 47 | .end = 0xb80fffff, | ||
| 48 | .flags = IORESOURCE_MEM | ||
| 49 | }, | ||
| 50 | { | ||
| 51 | .start = 0xbb000000, | ||
| 52 | .end = 0xbb000004, | ||
| 53 | .flags = IORESOURCE_MEM | ||
| 54 | }, | ||
| 55 | { | ||
| 56 | .start = 0xbff00000, | ||
| 57 | .end = 0xbff00020, | ||
| 58 | .flags = IORESOURCE_MEM | ||
| 59 | }, | ||
| 60 | { | ||
| 61 | .start = 27, | ||
| 62 | .end = 27, | ||
| 63 | .flags = IORESOURCE_IRQ | ||
| 64 | }, | ||
| 65 | { | ||
| 66 | .flags = 0x00 | ||
| 67 | } | ||
| 68 | }; | ||
| 69 | |||
| 70 | static struct platform_device snirm_82596_rm200_pdev = { | ||
| 71 | .name = "snirm_82596", | ||
| 72 | .num_resources = ARRAY_SIZE(snirm_82596_rm200_rsrc), | ||
| 73 | .resource = snirm_82596_rm200_rsrc | ||
| 74 | }; | ||
| 75 | |||
| 76 | static struct resource snirm_53c710_rm200_rsrc[] = { | ||
| 77 | { | ||
| 78 | .start = 0xb9000000, | ||
| 79 | .end = 0xb90fffff, | ||
| 80 | .flags = IORESOURCE_MEM | ||
| 81 | }, | ||
| 82 | { | ||
| 83 | .start = 26, | ||
| 84 | .end = 26, | ||
| 85 | .flags = IORESOURCE_IRQ | ||
| 86 | } | ||
| 87 | }; | ||
| 88 | |||
| 89 | static struct platform_device snirm_53c710_rm200_pdev = { | ||
| 90 | .name = "snirm_53c710", | ||
| 91 | .num_resources = ARRAY_SIZE(snirm_53c710_rm200_rsrc), | ||
| 92 | .resource = snirm_53c710_rm200_rsrc | ||
| 93 | }; | ||
| 94 | |||
| 95 | static int __init snirm_setup_devinit(void) | ||
| 96 | { | ||
| 97 | if (sni_brd_type == SNI_BRD_RM200) { | ||
| 98 | platform_device_register(&rm200_serial8250_device); | ||
| 99 | platform_device_register(&snirm_82596_rm200_pdev); | ||
| 100 | platform_device_register(&snirm_53c710_rm200_pdev); | ||
| 101 | } | ||
| 102 | return 0; | ||
| 103 | } | ||
| 104 | |||
| 105 | device_initcall(snirm_setup_devinit); | ||
| 106 | |||
| 107 | |||
| 108 | #define SNI_RM200_INT_STAT_REG 0xbc000000 | ||
| 109 | #define SNI_RM200_INT_ENA_REG 0xbc080000 | ||
| 110 | |||
| 111 | #define SNI_RM200_INT_START 24 | ||
| 112 | #define SNI_RM200_INT_END 28 | ||
| 113 | |||
| 114 | static void enable_rm200_irq(unsigned int irq) | ||
| 115 | { | ||
| 116 | unsigned int mask = 1 << (irq - SNI_RM200_INT_START); | ||
| 117 | |||
| 118 | *(volatile u8 *)SNI_RM200_INT_ENA_REG &= ~mask; | ||
| 119 | } | ||
| 120 | |||
| 121 | void disable_rm200_irq(unsigned int irq) | ||
| 122 | { | ||
| 123 | unsigned int mask = 1 << (irq - SNI_RM200_INT_START); | ||
| 124 | |||
| 125 | *(volatile u8 *)SNI_RM200_INT_ENA_REG |= mask; | ||
| 126 | } | ||
| 127 | |||
| 128 | void end_rm200_irq(unsigned int irq) | ||
| 129 | { | ||
| 130 | if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) | ||
| 131 | enable_rm200_irq(irq); | ||
| 132 | } | ||
| 133 | |||
| 134 | static struct irq_chip rm200_irq_type = { | ||
| 135 | .typename = "RM200", | ||
| 136 | .ack = disable_rm200_irq, | ||
| 137 | .mask = disable_rm200_irq, | ||
| 138 | .mask_ack = disable_rm200_irq, | ||
| 139 | .unmask = enable_rm200_irq, | ||
| 140 | .end = end_rm200_irq, | ||
| 141 | }; | ||
| 142 | |||
| 143 | static void sni_rm200_hwint(void) | ||
| 144 | { | ||
| 145 | u32 pending = read_c0_cause() & read_c0_status(); | ||
| 146 | u8 mask; | ||
| 147 | u8 stat; | ||
| 148 | int irq; | ||
| 149 | |||
| 150 | if (pending & C_IRQ5) | ||
| 151 | do_IRQ (SNI_MIPS_IRQ_CPU_BASE + 7); | ||
| 152 | else if (pending & C_IRQ0) { | ||
| 153 | clear_c0_status (IE_IRQ0); | ||
| 154 | mask = *(volatile u8 *)SNI_RM200_INT_ENA_REG ^ 0x1f; | ||
| 155 | stat = *(volatile u8 *)SNI_RM200_INT_STAT_REG ^ 0x14; | ||
| 156 | irq = ffs(stat & mask & 0x1f); | ||
| 157 | |||
| 158 | if (likely(irq > 0)) | ||
| 159 | do_IRQ (irq + SNI_RM200_INT_START - 1); | ||
| 160 | set_c0_status (IE_IRQ0); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | |||
| 164 | void __init sni_rm200_irq_init(void) | ||
| 165 | { | ||
| 166 | int i; | ||
| 167 | |||
| 168 | * (volatile u8 *)SNI_RM200_INT_ENA_REG = 0x1f; | ||
| 169 | |||
| 170 | mips_cpu_irq_init(); | ||
| 171 | /* Actually we've got more interrupts to handle ... */ | ||
| 172 | for (i = SNI_RM200_INT_START; i <= SNI_RM200_INT_END; i++) | ||
| 173 | set_irq_chip(i, &rm200_irq_type); | ||
| 174 | sni_hwint = sni_rm200_hwint; | ||
| 175 | change_c0_status(ST0_IM, IE_IRQ0); | ||
| 176 | setup_irq (SNI_RM200_INT_START + 0, &sni_isa_irq); | ||
| 177 | } | ||
| 178 | |||
| 179 | void sni_rm200_init(void) | ||
| 180 | { | ||
| 181 | set_io_port_base(SNI_PORT_BASE + 0x02000000); | ||
| 182 | ioport_resource.end += 0x02000000; | ||
| 183 | ds1216_base = (volatile unsigned char *) SNI_DS1216_RM200_BASE; | ||
| 184 | rtc_mips_get_time = ds1216_get_cmos_time; | ||
| 185 | board_time_init = sni_cpu_time_init; | ||
| 186 | } | ||
diff --git a/arch/mips/sni/setup.c b/arch/mips/sni/setup.c index afeb7f13e5b5..68d7cf609b4f 100644 --- a/arch/mips/sni/setup.c +++ b/arch/mips/sni/setup.c | |||
| @@ -6,16 +6,10 @@ | |||
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) | 8 | * Copyright (C) 1996, 97, 98, 2000, 03, 04, 06 Ralf Baechle (ralf@linux-mips.org) |
| 9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 9 | */ | 10 | */ |
| 10 | #include <linux/eisa.h> | 11 | #include <linux/eisa.h> |
| 11 | #include <linux/hdreg.h> | ||
| 12 | #include <linux/ioport.h> | ||
| 13 | #include <linux/sched.h> | ||
| 14 | #include <linux/init.h> | 12 | #include <linux/init.h> |
| 15 | #include <linux/interrupt.h> | ||
| 16 | #include <linux/mc146818rtc.h> | ||
| 17 | #include <linux/pm.h> | ||
| 18 | #include <linux/pci.h> | ||
| 19 | #include <linux/console.h> | 13 | #include <linux/console.h> |
| 20 | #include <linux/fb.h> | 14 | #include <linux/fb.h> |
| 21 | #include <linux/screen_info.h> | 15 | #include <linux/screen_info.h> |
| @@ -25,52 +19,16 @@ | |||
| 25 | #include <asm/sgialib.h> | 19 | #include <asm/sgialib.h> |
| 26 | #endif | 20 | #endif |
| 27 | 21 | ||
| 28 | #include <asm/bcache.h> | ||
| 29 | #include <asm/bootinfo.h> | ||
| 30 | #include <asm/io.h> | 22 | #include <asm/io.h> |
| 31 | #include <asm/irq.h> | ||
| 32 | #include <asm/mc146818-time.h> | ||
| 33 | #include <asm/processor.h> | ||
| 34 | #include <asm/reboot.h> | 23 | #include <asm/reboot.h> |
| 35 | #include <asm/sni.h> | 24 | #include <asm/sni.h> |
| 36 | #include <asm/time.h> | 25 | |
| 37 | #include <asm/traps.h> | 26 | unsigned int sni_brd_type; |
| 38 | 27 | ||
| 39 | extern void sni_machine_restart(char *command); | 28 | extern void sni_machine_restart(char *command); |
| 40 | extern void sni_machine_halt(void); | 29 | extern void sni_machine_halt(void); |
| 41 | extern void sni_machine_power_off(void); | 30 | extern void sni_machine_power_off(void); |
| 42 | 31 | ||
| 43 | void __init plat_timer_setup(struct irqaction *irq) | ||
| 44 | { | ||
| 45 | /* set the clock to 100 Hz */ | ||
| 46 | outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB, ch 0 */ | ||
| 47 | outb_p(LATCH & 0xff , 0x40); /* LSB */ | ||
| 48 | outb(LATCH >> 8 , 0x40); /* MSB */ | ||
| 49 | setup_irq(0, irq); | ||
| 50 | } | ||
| 51 | |||
| 52 | /* | ||
| 53 | * A bit more gossip about the iron we're running on ... | ||
| 54 | */ | ||
| 55 | static inline void sni_pcimt_detect(void) | ||
| 56 | { | ||
| 57 | char boardtype[80]; | ||
| 58 | unsigned char csmsr; | ||
| 59 | char *p = boardtype; | ||
| 60 | unsigned int asic; | ||
| 61 | |||
| 62 | csmsr = *(volatile unsigned char *)PCIMT_CSMSR; | ||
| 63 | |||
| 64 | p += sprintf(p, "%s PCI", (csmsr & 0x80) ? "RM200" : "RM300"); | ||
| 65 | if ((csmsr & 0x80) == 0) | ||
| 66 | p += sprintf(p, ", board revision %s", | ||
| 67 | (csmsr & 0x20) ? "D" : "C"); | ||
| 68 | asic = csmsr & 0x80; | ||
| 69 | asic = (csmsr & 0x08) ? asic : !asic; | ||
| 70 | p += sprintf(p, ", ASIC PCI Rev %s", asic ? "1.0" : "1.1"); | ||
| 71 | printk("%s.\n", boardtype); | ||
| 72 | } | ||
| 73 | |||
| 74 | static void __init sni_display_setup(void) | 32 | static void __init sni_display_setup(void) |
| 75 | { | 33 | { |
| 76 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC) | 34 | #if defined(CONFIG_VT) && defined(CONFIG_VGA_CONSOLE) && defined(CONFIG_ARC) |
| @@ -90,175 +48,11 @@ static void __init sni_display_setup(void) | |||
| 90 | #endif | 48 | #endif |
| 91 | } | 49 | } |
| 92 | 50 | ||
| 93 | static struct resource sni_io_resource = { | ||
| 94 | .start = 0x00001000UL, | ||
| 95 | .end = 0x03bfffffUL, | ||
| 96 | .name = "PCIMT IO MEM", | ||
| 97 | .flags = IORESOURCE_IO, | ||
| 98 | }; | ||
| 99 | |||
| 100 | static struct resource pcimt_io_resources[] = { | ||
| 101 | { | ||
| 102 | .start = 0x00, | ||
| 103 | .end = 0x1f, | ||
| 104 | .name = "dma1", | ||
| 105 | .flags = IORESOURCE_BUSY | ||
| 106 | }, { | ||
| 107 | .start = 0x40, | ||
| 108 | .end = 0x5f, | ||
| 109 | .name = "timer", | ||
| 110 | .flags = IORESOURCE_BUSY | ||
| 111 | }, { | ||
| 112 | .start = 0x60, | ||
| 113 | .end = 0x6f, | ||
| 114 | .name = "keyboard", | ||
| 115 | .flags = IORESOURCE_BUSY | ||
| 116 | }, { | ||
| 117 | .start = 0x80, | ||
| 118 | .end = 0x8f, | ||
| 119 | .name = "dma page reg", | ||
| 120 | .flags = IORESOURCE_BUSY | ||
| 121 | }, { | ||
| 122 | .start = 0xc0, | ||
| 123 | .end = 0xdf, | ||
| 124 | .name = "dma2", | ||
| 125 | .flags = IORESOURCE_BUSY | ||
| 126 | }, { | ||
| 127 | .start = 0xcfc, | ||
| 128 | .end = 0xcff, | ||
| 129 | .name = "PCI config data", | ||
| 130 | .flags = IORESOURCE_BUSY | ||
| 131 | } | ||
| 132 | }; | ||
| 133 | |||
| 134 | static struct resource sni_mem_resource = { | ||
| 135 | .start = 0x10000000UL, | ||
| 136 | .end = 0xffffffffUL, | ||
| 137 | .name = "PCIMT PCI MEM", | ||
| 138 | .flags = IORESOURCE_MEM | ||
| 139 | }; | ||
| 140 | |||
| 141 | /* | ||
| 142 | * The RM200/RM300 has a few holes in it's PCI/EISA memory address space used | ||
| 143 | * for other purposes. Be paranoid and allocate all of the before the PCI | ||
| 144 | * code gets a chance to to map anything else there ... | ||
| 145 | * | ||
| 146 | * This leaves the following areas available: | ||
| 147 | * | ||
| 148 | * 0x10000000 - 0x1009ffff (640kB) PCI/EISA/ISA Bus Memory | ||
| 149 | * 0x10100000 - 0x13ffffff ( 15MB) PCI/EISA/ISA Bus Memory | ||
| 150 | * 0x18000000 - 0x1fbfffff (124MB) PCI/EISA Bus Memory | ||
| 151 | * 0x1ff08000 - 0x1ffeffff (816kB) PCI/EISA Bus Memory | ||
| 152 | * 0xa0000000 - 0xffffffff (1.5GB) PCI/EISA Bus Memory | ||
| 153 | */ | ||
| 154 | static struct resource pcimt_mem_resources[] = { | ||
| 155 | { | ||
| 156 | .start = 0x100a0000, | ||
| 157 | .end = 0x100bffff, | ||
| 158 | .name = "Video RAM area", | ||
| 159 | .flags = IORESOURCE_BUSY | ||
| 160 | }, { | ||
| 161 | .start = 0x100c0000, | ||
| 162 | .end = 0x100fffff, | ||
| 163 | .name = "ISA Reserved", | ||
| 164 | .flags = IORESOURCE_BUSY | ||
| 165 | }, { | ||
| 166 | .start = 0x14000000, | ||
| 167 | .end = 0x17bfffff, | ||
| 168 | .name = "PCI IO", | ||
| 169 | .flags = IORESOURCE_BUSY | ||
| 170 | }, { | ||
| 171 | .start = 0x17c00000, | ||
| 172 | .end = 0x17ffffff, | ||
| 173 | .name = "Cache Replacement Area", | ||
| 174 | .flags = IORESOURCE_BUSY | ||
| 175 | }, { | ||
| 176 | .start = 0x1a000000, | ||
| 177 | .end = 0x1a000003, | ||
| 178 | .name = "PCI INT Acknowledge", | ||
| 179 | .flags = IORESOURCE_BUSY | ||
| 180 | }, { | ||
| 181 | .start = 0x1fc00000, | ||
| 182 | .end = 0x1fc7ffff, | ||
| 183 | .name = "Boot PROM", | ||
| 184 | .flags = IORESOURCE_BUSY | ||
| 185 | }, { | ||
| 186 | .start = 0x1fc80000, | ||
| 187 | .end = 0x1fcfffff, | ||
| 188 | .name = "Diag PROM", | ||
| 189 | .flags = IORESOURCE_BUSY | ||
| 190 | }, { | ||
| 191 | .start = 0x1fd00000, | ||
| 192 | .end = 0x1fdfffff, | ||
| 193 | .name = "X-Bus", | ||
| 194 | .flags = IORESOURCE_BUSY | ||
| 195 | }, { | ||
| 196 | .start = 0x1fe00000, | ||
| 197 | .end = 0x1fefffff, | ||
| 198 | .name = "BIOS map", | ||
| 199 | .flags = IORESOURCE_BUSY | ||
| 200 | }, { | ||
| 201 | .start = 0x1ff00000, | ||
| 202 | .end = 0x1ff7ffff, | ||
| 203 | .name = "NVRAM / EEPROM", | ||
| 204 | .flags = IORESOURCE_BUSY | ||
| 205 | }, { | ||
| 206 | .start = 0x1fff0000, | ||
| 207 | .end = 0x1fffefff, | ||
| 208 | .name = "ASIC PCI", | ||
| 209 | .flags = IORESOURCE_BUSY | ||
| 210 | }, { | ||
| 211 | .start = 0x1ffff000, | ||
| 212 | .end = 0x1fffffff, | ||
| 213 | .name = "MP Agent", | ||
| 214 | .flags = IORESOURCE_BUSY | ||
| 215 | }, { | ||
| 216 | .start = 0x20000000, | ||
| 217 | .end = 0x9fffffff, | ||
| 218 | .name = "Main Memory", | ||
| 219 | .flags = IORESOURCE_BUSY | ||
| 220 | } | ||
| 221 | }; | ||
| 222 | |||
| 223 | static void __init sni_resource_init(void) | ||
| 224 | { | ||
| 225 | int i; | ||
| 226 | |||
| 227 | /* request I/O space for devices used on all i[345]86 PCs */ | ||
| 228 | for (i = 0; i < ARRAY_SIZE(pcimt_io_resources); i++) | ||
| 229 | request_resource(&ioport_resource, pcimt_io_resources + i); | ||
| 230 | |||
| 231 | /* request mem space for pcimt-specific devices */ | ||
| 232 | for (i = 0; i < ARRAY_SIZE(pcimt_mem_resources); i++) | ||
| 233 | request_resource(&sni_mem_resource, pcimt_mem_resources + i); | ||
| 234 | |||
| 235 | ioport_resource.end = sni_io_resource.end; | ||
| 236 | } | ||
| 237 | |||
| 238 | extern struct pci_ops sni_pci_ops; | ||
| 239 | |||
| 240 | static struct pci_controller sni_controller = { | ||
| 241 | .pci_ops = &sni_pci_ops, | ||
| 242 | .mem_resource = &sni_mem_resource, | ||
| 243 | .mem_offset = 0x10000000UL, | ||
| 244 | .io_resource = &sni_io_resource, | ||
| 245 | .io_offset = 0x00000000UL | ||
| 246 | }; | ||
| 247 | |||
| 248 | static inline void sni_pcimt_time_init(void) | ||
| 249 | { | ||
| 250 | rtc_mips_get_time = mc146818_get_cmos_time; | ||
| 251 | rtc_mips_set_time = mc146818_set_rtc_mmss; | ||
| 252 | } | ||
| 253 | 51 | ||
| 254 | void __init plat_mem_setup(void) | 52 | void __init plat_mem_setup(void) |
| 255 | { | 53 | { |
| 256 | sni_pcimt_detect(); | ||
| 257 | sni_pcimt_sc_init(); | ||
| 258 | sni_pcimt_time_init(); | ||
| 259 | |||
| 260 | set_io_port_base(SNI_PORT_BASE); | 54 | set_io_port_base(SNI_PORT_BASE); |
| 261 | ioport_resource.end = sni_io_resource.end; | 55 | // ioport_resource.end = sni_io_resource.end; |
| 262 | 56 | ||
| 263 | /* | 57 | /* |
| 264 | * Setup (E)ISA I/O memory access stuff | 58 | * Setup (E)ISA I/O memory access stuff |
| @@ -268,15 +62,33 @@ void __init plat_mem_setup(void) | |||
| 268 | EISA_bus = 1; | 62 | EISA_bus = 1; |
| 269 | #endif | 63 | #endif |
| 270 | 64 | ||
| 271 | sni_resource_init(); | 65 | switch (sni_brd_type) { |
| 66 | case SNI_BRD_10: | ||
| 67 | case SNI_BRD_10NEW: | ||
| 68 | case SNI_BRD_TOWER_OASIC: | ||
| 69 | case SNI_BRD_MINITOWER: | ||
| 70 | sni_a20r_init(); | ||
| 71 | break; | ||
| 72 | |||
| 73 | case SNI_BRD_PCI_TOWER: | ||
| 74 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 75 | sni_pcit_init(); | ||
| 76 | break; | ||
| 77 | |||
| 78 | case SNI_BRD_RM200: | ||
| 79 | sni_rm200_init(); | ||
| 80 | break; | ||
| 81 | |||
| 82 | case SNI_BRD_PCI_MTOWER: | ||
| 83 | case SNI_BRD_PCI_DESKTOP: | ||
| 84 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 85 | sni_pcimt_init(); | ||
| 86 | break; | ||
| 87 | } | ||
| 272 | 88 | ||
| 273 | _machine_restart = sni_machine_restart; | 89 | _machine_restart = sni_machine_restart; |
| 274 | _machine_halt = sni_machine_halt; | 90 | _machine_halt = sni_machine_halt; |
| 275 | pm_power_off = sni_machine_power_off; | 91 | pm_power_off = sni_machine_power_off; |
| 276 | 92 | ||
| 277 | sni_display_setup(); | 93 | sni_display_setup(); |
| 278 | |||
| 279 | #ifdef CONFIG_PCI | ||
| 280 | register_pci_controller(&sni_controller); | ||
| 281 | #endif | ||
| 282 | } | 94 | } |
diff --git a/arch/mips/sni/sniprom.c b/arch/mips/sni/sniprom.c index 1213d166f22e..6a44bbf0b732 100644 --- a/arch/mips/sni/sniprom.c +++ b/arch/mips/sni/sniprom.c | |||
| @@ -12,6 +12,7 @@ | |||
| 12 | #include <linux/kernel.h> | 12 | #include <linux/kernel.h> |
| 13 | #include <linux/init.h> | 13 | #include <linux/init.h> |
| 14 | #include <linux/string.h> | 14 | #include <linux/string.h> |
| 15 | #include <linux/console.h> | ||
| 15 | 16 | ||
| 16 | #include <asm/addrspace.h> | 17 | #include <asm/addrspace.h> |
| 17 | #include <asm/sni.h> | 18 | #include <asm/sni.h> |
| @@ -31,7 +32,7 @@ | |||
| 31 | #define PROM_ENTRY(x) (PROM_VEC + (x)) | 32 | #define PROM_ENTRY(x) (PROM_VEC + (x)) |
| 32 | 33 | ||
| 33 | 34 | ||
| 34 | #undef DEBUG | 35 | #define DEBUG |
| 35 | #ifdef DEBUG | 36 | #ifdef DEBUG |
| 36 | #define DBG_PRINTF(x...) prom_printf(x) | 37 | #define DBG_PRINTF(x...) prom_printf(x) |
| 37 | #else | 38 | #else |
| @@ -93,14 +94,14 @@ static void sni_idprom_dump(void) | |||
| 93 | { | 94 | { |
| 94 | int i; | 95 | int i; |
| 95 | 96 | ||
| 96 | prom_printf("SNI IDProm dump (first 128byte):\n"); | 97 | prom_printf("SNI IDProm dump:\n"); |
| 97 | for(i=0;i<128;i++) { | 98 | for (i = 0; i < 256; i++) { |
| 98 | if (i%16 == 0) | 99 | if (i%16 == 0) |
| 99 | prom_printf("%04x ", i); | 100 | prom_printf("%04x ", i); |
| 100 | 101 | ||
| 101 | prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE+i)); | 102 | prom_printf("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i)); |
| 102 | 103 | ||
| 103 | if (i%16 == 15) | 104 | if (i % 16 == 15) |
| 104 | prom_printf("\n"); | 105 | prom_printf("\n"); |
| 105 | } | 106 | } |
| 106 | } | 107 | } |
| @@ -118,7 +119,7 @@ static void sni_mem_init(void ) | |||
| 118 | } memconf[8]; | 119 | } memconf[8]; |
| 119 | 120 | ||
| 120 | /* MemSIZE from prom in 16MByte chunks */ | 121 | /* MemSIZE from prom in 16MByte chunks */ |
| 121 | memsize=*((unsigned char *) SNI_IDPROM_MEMSIZE) * 16; | 122 | memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16; |
| 122 | 123 | ||
| 123 | DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize); | 124 | DBG_PRINTF("IDProm memsize: %lu MByte\n", memsize); |
| 124 | 125 | ||
| @@ -126,26 +127,134 @@ static void sni_mem_init(void ) | |||
| 126 | __prom_get_memconf(&memconf); | 127 | __prom_get_memconf(&memconf); |
| 127 | 128 | ||
| 128 | DBG_PRINTF("prom_get_mem_conf memory configuration:\n"); | 129 | DBG_PRINTF("prom_get_mem_conf memory configuration:\n"); |
| 129 | for(i=0;i<8 && memconf[i].size;i++) { | 130 | for (i = 0;i < 8 && memconf[i].size; i++) { |
| 130 | prom_printf("Bank%d: %08x @ %08x\n", i, | 131 | if (sni_brd_type == SNI_BRD_PCI_TOWER || |
| 132 | sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) { | ||
| 133 | if (memconf[i].base >= 0x20000000 && | ||
| 134 | memconf[i].base < 0x30000000) { | ||
| 135 | memconf[i].base -= 0x20000000; | ||
| 136 | } | ||
| 137 | } | ||
| 138 | DBG_PRINTF("Bank%d: %08x @ %08x\n", i, | ||
| 131 | memconf[i].size, memconf[i].base); | 139 | memconf[i].size, memconf[i].base); |
| 132 | add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM); | 140 | add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM); |
| 133 | } | 141 | } |
| 134 | } | 142 | } |
| 135 | 143 | ||
| 144 | static void __init sni_console_setup(void) | ||
| 145 | { | ||
| 146 | char *ctype; | ||
| 147 | char *cdev; | ||
| 148 | char *baud; | ||
| 149 | int port; | ||
| 150 | static char options[8]; | ||
| 151 | |||
| 152 | cdev = prom_getenv ("console_dev"); | ||
| 153 | if (strncmp (cdev, "tty", 3) == 0) { | ||
| 154 | ctype = prom_getenv ("console"); | ||
| 155 | switch (*ctype) { | ||
| 156 | default: | ||
| 157 | case 'l': | ||
| 158 | port = 0; | ||
| 159 | baud = prom_getenv("lbaud"); | ||
| 160 | break; | ||
| 161 | case 'r': | ||
| 162 | port = 1; | ||
| 163 | baud = prom_getenv("rbaud"); | ||
| 164 | break; | ||
| 165 | } | ||
| 166 | if (baud) | ||
| 167 | strcpy(options, baud); | ||
| 168 | add_preferred_console("ttyS", port, baud ? options : NULL); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | |||
| 136 | void __init prom_init(void) | 172 | void __init prom_init(void) |
| 137 | { | 173 | { |
| 138 | int argc = fw_arg0; | 174 | int argc = fw_arg0; |
| 139 | char **argv = (void *)fw_arg1; | 175 | char **argv = (void *)fw_arg1; |
| 140 | unsigned int sni_brd_type = *(unsigned char *) SNI_IDPROM_BRDTYPE; | ||
| 141 | int i; | 176 | int i; |
| 177 | int cputype; | ||
| 142 | 178 | ||
| 143 | DBG_PRINTF("Found SNI brdtype %02x\n", sni_brd_type); | 179 | sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE; |
| 180 | cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE; | ||
| 181 | switch (sni_brd_type) { | ||
| 182 | case SNI_BRD_TOWER_OASIC: | ||
| 183 | switch (cputype) { | ||
| 184 | case SNI_CPU_M8030: | ||
| 185 | systype = "RM400-330"; | ||
| 186 | break; | ||
| 187 | case SNI_CPU_M8031: | ||
| 188 | systype = "RM400-430"; | ||
| 189 | break; | ||
| 190 | case SNI_CPU_M8037: | ||
| 191 | systype = "RM400-530"; | ||
| 192 | break; | ||
| 193 | case SNI_CPU_M8034: | ||
| 194 | systype = "RM400-730"; | ||
| 195 | break; | ||
| 196 | default: | ||
| 197 | systype = "RM400-xxx"; | ||
| 198 | break; | ||
| 199 | } | ||
| 200 | break; | ||
| 201 | case SNI_BRD_MINITOWER: | ||
| 202 | switch (cputype) { | ||
| 203 | case SNI_CPU_M8021: | ||
| 204 | case SNI_CPU_M8043: | ||
| 205 | systype = "RM400-120"; | ||
| 206 | break; | ||
| 207 | case SNI_CPU_M8040: | ||
| 208 | systype = "RM400-220"; | ||
| 209 | break; | ||
| 210 | case SNI_CPU_M8053: | ||
| 211 | systype = "RM400-225"; | ||
| 212 | break; | ||
| 213 | case SNI_CPU_M8050: | ||
| 214 | systype = "RM400-420"; | ||
| 215 | break; | ||
| 216 | default: | ||
| 217 | systype = "RM400-xxx"; | ||
| 218 | break; | ||
| 219 | } | ||
| 220 | break; | ||
| 221 | case SNI_BRD_PCI_TOWER: | ||
| 222 | systype = "RM400-Cxx"; | ||
| 223 | break; | ||
| 224 | case SNI_BRD_RM200: | ||
| 225 | systype = "RM200-xxx"; | ||
| 226 | break; | ||
| 227 | case SNI_BRD_PCI_MTOWER: | ||
| 228 | systype = "RM300-Cxx"; | ||
| 229 | break; | ||
| 230 | case SNI_BRD_PCI_DESKTOP: | ||
| 231 | switch (read_c0_prid() & 0xff00) { | ||
| 232 | case PRID_IMP_R4600: | ||
| 233 | case PRID_IMP_R4700: | ||
| 234 | systype = "RM200-C20"; | ||
| 235 | break; | ||
| 236 | case PRID_IMP_R5000: | ||
| 237 | systype = "RM200-C40"; | ||
| 238 | break; | ||
| 239 | default: | ||
| 240 | systype = "RM200-Cxx"; | ||
| 241 | break; | ||
| 242 | } | ||
| 243 | break; | ||
| 244 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 245 | systype = "RM400-Exx"; | ||
| 246 | break; | ||
| 247 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 248 | systype = "RM300-Exx"; | ||
| 249 | break; | ||
| 250 | } | ||
| 251 | DBG_PRINTF("Found SNI brdtype %02x name %s\n", sni_brd_type,systype); | ||
| 144 | 252 | ||
| 145 | #ifdef DEBUG | 253 | #ifdef DEBUG |
| 146 | sni_idprom_dump(); | 254 | sni_idprom_dump(); |
| 147 | #endif | 255 | #endif |
| 148 | sni_mem_init(); | 256 | sni_mem_init(); |
| 257 | sni_console_setup(); | ||
| 149 | 258 | ||
| 150 | /* copy prom cmdline parameters to kernel cmdline */ | 259 | /* copy prom cmdline parameters to kernel cmdline */ |
| 151 | for (i = 1; i < argc; i++) { | 260 | for (i = 1; i < argc; i++) { |
diff --git a/arch/mips/sni/time.c b/arch/mips/sni/time.c new file mode 100644 index 000000000000..20028fc7757e --- /dev/null +++ b/arch/mips/sni/time.c | |||
| @@ -0,0 +1,148 @@ | |||
| 1 | #include <linux/types.h> | ||
| 2 | #include <linux/interrupt.h> | ||
| 3 | #include <linux/time.h> | ||
| 4 | |||
| 5 | #include <asm/sni.h> | ||
| 6 | #include <asm/time.h> | ||
| 7 | |||
| 8 | #define SNI_CLOCK_TICK_RATE 3686400 | ||
| 9 | #define SNI_COUNTER2_DIV 64 | ||
| 10 | #define SNI_COUNTER0_DIV ((SNI_CLOCK_TICK_RATE / SNI_COUNTER2_DIV) / HZ) | ||
| 11 | |||
| 12 | static void sni_a20r_timer_ack(void) | ||
| 13 | { | ||
| 14 | *(volatile u8 *)A20R_PT_TIM0_ACK = 0x0; wmb(); | ||
| 15 | } | ||
| 16 | |||
| 17 | /* | ||
| 18 | * a20r platform uses 2 counters to divide the input frequency. | ||
| 19 | * Counter 2 output is connected to Counter 0 & 1 input. | ||
| 20 | */ | ||
| 21 | static void __init sni_a20r_timer_setup(struct irqaction *irq) | ||
| 22 | { | ||
| 23 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0x34; wmb(); | ||
| 24 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV) & 0xff; wmb(); | ||
| 25 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 0) = (SNI_COUNTER0_DIV >> 8) & 0xff; wmb(); | ||
| 26 | |||
| 27 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 12) = 0xb4; wmb(); | ||
| 28 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV) & 0xff; wmb(); | ||
| 29 | *(volatile u8 *)(A20R_PT_CLOCK_BASE + 8) = (SNI_COUNTER2_DIV >> 8) & 0xff; wmb(); | ||
| 30 | |||
| 31 | setup_irq(SNI_A20R_IRQ_TIMER, irq); | ||
| 32 | mips_timer_ack = sni_a20r_timer_ack; | ||
| 33 | } | ||
| 34 | |||
| 35 | #define SNI_8254_TICK_RATE 1193182UL | ||
| 36 | |||
| 37 | #define SNI_8254_TCSAMP_COUNTER ((SNI_8254_TICK_RATE / HZ) + 255) | ||
| 38 | |||
| 39 | static __init unsigned long dosample(void) | ||
| 40 | { | ||
| 41 | u32 ct0, ct1; | ||
| 42 | volatile u8 msb, lsb; | ||
| 43 | |||
| 44 | /* Start the counter. */ | ||
| 45 | outb_p (0x34, 0x43); | ||
| 46 | outb_p(SNI_8254_TCSAMP_COUNTER & 0xff, 0x40); | ||
| 47 | outb (SNI_8254_TCSAMP_COUNTER >> 8, 0x40); | ||
| 48 | |||
| 49 | /* Get initial counter invariant */ | ||
| 50 | ct0 = read_c0_count(); | ||
| 51 | |||
| 52 | /* Latch and spin until top byte of counter0 is zero */ | ||
| 53 | do { | ||
| 54 | outb (0x00, 0x43); | ||
| 55 | lsb = inb (0x40); | ||
| 56 | msb = inb (0x40); | ||
| 57 | ct1 = read_c0_count(); | ||
| 58 | } while (msb); | ||
| 59 | |||
| 60 | /* Stop the counter. */ | ||
| 61 | outb (0x38, 0x43); | ||
| 62 | /* | ||
| 63 | * Return the difference, this is how far the r4k counter increments | ||
| 64 | * for every 1/HZ seconds. We round off the nearest 1 MHz of master | ||
| 65 | * clock (= 1000000 / HZ / 2). | ||
| 66 | */ | ||
| 67 | /*return (ct1 - ct0 + (500000/HZ/2)) / (500000/HZ) * (500000/HZ);*/ | ||
| 68 | return (ct1 - ct0) / (500000/HZ) * (500000/HZ); | ||
| 69 | } | ||
| 70 | |||
| 71 | /* | ||
| 72 | * Here we need to calibrate the cycle counter to at least be close. | ||
| 73 | */ | ||
| 74 | __init void sni_cpu_time_init(void) | ||
| 75 | { | ||
| 76 | unsigned long r4k_ticks[3]; | ||
| 77 | unsigned long r4k_tick; | ||
| 78 | |||
| 79 | /* | ||
| 80 | * Figure out the r4k offset, the algorithm is very simple and works in | ||
| 81 | * _all_ cases as long as the 8254 counter register itself works ok (as | ||
| 82 | * an interrupt driving timer it does not because of bug, this is why | ||
| 83 | * we are using the onchip r4k counter/compare register to serve this | ||
| 84 | * purpose, but for r4k_offset calculation it will work ok for us). | ||
| 85 | * There are other very complicated ways of performing this calculation | ||
| 86 | * but this one works just fine so I am not going to futz around. ;-) | ||
| 87 | */ | ||
| 88 | printk(KERN_INFO "Calibrating system timer... "); | ||
| 89 | dosample(); /* Prime cache. */ | ||
| 90 | dosample(); /* Prime cache. */ | ||
| 91 | /* Zero is NOT an option. */ | ||
| 92 | do { | ||
| 93 | r4k_ticks[0] = dosample(); | ||
| 94 | } while (!r4k_ticks[0]); | ||
| 95 | do { | ||
| 96 | r4k_ticks[1] = dosample(); | ||
| 97 | } while (!r4k_ticks[1]); | ||
| 98 | |||
| 99 | if (r4k_ticks[0] != r4k_ticks[1]) { | ||
| 100 | printk("warning: timer counts differ, retrying... "); | ||
| 101 | r4k_ticks[2] = dosample(); | ||
| 102 | if (r4k_ticks[2] == r4k_ticks[0] | ||
| 103 | || r4k_ticks[2] == r4k_ticks[1]) | ||
| 104 | r4k_tick = r4k_ticks[2]; | ||
| 105 | else { | ||
| 106 | printk("disagreement, using average... "); | ||
| 107 | r4k_tick = (r4k_ticks[0] + r4k_ticks[1] | ||
| 108 | + r4k_ticks[2]) / 3; | ||
| 109 | } | ||
| 110 | } else | ||
| 111 | r4k_tick = r4k_ticks[0]; | ||
| 112 | |||
| 113 | printk("%d [%d.%04d MHz CPU]\n", (int) r4k_tick, | ||
| 114 | (int) (r4k_tick / (500000 / HZ)), | ||
| 115 | (int) (r4k_tick % (500000 / HZ))); | ||
| 116 | |||
| 117 | mips_hpt_frequency = r4k_tick * HZ; | ||
| 118 | } | ||
| 119 | |||
| 120 | /* | ||
| 121 | * R4k counter based timer interrupt. Works on RM200-225 and possibly | ||
| 122 | * others but not on RM400 | ||
| 123 | */ | ||
| 124 | static void __init sni_cpu_timer_setup(struct irqaction *irq) | ||
| 125 | { | ||
| 126 | setup_irq(SNI_MIPS_IRQ_CPU_TIMER, irq); | ||
| 127 | } | ||
| 128 | |||
| 129 | void __init plat_timer_setup(struct irqaction *irq) | ||
| 130 | { | ||
| 131 | switch (sni_brd_type) { | ||
| 132 | case SNI_BRD_10: | ||
| 133 | case SNI_BRD_10NEW: | ||
| 134 | case SNI_BRD_TOWER_OASIC: | ||
| 135 | case SNI_BRD_MINITOWER: | ||
| 136 | sni_a20r_timer_setup (irq); | ||
| 137 | break; | ||
| 138 | |||
| 139 | case SNI_BRD_PCI_TOWER: | ||
| 140 | case SNI_BRD_RM200: | ||
| 141 | case SNI_BRD_PCI_MTOWER: | ||
| 142 | case SNI_BRD_PCI_DESKTOP: | ||
| 143 | case SNI_BRD_PCI_TOWER_CPLUS: | ||
| 144 | case SNI_BRD_PCI_MTOWER_CPLUS: | ||
| 145 | sni_cpu_timer_setup (irq); | ||
| 146 | break; | ||
| 147 | } | ||
| 148 | } | ||
diff --git a/include/asm-mips/ds1216.h b/include/asm-mips/ds1216.h new file mode 100644 index 000000000000..1ff8b73f7a6a --- /dev/null +++ b/include/asm-mips/ds1216.h | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | #ifndef _DS1216_H | ||
| 2 | #define _DS1216_H | ||
| 3 | |||
| 4 | extern volatile unsigned char *ds1216_base; | ||
| 5 | unsigned long ds1216_get_cmos_time(void); | ||
| 6 | int ds1216_set_rtc_mmss(unsigned long nowtime); | ||
| 7 | |||
| 8 | #define DS1216_SEC_BYTE 1 | ||
| 9 | #define DS1216_MIN_BYTE 2 | ||
| 10 | #define DS1216_HOUR_BYTE 3 | ||
| 11 | #define DS1216_HOUR_MASK (0x1f) | ||
| 12 | #define DS1216_AMPM_MASK (1<<5) | ||
| 13 | #define DS1216_1224_MASK (1<<7) | ||
| 14 | #define DS1216_DAY_BYTE 4 | ||
| 15 | #define DS1216_DAY_MASK (0x7) | ||
| 16 | #define DS1216_DATE_BYTE 5 | ||
| 17 | #define DS1216_DATE_MASK (0x3f) | ||
| 18 | #define DS1216_MONTH_BYTE 6 | ||
| 19 | #define DS1216_MONTH_MASK (0x1f) | ||
| 20 | #define DS1216_YEAR_BYTE 7 | ||
| 21 | |||
| 22 | #define DS1216_SEC(buf) (buf[DS1216_SEC_BYTE]) | ||
| 23 | #define DS1216_MIN(buf) (buf[DS1216_MIN_BYTE]) | ||
| 24 | #define DS1216_HOUR(buf) (buf[DS1216_HOUR_BYTE] & DS1216_HOUR_MASK) | ||
| 25 | #define DS1216_AMPM(buf) (buf[DS1216_HOUR_BYTE] & DS1216_AMPM_MASK) | ||
| 26 | #define DS1216_1224(buf) (buf[DS1216_HOUR_BYTE] & DS1216_1224_MASK) | ||
| 27 | #define DS1216_DATE(buf) (buf[DS1216_DATE_BYTE] & DS1216_DATE_MASK) | ||
| 28 | #define DS1216_MONTH(buf) (buf[DS1216_MONTH_BYTE] & DS1216_MONTH_MASK) | ||
| 29 | #define DS1216_YEAR(buf) (buf[DS1216_YEAR_BYTE]) | ||
| 30 | |||
| 31 | #endif | ||
diff --git a/include/asm-mips/mach-rm/cpu-feature-overrides.h b/include/asm-mips/mach-rm/cpu-feature-overrides.h index 11410ae10d36..7e07283140a3 100644 --- a/include/asm-mips/mach-rm/cpu-feature-overrides.h +++ b/include/asm-mips/mach-rm/cpu-feature-overrides.h | |||
| @@ -21,9 +21,7 @@ | |||
| 21 | #define cpu_has_watch 0 | 21 | #define cpu_has_watch 0 |
| 22 | #define cpu_has_mips16 0 | 22 | #define cpu_has_mips16 0 |
| 23 | #define cpu_has_divec 0 | 23 | #define cpu_has_divec 0 |
| 24 | #define cpu_has_vce 0 | ||
| 25 | #define cpu_has_cache_cdex_p 1 | 24 | #define cpu_has_cache_cdex_p 1 |
| 26 | #define cpu_has_cache_cdex_s 0 | ||
| 27 | #define cpu_has_prefetch 0 | 25 | #define cpu_has_prefetch 0 |
| 28 | #define cpu_has_mcheck 0 | 26 | #define cpu_has_mcheck 0 |
| 29 | #define cpu_has_ejtag 0 | 27 | #define cpu_has_ejtag 0 |
| @@ -35,9 +33,6 @@ | |||
| 35 | #define cpu_has_nofpuex 0 | 33 | #define cpu_has_nofpuex 0 |
| 36 | #define cpu_has_64bits 1 | 34 | #define cpu_has_64bits 1 |
| 37 | 35 | ||
| 38 | #define cpu_dcache_line_size() 32 | ||
| 39 | #define cpu_icache_line_size() 32 | ||
| 40 | |||
| 41 | #define cpu_has_mips32r1 0 | 36 | #define cpu_has_mips32r1 0 |
| 42 | #define cpu_has_mips32r2 0 | 37 | #define cpu_has_mips32r2 0 |
| 43 | #define cpu_has_mips64r1 0 | 38 | #define cpu_has_mips64r1 0 |
diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h index b9ba54d0dd35..62f9be6f7320 100644 --- a/include/asm-mips/sni.h +++ b/include/asm-mips/sni.h | |||
| @@ -6,12 +6,72 @@ | |||
| 6 | * for more details. | 6 | * for more details. |
| 7 | * | 7 | * |
| 8 | * Copyright (C) 1997, 1998 by Ralf Baechle | 8 | * Copyright (C) 1997, 1998 by Ralf Baechle |
| 9 | * Copyright (C) 2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de) | ||
| 9 | */ | 10 | */ |
| 10 | #ifndef __ASM_SNI_H | 11 | #ifndef __ASM_SNI_H |
| 11 | #define __ASM_SNI_H | 12 | #define __ASM_SNI_H |
| 12 | 13 | ||
| 14 | extern unsigned int sni_brd_type; | ||
| 15 | |||
| 16 | #define SNI_BRD_10 2 | ||
| 17 | #define SNI_BRD_10NEW 3 | ||
| 18 | #define SNI_BRD_TOWER_OASIC 4 | ||
| 19 | #define SNI_BRD_MINITOWER 5 | ||
| 20 | #define SNI_BRD_PCI_TOWER 6 | ||
| 21 | #define SNI_BRD_RM200 7 | ||
| 22 | #define SNI_BRD_PCI_MTOWER 8 | ||
| 23 | #define SNI_BRD_PCI_DESKTOP 9 | ||
| 24 | #define SNI_BRD_PCI_TOWER_CPLUS 10 | ||
| 25 | #define SNI_BRD_PCI_MTOWER_CPLUS 11 | ||
| 26 | |||
| 27 | /* RM400 cpu types */ | ||
| 28 | #define SNI_CPU_M8021 0x01 | ||
| 29 | #define SNI_CPU_M8030 0x04 | ||
| 30 | #define SNI_CPU_M8031 0x06 | ||
| 31 | #define SNI_CPU_M8034 0x0f | ||
| 32 | #define SNI_CPU_M8037 0x07 | ||
| 33 | #define SNI_CPU_M8040 0x05 | ||
| 34 | #define SNI_CPU_M8043 0x09 | ||
| 35 | #define SNI_CPU_M8050 0x0b | ||
| 36 | #define SNI_CPU_M8053 0x0d | ||
| 37 | |||
| 13 | #define SNI_PORT_BASE 0xb4000000 | 38 | #define SNI_PORT_BASE 0xb4000000 |
| 14 | 39 | ||
| 40 | #ifndef __MIPSEL__ | ||
| 41 | /* | ||
| 42 | * ASIC PCI registers for big endian configuration. | ||
| 43 | */ | ||
| 44 | #define PCIMT_UCONF 0xbfff0004 | ||
| 45 | #define PCIMT_IOADTIMEOUT2 0xbfff000c | ||
| 46 | #define PCIMT_IOMEMCONF 0xbfff0014 | ||
| 47 | #define PCIMT_IOMMU 0xbfff001c | ||
| 48 | #define PCIMT_IOADTIMEOUT1 0xbfff0024 | ||
| 49 | #define PCIMT_DMAACCESS 0xbfff002c | ||
| 50 | #define PCIMT_DMAHIT 0xbfff0034 | ||
| 51 | #define PCIMT_ERRSTATUS 0xbfff003c | ||
| 52 | #define PCIMT_ERRADDR 0xbfff0044 | ||
| 53 | #define PCIMT_SYNDROME 0xbfff004c | ||
| 54 | #define PCIMT_ITPEND 0xbfff0054 | ||
| 55 | #define IT_INT2 0x01 | ||
| 56 | #define IT_INTD 0x02 | ||
| 57 | #define IT_INTC 0x04 | ||
| 58 | #define IT_INTB 0x08 | ||
| 59 | #define IT_INTA 0x10 | ||
| 60 | #define IT_EISA 0x20 | ||
| 61 | #define IT_SCSI 0x40 | ||
| 62 | #define IT_ETH 0x80 | ||
| 63 | #define PCIMT_IRQSEL 0xbfff005c | ||
| 64 | #define PCIMT_TESTMEM 0xbfff0064 | ||
| 65 | #define PCIMT_ECCREG 0xbfff006c | ||
| 66 | #define PCIMT_CONFIG_ADDRESS 0xbfff0074 | ||
| 67 | #define PCIMT_ASIC_ID 0xbfff007c /* read */ | ||
| 68 | #define PCIMT_SOFT_RESET 0xbfff007c /* write */ | ||
| 69 | #define PCIMT_PIA_OE 0xbfff0084 | ||
| 70 | #define PCIMT_PIA_DATAOUT 0xbfff008c | ||
| 71 | #define PCIMT_PIA_DATAIN 0xbfff0094 | ||
| 72 | #define PCIMT_CACHECONF 0xbfff009c | ||
| 73 | #define PCIMT_INVSPACE 0xbfff00a4 | ||
| 74 | #else | ||
| 15 | /* | 75 | /* |
| 16 | * ASIC PCI registers for little endian configuration. | 76 | * ASIC PCI registers for little endian configuration. |
| 17 | */ | 77 | */ |
| @@ -45,6 +105,8 @@ | |||
| 45 | #define PCIMT_PIA_DATAIN 0xbfff0090 | 105 | #define PCIMT_PIA_DATAIN 0xbfff0090 |
| 46 | #define PCIMT_CACHECONF 0xbfff0098 | 106 | #define PCIMT_CACHECONF 0xbfff0098 |
| 47 | #define PCIMT_INVSPACE 0xbfff00a0 | 107 | #define PCIMT_INVSPACE 0xbfff00a0 |
| 108 | #endif | ||
| 109 | |||
| 48 | #define PCIMT_PCI_CONF 0xbfff0100 | 110 | #define PCIMT_PCI_CONF 0xbfff0100 |
| 49 | 111 | ||
| 50 | /* | 112 | /* |
| @@ -73,6 +135,36 @@ | |||
| 73 | #define PCIMT_PWDN 0xbfdf0000 | 135 | #define PCIMT_PWDN 0xbfdf0000 |
| 74 | 136 | ||
| 75 | /* | 137 | /* |
| 138 | * A20R based boards | ||
| 139 | */ | ||
| 140 | #define A20R_PT_CLOCK_BASE 0xbc040000 | ||
| 141 | #define A20R_PT_TIM0_ACK 0xbc050000 | ||
| 142 | #define A20R_PT_TIM1_ACK 0xbc060000 | ||
| 143 | |||
| 144 | #define SNI_MIPS_IRQ_CPU_BASE 16 | ||
| 145 | #define SNI_MIPS_IRQ_CPU_TIMER (SNI_MIPS_IRQ_CPU_BASE+7) | ||
| 146 | |||
| 147 | #define SNI_A20R_IRQ_BASE SNI_MIPS_IRQ_CPU_BASE | ||
| 148 | #define SNI_A20R_IRQ_TIMER (SNI_A20R_IRQ_BASE+5) | ||
| 149 | |||
| 150 | #define SNI_DS1216_A20R_BASE 0xbc081ffc | ||
| 151 | #define SNI_DS1216_RM200_BASE 0xbcd41ffc | ||
| 152 | |||
| 153 | #define SNI_PCIT_INT_REG 0xbfff000c | ||
| 154 | |||
| 155 | #define SNI_PCIT_INT_START 24 | ||
| 156 | #define SNI_PCIT_INT_END 30 | ||
| 157 | |||
| 158 | #define PCIT_IRQ_ETHERNET (SNI_MIPS_IRQ_CPU_BASE + 5) | ||
| 159 | #define PCIT_IRQ_INTA (SNI_PCIT_INT_START + 0) | ||
| 160 | #define PCIT_IRQ_INTB (SNI_PCIT_INT_START + 1) | ||
| 161 | #define PCIT_IRQ_INTC (SNI_PCIT_INT_START + 2) | ||
| 162 | #define PCIT_IRQ_INTD (SNI_PCIT_INT_START + 3) | ||
| 163 | #define PCIT_IRQ_SCSI0 (SNI_PCIT_INT_START + 4) | ||
| 164 | #define PCIT_IRQ_SCSI1 (SNI_PCIT_INT_START + 5) | ||
| 165 | |||
| 166 | |||
| 167 | /* | ||
| 76 | * Interrupt 0-16 are EISA interrupts. Interrupts from 16 on are assigned | 168 | * Interrupt 0-16 are EISA interrupts. Interrupts from 16 on are assigned |
| 77 | * to the other interrupts generated by ASIC PCI. | 169 | * to the other interrupts generated by ASIC PCI. |
| 78 | * | 170 | * |
| @@ -80,18 +172,22 @@ | |||
| 80 | * ASIC PCI interrupt. | 172 | * ASIC PCI interrupt. |
| 81 | */ | 173 | */ |
| 82 | #define PCIMT_KEYBOARD_IRQ 1 | 174 | #define PCIMT_KEYBOARD_IRQ 1 |
| 83 | #define PCIMT_IRQ_INT2 16 | 175 | #define PCIMT_IRQ_INT2 24 |
| 84 | #define PCIMT_IRQ_INTD 17 | 176 | #define PCIMT_IRQ_INTD 25 |
| 85 | #define PCIMT_IRQ_INTC 18 | 177 | #define PCIMT_IRQ_INTC 26 |
| 86 | #define PCIMT_IRQ_INTB 19 | 178 | #define PCIMT_IRQ_INTB 27 |
| 87 | #define PCIMT_IRQ_INTA 20 | 179 | #define PCIMT_IRQ_INTA 28 |
| 88 | #define PCIMT_IRQ_EISA 21 | 180 | #define PCIMT_IRQ_EISA 29 |
| 89 | #define PCIMT_IRQ_SCSI 22 | 181 | #define PCIMT_IRQ_SCSI 30 |
| 90 | #define PCIMT_IRQ_ETHERNET 23 | 182 | |
| 183 | #define PCIMT_IRQ_ETHERNET (SNI_MIPS_IRQ_CPU_BASE+6) | ||
| 184 | |||
| 185 | #if 0 | ||
| 91 | #define PCIMT_IRQ_TEMPERATURE 24 | 186 | #define PCIMT_IRQ_TEMPERATURE 24 |
| 92 | #define PCIMT_IRQ_EISA_NMI 25 | 187 | #define PCIMT_IRQ_EISA_NMI 25 |
| 93 | #define PCIMT_IRQ_POWER_OFF 26 | 188 | #define PCIMT_IRQ_POWER_OFF 26 |
| 94 | #define PCIMT_IRQ_BUTTON 27 | 189 | #define PCIMT_IRQ_BUTTON 27 |
| 190 | #endif | ||
| 95 | 191 | ||
| 96 | /* | 192 | /* |
| 97 | * Base address for the mapped 16mb EISA bus segment. | 193 | * Base address for the mapped 16mb EISA bus segment. |
| @@ -101,4 +197,24 @@ | |||
| 101 | /* PCI EISA Interrupt acknowledge */ | 197 | /* PCI EISA Interrupt acknowledge */ |
| 102 | #define PCIMT_INT_ACKNOWLEDGE 0xba000000 | 198 | #define PCIMT_INT_ACKNOWLEDGE 0xba000000 |
| 103 | 199 | ||
| 200 | /* board specific init functions */ | ||
| 201 | extern void sni_a20r_init (void); | ||
| 202 | extern void sni_pcit_init (void); | ||
| 203 | extern void sni_rm200_init (void); | ||
| 204 | extern void sni_pcimt_init (void); | ||
| 205 | |||
| 206 | /* board specific irq init functions */ | ||
| 207 | extern void sni_a20r_irq_init (void); | ||
| 208 | extern void sni_pcit_irq_init (void); | ||
| 209 | extern void sni_pcit_cplus_irq_init (void); | ||
| 210 | extern void sni_rm200_irq_init (void); | ||
| 211 | extern void sni_pcimt_irq_init (void); | ||
| 212 | |||
| 213 | /* timer inits */ | ||
| 214 | extern void sni_cpu_time_init(void); | ||
| 215 | |||
| 216 | /* common irq stuff */ | ||
| 217 | extern void (*sni_hwint)(void); | ||
| 218 | extern struct irqaction sni_isa_irq; | ||
| 219 | |||
| 104 | #endif /* __ASM_SNI_H */ | 220 | #endif /* __ASM_SNI_H */ |
