File Index
Files and directories
Sign in
FILE

mvme5100.c

File preview with syntax highlighting.

linux-6.19.14/arch/powerpc/platforms/embedded6xx/mvme5100.c C
  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_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
 38static phys_addr_t pci_membase;
 39static u_char *restart;
 40
 41static 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
 52static 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
107static 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
148static const struct of_device_id mvme5100_of_bus_ids[] __initconst = {
149	{ .compatible = "hawk-bridge", },
150	{},
151};
152
153/*
154 * Setup the architecture
155 */
156static 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
164static 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
172static 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
178static 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
190static 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
197machine_device_initcall(mvme5100, probe_of_platform_devices);
198
199define_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};
~/ Read-only file preview.