1/* 2 * MPC85xx setup and early boot code plus other random bits. 3 * 4 * Maintained by Kumar Gala (see MAINTAINERS for contact information) 5 * 6 * Copyright 2005 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/stddef.h> 15#include <linux/kernel.h> 16#include <linux/pci.h> 17#include <linux/kdev_t.h> 18#include <linux/delay.h> 19#include <linux/seq_file.h> 20 21#include <asm/system.h> 22#include <asm/time.h> 23#include <asm/machdep.h> 24#include <asm/pci-bridge.h> 25#include <asm/mpc85xx.h> 26#include <asm/prom.h> 27#include <asm/mpic.h> 28#include <mm/mmu_decl.h> 29#include <asm/udbg.h> 30 31#include <sysdev/fsl_soc.h> 32#include "mpc85xx.h" 33 34#ifdef CONFIG_CPM2 35#include <linux/fs_enet_pd.h> 36#include <asm/cpm2.h> 37#include <sysdev/cpm2_pic.h> 38#include <asm/fs_pd.h> 39#endif 40 41#ifndef CONFIG_PCI 42unsigned long isa_io_base = 0; 43unsigned long isa_mem_base = 0; 44#endif 45 46#ifdef CONFIG_PCI 47static int mpc85xx_exclude_device(u_char bus, u_char devfn) 48{ 49 if (bus == 0 && PCI_SLOT(devfn) == 0) 50 return PCIBIOS_DEVICE_NOT_FOUND; 51 else 52 return PCIBIOS_SUCCESSFUL; 53} 54#endif /* CONFIG_PCI */ 55 56#ifdef CONFIG_CPM2 57 58static void cpm2_cascade(unsigned int irq, struct irq_desc *desc) 59{ 60 int cascade_irq; 61 62 while ((cascade_irq = cpm2_get_irq()) >= 0) { 63 generic_handle_irq(cascade_irq); 64 } 65 desc->chip->eoi(irq); 66} 67 68#endif /* CONFIG_CPM2 */ 69 70static void __init mpc85xx_ads_pic_init(void) 71{ 72 struct mpic *mpic; 73 struct resource r; 74 struct device_node *np = NULL; 75#ifdef CONFIG_CPM2 76 int irq; 77#endif 78 79 np = of_find_node_by_type(np, "open-pic"); 80 81 if (np == NULL) { 82 printk(KERN_ERR "Could not find open-pic node\n"); 83 return; 84 } 85 86 if(of_address_to_resource(np, 0, &r)) { 87 printk(KERN_ERR "Could not map mpic register space\n"); 88 of_node_put(np); 89 return; 90 } 91 92 mpic = mpic_alloc(np, r.start, 93 MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, 94 4, 0, " OpenPIC "); 95 BUG_ON(mpic == NULL); 96 of_node_put(np); 97 98 mpic_assign_isu(mpic, 0, r.start + 0x10200); 99 mpic_assign_isu(mpic, 1, r.start + 0x10280); 100 mpic_assign_isu(mpic, 2, r.start + 0x10300); 101 mpic_assign_isu(mpic, 3, r.start + 0x10380); 102 mpic_assign_isu(mpic, 4, r.start + 0x10400); 103 mpic_assign_isu(mpic, 5, r.start + 0x10480); 104 mpic_assign_isu(mpic, 6, r.start + 0x10500); 105 mpic_assign_isu(mpic, 7, r.start + 0x10580); 106 107 /* Unused on this platform (leave room for 8548) */ 108 mpic_assign_isu(mpic, 8, r.start + 0x10600); 109 mpic_assign_isu(mpic, 9, r.start + 0x10680); 110 mpic_assign_isu(mpic, 10, r.start + 0x10700); 111 mpic_assign_isu(mpic, 11, r.start + 0x10780); 112 113 /* External Interrupts */ 114 mpic_assign_isu(mpic, 12, r.start + 0x10000); 115 mpic_assign_isu(mpic, 13, r.start + 0x10080); 116 mpic_assign_isu(mpic, 14, r.start + 0x10100); 117 118 mpic_init(mpic); 119 120#ifdef CONFIG_CPM2 121 /* Setup CPM2 PIC */ 122 np = of_find_node_by_type(NULL, "cpm-pic"); 123 if (np == NULL) { 124 printk(KERN_ERR "PIC init: can not find cpm-pic node\n"); 125 return; 126 } 127 irq = irq_of_parse_and_map(np, 0); 128 129 cpm2_pic_init(np); 130 set_irq_chained_handler(irq, cpm2_cascade); 131#endif 132} 133 134/* 135 * Setup the architecture 136 */ 137#ifdef CONFIG_CPM2 138void init_fcc_ioports(struct fs_platform_info *fpi) 139{ 140 struct io_port *io = cpm2_map(im_ioport); 141 int fcc_no = fs_get_fcc_index(fpi->fs_no); 142 int target; 143 u32 tempval; 144 145 switch(fcc_no) { 146 case 1: 147 tempval = in_be32(&io->iop_pdirb); 148 tempval &= ~PB2_DIRB0; 149 tempval |= PB2_DIRB1; 150 out_be32(&io->iop_pdirb, tempval); 151 152 tempval = in_be32(&io->iop_psorb); 153 tempval &= ~PB2_PSORB0; 154 tempval |= PB2_PSORB1; 155 out_be32(&io->iop_psorb, tempval); 156 157 tempval = in_be32(&io->iop_pparb); 158 tempval |= (PB2_DIRB0 | PB2_DIRB1); 159 out_be32(&io->iop_pparb, tempval); 160 161 target = CPM_CLK_FCC2; 162 break; 163 case 2: 164 tempval = in_be32(&io->iop_pdirb); 165 tempval &= ~PB3_DIRB0; 166 tempval |= PB3_DIRB1; 167 out_be32(&io->iop_pdirb, tempval); 168 169 tempval = in_be32(&io->iop_psorb); 170 tempval &= ~PB3_PSORB0; 171 tempval |= PB3_PSORB1; 172 out_be32(&io->iop_psorb, tempval); 173 174 tempval = in_be32(&io->iop_pparb); 175 tempval |= (PB3_DIRB0 | PB3_DIRB1); 176 out_be32(&io->iop_pparb, tempval); 177 178 tempval = in_be32(&io->iop_pdirc); 179 tempval |= PC3_DIRC1; 180 out_be32(&io->iop_pdirc, tempval); 181 182 tempval = in_be32(&io->iop_pparc); 183 tempval |= PC3_DIRC1; 184 out_be32(&io->iop_pparc, tempval); 185 186 target = CPM_CLK_FCC3; 187 break; 188 default: 189 printk(KERN_ERR "init_fcc_ioports: invalid FCC number\n"); 190 return; 191 } 192 193 /* Port C has clocks...... */ 194 tempval = in_be32(&io->iop_psorc); 195 tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 196 out_be32(&io->iop_psorc, tempval); 197 198 tempval = in_be32(&io->iop_pdirc); 199 tempval &= ~(PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 200 out_be32(&io->iop_pdirc, tempval); 201 tempval = in_be32(&io->iop_pparc); 202 tempval |= (PC_CLK(fpi->clk_rx - 8) | PC_CLK(fpi->clk_tx - 8)); 203 out_be32(&io->iop_pparc, tempval); 204 205 cpm2_unmap(io); 206 207 /* Configure Serial Interface clock routing. 208 * First, clear FCC bits to zero, 209 * then set the ones we want. 210 */ 211 cpm2_clk_setup(target, fpi->clk_rx, CPM_CLK_RX); 212 cpm2_clk_setup(target, fpi->clk_tx, CPM_CLK_TX); 213} 214#endif 215 216static void __init mpc85xx_ads_setup_arch(void) 217{ 218 struct device_node *cpu; 219#ifdef CONFIG_PCI 220 struct device_node *np; 221#endif 222 223 if (ppc_md.progress) 224 ppc_md.progress("mpc85xx_ads_setup_arch()", 0); 225 226 cpu = of_find_node_by_type(NULL, "cpu"); 227 if (cpu != 0) { 228 const unsigned int *fp; 229 230 fp = of_get_property(cpu, "clock-frequency", NULL); 231 if (fp != 0) 232 loops_per_jiffy = *fp / HZ; 233 else 234 loops_per_jiffy = 50000000 / HZ; 235 of_node_put(cpu); 236 } 237 238#ifdef CONFIG_CPM2 239 cpm2_reset(); 240#endif 241 242#ifdef CONFIG_PCI 243 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 244 add_bridge(np); 245 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 246#endif 247} 248 249static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) 250{ 251 uint pvid, svid, phid1; 252 uint memsize = total_memory; 253 254 pvid = mfspr(SPRN_PVR); 255 svid = mfspr(SPRN_SVR); 256 257 seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); 258 seq_printf(m, "Machine\t\t: mpc85xx\n"); 259 seq_printf(m, "PVR\t\t: 0x%x\n", pvid); 260 seq_printf(m, "SVR\t\t: 0x%x\n", svid); 261 262 /* Display cpu Pll setting */ 263 phid1 = mfspr(SPRN_HID1); 264 seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); 265 266 /* Display the amount of memory */ 267 seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); 268} 269 270/* 271 * Called very early, device-tree isn't unflattened 272 */ 273static int __init mpc85xx_ads_probe(void) 274{ 275 unsigned long root = of_get_flat_dt_root(); 276 277 return of_flat_dt_is_compatible(root, "MPC85xxADS"); 278} 279 280define_machine(mpc85xx_ads) { 281 .name = "MPC85xx ADS", 282 .probe = mpc85xx_ads_probe, 283 .setup_arch = mpc85xx_ads_setup_arch, 284 .init_IRQ = mpc85xx_ads_pic_init, 285 .show_cpuinfo = mpc85xx_ads_show_cpuinfo, 286 .get_irq = mpic_get_irq, 287 .restart = mpc85xx_restart, 288 .calibrate_decr = generic_calibrate_decr, 289 .progress = udbg_progress, 290}; 291