Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.14 325 lines 8.4 kB view raw
1/* 2 * arch/ppc/platforms/spruce.c 3 * 4 * Board and PCI setup routines for IBM Spruce 5 * 6 * Author: MontaVista Software <source@mvista.com> 7 * 8 * 2000-2004 (c) MontaVista, Software, Inc. This file is licensed under 9 * the terms of the GNU General Public License version 2. This program 10 * is licensed "as is" without any warranty of any kind, whether express 11 * or implied. 12 */ 13 14#include <linux/config.h> 15#include <linux/stddef.h> 16#include <linux/kernel.h> 17#include <linux/init.h> 18#include <linux/errno.h> 19#include <linux/reboot.h> 20#include <linux/pci.h> 21#include <linux/kdev_t.h> 22#include <linux/types.h> 23#include <linux/major.h> 24#include <linux/initrd.h> 25#include <linux/console.h> 26#include <linux/delay.h> 27#include <linux/seq_file.h> 28#include <linux/ide.h> 29#include <linux/root_dev.h> 30#include <linux/serial.h> 31#include <linux/tty.h> 32#include <linux/serial_core.h> 33 34#include <asm/system.h> 35#include <asm/pgtable.h> 36#include <asm/page.h> 37#include <asm/dma.h> 38#include <asm/io.h> 39#include <asm/machdep.h> 40#include <asm/time.h> 41#include <asm/todc.h> 42#include <asm/bootinfo.h> 43#include <asm/kgdb.h> 44 45#include <syslib/cpc700.h> 46 47#include "spruce.h" 48 49static inline int 50spruce_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) 51{ 52 static char pci_irq_table[][4] = 53 /* 54 * PCI IDSEL/INTPIN->INTLINE 55 * A B C D 56 */ 57 { 58 {23, 24, 25, 26}, /* IDSEL 1 - PCI slot 3 */ 59 {24, 25, 26, 23}, /* IDSEL 2 - PCI slot 2 */ 60 {25, 26, 23, 24}, /* IDSEL 3 - PCI slot 1 */ 61 {26, 23, 24, 25}, /* IDSEL 4 - PCI slot 0 */ 62 }; 63 64 const long min_idsel = 1, max_idsel = 4, irqs_per_slot = 4; 65 return PCI_IRQ_TABLE_LOOKUP; 66} 67 68static void __init 69spruce_setup_hose(void) 70{ 71 struct pci_controller *hose; 72 73 /* Setup hose */ 74 hose = pcibios_alloc_controller(); 75 if (!hose) 76 return; 77 78 hose->first_busno = 0; 79 hose->last_busno = 0xff; 80 81 pci_init_resource(&hose->io_resource, 82 SPRUCE_PCI_LOWER_IO, 83 SPRUCE_PCI_UPPER_IO, 84 IORESOURCE_IO, 85 "PCI host bridge"); 86 87 pci_init_resource(&hose->mem_resources[0], 88 SPRUCE_PCI_LOWER_MEM, 89 SPRUCE_PCI_UPPER_MEM, 90 IORESOURCE_MEM, 91 "PCI host bridge"); 92 93 hose->io_space.start = SPRUCE_PCI_LOWER_IO; 94 hose->io_space.end = SPRUCE_PCI_UPPER_IO; 95 hose->mem_space.start = SPRUCE_PCI_LOWER_MEM; 96 hose->mem_space.end = SPRUCE_PCI_UPPER_MEM; 97 hose->io_base_virt = (void *)SPRUCE_ISA_IO_BASE; 98 99 setup_indirect_pci(hose, 100 SPRUCE_PCI_CONFIG_ADDR, 101 SPRUCE_PCI_CONFIG_DATA); 102 103 hose->last_busno = pciauto_bus_scan(hose, hose->first_busno); 104 105 ppc_md.pci_swizzle = common_swizzle; 106 ppc_md.pci_map_irq = spruce_map_irq; 107} 108 109/* 110 * CPC700 PIC interrupt programming table 111 * 112 * First entry is the sensitivity (level/edge), second is the polarity. 113 */ 114unsigned int cpc700_irq_assigns[32][2] = { 115 { 1, 1 }, /* IRQ 0: ECC Correctable Error - rising edge */ 116 { 1, 1 }, /* IRQ 1: PCI Write Mem Range - rising edge */ 117 { 0, 1 }, /* IRQ 2: PCI Write Command Reg - active high */ 118 { 0, 1 }, /* IRQ 3: UART 0 - active high */ 119 { 0, 1 }, /* IRQ 4: UART 1 - active high */ 120 { 0, 1 }, /* IRQ 5: ICC 0 - active high */ 121 { 0, 1 }, /* IRQ 6: ICC 1 - active high */ 122 { 0, 1 }, /* IRQ 7: GPT Compare 0 - active high */ 123 { 0, 1 }, /* IRQ 8: GPT Compare 1 - active high */ 124 { 0, 1 }, /* IRQ 9: GPT Compare 2 - active high */ 125 { 0, 1 }, /* IRQ 10: GPT Compare 3 - active high */ 126 { 0, 1 }, /* IRQ 11: GPT Compare 4 - active high */ 127 { 0, 1 }, /* IRQ 12: GPT Capture 0 - active high */ 128 { 0, 1 }, /* IRQ 13: GPT Capture 1 - active high */ 129 { 0, 1 }, /* IRQ 14: GPT Capture 2 - active high */ 130 { 0, 1 }, /* IRQ 15: GPT Capture 3 - active high */ 131 { 0, 1 }, /* IRQ 16: GPT Capture 4 - active high */ 132 { 0, 0 }, /* IRQ 17: Reserved */ 133 { 0, 0 }, /* IRQ 18: Reserved */ 134 { 0, 0 }, /* IRQ 19: Reserved */ 135 { 0, 1 }, /* IRQ 20: FPGA EXT_IRQ0 - active high */ 136 { 1, 1 }, /* IRQ 21: Mouse - rising edge */ 137 { 1, 1 }, /* IRQ 22: Keyboard - rising edge */ 138 { 0, 0 }, /* IRQ 23: PCI Slot 3 - active low */ 139 { 0, 0 }, /* IRQ 24: PCI Slot 2 - active low */ 140 { 0, 0 }, /* IRQ 25: PCI Slot 1 - active low */ 141 { 0, 0 }, /* IRQ 26: PCI Slot 0 - active low */ 142}; 143 144static void __init 145spruce_calibrate_decr(void) 146{ 147 int freq, divisor = 4; 148 149 /* determine processor bus speed */ 150 freq = SPRUCE_BUS_SPEED; 151 tb_ticks_per_jiffy = freq / HZ / divisor; 152 tb_to_us = mulhwu_scale_factor(freq/divisor, 1000000); 153} 154 155static int 156spruce_show_cpuinfo(struct seq_file *m) 157{ 158 seq_printf(m, "vendor\t\t: IBM\n"); 159 seq_printf(m, "machine\t\t: Spruce\n"); 160 161 return 0; 162} 163 164static void __init 165spruce_early_serial_map(void) 166{ 167 u32 uart_clk; 168 struct uart_port serial_req; 169 170 if (SPRUCE_UARTCLK_IS_33M(readb(SPRUCE_FPGA_REG_A))) 171 uart_clk = SPRUCE_BAUD_33M * 16; 172 else 173 uart_clk = SPRUCE_BAUD_30M * 16; 174 175 /* Setup serial port access */ 176 memset(&serial_req, 0, sizeof(serial_req)); 177 serial_req.uartclk = uart_clk; 178 serial_req.irq = UART0_INT; 179 serial_req.flags = ASYNC_BOOT_AUTOCONF; 180 serial_req.iotype = SERIAL_IO_MEM; 181 serial_req.membase = (u_char *)UART0_IO_BASE; 182 serial_req.regshift = 0; 183 184#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) 185 gen550_init(0, &serial_req); 186#endif 187#ifdef CONFIG_SERIAL_8250 188 if (early_serial_setup(&serial_req) != 0) 189 printk("Early serial init of port 0 failed\n"); 190#endif 191 192 /* Assume early_serial_setup() doesn't modify serial_req */ 193 serial_req.line = 1; 194 serial_req.irq = UART1_INT; 195 serial_req.membase = (u_char *)UART1_IO_BASE; 196 197#if defined(CONFIG_KGDB) || defined(CONFIG_SERIAL_TEXT_DEBUG) 198 gen550_init(1, &serial_req); 199#endif 200#ifdef CONFIG_SERIAL_8250 201 if (early_serial_setup(&serial_req) != 0) 202 printk("Early serial init of port 1 failed\n"); 203#endif 204} 205 206TODC_ALLOC(); 207 208static void __init 209spruce_setup_arch(void) 210{ 211 /* Setup TODC access */ 212 TODC_INIT(TODC_TYPE_DS1643, 0, 0, SPRUCE_RTC_BASE_ADDR, 8); 213 214 /* init to some ~sane value until calibrate_delay() runs */ 215 loops_per_jiffy = 50000000 / HZ; 216 217 /* Setup PCI host bridge */ 218 spruce_setup_hose(); 219 220#ifdef CONFIG_BLK_DEV_INITRD 221 if (initrd_start) 222 ROOT_DEV = Root_RAM0; 223 else 224#endif 225#ifdef CONFIG_ROOT_NFS 226 ROOT_DEV = Root_NFS; 227#else 228 ROOT_DEV = Root_SDA1; 229#endif 230 231 /* Identify the system */ 232 printk(KERN_INFO "System Identification: IBM Spruce\n"); 233 printk(KERN_INFO "Port by MontaVista Software, Inc. (source@mvista.com)\n"); 234} 235 236static void 237spruce_restart(char *cmd) 238{ 239 local_irq_disable(); 240 241 /* SRR0 has system reset vector, SRR1 has default MSR value */ 242 /* rfi restores MSR from SRR1 and sets the PC to the SRR0 value */ 243 __asm__ __volatile__ 244 ("\n\ 245 lis 3,0xfff0 \n\ 246 ori 3,3,0x0100 \n\ 247 mtspr 26,3 \n\ 248 li 3,0 \n\ 249 mtspr 27,3 \n\ 250 rfi \n\ 251 "); 252 for(;;); 253} 254 255static void 256spruce_power_off(void) 257{ 258 for(;;); 259} 260 261static void 262spruce_halt(void) 263{ 264 spruce_restart(NULL); 265} 266 267static void __init 268spruce_map_io(void) 269{ 270 io_block_mapping(SPRUCE_PCI_IO_BASE, SPRUCE_PCI_PHY_IO_BASE, 271 0x08000000, _PAGE_IO); 272} 273 274/* 275 * Set BAT 3 to map 0xf8000000 to end of physical memory space 1-to-1. 276 */ 277static __inline__ void 278spruce_set_bat(void) 279{ 280 mb(); 281 mtspr(SPRN_DBAT1U, 0xf8000ffe); 282 mtspr(SPRN_DBAT1L, 0xf800002a); 283 mb(); 284} 285 286void __init 287platform_init(unsigned long r3, unsigned long r4, unsigned long r5, 288 unsigned long r6, unsigned long r7) 289{ 290 parse_bootinfo(find_bootinfo()); 291 292 /* Map in board regs, etc. */ 293 spruce_set_bat(); 294 295 isa_io_base = SPRUCE_ISA_IO_BASE; 296 pci_dram_offset = SPRUCE_PCI_SYS_MEM_BASE; 297 298 ppc_md.setup_arch = spruce_setup_arch; 299 ppc_md.show_cpuinfo = spruce_show_cpuinfo; 300 ppc_md.init_IRQ = cpc700_init_IRQ; 301 ppc_md.get_irq = cpc700_get_irq; 302 303 ppc_md.setup_io_mappings = spruce_map_io; 304 305 ppc_md.restart = spruce_restart; 306 ppc_md.power_off = spruce_power_off; 307 ppc_md.halt = spruce_halt; 308 309 ppc_md.time_init = todc_time_init; 310 ppc_md.set_rtc_time = todc_set_rtc_time; 311 ppc_md.get_rtc_time = todc_get_rtc_time; 312 ppc_md.calibrate_decr = spruce_calibrate_decr; 313 314 ppc_md.nvram_read_val = todc_direct_read_val; 315 ppc_md.nvram_write_val = todc_direct_write_val; 316 317 spruce_early_serial_map(); 318 319#ifdef CONFIG_SERIAL_TEXT_DEBUG 320 ppc_md.progress = gen550_progress; 321#endif /* CONFIG_SERIAL_TEXT_DEBUG */ 322#ifdef CONFIG_KGDB 323 ppc_md.kgdb_map_scc = gen550_kgdb_map_scc; 324#endif 325}