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/pci.h> 17#include <linux/kdev_t.h> 18#include <linux/delay.h> 19#include <linux/seq_file.h> 20#include <linux/of_platform.h> 21 22#include <asm/system.h> 23#include <asm/time.h> 24#include <asm/machdep.h> 25#include <asm/pci-bridge.h> 26#include <asm/mpic.h> 27#include <mm/mmu_decl.h> 28#include <asm/udbg.h> 29 30#include <sysdev/fsl_soc.h> 31#include <sysdev/fsl_pci.h> 32 33#ifdef CONFIG_CPM2 34#include <asm/cpm2.h> 35#include <sysdev/cpm2_pic.h> 36#endif 37 38#ifdef CONFIG_PCI 39static int mpc85xx_exclude_device(struct pci_controller *hose, 40 u_char bus, u_char devfn) 41{ 42 if (bus == 0 && PCI_SLOT(devfn) == 0) 43 return PCIBIOS_DEVICE_NOT_FOUND; 44 else 45 return PCIBIOS_SUCCESSFUL; 46} 47#endif /* CONFIG_PCI */ 48 49#ifdef CONFIG_CPM2 50 51static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) 52{ 53 int cascade_irq; 54 55 while ((cascade_irq = cpm2_get_irq()) >= 0) 56 generic_handle_irq(cascade_irq); 57 58 desc->chip->eoi(irq); 59} 60 61#endif /* CONFIG_CPM2 */ 62 63static void __init mpc85xx_ads_pic_init(void) 64{ 65 struct mpic *mpic; 66 struct resource r; 67 struct device_node *np = NULL; 68#ifdef CONFIG_CPM2 69 int irq; 70#endif 71 72 np = of_find_node_by_type(np, "open-pic"); 73 if (!np) { 74 printk(KERN_ERR "Could not find open-pic node\n"); 75 return; 76 } 77 78 if (of_address_to_resource(np, 0, &r)) { 79 printk(KERN_ERR "Could not map mpic register space\n"); 80 of_node_put(np); 81 return; 82 } 83 84 mpic = mpic_alloc(np, r.start, 85 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 86 0, 256, " OpenPIC "); 87 BUG_ON(mpic == NULL); 88 of_node_put(np); 89 90 mpic_init(mpic); 91 92#ifdef CONFIG_CPM2 93 /* Setup CPM2 PIC */ 94 np = of_find_compatible_node(NULL, NULL, "fsl,cpm2-pic"); 95 if (np == NULL) { 96 printk(KERN_ERR "PIC init: can not find fsl,cpm2-pic node\n"); 97 return; 98 } 99 irq = irq_of_parse_and_map(np, 0); 100 101 cpm2_pic_init(np); 102 of_node_put(np); 103 set_irq_chained_handler(irq, cpm2_cascade); 104#endif 105} 106 107/* 108 * Setup the architecture 109 */ 110#ifdef CONFIG_CPM2 111struct cpm_pin { 112 int port, pin, flags; 113}; 114 115static const struct cpm_pin mpc8560_ads_pins[] = { 116 /* SCC1 */ 117 {3, 29, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 118 {3, 30, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 119 {3, 31, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 120 121 /* SCC2 */ 122 {2, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 123 {2, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 124 {3, 26, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 125 {3, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 126 {3, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 127 128 /* FCC2 */ 129 {1, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 130 {1, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 131 {1, 20, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 132 {1, 21, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 133 {1, 22, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 134 {1, 23, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 135 {1, 24, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 136 {1, 25, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 137 {1, 26, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 138 {1, 27, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 139 {1, 28, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 140 {1, 29, CPM_PIN_OUTPUT | CPM_PIN_SECONDARY}, 141 {1, 30, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 142 {1, 31, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 143 {2, 18, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK14 */ 144 {2, 19, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK13 */ 145 146 /* FCC3 */ 147 {1, 4, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 148 {1, 5, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 149 {1, 6, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 150 {1, 8, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 151 {1, 9, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 152 {1, 10, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 153 {1, 11, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 154 {1, 12, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 155 {1, 13, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 156 {1, 14, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 157 {1, 15, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 158 {1, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 159 {1, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, 160 {2, 16, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK16 */ 161 {2, 17, CPM_PIN_INPUT | CPM_PIN_PRIMARY}, /* CLK15 */ 162 {2, 27, CPM_PIN_OUTPUT | CPM_PIN_PRIMARY}, 163}; 164 165static void __init init_ioports(void) 166{ 167 int i; 168 169 for (i = 0; i < ARRAY_SIZE(mpc8560_ads_pins); i++) { 170 const struct cpm_pin *pin = &mpc8560_ads_pins[i]; 171 cpm2_set_pin(pin->port, pin->pin, pin->flags); 172 } 173 174 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_RX); 175 cpm2_clk_setup(CPM_CLK_SCC1, CPM_BRG1, CPM_CLK_TX); 176 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_RX); 177 cpm2_clk_setup(CPM_CLK_SCC2, CPM_BRG2, CPM_CLK_TX); 178 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK13, CPM_CLK_RX); 179 cpm2_clk_setup(CPM_CLK_FCC2, CPM_CLK14, CPM_CLK_TX); 180 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK15, CPM_CLK_RX); 181 cpm2_clk_setup(CPM_CLK_FCC3, CPM_CLK16, CPM_CLK_TX); 182} 183#endif 184 185static void __init mpc85xx_ads_setup_arch(void) 186{ 187#ifdef CONFIG_PCI 188 struct device_node *np; 189#endif 190 191 if (ppc_md.progress) 192 ppc_md.progress("mpc85xx_ads_setup_arch()", 0); 193 194#ifdef CONFIG_CPM2 195 cpm2_reset(); 196 init_ioports(); 197#endif 198 199#ifdef CONFIG_PCI 200 for_each_compatible_node(np, "pci", "fsl,mpc8540-pci") 201 fsl_add_bridge(np, 1); 202 203 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 204#endif 205} 206 207static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) 208{ 209 uint pvid, svid, phid1; 210 211 pvid = mfspr(SPRN_PVR); 212 svid = mfspr(SPRN_SVR); 213 214 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); 215 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 216 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 217 218 /* Display cpu Pll setting */ 219 phid1 = mfspr(SPRN_HID1); 220 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); 221} 222 223static struct of_device_id __initdata of_bus_ids[] = { 224 { .name = "soc", }, 225 { .type = "soc", }, 226 { .name = "cpm", }, 227 { .name = "localbus", }, 228 { .compatible = "simple-bus", }, 229 { .compatible = "gianfar", }, 230 {}, 231}; 232 233static int __init declare_of_platform_devices(void) 234{ 235 of_platform_bus_probe(NULL, of_bus_ids, NULL); 236 237 return 0; 238} 239machine_device_initcall(mpc85xx_ads, declare_of_platform_devices); 240 241/* 242 * Called very early, device-tree isn't unflattened 243 */ 244static int __init mpc85xx_ads_probe(void) 245{ 246 unsigned long root = of_get_flat_dt_root(); 247 248 return of_flat_dt_is_compatible(root, "MPC85xxADS"); 249} 250 251define_machine(mpc85xx_ads) { 252 .name = "MPC85xx ADS", 253 .probe = mpc85xx_ads_probe, 254 .setup_arch = mpc85xx_ads_setup_arch, 255 .init_IRQ = mpc85xx_ads_pic_init, 256 .show_cpuinfo = mpc85xx_ads_show_cpuinfo, 257 .get_irq = mpic_get_irq, 258 .restart = fsl_rstcr_restart, 259 .calibrate_decr = generic_calibrate_decr, 260 .progress = udbg_progress, 261}; 262