2 * Board setup routines for the Motorola/Emerson MVME5100.
4 * Copyright 2013 CSC Australia Pty. Ltd.
6 * Based on earlier code by:
8 * Matt Porter, MontaVista Software Inc.
9 * Copyright 2001 MontaVista Software Inc.
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.
16 * Author: Stephen Chivers <schivers@csc.com>
20 #include <linux/of_platform.h>
22 #include <asm/i8259.h>
23 #include <asm/pci-bridge.h>
26 #include <mm/mmu_decl.h>
29 #define HAWK_MPIC_SIZE 0x00040000U
30 #define MVME5100_PCI_MEM_OFFSET 0x00000000
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
42 static phys_addr_t pci_membase
;
43 static u_char
*restart
;
45 static void mvme5100_8259_cascade(struct irq_desc
*desc
)
47 struct irq_chip
*chip
= irq_desc_get_chip(desc
);
48 unsigned int cascade_irq
= i8259_irq();
51 generic_handle_irq(cascade_irq
);
53 chip
->irq_eoi(&desc
->irq_data
);
56 static void __init
mvme5100_pic_init(void)
59 struct device_node
*np
;
60 struct device_node
*cp
= NULL
;
62 unsigned long intack
= 0;
63 const u32
*prop
= NULL
;
65 np
= of_find_node_by_type(NULL
, "open-pic");
67 pr_err("Could not find open-pic node\n");
71 mpic
= mpic_alloc(np
, pci_membase
, 0, 16, 256, " OpenPIC ");
76 mpic_assign_isu(mpic
, 0, pci_membase
+ 0x10000);
80 cp
= of_find_compatible_node(NULL
, NULL
, "chrp,iic");
82 pr_warn("mvme5100_pic_init: couldn't find i8259\n");
86 cirq
= irq_of_parse_and_map(cp
, 0);
88 pr_warn("mvme5100_pic_init: no cascade interrupt?\n");
92 np
= of_find_compatible_node(NULL
, "pci", "mpc10x-pci");
94 prop
= of_get_property(np
, "8259-interrupt-acknowledge", NULL
);
103 pr_debug("mvme5100_pic_init: PCI 8259 intack at 0x%016lx\n",
106 i8259_init(cp
, intack
);
108 irq_set_chained_handler(cirq
, mvme5100_8259_cascade
);
111 static int __init
mvme5100_add_bridge(struct device_node
*dev
)
113 const int *bus_range
;
115 struct pci_controller
*hose
;
116 unsigned short devid
;
118 pr_info("Adding PCI host bridge %pOF\n", dev
);
120 bus_range
= of_get_property(dev
, "bus-range", &len
);
122 hose
= pcibios_alloc_controller(dev
);
126 hose
->first_busno
= bus_range
? bus_range
[0] : 0;
127 hose
->last_busno
= bus_range
? bus_range
[1] : 0xff;
129 setup_indirect_pci(hose
, 0xfe000cf8, 0xfe000cfc, 0);
131 pci_process_bridge_OF_ranges(hose
, dev
, 1);
133 early_read_config_word(hose
, 0, 0, PCI_DEVICE_ID
, &devid
);
135 if (devid
!= PCI_DEVICE_ID_MOTOROLA_HAWK
) {
136 pr_err("HAWK PHB not present?\n");
140 early_read_config_dword(hose
, 0, 0, PCI_BASE_ADDRESS_1
, &pci_membase
);
142 if (pci_membase
== 0) {
143 pr_err("HAWK PHB mibar not correctly set?\n");
147 pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase
);
152 static const struct of_device_id mvme5100_of_bus_ids
[] __initconst
= {
153 { .compatible
= "hawk-bridge", },
158 * Setup the architecture
160 static void __init
mvme5100_setup_arch(void)
162 struct device_node
*np
;
165 ppc_md
.progress("mvme5100_setup_arch()", 0);
167 for_each_compatible_node(np
, "pci", "hawk-pci")
168 mvme5100_add_bridge(np
);
170 restart
= ioremap(BOARD_MODRST_REG
, 4);
174 static void mvme5100_show_cpuinfo(struct seq_file
*m
)
176 seq_puts(m
, "Vendor\t\t: Motorola/Emerson\n");
177 seq_puts(m
, "Machine\t\t: MVME5100\n");
180 static void __noreturn
mvme5100_restart(char *cmd
)
184 mtmsr(mfmsr() | MSR_IP
);
186 out_8((u_char
*) restart
, 0x01);
193 * Called very early, device-tree isn't unflattened
195 static int __init
mvme5100_probe(void)
197 return of_machine_is_compatible("MVME5100");
200 static int __init
probe_of_platform_devices(void)
203 of_platform_bus_probe(NULL
, mvme5100_of_bus_ids
, NULL
);
207 machine_device_initcall(mvme5100
, probe_of_platform_devices
);
209 define_machine(mvme5100
) {
211 .probe
= mvme5100_probe
,
212 .setup_arch
= mvme5100_setup_arch
,
213 .init_IRQ
= mvme5100_pic_init
,
214 .show_cpuinfo
= mvme5100_show_cpuinfo
,
215 .get_irq
= mpic_get_irq
,
216 .restart
= mvme5100_restart
,
217 .calibrate_decr
= generic_calibrate_decr
,
218 .progress
= udbg_progress
,