1 /* 2 * Copyright (C) 2009 Extreme Engineering Solutions, Inc. 3 * 4 * X-ES board-specific functionality 5 * 6 * Based on mpc85xx_ds code from Freescale Semiconductor, Inc. 7 * 8 * Author: Nate Case <ncase@xes-inc.com> 9 * 10 * This is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License version 2 as 12 * published by the Free Software Foundation. 13 */ 14 15 #include <linux/stddef.h> 16 #include <linux/kernel.h> 17 #include <linux/pci.h> 18 #include <linux/kdev_t.h> 19 #include <linux/delay.h> 20 #include <linux/seq_file.h> 21 #include <linux/interrupt.h> 22 #include <linux/of_platform.h> 23 24 #include <asm/system.h> 25 #include <asm/time.h> 26 #include <asm/machdep.h> 27 #include <asm/pci-bridge.h> 28 #include <mm/mmu_decl.h> 29 #include <asm/prom.h> 30 #include <asm/udbg.h> 31 #include <asm/mpic.h> 32 33 #include <sysdev/fsl_soc.h> 34 #include <sysdev/fsl_pci.h> 35 36 /* A few bit definitions needed for fixups on some boards */ 37 #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ 38 #define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */ 39 #define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */ 40 41 void __init xes_mpc85xx_pic_init(void) 42 { 43 struct mpic *mpic; 44 struct resource r; 45 struct device_node *np; 46 47 np = of_find_node_by_type(NULL, "open-pic"); 48 if (np == NULL) { 49 printk(KERN_ERR "Could not find open-pic node\n"); 50 return; 51 } 52 53 if (of_address_to_resource(np, 0, &r)) { 54 printk(KERN_ERR "Failed to map mpic register space\n"); 55 of_node_put(np); 56 return; 57 } 58 59 mpic = mpic_alloc(np, r.start, 60 MPIC_PRIMARY | MPIC_WANTS_RESET | 61 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, 62 0, 256, " OpenPIC "); 63 BUG_ON(mpic == NULL); 64 of_node_put(np); 65 66 mpic_init(mpic); 67 } 68 69 static void xes_mpc85xx_configure_l2(void __iomem *l2_base) 70 { 71 volatile uint32_t ctl, tmp; 72 73 asm volatile("msync; isync"); 74 tmp = in_be32(l2_base); 75 76 /* 77 * xMon may have enabled part of L2 as SRAM, so we need to set it 78 * up for all cache mode just to be safe. 79 */ 80 printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n"); 81 82 ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I; 83 if (of_machine_is_compatible("MPC8540") || 84 of_machine_is_compatible("MPC8560")) 85 /* 86 * Assume L2 SRAM is used fully for cache, so set 87 * L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3). 88 */ 89 ctl |= (tmp & MPC85xx_L2CTL_L2SIZ_MASK) >> 2; 90 91 asm volatile("msync; isync"); 92 out_be32(l2_base, ctl); 93 asm volatile("msync; isync"); 94 } 95 96 static void xes_mpc85xx_fixups(void) 97 { 98 struct device_node *np; 99 int err; 100 101 /* 102 * Legacy xMon firmware on some X-ES boards does not enable L2 103 * as cache. We must ensure that they get enabled here. 104 */ 105 for_each_node_by_name(np, "l2-cache-controller") { 106 struct resource r[2]; 107 void __iomem *l2_base; 108 109 /* Only MPC8548, MPC8540, and MPC8560 boards are affected */ 110 if (!of_device_is_compatible(np, 111 "fsl,mpc8548-l2-cache-controller") && 112 !of_device_is_compatible(np, 113 "fsl,mpc8540-l2-cache-controller") && 114 !of_device_is_compatible(np, 115 "fsl,mpc8560-l2-cache-controller")) 116 continue; 117 118 err = of_address_to_resource(np, 0, &r[0]); 119 if (err) { 120 printk(KERN_WARNING "xes_mpc85xx: Could not get " 121 "resource for device tree node '%s'", 122 np->full_name); 123 continue; 124 } 125 126 l2_base = ioremap(r[0].start, r[0].end - r[0].start + 1); 127 128 xes_mpc85xx_configure_l2(l2_base); 129 } 130 } 131 132 #ifdef CONFIG_PCI 133 static int primary_phb_addr; 134 #endif 135 136 /* 137 * Setup the architecture 138 */ 139 #ifdef CONFIG_SMP 140 extern void __init mpc85xx_smp_init(void); 141 #endif 142 static void __init xes_mpc85xx_setup_arch(void) 143 { 144 #ifdef CONFIG_PCI 145 struct device_node *np; 146 #endif 147 struct device_node *root; 148 const char *model = "Unknown"; 149 150 root = of_find_node_by_path("/"); 151 if (root == NULL) 152 return; 153 154 model = of_get_property(root, "model", NULL); 155 156 printk(KERN_INFO "X-ES MPC85xx-based single-board computer: %s\n", 157 model + strlen("xes,")); 158 159 xes_mpc85xx_fixups(); 160 161 #ifdef CONFIG_PCI 162 for_each_node_by_type(np, "pci") { 163 if (of_device_is_compatible(np, "fsl,mpc8540-pci") || 164 of_device_is_compatible(np, "fsl,mpc8548-pcie")) { 165 struct resource rsrc; 166 of_address_to_resource(np, 0, &rsrc); 167 if ((rsrc.start & 0xfffff) == primary_phb_addr) 168 fsl_add_bridge(np, 1); 169 else 170 fsl_add_bridge(np, 0); 171 } 172 } 173 #endif 174 175 #ifdef CONFIG_SMP 176 mpc85xx_smp_init(); 177 #endif 178 } 179 180 static struct of_device_id __initdata xes_mpc85xx_ids[] = { 181 { .type = "soc", }, 182 { .compatible = "soc", }, 183 { .compatible = "simple-bus", }, 184 { .compatible = "gianfar", }, 185 {}, 186 }; 187 188 static int __init xes_mpc85xx_publish_devices(void) 189 { 190 return of_platform_bus_probe(NULL, xes_mpc85xx_ids, NULL); 191 } 192 machine_device_initcall(xes_mpc8572, xes_mpc85xx_publish_devices); 193 machine_device_initcall(xes_mpc8548, xes_mpc85xx_publish_devices); 194 machine_device_initcall(xes_mpc8540, xes_mpc85xx_publish_devices); 195 196 /* 197 * Called very early, device-tree isn't unflattened 198 */ 199 static int __init xes_mpc8572_probe(void) 200 { 201 unsigned long root = of_get_flat_dt_root(); 202 203 if (of_flat_dt_is_compatible(root, "xes,MPC8572")) { 204 #ifdef CONFIG_PCI 205 primary_phb_addr = 0x8000; 206 #endif 207 return 1; 208 } else { 209 return 0; 210 } 211 } 212 213 static int __init xes_mpc8548_probe(void) 214 { 215 unsigned long root = of_get_flat_dt_root(); 216 217 if (of_flat_dt_is_compatible(root, "xes,MPC8548")) { 218 #ifdef CONFIG_PCI 219 primary_phb_addr = 0xb000; 220 #endif 221 return 1; 222 } else { 223 return 0; 224 } 225 } 226 227 static int __init xes_mpc8540_probe(void) 228 { 229 unsigned long root = of_get_flat_dt_root(); 230 231 if (of_flat_dt_is_compatible(root, "xes,MPC8540")) { 232 #ifdef CONFIG_PCI 233 primary_phb_addr = 0xb000; 234 #endif 235 return 1; 236 } else { 237 return 0; 238 } 239 } 240 241 define_machine(xes_mpc8572) { 242 .name = "X-ES MPC8572", 243 .probe = xes_mpc8572_probe, 244 .setup_arch = xes_mpc85xx_setup_arch, 245 .init_IRQ = xes_mpc85xx_pic_init, 246 #ifdef CONFIG_PCI 247 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 248 #endif 249 .get_irq = mpic_get_irq, 250 .restart = fsl_rstcr_restart, 251 .calibrate_decr = generic_calibrate_decr, 252 .progress = udbg_progress, 253 }; 254 255 define_machine(xes_mpc8548) { 256 .name = "X-ES MPC8548", 257 .probe = xes_mpc8548_probe, 258 .setup_arch = xes_mpc85xx_setup_arch, 259 .init_IRQ = xes_mpc85xx_pic_init, 260 #ifdef CONFIG_PCI 261 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 262 #endif 263 .get_irq = mpic_get_irq, 264 .restart = fsl_rstcr_restart, 265 .calibrate_decr = generic_calibrate_decr, 266 .progress = udbg_progress, 267 }; 268 269 define_machine(xes_mpc8540) { 270 .name = "X-ES MPC8540", 271 .probe = xes_mpc8540_probe, 272 .setup_arch = xes_mpc85xx_setup_arch, 273 .init_IRQ = xes_mpc85xx_pic_init, 274 #ifdef CONFIG_PCI 275 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 276 #endif 277 .get_irq = mpic_get_irq, 278 .restart = fsl_rstcr_restart, 279 .calibrate_decr = generic_calibrate_decr, 280 .progress = udbg_progress, 281 }; 282