linux/arch/powerpc/platforms/85xx/ge_imp3a.c
<<
>>
Prefs
   1/*
   2 * GE IMP3A Board Setup
   3 *
   4 * Author Martyn Welch <martyn.welch@ge.com>
   5 *
   6 * Copyright 2010 GE Intelligent Platforms Embedded Systems, 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 * Based on: mpc85xx_ds.c (MPC85xx DS Board Setup)
  14 * Copyright 2007 Freescale Semiconductor Inc.
  15 */
  16
  17#include <linux/stddef.h>
  18#include <linux/kernel.h>
  19#include <linux/pci.h>
  20#include <linux/kdev_t.h>
  21#include <linux/delay.h>
  22#include <linux/seq_file.h>
  23#include <linux/interrupt.h>
  24#include <linux/of_platform.h>
  25
  26#include <asm/time.h>
  27#include <asm/machdep.h>
  28#include <asm/pci-bridge.h>
  29#include <mm/mmu_decl.h>
  30#include <asm/prom.h>
  31#include <asm/udbg.h>
  32#include <asm/mpic.h>
  33#include <asm/swiotlb.h>
  34#include <asm/nvram.h>
  35
  36#include <sysdev/fsl_soc.h>
  37#include <sysdev/fsl_pci.h>
  38#include "smp.h"
  39
  40#include "mpc85xx.h"
  41#include <sysdev/ge/ge_pic.h>
  42
  43void __iomem *imp3a_regs;
  44
  45void __init ge_imp3a_pic_init(void)
  46{
  47        struct mpic *mpic;
  48        struct device_node *np;
  49        struct device_node *cascade_node = NULL;
  50
  51        if (of_machine_is_compatible("fsl,MPC8572DS-CAMP")) {
  52                mpic = mpic_alloc(NULL, 0,
  53                        MPIC_NO_RESET |
  54                        MPIC_BIG_ENDIAN |
  55                        MPIC_SINGLE_DEST_CPU,
  56                        0, 256, " OpenPIC  ");
  57        } else {
  58                mpic = mpic_alloc(NULL, 0,
  59                          MPIC_BIG_ENDIAN |
  60                          MPIC_SINGLE_DEST_CPU,
  61                        0, 256, " OpenPIC  ");
  62        }
  63
  64        BUG_ON(mpic == NULL);
  65        mpic_init(mpic);
  66        /*
  67         * There is a simple interrupt handler in the main FPGA, this needs
  68         * to be cascaded into the MPIC
  69         */
  70        for_each_node_by_type(np, "interrupt-controller")
  71                if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
  72                        cascade_node = np;
  73                        break;
  74                }
  75
  76        if (cascade_node == NULL) {
  77                printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
  78                return;
  79        }
  80
  81        gef_pic_init(cascade_node);
  82        of_node_put(cascade_node);
  83}
  84
  85static void ge_imp3a_pci_assign_primary(void)
  86{
  87#ifdef CONFIG_PCI
  88        struct device_node *np;
  89        struct resource rsrc;
  90
  91        for_each_node_by_type(np, "pci") {
  92                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
  93                    of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
  94                    of_device_is_compatible(np, "fsl,p2020-pcie")) {
  95                        of_address_to_resource(np, 0, &rsrc);
  96                        if ((rsrc.start & 0xfffff) == 0x9000)
  97                                fsl_pci_primary = np;
  98                }
  99        }
 100#endif
 101}
 102
 103/*
 104 * Setup the architecture
 105 */
 106static void __init ge_imp3a_setup_arch(void)
 107{
 108        struct device_node *regs;
 109
 110        if (ppc_md.progress)
 111                ppc_md.progress("ge_imp3a_setup_arch()", 0);
 112
 113        mpc85xx_smp_init();
 114
 115        ge_imp3a_pci_assign_primary();
 116
 117        swiotlb_detect_4g();
 118
 119        /* Remap basic board registers */
 120        regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
 121        if (regs) {
 122                imp3a_regs = of_iomap(regs, 0);
 123                if (imp3a_regs == NULL)
 124                        printk(KERN_WARNING "Unable to map board registers\n");
 125                of_node_put(regs);
 126        }
 127
 128#if defined(CONFIG_MMIO_NVRAM)
 129        mmio_nvram_init();
 130#endif
 131
 132        printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
 133}
 134
 135/* Return the PCB revision */
 136static unsigned int ge_imp3a_get_pcb_rev(void)
 137{
 138        unsigned int reg;
 139
 140        reg = ioread16(imp3a_regs);
 141        return (reg >> 8) & 0xff;
 142}
 143
 144/* Return the board (software) revision */
 145static unsigned int ge_imp3a_get_board_rev(void)
 146{
 147        unsigned int reg;
 148
 149        reg = ioread16(imp3a_regs + 0x2);
 150        return reg & 0xff;
 151}
 152
 153/* Return the FPGA revision */
 154static unsigned int ge_imp3a_get_fpga_rev(void)
 155{
 156        unsigned int reg;
 157
 158        reg = ioread16(imp3a_regs + 0x2);
 159        return (reg >> 8) & 0xff;
 160}
 161
 162/* Return compactPCI Geographical Address */
 163static unsigned int ge_imp3a_get_cpci_geo_addr(void)
 164{
 165        unsigned int reg;
 166
 167        reg = ioread16(imp3a_regs + 0x6);
 168        return (reg & 0x0f00) >> 8;
 169}
 170
 171/* Return compactPCI System Controller Status */
 172static unsigned int ge_imp3a_get_cpci_is_syscon(void)
 173{
 174        unsigned int reg;
 175
 176        reg = ioread16(imp3a_regs + 0x6);
 177        return reg & (1 << 12);
 178}
 179
 180static void ge_imp3a_show_cpuinfo(struct seq_file *m)
 181{
 182        seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 183
 184        seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
 185                ('A' + ge_imp3a_get_board_rev() - 1));
 186
 187        seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
 188
 189        seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
 190
 191        seq_printf(m, "cPCI syscon\t: %s\n",
 192                ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
 193}
 194
 195/*
 196 * Called very early, device-tree isn't unflattened
 197 */
 198static int __init ge_imp3a_probe(void)
 199{
 200        return of_machine_is_compatible("ge,IMP3A");
 201}
 202
 203machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
 204
 205define_machine(ge_imp3a) {
 206        .name                   = "GE_IMP3A",
 207        .probe                  = ge_imp3a_probe,
 208        .setup_arch             = ge_imp3a_setup_arch,
 209        .init_IRQ               = ge_imp3a_pic_init,
 210        .show_cpuinfo           = ge_imp3a_show_cpuinfo,
 211#ifdef CONFIG_PCI
 212        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 213        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 214#endif
 215        .get_irq                = mpic_get_irq,
 216        .calibrate_decr         = generic_calibrate_decr,
 217        .progress               = udbg_progress,
 218};
 219