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