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