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 #if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32) 72 /* 73 * Inbound windows don't cover the full lower 4 GiB 74 * due to conflicts with PCICSRBAR and outbound windows, 75 * so limit the DMA32 zone to 2 GiB, to allow consistent 76 * allocations to succeed. 77 */ 78 limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT)); 79 #endif 80 81 pr_info("%s board\n", ppc_md.name); 82 83 mpc85xx_qe_init(); 84 } 85 86 static const struct of_device_id of_device_ids[] = { 87 { 88 .compatible = "simple-bus" 89 }, 90 { 91 .compatible = "mdio-mux-gpio" 92 }, 93 { 94 .compatible = "fsl,fpga-ngpixis" 95 }, 96 { 97 .compatible = "fsl,fpga-qixis" 98 }, 99 { 100 .compatible = "fsl,srio", 101 }, 102 { 103 .compatible = "fsl,p4080-pcie", 104 }, 105 { 106 .compatible = "fsl,qoriq-pcie-v2.2", 107 }, 108 { 109 .compatible = "fsl,qoriq-pcie-v2.3", 110 }, 111 { 112 .compatible = "fsl,qoriq-pcie-v2.4", 113 }, 114 { 115 .compatible = "fsl,qoriq-pcie-v3.0", 116 }, 117 { 118 .compatible = "fsl,qe", 119 }, 120 /* The following two are for the Freescale hypervisor */ 121 { 122 .name = "hypervisor", 123 }, 124 { 125 .name = "handles", 126 }, 127 {} 128 }; 129 130 int __init corenet_gen_publish_devices(void) 131 { 132 return of_platform_bus_probe(NULL, of_device_ids, NULL); 133 } 134 135 static const char * const boards[] __initconst = { 136 "fsl,P2041RDB", 137 "fsl,P3041DS", 138 "fsl,OCA4080", 139 "fsl,P4080DS", 140 "fsl,P5020DS", 141 "fsl,P5040DS", 142 "fsl,T2080QDS", 143 "fsl,T2080RDB", 144 "fsl,T2081QDS", 145 "fsl,T4240QDS", 146 "fsl,T4240RDB", 147 "fsl,B4860QDS", 148 "fsl,B4420QDS", 149 "fsl,B4220QDS", 150 "fsl,T1023RDB", 151 "fsl,T1024QDS", 152 "fsl,T1024RDB", 153 "fsl,T1040D4RDB", 154 "fsl,T1042D4RDB", 155 "fsl,T1040QDS", 156 "fsl,T1042QDS", 157 "fsl,T1040RDB", 158 "fsl,T1042RDB", 159 "fsl,T1042RDB_PI", 160 "keymile,kmcent2", 161 "keymile,kmcoge4", 162 "varisys,CYRUS", 163 NULL 164 }; 165 166 /* 167 * Called very early, device-tree isn't unflattened 168 */ 169 static int __init corenet_generic_probe(void) 170 { 171 char hv_compat[24]; 172 int i; 173 #ifdef CONFIG_SMP 174 extern struct smp_ops_t smp_85xx_ops; 175 #endif 176 177 if (of_device_compatible_match(of_root, boards)) 178 return 1; 179 180 /* Check if we're running under the Freescale hypervisor */ 181 for (i = 0; boards[i]; i++) { 182 snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]); 183 if (of_machine_is_compatible(hv_compat)) { 184 ppc_md.init_IRQ = ehv_pic_init; 185 186 ppc_md.get_irq = ehv_pic_get_irq; 187 ppc_md.restart = fsl_hv_restart; 188 pm_power_off = fsl_hv_halt; 189 ppc_md.halt = fsl_hv_halt; 190 #ifdef CONFIG_SMP 191 /* 192 * Disable the timebase sync operations because we 193 * can't write to the timebase registers under the 194 * hypervisor. 195 */ 196 smp_85xx_ops.give_timebase = NULL; 197 smp_85xx_ops.take_timebase = NULL; 198 #endif 199 return 1; 200 } 201 } 202 203 return 0; 204 } 205 206 define_machine(corenet_generic) { 207 .name = "CoreNet Generic", 208 .probe = corenet_generic_probe, 209 .setup_arch = corenet_gen_setup_arch, 210 .init_IRQ = corenet_gen_pic_init, 211 #ifdef CONFIG_PCI 212 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 213 .pcibios_fixup_phb = fsl_pcibios_fixup_phb, 214 #endif 215 /* 216 * Core reset may cause issues if using the proxy mode of MPIC. 217 * So, use the mixed mode of MPIC if enabling CPU hotplug. 218 * 219 * Likewise, problems have been seen with kexec when coreint is enabled. 220 */ 221 #if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_KEXEC_CORE) 222 .get_irq = mpic_get_irq, 223 #else 224 .get_irq = mpic_get_coreint_irq, 225 #endif 226 .calibrate_decr = generic_calibrate_decr, 227 .progress = udbg_progress, 228 #ifdef CONFIG_PPC64 229 .power_save = book3e_idle, 230 #else 231 .power_save = e500_idle, 232 #endif 233 }; 234 235 machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); 236 237 #ifdef CONFIG_SWIOTLB 238 machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier); 239 #endif 240