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        unsigned long root = of_get_flat_dt_root();
  51
  52        if (of_flat_dt_is_compatible(root, "fsl,MPC8572DS-CAMP")) {
  53                mpic = mpic_alloc(NULL, 0,
  54                        MPIC_NO_RESET |
  55                        MPIC_BIG_ENDIAN |
  56                        MPIC_SINGLE_DEST_CPU,
  57                        0, 256, " OpenPIC  ");
  58        } else {
  59                mpic = mpic_alloc(NULL, 0,
  60                          MPIC_BIG_ENDIAN |
  61                          MPIC_SINGLE_DEST_CPU,
  62                        0, 256, " OpenPIC  ");
  63        }
  64
  65        BUG_ON(mpic == NULL);
  66        mpic_init(mpic);
  67        /*
  68         * There is a simple interrupt handler in the main FPGA, this needs
  69         * to be cascaded into the MPIC
  70         */
  71        for_each_node_by_type(np, "interrupt-controller")
  72                if (of_device_is_compatible(np, "gef,fpga-pic-1.00")) {
  73                        cascade_node = np;
  74                        break;
  75                }
  76
  77        if (cascade_node == NULL) {
  78                printk(KERN_WARNING "IMP3A: No FPGA PIC\n");
  79                return;
  80        }
  81
  82        gef_pic_init(cascade_node);
  83        of_node_put(cascade_node);
  84}
  85
  86static void ge_imp3a_pci_assign_primary(void)
  87{
  88#ifdef CONFIG_PCI
  89        struct device_node *np;
  90        struct resource rsrc;
  91
  92        for_each_node_by_type(np, "pci") {
  93                if (of_device_is_compatible(np, "fsl,mpc8540-pci") ||
  94                    of_device_is_compatible(np, "fsl,mpc8548-pcie") ||
  95                    of_device_is_compatible(np, "fsl,p2020-pcie")) {
  96                        of_address_to_resource(np, 0, &rsrc);
  97                        if ((rsrc.start & 0xfffff) == 0x9000)
  98                                fsl_pci_primary = np;
  99                }
 100        }
 101#endif
 102}
 103
 104/*
 105 * Setup the architecture
 106 */
 107static void __init ge_imp3a_setup_arch(void)
 108{
 109        struct device_node *regs;
 110
 111        if (ppc_md.progress)
 112                ppc_md.progress("ge_imp3a_setup_arch()", 0);
 113
 114        mpc85xx_smp_init();
 115
 116        ge_imp3a_pci_assign_primary();
 117
 118        swiotlb_detect_4g();
 119
 120        /* Remap basic board registers */
 121        regs = of_find_compatible_node(NULL, NULL, "ge,imp3a-fpga-regs");
 122        if (regs) {
 123                imp3a_regs = of_iomap(regs, 0);
 124                if (imp3a_regs == NULL)
 125                        printk(KERN_WARNING "Unable to map board registers\n");
 126                of_node_put(regs);
 127        }
 128
 129#if defined(CONFIG_MMIO_NVRAM)
 130        mmio_nvram_init();
 131#endif
 132
 133        printk(KERN_INFO "GE Intelligent Platforms IMP3A 3U cPCI SBC\n");
 134}
 135
 136/* Return the PCB revision */
 137static unsigned int ge_imp3a_get_pcb_rev(void)
 138{
 139        unsigned int reg;
 140
 141        reg = ioread16(imp3a_regs);
 142        return (reg >> 8) & 0xff;
 143}
 144
 145/* Return the board (software) revision */
 146static unsigned int ge_imp3a_get_board_rev(void)
 147{
 148        unsigned int reg;
 149
 150        reg = ioread16(imp3a_regs + 0x2);
 151        return reg & 0xff;
 152}
 153
 154/* Return the FPGA revision */
 155static unsigned int ge_imp3a_get_fpga_rev(void)
 156{
 157        unsigned int reg;
 158
 159        reg = ioread16(imp3a_regs + 0x2);
 160        return (reg >> 8) & 0xff;
 161}
 162
 163/* Return compactPCI Geographical Address */
 164static unsigned int ge_imp3a_get_cpci_geo_addr(void)
 165{
 166        unsigned int reg;
 167
 168        reg = ioread16(imp3a_regs + 0x6);
 169        return (reg & 0x0f00) >> 8;
 170}
 171
 172/* Return compactPCI System Controller Status */
 173static unsigned int ge_imp3a_get_cpci_is_syscon(void)
 174{
 175        unsigned int reg;
 176
 177        reg = ioread16(imp3a_regs + 0x6);
 178        return reg & (1 << 12);
 179}
 180
 181static void ge_imp3a_show_cpuinfo(struct seq_file *m)
 182{
 183        seq_printf(m, "Vendor\t\t: GE Intelligent Platforms\n");
 184
 185        seq_printf(m, "Revision\t: %u%c\n", ge_imp3a_get_pcb_rev(),
 186                ('A' + ge_imp3a_get_board_rev() - 1));
 187
 188        seq_printf(m, "FPGA Revision\t: %u\n", ge_imp3a_get_fpga_rev());
 189
 190        seq_printf(m, "cPCI geo. addr\t: %u\n", ge_imp3a_get_cpci_geo_addr());
 191
 192        seq_printf(m, "cPCI syscon\t: %s\n",
 193                ge_imp3a_get_cpci_is_syscon() ? "yes" : "no");
 194}
 195
 196/*
 197 * Called very early, device-tree isn't unflattened
 198 */
 199static int __init ge_imp3a_probe(void)
 200{
 201        unsigned long root = of_get_flat_dt_root();
 202
 203        return of_flat_dt_is_compatible(root, "ge,IMP3A");
 204}
 205
 206machine_arch_initcall(ge_imp3a, mpc85xx_common_publish_devices);
 207
 208machine_arch_initcall(ge_imp3a, swiotlb_setup_bus_notifier);
 209
 210define_machine(ge_imp3a) {
 211        .name                   = "GE_IMP3A",
 212        .probe                  = ge_imp3a_probe,
 213        .setup_arch             = ge_imp3a_setup_arch,
 214        .init_IRQ               = ge_imp3a_pic_init,
 215        .show_cpuinfo           = ge_imp3a_show_cpuinfo,
 216#ifdef CONFIG_PCI
 217        .pcibios_fixup_bus      = fsl_pcibios_fixup_bus,
 218        .pcibios_fixup_phb      = fsl_pcibios_fixup_phb,
 219#endif
 220        .get_irq                = mpic_get_irq,
 221        .restart                = fsl_rstcr_restart,
 222        .calibrate_decr         = generic_calibrate_decr,
 223        .progress               = udbg_progress,
 224};
 225