setup.c 5.0 KB
Newer Older
1
/*
2
 *  linux/arch/powerpc/platforms/cell/cell_setup.c
3 4 5 6 7
 *
 *  Copyright (C) 1995  Linus Torvalds
 *  Adapted from 'alpha' version by Gary Thomas
 *  Modified by Cort Dougan (cort@cs.nmt.edu)
 *  Modified by PPC64 Team, IBM Corp
8
 *  Modified by Cell Team, IBM Deutschland Entwicklung GmbH
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 */
#undef DEBUG

#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/reboot.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/console.h>
31 32
#include <linux/mutex.h>
#include <linux/memory_hotplug.h>
33 34 35 36

#include <asm/mmu.h>
#include <asm/processor.h>
#include <asm/io.h>
M
Michael Ellerman 已提交
37
#include <asm/kexec.h>
38 39 40 41 42 43 44 45 46 47
#include <asm/pgtable.h>
#include <asm/prom.h>
#include <asm/rtas.h>
#include <asm/pci-bridge.h>
#include <asm/iommu.h>
#include <asm/dma.h>
#include <asm/machdep.h>
#include <asm/time.h>
#include <asm/nvram.h>
#include <asm/cputable.h>
48
#include <asm/ppc-pci.h>
49
#include <asm/irq.h>
50
#include <asm/spu.h>
51
#include <asm/spu_priv1.h>
52
#include <asm/udbg.h>
53
#include <asm/mpic.h>
54
#include <asm/of_platform.h>
55

56
#include "interrupt.h"
57
#include "cbe_regs.h"
58
#include "pervasive.h"
59
#include "ras.h"
60 61 62 63 64 65 66

#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif

67
static void cell_show_cpuinfo(struct seq_file *m)
68 69 70 71 72 73 74
{
	struct device_node *root;
	const char *model = "";

	root = of_find_node_by_path("/");
	if (root)
		model = get_property(root, "model", NULL);
75
	seq_printf(m, "machine\t\t: CHRP %s\n", model);
76 77 78
	of_node_put(root);
}

79
static void cell_progress(char *s, unsigned short hex)
80 81 82 83
{
	printk("*** %04x : %s\n", hex, s ? s : "");
}

84 85
static int __init cell_publish_devices(void)
{
86 87 88 89 90 91
	if (!machine_is(cell))
		return 0;

	/* Publish OF platform devices for southbridge IOs */
	of_platform_bus_probe(NULL, NULL, NULL);

92 93 94 95
	return 0;
}
device_initcall(cell_publish_devices);

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
{
	struct mpic *mpic = desc->handler_data;
	unsigned int virq;

	virq = mpic_get_one_irq(mpic);
	if (virq != NO_IRQ)
		generic_handle_irq(virq);
	desc->chip->eoi(irq);
}

static void __init mpic_init_IRQ(void)
{
	struct device_node *dn;
	struct mpic *mpic;
	unsigned int virq;

	for (dn = NULL;
	     (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
		if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
			continue;

		/* The MPIC driver will get everything it needs from the
		 * device-tree, just pass 0 to all arguments
		 */
		mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC     ");
		if (mpic == NULL)
			continue;
		mpic_init(mpic);

		virq = irq_of_parse_and_map(dn, 0);
		if (virq == NO_IRQ)
			continue;

		printk(KERN_INFO "%s : hooking up to IRQ %d\n",
		       dn->full_name, virq);
		set_irq_data(virq, mpic);
		set_irq_chained_handler(virq, cell_mpic_cascade);
	}
}


138 139 140 141
static void __init cell_init_irq(void)
{
	iic_init_IRQ();
	spider_init_IRQ();
142
	mpic_init_IRQ();
143 144
}

145
static void __init cell_setup_arch(void)
146
{
147
#ifdef CONFIG_SPU_BASE
148 149
	spu_priv1_ops = &spu_priv1_mmio_ops;
	spu_management_ops = &spu_management_of_ops;
150
#endif
151

152 153 154 155 156 157
	cbe_regs_init();

#ifdef CONFIG_CBE_RAS
	cbe_ras_init();
#endif

158
#ifdef CONFIG_SMP
159
	smp_init_cell();
160 161 162 163 164 165 166 167 168 169 170 171
#endif
	/* init to some ~sane value until calibrate_delay() runs */
	loops_per_jiffy = 50000000;

	if (ROOT_DEV == 0) {
		printk("No ramdisk, default root is /dev/hda2\n");
		ROOT_DEV = Root_HDA2;
	}

	/* Find and initialize PCI host bridges */
	init_pci_config_tokens();
	find_and_init_phbs();
172
	cbe_pervasive_init();
173 174 175 176
#ifdef CONFIG_DUMMY_CONSOLE
	conswitchp = &dummy_con;
#endif

177
	mmio_nvram_init();
178 179
}

180
static int __init cell_probe(void)
181
{
182
	unsigned long root = of_get_flat_dt_root();
183

184 185 186 187 188
	if (!of_flat_dt_is_compatible(root, "IBM,CBEA") &&
	    !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
		return 0;

	hpte_init_native();
189

190
	return 1;
191 192
}

193 194 195 196 197 198 199 200 201
/*
 * Cell has no legacy IO; anything calling this function has to
 * fail or bad things will happen
 */
static int cell_check_legacy_ioport(unsigned int baseport)
{
	return -ENODEV;
}

202 203
define_machine(cell) {
	.name			= "Cell",
204 205 206
	.probe			= cell_probe,
	.setup_arch		= cell_setup_arch,
	.show_cpuinfo		= cell_show_cpuinfo,
207 208 209 210 211 212 213
	.restart		= rtas_restart,
	.power_off		= rtas_power_off,
	.halt			= rtas_halt,
	.get_boot_time		= rtas_get_boot_time,
	.get_rtc_time		= rtas_get_rtc_time,
	.set_rtc_time		= rtas_set_rtc_time,
	.calibrate_decr		= generic_calibrate_decr,
214
	.check_legacy_ioport	= cell_check_legacy_ioport,
215
	.progress		= cell_progress,
216
	.init_IRQ       	= cell_init_irq,
217
	.pci_setup_phb		= rtas_setup_phb,
M
Michael Ellerman 已提交
218 219 220
#ifdef CONFIG_KEXEC
	.machine_kexec		= default_machine_kexec,
	.machine_kexec_prepare	= default_machine_kexec_prepare,
221
	.machine_crash_shutdown	= default_machine_crash_shutdown,
M
Michael Ellerman 已提交
222
#endif
223
};