linux/arch/powerpc/platforms/85xx/corenet_generic.c
<<
>>
Prefs
   1/*
   2 * Corenet based SoC DS Setup
   3 *
   4 * Maintained by Kumar Gala (see MAINTAINERS for contact information)
   5 *
   6 * Copyright 2009-2011 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/kernel.h>
  15#include <linux/pci.h>
  16#include <linux/kdev_t.h>
  17#include <linux/delay.h>
  18#include <linux/interrupt.h>
  19
  20#include <asm/time.h>
  21#include <asm/machdep.h>
  22#include <asm/pci-bridge.h>
  23#include <asm/pgtable.h>
  24#include <asm/ppc-pci.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/ehv_pic.h>
  30#include <asm/qe_ic.h>
  31
  32#include <linux/of_platform.h>
  33#include <sysdev/fsl_soc.h>
  34#include <sysdev/fsl_pci.h>
  35#include "smp.h"
  36#include "mpc85xx.h"
  37
  38void __init corenet_gen_pic_init(void)
  39{
  40        struct mpic *mpic;
  41        unsigned int flags = MPIC_BIG_ENDIAN | MPIC_SINGLE_DEST_CPU |
  42                MPIC_NO_RESET;
  43
  44        struct device_node *np;
  45
  46        if (ppc_md.get_irq == mpic_get_coreint_irq)
  47                flags |= MPIC_ENABLE_COREINT;
  48
  49        mpic = mpic_alloc(NULL, 0, flags, 0, 512, " OpenPIC  ");
  50        BUG_ON(mpic == NULL);
  51
  52        mpic_init(mpic);
  53
  54        np = of_find_compatible_node(NULL, NULL, "fsl,qe-ic");
  55        if (np) {
  56                qe_ic_init(np, 0, qe_ic_cascade_low_mpic,
  57                                qe_ic_cascade_high_mpic);
  58                of_node_put(np);
  59        }
  60}
  61
  62/*
  63 * Setup the architecture
  64 */
  65void __init corenet_gen_setup_arch(void)
  66{
  67        mpc85xx_smp_init();
  68
  69        swiotlb_detect_4g();
  70
  71#if defined(CONFIG_FSL_PCI) && defined(CONFIG_ZONE_DMA32)
  72        /*
  73         * Inbound windows don't cover the full lower 4 GiB
  74         * due to conflicts with PCICSRBAR and outbound windows,
  75         * so limit the DMA32 zone to 2 GiB, to allow consistent
  76         * allocations to succeed.
  77         */
  78        limit_zone_pfn(ZONE_DMA32, 1UL << (31 - PAGE_SHIFT));
  79#endif
  80
  81        pr_info("%s board\n", ppc_md.name);
  82
  83        mpc85xx_qe_init();
  84}
  85
  86static const struct of_device_id of_device_ids[] = {
  87        {
  88                .compatible     = "simple-bus"
  89        },
  90        {
  91                .compatible     = "mdio-mux-gpio"
  92        },
  93        {
  94                .compatible     = "fsl,fpga-ngpixis"
  95        },
  96        {
  97                .compatible     = "fsl,fpga-qixis"
  98        },
  99        {
 100                .compatible     = "fsl,srio",
 101        },
 102        {
 103                .compatible     = "fsl,p4080-pcie",
 104        },
 105        {
 106                .compatible     = "fsl,qoriq-pcie-v2.2",
 107        },
 108        {
 109                .compatible     = "fsl,qoriq-pcie-v2.3",
 110        },
 111        {
 112                .compatible     = "fsl,qoriq-pcie-v2.4",
 113        },
 114        {
 115                .compatible     = "fsl,qoriq-pcie-v3.0",
 116        },
 117        {
 118                .compatible     = "fsl,qe",
 119        },
 120        {
 121                .compatible    = "fsl,fman",
 122        },
 123        /* The following two are for the Freescale hypervisor */
 124        {
 125                .name           = "hypervisor",
 126        },
 127        {
 128                .name           = "handles",
 129        },
 130        {}
 131};
 132
 133int __init corenet_gen_publish_devices(void)
 134{
 135        return of_platform_bus_probe(NULL, of_device_ids, NULL);
 136}
 137
 138static const char * const boards[] __initconst = {
 139        "fsl,P2041RDB",
 140        "fsl,P3041DS",
 141        "fsl,OCA4080",
 142        "fsl,P4080DS",
 143        "fsl,P5020DS",
 144        "fsl,P5040DS",
 145        "fsl,T2080QDS",
 146        "fsl,T2080RDB",
 147        "fsl,T2081QDS",
 148        "fsl,T4240QDS",
 149        "fsl,T4240RDB",
 150        "fsl,B4860QDS",
 151        "fsl,B4420QDS",
 152        "fsl,B4220QDS",
 153        "fsl,T1023RDB",
 154        "fsl,T1024QDS",
 155        "fsl,T1024RDB",
 156        "fsl,T1040QDS",
 157        "fsl,T1042QDS",
 158        "fsl,T1040RDB",
 159        "fsl,T1042RDB",
 160        "fsl,T1042RDB_PI",
 161        "keymile,kmcoge4",
 162        NULL
 163};
 164
 165/*
 166 * Called very early, device-tree isn't unflattened
 167 */
 168static int __init corenet_generic_probe(void)
 169{
 170        unsigned long root = of_get_flat_dt_root();
 171        char hv_compat[24];
 172        int i;
 173#ifdef CONFIG_SMP
 174        extern struct smp_ops_t smp_85xx_ops;
 175#endif
 176
 177        if (of_flat_dt_match(root, boards))
 178                return 1;
 179
 180        /* Check if we're running under the Freescale hypervisor */
 181        for (i = 0; boards[i]; i++) {
 182                snprintf(hv_compat, sizeof(hv_compat), "%s-hv", boards[i]);
 183                if (of_flat_dt_is_compatible(root, hv_compat)) {
 184                        ppc_md.init_IRQ = ehv_pic_init;
 185
 186                        ppc_md.get_irq = ehv_pic_get_irq;
 187                        ppc_md.restart = fsl_hv_restart;
 188                        pm_power_off = fsl_hv_halt;
 189                        ppc_md.halt = fsl_hv_halt;
 190#ifdef CONFIG_SMP
 191                        /*
 192                         * Disable the timebase sync operations because we
 193                         * can't write to the timebase registers under the
 194                         * hypervisor.
 195                         */
 196                        smp_85xx_ops.give_timebase = NULL;
 197                        smp_85xx_ops.take_timebase = NULL;
 198#endif
 199                        return 1;
 200                }
 201        }
 202
 203        return 0;
 204}
 205
 206define_machine(corenet_generic) {
 207        .name                   = "CoreNet Generic",
 208        .probe                  = corenet_generic_probe,
 209        .setup_arch             = corenet_gen_setup_arch,
 210        .init_IRQ               = corenet_gen_pic_init,
 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_coreint_irq,
 216        .restart                = fsl_rstcr_restart,
 217        .calibrate_decr         = generic_calibrate_decr,
 218        .progress               = udbg_progress,
 219#ifdef CONFIG_PPC64
 220        .power_save             = book3e_idle,
 221#else
 222        .power_save             = e500_idle,
 223#endif
 224};
 225
 226machine_arch_initcall(corenet_generic, corenet_gen_publish_devices);
 227
 228#ifdef CONFIG_SWIOTLB
 229machine_arch_initcall(corenet_generic, swiotlb_setup_bus_notifier);
 230#endif
 231