root/arch/powerpc/platforms/embedded6xx/mvme5100.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. mvme5100_8259_cascade
  2. mvme5100_pic_init
  3. mvme5100_add_bridge
  4. mvme5100_setup_arch
  5. mvme5100_show_cpuinfo
  6. mvme5100_restart
  7. mvme5100_probe
  8. probe_of_platform_devices
  9. define_machine

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  * Board setup routines for the Motorola/Emerson MVME5100.
   4  *
   5  * Copyright 2013 CSC Australia Pty. Ltd.
   6  *
   7  * Based on earlier code by:
   8  *
   9  *    Matt Porter, MontaVista Software Inc.
  10  *    Copyright 2001 MontaVista Software Inc.
  11  *
  12  * Author: Stephen Chivers <schivers@csc.com>
  13  */
  14 
  15 #include <linux/of_platform.h>
  16 
  17 #include <asm/i8259.h>
  18 #include <asm/pci-bridge.h>
  19 #include <asm/mpic.h>
  20 #include <asm/prom.h>
  21 #include <mm/mmu_decl.h>
  22 #include <asm/udbg.h>
  23 
  24 #define HAWK_MPIC_SIZE          0x00040000U
  25 #define MVME5100_PCI_MEM_OFFSET 0x00000000
  26 
  27 /* Board register addresses. */
  28 #define BOARD_STATUS_REG        0xfef88080
  29 #define BOARD_MODFAIL_REG       0xfef88090
  30 #define BOARD_MODRST_REG        0xfef880a0
  31 #define BOARD_TBEN_REG          0xfef880c0
  32 #define BOARD_SW_READ_REG       0xfef880e0
  33 #define BOARD_GEO_ADDR_REG      0xfef880e8
  34 #define BOARD_EXT_FEATURE1_REG  0xfef880f0
  35 #define BOARD_EXT_FEATURE2_REG  0xfef88100
  36 
  37 static phys_addr_t pci_membase;
  38 static u_char *restart;
  39 
  40 static void mvme5100_8259_cascade(struct irq_desc *desc)
  41 {
  42         struct irq_chip *chip = irq_desc_get_chip(desc);
  43         unsigned int cascade_irq = i8259_irq();
  44 
  45         if (cascade_irq)
  46                 generic_handle_irq(cascade_irq);
  47 
  48         chip->irq_eoi(&desc->irq_data);
  49 }
  50 
  51 static void __init mvme5100_pic_init(void)
  52 {
  53         struct mpic *mpic;
  54         struct device_node *np;
  55         struct device_node *cp = NULL;
  56         unsigned int cirq;
  57         unsigned long intack = 0;
  58         const u32 *prop = NULL;
  59 
  60         np = of_find_node_by_type(NULL, "open-pic");
  61         if (!np) {
  62                 pr_err("Could not find open-pic node\n");
  63                 return;
  64         }
  65 
  66         mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC  ");
  67 
  68         BUG_ON(mpic == NULL);
  69         of_node_put(np);
  70 
  71         mpic_assign_isu(mpic, 0, pci_membase + 0x10000);
  72 
  73         mpic_init(mpic);
  74 
  75         cp = of_find_compatible_node(NULL, NULL, "chrp,iic");
  76         if (cp == NULL) {
  77                 pr_warn("mvme5100_pic_init: couldn't find i8259\n");
  78                 return;
  79         }
  80 
  81         cirq = irq_of_parse_and_map(cp, 0);
  82         if (!cirq) {
  83                 pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
  84                 return;
  85         }
  86 
  87         np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");
  88         if (np) {
  89                 prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
  90 
  91                 if (prop)
  92                         intack = prop[0];
  93 
  94                 of_node_put(np);
  95         }
  96 
  97         if (intack)
  98                 pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
  99                    intack);
 100 
 101         i8259_init(cp, intack);
 102         of_node_put(cp);
 103         irq_set_chained_handler(cirq, mvme5100_8259_cascade);
 104 }
 105 
 106 static int __init mvme5100_add_bridge(struct device_node *dev)
 107 {
 108         const int               *bus_range;
 109         int                     len;
 110         struct pci_controller   *hose;
 111         unsigned short          devid;
 112 
 113         pr_info("Adding PCI host bridge %pOF\n", dev);
 114 
 115         bus_range = of_get_property(dev, "bus-range", &len);
 116 
 117         hose = pcibios_alloc_controller(dev);
 118         if (hose == NULL)
 119                 return -ENOMEM;
 120 
 121         hose->first_busno = bus_range ? bus_range[0] : 0;
 122         hose->last_busno = bus_range ? bus_range[1] : 0xff;
 123 
 124         setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0);
 125 
 126         pci_process_bridge_OF_ranges(hose, dev, 1);
 127 
 128         early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);
 129 
 130         if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
 131                 pr_err("HAWK PHB not present?\n");
 132                 return 0;
 133         }
 134 
 135         early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
 136 
 137         if (pci_membase == 0) {
 138                 pr_err("HAWK PHB mibar not correctly set?\n");
 139                 return 0;
 140         }
 141 
 142         pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
 143 
 144         return 0;
 145 }
 146 
 147 static const struct of_device_id mvme5100_of_bus_ids[] __initconst = {
 148         { .compatible = "hawk-bridge", },
 149         {},
 150 };
 151 
 152 /*
 153  * Setup the architecture
 154  */
 155 static void __init mvme5100_setup_arch(void)
 156 {
 157         struct device_node *np;
 158 
 159         if (ppc_md.progress)
 160                 ppc_md.progress("mvme5100_setup_arch()", 0);
 161 
 162         for_each_compatible_node(np, "pci", "hawk-pci")
 163                 mvme5100_add_bridge(np);
 164 
 165         restart = ioremap(BOARD_MODRST_REG, 4);
 166 }
 167 
 168 
 169 static void mvme5100_show_cpuinfo(struct seq_file *m)
 170 {
 171         seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");
 172         seq_puts(m, "Machine\t\t: MVME5100\n");
 173 }
 174 
 175 static void __noreturn mvme5100_restart(char *cmd)
 176 {
 177 
 178         local_irq_disable();
 179         mtmsr(mfmsr() | MSR_IP);
 180 
 181         out_8((u_char *) restart, 0x01);
 182 
 183         while (1)
 184                 ;
 185 }
 186 
 187 /*
 188  * Called very early, device-tree isn't unflattened
 189  */
 190 static int __init mvme5100_probe(void)
 191 {
 192         return of_machine_is_compatible("MVME5100");
 193 }
 194 
 195 static int __init probe_of_platform_devices(void)
 196 {
 197 
 198         of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);
 199         return 0;
 200 }
 201 
 202 machine_device_initcall(mvme5100, probe_of_platform_devices);
 203 
 204 define_machine(mvme5100) {
 205         .name                   = "MVME5100",
 206         .probe                  = mvme5100_probe,
 207         .setup_arch             = mvme5100_setup_arch,
 208         .init_IRQ               = mvme5100_pic_init,
 209         .show_cpuinfo           = mvme5100_show_cpuinfo,
 210         .get_irq                = mpic_get_irq,
 211         .restart                = mvme5100_restart,
 212         .calibrate_decr         = generic_calibrate_decr,
 213         .progress               = udbg_progress,
 214 };

/* [<][>][^][v][top][bottom][index][help] */