1/* 2 * Architecture- / platform-specific boot-time initialization code for 3 * IBM PowerPC 4xx based boards. Adapted from original 4 * code by Gary Thomas, Cort Dougan <cort@fsmlabs.com>, and Dan Malek 5 * <dan@net4x.com>. 6 * 7 * Copyright(c) 1999-2000 Grant Erickson <grant@lcse.umn.edu> 8 * 9 * Rewritten and ported to the merged powerpc tree: 10 * Copyright 2007 IBM Corporation 11 * Josh Boyer <jwboyer@linux.vnet.ibm.com> 12 * 13 * Adapted to EP405 by Ben. Herrenschmidt <benh@kernel.crashing.org> 14 * 15 * TODO: Wire up the PCI IRQ mux and the southbridge interrupts 16 * 17 * 2002 (c) MontaVista, Software, Inc. This file is licensed under 18 * the terms of the GNU General Public License version 2. This program 19 * is licensed "as is" without any warranty of any kind, whether express 20 * or implied. 21 */ 22 23#include <linux/init.h> 24#include <linux/of_platform.h> 25 26#include <asm/machdep.h> 27#include <asm/prom.h> 28#include <asm/udbg.h> 29#include <asm/time.h> 30#include <asm/uic.h> 31#include <asm/pci-bridge.h> 32#include <asm/ppc4xx.h> 33 34static struct device_node *bcsr_node; 35static void __iomem *bcsr_regs; 36 37/* BCSR registers */ 38#define BCSR_ID 0 39#define BCSR_PCI_CTRL 1 40#define BCSR_FLASH_NV_POR_CTRL 2 41#define BCSR_FENET_UART_CTRL 3 42#define BCSR_PCI_IRQ 4 43#define BCSR_XIRQ_SELECT 5 44#define BCSR_XIRQ_ROUTING 6 45#define BCSR_XIRQ_STATUS 7 46#define BCSR_XIRQ_STATUS2 8 47#define BCSR_SW_STAT_LED_CTRL 9 48#define BCSR_GPIO_IRQ_PAR_CTRL 10 49/* there's more, can't be bothered typing them tho */ 50 51 52static const struct of_device_id ep405_of_bus[] __initconst = { 53 { .compatible = "ibm,plb3", }, 54 { .compatible = "ibm,opb", }, 55 { .compatible = "ibm,ebc", }, 56 {}, 57}; 58 59static int __init ep405_device_probe(void) 60{ 61 of_platform_bus_probe(NULL, ep405_of_bus, NULL); 62 63 return 0; 64} 65machine_device_initcall(ep405, ep405_device_probe); 66 67static void __init ep405_init_bcsr(void) 68{ 69 const u8 *irq_routing; 70 int i; 71 72 /* Find the bloody thing & map it */ 73 bcsr_node = of_find_compatible_node(NULL, NULL, "ep405-bcsr"); 74 if (bcsr_node == NULL) { 75 printk(KERN_ERR "EP405 BCSR not found !\n"); 76 return; 77 } 78 bcsr_regs = of_iomap(bcsr_node, 0); 79 if (bcsr_regs == NULL) { 80 printk(KERN_ERR "EP405 BCSR failed to map !\n"); 81 return; 82 } 83 84 /* Get the irq-routing property and apply the routing to the CPLD */ 85 irq_routing = of_get_property(bcsr_node, "irq-routing", NULL); 86 if (irq_routing == NULL) 87 return; 88 for (i = 0; i < 16; i++) { 89 u8 irq = irq_routing[i]; 90 out_8(bcsr_regs + BCSR_XIRQ_SELECT, i); 91 out_8(bcsr_regs + BCSR_XIRQ_ROUTING, irq); 92 } 93 in_8(bcsr_regs + BCSR_XIRQ_SELECT); 94 mb(); 95 out_8(bcsr_regs + BCSR_GPIO_IRQ_PAR_CTRL, 0xfe); 96} 97 98static void __init ep405_setup_arch(void) 99{ 100 /* Find & init the BCSR CPLD */ 101 ep405_init_bcsr(); 102 103 pci_set_flags(PCI_REASSIGN_ALL_RSRC); 104} 105 106static int __init ep405_probe(void) 107{ 108 unsigned long root = of_get_flat_dt_root(); 109 110 if (!of_flat_dt_is_compatible(root, "ep405")) 111 return 0; 112 113 return 1; 114} 115 116define_machine(ep405) { 117 .name = "EP405", 118 .probe = ep405_probe, 119 .setup_arch = ep405_setup_arch, 120 .progress = udbg_progress, 121 .init_IRQ = uic_init_tree, 122 .get_irq = uic_get_irq, 123 .restart = ppc4xx_reset_system, 124 .calibrate_decr = generic_calibrate_decr, 125}; 126