Version:  2.6.34 2.6.35 2.6.36 2.6.37 2.6.38 2.6.39 3.0 3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10 3.11 3.12 3.13 3.14

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

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

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us