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 v3.0 363 lines 9.0 kB view raw
1/* 2 * MPC85xx setup and early boot code plus other random bits. 3 * 4 * Maintained by Kumar Gala (see MAINTAINERS for contact information) 5 * 6 * Copyright 2005 Freescale Semiconductor Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify it 9 * under the terms of the GNU General Public License as published by the 10 * Free Software Foundation; either version 2 of the License, or (at your 11 * option) any later version. 12 */ 13 14#include <linux/stddef.h> 15#include <linux/kernel.h> 16#include <linux/init.h> 17#include <linux/errno.h> 18#include <linux/reboot.h> 19#include <linux/pci.h> 20#include <linux/kdev_t.h> 21#include <linux/major.h> 22#include <linux/console.h> 23#include <linux/delay.h> 24#include <linux/seq_file.h> 25#include <linux/initrd.h> 26#include <linux/module.h> 27#include <linux/interrupt.h> 28#include <linux/fsl_devices.h> 29#include <linux/of_platform.h> 30 31#include <asm/system.h> 32#include <asm/pgtable.h> 33#include <asm/page.h> 34#include <asm/atomic.h> 35#include <asm/time.h> 36#include <asm/io.h> 37#include <asm/machdep.h> 38#include <asm/ipic.h> 39#include <asm/pci-bridge.h> 40#include <asm/irq.h> 41#include <mm/mmu_decl.h> 42#include <asm/prom.h> 43#include <asm/udbg.h> 44#include <asm/mpic.h> 45#include <asm/i8259.h> 46 47#include <sysdev/fsl_soc.h> 48#include <sysdev/fsl_pci.h> 49 50/* CADMUS info */ 51/* xxx - galak, move into device tree */ 52#define CADMUS_BASE (0xf8004000) 53#define CADMUS_SIZE (256) 54#define CM_VER (0) 55#define CM_CSR (1) 56#define CM_RST (2) 57 58 59static int cds_pci_slot = 2; 60static volatile u8 *cadmus; 61 62#ifdef CONFIG_PCI 63 64#define ARCADIA_HOST_BRIDGE_IDSEL 17 65#define ARCADIA_2ND_BRIDGE_IDSEL 3 66 67static int mpc85xx_exclude_device(struct pci_controller *hose, 68 u_char bus, u_char devfn) 69{ 70 /* We explicitly do not go past the Tundra 320 Bridge */ 71 if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) 72 return PCIBIOS_DEVICE_NOT_FOUND; 73 if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) 74 return PCIBIOS_DEVICE_NOT_FOUND; 75 else 76 return PCIBIOS_SUCCESSFUL; 77} 78 79static void mpc85xx_cds_restart(char *cmd) 80{ 81 struct pci_dev *dev; 82 u_char tmp; 83 84 if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, PCI_DEVICE_ID_VIA_82C686, 85 NULL))) { 86 87 /* Use the VIA Super Southbridge to force a PCI reset */ 88 pci_read_config_byte(dev, 0x47, &tmp); 89 pci_write_config_byte(dev, 0x47, tmp | 1); 90 91 /* Flush the outbound PCI write queues */ 92 pci_read_config_byte(dev, 0x47, &tmp); 93 94 /* 95 * At this point, the harware reset should have triggered. 96 * However, if it doesn't work for some mysterious reason, 97 * just fall through to the default reset below. 98 */ 99 100 pci_dev_put(dev); 101 } 102 103 /* 104 * If we can't find the VIA chip (maybe the P2P bridge is disabled) 105 * or the VIA chip reset didn't work, just use the default reset. 106 */ 107 fsl_rstcr_restart(NULL); 108} 109 110static void __init mpc85xx_cds_pci_irq_fixup(struct pci_dev *dev) 111{ 112 u_char c; 113 if (dev->vendor == PCI_VENDOR_ID_VIA) { 114 switch (dev->device) { 115 case PCI_DEVICE_ID_VIA_82C586_1: 116 /* 117 * U-Boot does not set the enable bits 118 * for the IDE device. Force them on here. 119 */ 120 pci_read_config_byte(dev, 0x40, &c); 121 c |= 0x03; /* IDE: Chip Enable Bits */ 122 pci_write_config_byte(dev, 0x40, c); 123 124 /* 125 * Since only primary interface works, force the 126 * IDE function to standard primary IDE interrupt 127 * w/ 8259 offset 128 */ 129 dev->irq = 14; 130 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 131 break; 132 /* 133 * Force legacy USB interrupt routing 134 */ 135 case PCI_DEVICE_ID_VIA_82C586_2: 136 /* There are two USB controllers. 137 * Identify them by functon number 138 */ 139 if (PCI_FUNC(dev->devfn) == 3) 140 dev->irq = 11; 141 else 142 dev->irq = 10; 143 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); 144 default: 145 break; 146 } 147 } 148} 149 150static void __devinit skip_fake_bridge(struct pci_dev *dev) 151{ 152 /* Make it an error to skip the fake bridge 153 * in pci_setup_device() in probe.c */ 154 dev->hdr_type = 0x7f; 155} 156DECLARE_PCI_FIXUP_EARLY(0x1957, 0x3fff, skip_fake_bridge); 157DECLARE_PCI_FIXUP_EARLY(0x3fff, 0x1957, skip_fake_bridge); 158DECLARE_PCI_FIXUP_EARLY(0xff3f, 0x5719, skip_fake_bridge); 159 160#ifdef CONFIG_PPC_I8259 161static void mpc85xx_8259_cascade_handler(unsigned int irq, 162 struct irq_desc *desc) 163{ 164 unsigned int cascade_irq = i8259_irq(); 165 166 if (cascade_irq != NO_IRQ) 167 /* handle an interrupt from the 8259 */ 168 generic_handle_irq(cascade_irq); 169 170 /* check for any interrupts from the shared IRQ line */ 171 handle_fasteoi_irq(irq, desc); 172} 173 174static irqreturn_t mpc85xx_8259_cascade_action(int irq, void *dev_id) 175{ 176 return IRQ_HANDLED; 177} 178 179static struct irqaction mpc85xxcds_8259_irqaction = { 180 .handler = mpc85xx_8259_cascade_action, 181 .flags = IRQF_SHARED, 182 .name = "8259 cascade", 183}; 184#endif /* PPC_I8259 */ 185#endif /* CONFIG_PCI */ 186 187static void __init mpc85xx_cds_pic_init(void) 188{ 189 struct mpic *mpic; 190 struct resource r; 191 struct device_node *np = NULL; 192 193 np = of_find_node_by_type(np, "open-pic"); 194 195 if (np == NULL) { 196 printk(KERN_ERR "Could not find open-pic node\n"); 197 return; 198 } 199 200 if (of_address_to_resource(np, 0, &r)) { 201 printk(KERN_ERR "Failed to map mpic register space\n"); 202 of_node_put(np); 203 return; 204 } 205 206 mpic = mpic_alloc(np, r.start, 207 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 208 0, 256, " OpenPIC "); 209 BUG_ON(mpic == NULL); 210 211 /* Return the mpic node */ 212 of_node_put(np); 213 214 mpic_init(mpic); 215} 216 217#if defined(CONFIG_PPC_I8259) && defined(CONFIG_PCI) 218static int mpc85xx_cds_8259_attach(void) 219{ 220 int ret; 221 struct device_node *np = NULL; 222 struct device_node *cascade_node = NULL; 223 int cascade_irq; 224 225 /* Initialize the i8259 controller */ 226 for_each_node_by_type(np, "interrupt-controller") 227 if (of_device_is_compatible(np, "chrp,iic")) { 228 cascade_node = np; 229 break; 230 } 231 232 if (cascade_node == NULL) { 233 printk(KERN_DEBUG "Could not find i8259 PIC\n"); 234 return -ENODEV; 235 } 236 237 cascade_irq = irq_of_parse_and_map(cascade_node, 0); 238 if (cascade_irq == NO_IRQ) { 239 printk(KERN_ERR "Failed to map cascade interrupt\n"); 240 return -ENXIO; 241 } 242 243 i8259_init(cascade_node, 0); 244 of_node_put(cascade_node); 245 246 /* 247 * Hook the interrupt to make sure desc->action is never NULL. 248 * This is required to ensure that the interrupt does not get 249 * disabled when the last user of the shared IRQ line frees their 250 * interrupt. 251 */ 252 if ((ret = setup_irq(cascade_irq, &mpc85xxcds_8259_irqaction))) { 253 printk(KERN_ERR "Failed to setup cascade interrupt\n"); 254 return ret; 255 } 256 257 /* Success. Connect our low-level cascade handler. */ 258 irq_set_handler(cascade_irq, mpc85xx_8259_cascade_handler); 259 260 return 0; 261} 262machine_device_initcall(mpc85xx_cds, mpc85xx_cds_8259_attach); 263 264#endif /* CONFIG_PPC_I8259 */ 265 266/* 267 * Setup the architecture 268 */ 269static void __init mpc85xx_cds_setup_arch(void) 270{ 271#ifdef CONFIG_PCI 272 struct device_node *np; 273#endif 274 275 if (ppc_md.progress) 276 ppc_md.progress("mpc85xx_cds_setup_arch()", 0); 277 278 cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE); 279 cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1; 280 281 if (ppc_md.progress) { 282 char buf[40]; 283 snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n", 284 cadmus[CM_VER], cds_pci_slot); 285 ppc_md.progress(buf, 0); 286 } 287 288#ifdef CONFIG_PCI 289 for_each_node_by_type(np, "pci") { 290 if (of_device_is_compatible(np, "fsl,mpc8540-pci") || 291 of_device_is_compatible(np, "fsl,mpc8548-pcie")) { 292 struct resource rsrc; 293 of_address_to_resource(np, 0, &rsrc); 294 if ((rsrc.start & 0xfffff) == 0x8000) 295 fsl_add_bridge(np, 1); 296 else 297 fsl_add_bridge(np, 0); 298 } 299 } 300 301 ppc_md.pci_irq_fixup = mpc85xx_cds_pci_irq_fixup; 302 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 303#endif 304} 305 306static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) 307{ 308 uint pvid, svid, phid1; 309 310 pvid = mfspr(SPRN_PVR); 311 svid = mfspr(SPRN_SVR); 312 313 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); 314 seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]); 315 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 316 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 317 318 /* Display cpu Pll setting */ 319 phid1 = mfspr(SPRN_HID1); 320 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); 321} 322 323 324/* 325 * Called very early, device-tree isn't unflattened 326 */ 327static int __init mpc85xx_cds_probe(void) 328{ 329 unsigned long root = of_get_flat_dt_root(); 330 331 return of_flat_dt_is_compatible(root, "MPC85xxCDS"); 332} 333 334static struct of_device_id __initdata of_bus_ids[] = { 335 { .type = "soc", }, 336 { .compatible = "soc", }, 337 { .compatible = "simple-bus", }, 338 { .compatible = "gianfar", }, 339 {}, 340}; 341 342static int __init declare_of_platform_devices(void) 343{ 344 return of_platform_bus_probe(NULL, of_bus_ids, NULL); 345} 346machine_device_initcall(mpc85xx_cds, declare_of_platform_devices); 347 348define_machine(mpc85xx_cds) { 349 .name = "MPC85xx CDS", 350 .probe = mpc85xx_cds_probe, 351 .setup_arch = mpc85xx_cds_setup_arch, 352 .init_IRQ = mpc85xx_cds_pic_init, 353 .show_cpuinfo = mpc85xx_cds_show_cpuinfo, 354 .get_irq = mpic_get_irq, 355#ifdef CONFIG_PCI 356 .restart = mpc85xx_cds_restart, 357 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 358#else 359 .restart = fsl_rstcr_restart, 360#endif 361 .calibrate_decr = generic_calibrate_decr, 362 .progress = udbg_progress, 363};