Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-or-later
0002 /*
0003  * Board setup routines for the Motorola/Emerson MVME5100.
0004  *
0005  * Copyright 2013 CSC Australia Pty. Ltd.
0006  *
0007  * Based on earlier code by:
0008  *
0009  *    Matt Porter, MontaVista Software Inc.
0010  *    Copyright 2001 MontaVista Software Inc.
0011  *
0012  * Author: Stephen Chivers <schivers@csc.com>
0013  */
0014 
0015 #include <linux/of_irq.h>
0016 #include <linux/of_platform.h>
0017 
0018 #include <asm/i8259.h>
0019 #include <asm/pci-bridge.h>
0020 #include <asm/mpic.h>
0021 #include <mm/mmu_decl.h>
0022 #include <asm/udbg.h>
0023 
0024 #define HAWK_MPIC_SIZE      0x00040000U
0025 #define MVME5100_PCI_MEM_OFFSET 0x00000000
0026 
0027 /* Board register addresses. */
0028 #define BOARD_STATUS_REG    0xfef88080
0029 #define BOARD_MODFAIL_REG   0xfef88090
0030 #define BOARD_MODRST_REG    0xfef880a0
0031 #define BOARD_TBEN_REG      0xfef880c0
0032 #define BOARD_SW_READ_REG   0xfef880e0
0033 #define BOARD_GEO_ADDR_REG  0xfef880e8
0034 #define BOARD_EXT_FEATURE1_REG  0xfef880f0
0035 #define BOARD_EXT_FEATURE2_REG  0xfef88100
0036 
0037 static phys_addr_t pci_membase;
0038 static u_char *restart;
0039 
0040 static void mvme5100_8259_cascade(struct irq_desc *desc)
0041 {
0042     struct irq_chip *chip = irq_desc_get_chip(desc);
0043     unsigned int cascade_irq = i8259_irq();
0044 
0045     if (cascade_irq)
0046         generic_handle_irq(cascade_irq);
0047 
0048     chip->irq_eoi(&desc->irq_data);
0049 }
0050 
0051 static void __init mvme5100_pic_init(void)
0052 {
0053     struct mpic *mpic;
0054     struct device_node *np;
0055     struct device_node *cp = NULL;
0056     unsigned int cirq;
0057     unsigned long intack = 0;
0058     const u32 *prop = NULL;
0059 
0060     np = of_find_node_by_type(NULL, "open-pic");
0061     if (!np) {
0062         pr_err("Could not find open-pic node\n");
0063         return;
0064     }
0065 
0066     mpic = mpic_alloc(np, pci_membase, 0, 16, 256, " OpenPIC  ");
0067 
0068     BUG_ON(mpic == NULL);
0069     of_node_put(np);
0070 
0071     mpic_assign_isu(mpic, 0, pci_membase + 0x10000);
0072 
0073     mpic_init(mpic);
0074 
0075     cp = of_find_compatible_node(NULL, NULL, "chrp,iic");
0076     if (cp == NULL) {
0077         pr_warn("mvme5100_pic_init: couldn't find i8259\n");
0078         return;
0079     }
0080 
0081     cirq = irq_of_parse_and_map(cp, 0);
0082     if (!cirq) {
0083         pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
0084         return;
0085     }
0086 
0087     np = of_find_compatible_node(NULL, "pci", "mpc10x-pci");
0088     if (np) {
0089         prop = of_get_property(np, "8259-interrupt-acknowledge", NULL);
0090 
0091         if (prop)
0092             intack = prop[0];
0093 
0094         of_node_put(np);
0095     }
0096 
0097     if (intack)
0098         pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
0099            intack);
0100 
0101     i8259_init(cp, intack);
0102     of_node_put(cp);
0103     irq_set_chained_handler(cirq, mvme5100_8259_cascade);
0104 }
0105 
0106 static int __init mvme5100_add_bridge(struct device_node *dev)
0107 {
0108     const int       *bus_range;
0109     int         len;
0110     struct pci_controller   *hose;
0111     unsigned short      devid;
0112 
0113     pr_info("Adding PCI host bridge %pOF\n", dev);
0114 
0115     bus_range = of_get_property(dev, "bus-range", &len);
0116 
0117     hose = pcibios_alloc_controller(dev);
0118     if (hose == NULL)
0119         return -ENOMEM;
0120 
0121     hose->first_busno = bus_range ? bus_range[0] : 0;
0122     hose->last_busno = bus_range ? bus_range[1] : 0xff;
0123 
0124     setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0);
0125 
0126     pci_process_bridge_OF_ranges(hose, dev, 1);
0127 
0128     early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid);
0129 
0130     if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) {
0131         pr_err("HAWK PHB not present?\n");
0132         return 0;
0133     }
0134 
0135     early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase);
0136 
0137     if (pci_membase == 0) {
0138         pr_err("HAWK PHB mibar not correctly set?\n");
0139         return 0;
0140     }
0141 
0142     pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase);
0143 
0144     return 0;
0145 }
0146 
0147 static const struct of_device_id mvme5100_of_bus_ids[] __initconst = {
0148     { .compatible = "hawk-bridge", },
0149     {},
0150 };
0151 
0152 /*
0153  * Setup the architecture
0154  */
0155 static void __init mvme5100_setup_arch(void)
0156 {
0157     if (ppc_md.progress)
0158         ppc_md.progress("mvme5100_setup_arch()", 0);
0159 
0160     restart = ioremap(BOARD_MODRST_REG, 4);
0161 }
0162 
0163 static void __init mvme5100_setup_pci(void)
0164 {
0165     struct device_node *np;
0166 
0167     for_each_compatible_node(np, "pci", "hawk-pci")
0168         mvme5100_add_bridge(np);
0169 }
0170 
0171 static void mvme5100_show_cpuinfo(struct seq_file *m)
0172 {
0173     seq_puts(m, "Vendor\t\t: Motorola/Emerson\n");
0174     seq_puts(m, "Machine\t\t: MVME5100\n");
0175 }
0176 
0177 static void __noreturn mvme5100_restart(char *cmd)
0178 {
0179 
0180     local_irq_disable();
0181     mtmsr(mfmsr() | MSR_IP);
0182 
0183     out_8((u_char *) restart, 0x01);
0184 
0185     while (1)
0186         ;
0187 }
0188 
0189 /*
0190  * Called very early, device-tree isn't unflattened
0191  */
0192 static int __init mvme5100_probe(void)
0193 {
0194     return of_machine_is_compatible("MVME5100");
0195 }
0196 
0197 static int __init probe_of_platform_devices(void)
0198 {
0199 
0200     of_platform_bus_probe(NULL, mvme5100_of_bus_ids, NULL);
0201     return 0;
0202 }
0203 
0204 machine_device_initcall(mvme5100, probe_of_platform_devices);
0205 
0206 define_machine(mvme5100) {
0207     .name           = "MVME5100",
0208     .probe          = mvme5100_probe,
0209     .setup_arch     = mvme5100_setup_arch,
0210     .discover_phbs      = mvme5100_setup_pci,
0211     .init_IRQ       = mvme5100_pic_init,
0212     .show_cpuinfo       = mvme5100_show_cpuinfo,
0213     .get_irq        = mpic_get_irq,
0214     .restart        = mvme5100_restart,
0215     .calibrate_decr     = generic_calibrate_decr,
0216     .progress       = udbg_progress,
0217 };