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 <asm/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 38void __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 */ 65void __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 86static 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 { 121 .compatible = "fsl,fman", 122 }, 123 /* The following two are for the Freescale hypervisor */ 124 { 125 .name = "hypervisor", 126 }, 127 { 128 .name = "handles", 129 }, 130 {} 131}; 132 133int __init corenet_gen_publish_devices(void) 134{ 135 return of_platform_bus_probe(NULL, of_device_ids, NULL); 136} 137 138static const char * const boards[] __initconst = { 139 "fsl,P2041RDB", 140 "fsl,P3041DS", 141 "fsl,OCA4080", 142 "fsl,P4080DS", 143 "fsl,P5020DS", 144 "fsl,P5040DS", 145 "fsl,T2080QDS", 146 "fsl,T2080RDB", 147 "fsl,T2081QDS", 148 "fsl,T4240QDS", 149 "fsl,T4240RDB", 150 "fsl,B4860QDS", 151 "fsl,B4420QDS", 152 "fsl,B4220QDS", 153 "fsl,T1040QDS", 154 "fsl,T1042QDS", 155 "fsl,T1040RDB", 156 "fsl,T1042RDB", 157 "fsl,T1042RDB_PI", 158 "keymile,kmcoge4", 159 NULL 160}; 161 162/* 163 * Called very early, device-tree isn't unflattened 164 */ 165static int __init corenet_generic_probe(void) 166{ 167 unsigned long root = of_get_flat_dt_root(); 168 char hv_compat[24]; 169 int i; 170#ifdef CONFIG_SMP 171 extern struct smp_ops_t smp_85xx_ops; 172#endif 173 174 if (of_flat_dt_match(root, boards)) 175 return 1; 176 177 /* Check if we're running under the Freescale hypervisor */ 178 for (i = 0; boards[i]; i++) { 179 snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]); 180 if (of_flat_dt_is_compatible(root, hv_compat)) { 181 ppc_md.init_IRQ = ehv_pic_init; 182 183 ppc_md.get_irq = ehv_pic_get_irq; 184 ppc_md.restart = fsl_hv_restart; 185 pm_power_off = fsl_hv_halt; 186 ppc_md.halt = fsl_hv_halt; 187#ifdef CONFIG_SMP 188 /* 189 * Disable the timebase sync operations because we 190 * can't write to the timebase registers under the 191 * hypervisor. 192 */ 193 smp_85xx_ops.give_timebase = NULL; 194 smp_85xx_ops.take_timebase = NULL; 195#endif 196 return 1; 197 } 198 } 199 200 return 0; 201} 202 203define_machine(corenet_generic) { 204 .name = "CoreNet Generic", 205 .probe = corenet_generic_probe, 206 .setup_arch = corenet_gen_setup_arch, 207 .init_IRQ = corenet_gen_pic_init, 208#ifdef CONFIG_PCI 209 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 210 .pcibios_fixup_phb = fsl_pcibios_fixup_phb, 211#endif 212 .get_irq = mpic_get_coreint_irq, 213 .restart = fsl_rstcr_restart, 214 .calibrate_decr = generic_calibrate_decr, 215 .progress = udbg_progress, 216#ifdef CONFIG_PPC64 217 .power_save = book3e_idle, 218#else 219 .power_save = e500_idle, 220#endif 221}; 222 223machine_arch_initcall(corenet_generic, corenet_gen_publish_devices); 224 225#ifdef CONFIG_SWIOTLB 226machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier); 227#endif 228