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 #include "smp.h" 36 37 #include "mpc85xx.h" 38 39 /* A few bit definitions needed for fixups on some boards */ 40 #define MPC85xx_L2CTL_L2E 0x80000000 /* L2 enable */ 41 #define MPC85xx_L2CTL_L2I 0x40000000 /* L2 flash invalidate */ 42 #define MPC85xx_L2CTL_L2SIZ_MASK 0x30000000 /* L2 SRAM size (R/O) */ 43 44 void __init xes_mpc85xx_pic_init(void) 45 { 46 struct mpic *mpic = mpic_alloc(NULL, 0, 47 MPIC_WANTS_RESET | 48 MPIC_BIG_ENDIAN | MPIC_BROKEN_FRR_NIRQS, 49 0, 256, " OpenPIC "); 50 BUG_ON(mpic == NULL); 51 mpic_init(mpic); 52 } 53 54 static void xes_mpc85xx_configure_l2(void __iomem *l2_base) 55 { 56 volatile uint32_t ctl, tmp; 57 58 asm volatile("msync; isync"); 59 tmp = in_be32(l2_base); 60 61 /* 62 * xMon may have enabled part of L2 as SRAM, so we need to set it 63 * up for all cache mode just to be safe. 64 */ 65 printk(KERN_INFO "xes_mpc85xx: Enabling L2 as cache\n"); 66 67 ctl = MPC85xx_L2CTL_L2E | MPC85xx_L2CTL_L2I; 68 if (of_machine_is_compatible("MPC8540") || 69 of_machine_is_compatible("MPC8560")) 70 /* 71 * Assume L2 SRAM is used fully for cache, so set 72 * L2BLKSZ (bits 4:5) to match L2SIZ (bits 2:3). 73 */ 74 ctl |= (tmp & MPC85xx_L2CTL_L2SIZ_MASK) >> 2; 75 76 asm volatile("msync; isync"); 77 out_be32(l2_base, ctl); 78 asm volatile("msync; isync"); 79 } 80 81 static void xes_mpc85xx_fixups(void) 82 { 83 struct device_node *np; 84 int err; 85 86 /* 87 * Legacy xMon firmware on some X-ES boards does not enable L2 88 * as cache. We must ensure that they get enabled here. 89 */ 90 for_each_node_by_name(np, "l2-cache-controller") { 91 struct resource r[2]; 92 void __iomem *l2_base; 93 94 /* Only MPC8548, MPC8540, and MPC8560 boards are affected */ 95 if (!of_device_is_compatible(np, 96 "fsl,mpc8548-l2-cache-controller") && 97 !of_device_is_compatible(np, 98 "fsl,mpc8540-l2-cache-controller") && 99 !of_device_is_compatible(np, 100 "fsl,mpc8560-l2-cache-controller")) 101 continue; 102 103 err = of_address_to_resource(np, 0, &r[0]); 104 if (err) { 105 printk(KERN_WARNING "xes_mpc85xx: Could not get " 106 "resource for device tree node '%s'", 107 np->full_name); 108 continue; 109 } 110 111 l2_base = ioremap(r[0].start, resource_size(&r[0])); 112 113 xes_mpc85xx_configure_l2(l2_base); 114 } 115 } 116 117 #ifdef CONFIG_PCI 118 static int primary_phb_addr; 119 #endif 120 121 /* 122 * Setup the architecture 123 */ 124 static void __init xes_mpc85xx_setup_arch(void) 125 { 126 #ifdef CONFIG_PCI 127 struct device_node *np; 128 #endif 129 struct device_node *root; 130 const char *model = "Unknown"; 131 132 root = of_find_node_by_path("/"); 133 if (root == NULL) 134 return; 135 136 model = of_get_property(root, "model", NULL); 137 138 printk(KERN_INFO "X-ES MPC85xx-based single-board computer: %s\n", 139 model + strlen("xes,")); 140 141 xes_mpc85xx_fixups(); 142 143 #ifdef CONFIG_PCI 144 for_each_node_by_type(np, "pci") { 145 if (of_device_is_compatible(np, "fsl,mpc8540-pci") || 146 of_device_is_compatible(np, "fsl,mpc8548-pcie")) { 147 struct resource rsrc; 148 of_address_to_resource(np, 0, &rsrc); 149 if ((rsrc.start & 0xfffff) == primary_phb_addr) 150 fsl_add_bridge(np, 1); 151 else 152 fsl_add_bridge(np, 0); 153 } 154 } 155 #endif 156 157 mpc85xx_smp_init(); 158 } 159 160 machine_device_initcall(xes_mpc8572, mpc85xx_common_publish_devices); 161 machine_device_initcall(xes_mpc8548, mpc85xx_common_publish_devices); 162 machine_device_initcall(xes_mpc8540, mpc85xx_common_publish_devices); 163 164 /* 165 * Called very early, device-tree isn't unflattened 166 */ 167 static int __init xes_mpc8572_probe(void) 168 { 169 unsigned long root = of_get_flat_dt_root(); 170 171 if (of_flat_dt_is_compatible(root, "xes,MPC8572")) { 172 #ifdef CONFIG_PCI 173 primary_phb_addr = 0x8000; 174 #endif 175 return 1; 176 } else { 177 return 0; 178 } 179 } 180 181 static int __init xes_mpc8548_probe(void) 182 { 183 unsigned long root = of_get_flat_dt_root(); 184 185 if (of_flat_dt_is_compatible(root, "xes,MPC8548")) { 186 #ifdef CONFIG_PCI 187 primary_phb_addr = 0xb000; 188 #endif 189 return 1; 190 } else { 191 return 0; 192 } 193 } 194 195 static int __init xes_mpc8540_probe(void) 196 { 197 unsigned long root = of_get_flat_dt_root(); 198 199 if (of_flat_dt_is_compatible(root, "xes,MPC8540")) { 200 #ifdef CONFIG_PCI 201 primary_phb_addr = 0xb000; 202 #endif 203 return 1; 204 } else { 205 return 0; 206 } 207 } 208 209 define_machine(xes_mpc8572) { 210 .name = "X-ES MPC8572", 211 .probe = xes_mpc8572_probe, 212 .setup_arch = xes_mpc85xx_setup_arch, 213 .init_IRQ = xes_mpc85xx_pic_init, 214 #ifdef CONFIG_PCI 215 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 216 #endif 217 .get_irq = mpic_get_irq, 218 .restart = fsl_rstcr_restart, 219 .calibrate_decr = generic_calibrate_decr, 220 .progress = udbg_progress, 221 }; 222 223 define_machine(xes_mpc8548) { 224 .name = "X-ES MPC8548", 225 .probe = xes_mpc8548_probe, 226 .setup_arch = xes_mpc85xx_setup_arch, 227 .init_IRQ = xes_mpc85xx_pic_init, 228 #ifdef CONFIG_PCI 229 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 230 #endif 231 .get_irq = mpic_get_irq, 232 .restart = fsl_rstcr_restart, 233 .calibrate_decr = generic_calibrate_decr, 234 .progress = udbg_progress, 235 }; 236 237 define_machine(xes_mpc8540) { 238 .name = "X-ES MPC8540", 239 .probe = xes_mpc8540_probe, 240 .setup_arch = xes_mpc85xx_setup_arch, 241 .init_IRQ = xes_mpc85xx_pic_init, 242 #ifdef CONFIG_PCI 243 .pcibios_fixup_bus = fsl_pcibios_fixup_bus, 244 #endif 245 .get_irq = mpic_get_irq, 246 .restart = fsl_rstcr_restart, 247 .calibrate_decr = generic_calibrate_decr, 248 .progress = udbg_progress, 249 }; 250