1 /* 2 * Corenet based SoC DS Setup 3 * 4 * Maintained by Kumar Gala (see MAINTAINERS for contact information) 5 * 6 * Copyright 2009-2011 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/kernel.h> 15 #include <linux/pci.h> 16 #include <linux/kdev_t.h> 17 #include <linux/delay.h> 18 #include <linux/interrupt.h> 19 20 #include <asm/time.h> 21 #include <asm/machdep.h> 22 #include <asm/pci-bridge.h> 23 #include <asm/pgtable.h> 24 #include <asm/ppc-pci.h> 25 #include <mm/mmu_decl.h> 26 #include <asm/prom.h> 27 #include <asm/udbg.h> 28 #include <asm/mpic.h> 29 #include <asm/ehv_pic.h> 30 #include <soc/fsl/qe/qe_ic.h> 31 32 #include <linux/of_platform.h> 33 #include <sysdev/fsl_soc.h> 34 #include <sysdev/fsl_pci.h> 35 #include "smp.h" 36 #include "mpc85xx.h" 37 38 void __init corenet_gen_pic_init(void) 39 { 40 struct mpic *mpic; 41 unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU | 42 MPIC_NO_RESET; 43 44 struct device_node *np; 45 46 if (ppc_md.get_irq == mpic_get_coreint_irq) 47 flags |= MPIC_ENABLE_COREINT; 48 49 mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC "); 50 BUG_ON(mpic == NULL); 51 52 mpic_init(mpic); 53 54 np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic"); 55 if (np) { 56 qe_ic_init(np, 0, qe_ic_cascade_low_mpic, 57 qe_ic_cascade_high_mpic); 58 of_node_put(np); 59 } 60 } 61 62 /* 63 * Setup the architecture 64 */ 65 void __init corenet_gen_setup_arch(void) 66 { 67 mpc85xx_smp_init(); 68 69 swiotlb_detect_4g(); 70 71 pr_info("%s board\n", ppc_md.name); 72 73 mpc85xx_qe_init(); 74 } 75 76 static const struct of_device_id of_device_ids[] = { 77 { 78 .compatible = "simple-bus" 79 }, 80 { 81 .compatible = "mdio-mux-gpio" 82 }, 83 { 84 .compatible = "fsl,fpga-ngpixis" 85 }, 86 { 87 .compatible = "fsl,fpga-qixis" 88 }, 89 { 90 .compatible = "fsl,srio", 91 }, 92 { 93 .compatible = "fsl,p4080-pcie", 94 }, 95 { 96 .compatible = "fsl,qoriq-pcie-v2.2", 97 }, 98 { 99 .compatible = "fsl,qoriq-pcie-v2.3", 100 }, 101 { 102 .compatible = "fsl,qoriq-pcie-v2.4", 103 }, 104 { 105 .compatible = "fsl,qoriq-pcie-v3.0", 106 }, 107 { 108 .compatible = "fsl,qe", 109 }, 110 /* The following two are for the Freescale hypervisor */ 111 { 112 .name = "hypervisor", 113 }, 114 { 115 .name = "handles", 116 }, 117 {} 118 }; 119 120 int __init corenet_gen_publish_devices(void) 121 { 122 return of_platform_bus_probe(NULL, of_device_ids, NULL); 123 } 124 125 static const char * const boards[] __initconst = { 126 "fsl,P2041RDB", 127 "fsl,P3041DS", 128 "fsl,OCA4080", 129 "fsl,P4080DS", 130 "fsl,P5020DS", 131 "fsl,P5040DS", 132 "fsl,T2080QDS", 133 "fsl,T2080RDB", 134 "fsl,T2081QDS", 135 "fsl,T4240QDS", 136 "fsl,T4240RDB", 137 "fsl,B4860QDS", 138 "fsl,B4420QDS", 139 "fsl,B4220QDS", 140 "fsl,T1023RDB", 141 "fsl,T1024QDS", 142 "fsl,T1024RDB", 143 "fsl,T1040D4RDB", 144 "fsl,T1042D4RDB", 145 "fsl,T1040QDS", 146 "fsl,T1042QDS", 147 "fsl,T1040RDB", 148 "fsl,T1042RDB", 149 "fsl,T1042RDB_PI", 150 "keymile,kmcent2", 151 "keymile,kmcoge4", 152 "varisys,CYRUS", 153 NULL 154 }; 155 156 /* 157 * Called very early, device-tree isn't unflattened 158 */ 159 static int __init corenet_generic_probe(void) 160 { 161 char hv_compat[24]; 162 int i; 163 #ifdef CONFIG_SMP 164 extern struct smp_ops_t smp_85xx_ops; 165 #endif 166 167 if (of_device_compatible_match(of_root, boards)) 168 return 1; 169 170 /* Check if we're running under the Freescale hypervisor */ 171 for (i = 0; boards[i]; i++) { 172 snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]); 173 if (of_machine_is_compatible(hv_compat)) { 174 ppc_md.init_IRQ = ehv_pic_init; 175 176 ppc_md.get_irq = ehv_pic_get_irq; 177 ppc_md.restart = fsl_hv_restart; 178 pm_power_off = fsl_hv_halt; 179 ppc_md.halt = fsl_hv_halt; 180 #ifdef CONFIG_SMP 181 /* 182 * Disable the timebase sync operations because we 183 * can't write to the timebase registers under the 184 * hypervisor. 185 */ 186 smp_85xx_ops.give_timebase = NULL; 187 smp_85xx_ops.take_timebase = NULL; 188 #endif 189 return 1; 190 } 191 } 192 193 return 0; 194 } 195 196 define_machine(corenet_generic) { 197 .name = "CoreNet Generic", 198 .probe = corenet_generic_probe, 199 .setup_arch = corenet_gen_setup_arch, 200 .init_IRQ = corenet_gen_pic_init, 201 #ifdef CONFIG_PCI 202 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 203 .pcibios_fixup_phb = fsl_pcibios_fixup_phb, 204 #endif 205 /* 206 * Core reset may cause issues if using the proxy mode of MPIC. 207 * So, use the mixed mode of MPIC if enabling CPU hotplug. 208 * 209 * Likewise, problems have been seen with kexec when coreint is enabled. 210 */ 211 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC_CORE) 212 .get_irq = mpic_get_irq, 213 #else 214 .get_irq = mpic_get_coreint_irq, 215 #endif 216 .calibrate_decr = generic_calibrate_decr, 217 .progress = udbg_progress, 218 #ifdef CONFIG_PPC64 219 .power_save = book3e_idle, 220 #else 221 .power_save = e500_idle, 222 #endif 223 }; 224 225 machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); 226 227 #ifdef CONFIG_SWIOTLB 228 machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier); 229 #endif 230