1/* 2 * Wind River SBC8548 setup and early boot code. 3 * 4 * Copyright 2007 Wind River Systems Inc. 5 * 6 * By Paul Gortmaker (see MAINTAINERS for contact information) 7 * 8 * Based largely on the MPC8548CDS support - Copyright 2005 Freescale Inc. 9 * 10 * 11 * This program is free software; you can redistribute it and/or modify it 12 * under the terms of the GNU General Public License as published by the 13 * Free Software Foundation; either version 2 of the License, or (at your 14 * option) any later version. 15 */ 16 17#include <linux/stddef.h> 18#include <linux/kernel.h> 19#include <linux/init.h> 20#include <linux/errno.h> 21#include <linux/reboot.h> 22#include <linux/pci.h> 23#include <linux/kdev_t.h> 24#include <linux/major.h> 25#include <linux/console.h> 26#include <linux/delay.h> 27#include <linux/seq_file.h> 28#include <linux/initrd.h> 29#include <linux/module.h> 30#include <linux/interrupt.h> 31#include <linux/fsl_devices.h> 32#include <linux/of_platform.h> 33 34#include <asm/system.h> 35#include <asm/pgtable.h> 36#include <asm/page.h> 37#include <asm/atomic.h> 38#include <asm/time.h> 39#include <asm/io.h> 40#include <asm/machdep.h> 41#include <asm/ipic.h> 42#include <asm/pci-bridge.h> 43#include <asm/irq.h> 44#include <mm/mmu_decl.h> 45#include <asm/prom.h> 46#include <asm/udbg.h> 47#include <asm/mpic.h> 48 49#include <sysdev/fsl_soc.h> 50#include <sysdev/fsl_pci.h> 51 52static int sbc_rev; 53 54static void __init sbc8548_pic_init(void) 55{ 56 struct mpic *mpic; 57 struct resource r; 58 struct device_node *np = NULL; 59 60 np = of_find_node_by_type(np, "open-pic"); 61 62 if (np == NULL) { 63 printk(KERN_ERR "Could not find open-pic node\n"); 64 return; 65 } 66 67 if (of_address_to_resource(np, 0, &r)) { 68 printk(KERN_ERR "Failed to map mpic register space\n"); 69 of_node_put(np); 70 return; 71 } 72 73 mpic = mpic_alloc(np, r.start, 74 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 75 0, 256, " OpenPIC "); 76 BUG_ON(mpic == NULL); 77 78 /* Return the mpic node */ 79 of_node_put(np); 80 81 mpic_init(mpic); 82} 83 84/* Extract the HW Rev from the EPLD on the board */ 85static int __init sbc8548_hw_rev(void) 86{ 87 struct device_node *np; 88 struct resource res; 89 unsigned int *rev; 90 int board_rev = 0; 91 92 np = of_find_compatible_node(NULL, NULL, "hw-rev"); 93 if (np == NULL) { 94 printk("No HW-REV found in DTB.\n"); 95 return -ENODEV; 96 } 97 98 of_address_to_resource(np, 0, &res); 99 of_node_put(np); 100 101 rev = ioremap(res.start,sizeof(unsigned int)); 102 board_rev = (*rev) >> 28; 103 iounmap(rev); 104 105 return board_rev; 106} 107 108/* 109 * Setup the architecture 110 */ 111static void __init sbc8548_setup_arch(void) 112{ 113#ifdef CONFIG_PCI 114 struct device_node *np; 115#endif 116 117 if (ppc_md.progress) 118 ppc_md.progress("sbc8548_setup_arch()", 0); 119 120#ifdef CONFIG_PCI 121 for_each_node_by_type(np, "pci") { 122 if (of_device_is_compatible(np, "fsl,mpc8540-pci") || 123 of_device_is_compatible(np, "fsl,mpc8548-pcie")) { 124 struct resource rsrc; 125 of_address_to_resource(np, 0, &rsrc); 126 if ((rsrc.start & 0xfffff) == 0x8000) 127 fsl_add_bridge(np, 1); 128 else 129 fsl_add_bridge(np, 0); 130 } 131 } 132#endif 133 sbc_rev = sbc8548_hw_rev(); 134} 135 136static void sbc8548_show_cpuinfo(struct seq_file *m) 137{ 138 uint pvid, svid, phid1; 139 140 pvid = mfspr(SPRN_PVR); 141 svid = mfspr(SPRN_SVR); 142 143 seq_printf(m, "Vendor\t\t: Wind River\n"); 144 seq_printf(m, "Machine\t\t: SBC8548 v%d\n", sbc_rev); 145 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 146 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 147 148 /* Display cpu Pll setting */ 149 phid1 = mfspr(SPRN_HID1); 150 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); 151} 152 153static struct of_device_id __initdata of_bus_ids[] = { 154 { .name = "soc", }, 155 { .type = "soc", }, 156 { .compatible = "simple-bus", }, 157 { .compatible = "gianfar", }, 158 {}, 159}; 160 161static int __init declare_of_platform_devices(void) 162{ 163 of_platform_bus_probe(NULL, of_bus_ids, NULL); 164 165 return 0; 166} 167machine_device_initcall(sbc8548, declare_of_platform_devices); 168 169/* 170 * Called very early, device-tree isn't unflattened 171 */ 172static int __init sbc8548_probe(void) 173{ 174 unsigned long root = of_get_flat_dt_root(); 175 176 return of_flat_dt_is_compatible(root, "SBC8548"); 177} 178 179define_machine(sbc8548) { 180 .name = "SBC8548", 181 .probe = sbc8548_probe, 182 .setup_arch = sbc8548_setup_arch, 183 .init_IRQ = sbc8548_pic_init, 184 .show_cpuinfo = sbc8548_show_cpuinfo, 185 .get_irq = mpic_get_irq, 186 .restart = fsl_rstcr_restart, 187#ifdef CONFIG_PCI 188 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 189#endif 190 .calibrate_decr = generic_calibrate_decr, 191 .progress = udbg_progress, 192}; 193