setup.c 15.5 KB
Newer Older
1
/*
2
 *  Powermac setup and early boot code plus other random bits.
3 4 5 6 7
 *
 *  PowerPC version
 *    Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
 *
 *  Adapted for Power Macintosh by Paul Mackerras
8
 *    Copyright (C) 1996 Paul Mackerras (paulus@samba.org)
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
 *
 *  Derived from "arch/alpha/kernel/setup.c"
 *    Copyright (C) 1995 Linus Torvalds
 *
 *  Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org)
 *
 *  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.
 *
 */

/*
 * bootup setup stuff..
 */

#include <linux/init.h>
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/tty.h>
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/ioport.h>
#include <linux/major.h>
#include <linux/initrd.h>
#include <linux/vt_kern.h>
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/adb.h>
#include <linux/cuda.h>
#include <linux/pmu.h>
#include <linux/irq.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/bitops.h>
#include <linux/suspend.h>
54 55
#include <linux/of_device.h>
#include <linux/of_platform.h>
56
#include <linux/lmb.h>
57 58 59 60 61 62 63

#include <asm/reg.h>
#include <asm/sections.h>
#include <asm/prom.h>
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/io.h>
M
Michael Ellerman 已提交
64
#include <asm/kexec.h>
65 66 67 68 69 70 71 72 73 74
#include <asm/pci-bridge.h>
#include <asm/ohare.h>
#include <asm/mediabay.h>
#include <asm/machdep.h>
#include <asm/dma.h>
#include <asm/cputable.h>
#include <asm/btext.h>
#include <asm/pmac_feature.h>
#include <asm/time.h>
#include <asm/mmu_context.h>
75 76 77
#include <asm/iommu.h>
#include <asm/smu.h>
#include <asm/pmc.h>
78
#include <asm/udbg.h>
79

80
#include "pmac.h"
81 82 83 84 85 86 87

#undef SHOW_GATWICK_IRQS

int ppc_override_l2cr = 0;
int ppc_override_l2cr_value;
int has_l2cache = 0;

88
int pmac_newworld;
89

90 91
static int current_root_goodness = -1;

92
extern struct machdep_calls pmac_md;
93 94 95

#define DEFAULT_ROOT_DEVICE Root_SDA1	/* sda1 - slightly silly choice */

96 97
#ifdef CONFIG_PPC64
int sccdbg;
98 99 100
#endif

sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;
101 102 103 104 105 106
EXPORT_SYMBOL(sys_ctrler);

#ifdef CONFIG_PMAC_SMU
unsigned long smu_cmdbuf_abs;
EXPORT_SYMBOL(smu_cmdbuf_abs);
#endif
107 108 109 110 111 112

#ifdef CONFIG_SMP
extern struct smp_ops_t psurge_smp_ops;
extern struct smp_ops_t core99_smp_ops;
#endif /* CONFIG_SMP */

113
static void pmac_show_cpuinfo(struct seq_file *m)
114 115
{
	struct device_node *np;
116
	const char *pp;
117
	int plen;
118 119
	int mbmodel;
	unsigned int mbflags;
120 121
	char* mbname;

122 123 124 125 126 127
	mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
				    PMAC_MB_INFO_MODEL, 0);
	mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL,
				    PMAC_MB_INFO_FLAGS, 0);
	if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME,
			      (long) &mbname) != 0)
128 129 130 131
		mbname = "Unknown";

	/* find motherboard type */
	seq_printf(m, "machine\t\t: ");
132
	np = of_find_node_by_path("/");
133
	if (np != NULL) {
134
		pp = of_get_property(np, "model", NULL);
135 136 137 138
		if (pp != NULL)
			seq_printf(m, "%s\n", pp);
		else
			seq_printf(m, "PowerMac\n");
139
		pp = of_get_property(np, "compatible", &plen);
140 141 142 143 144 145 146 147 148 149
		if (pp != NULL) {
			seq_printf(m, "motherboard\t:");
			while (plen > 0) {
				int l = strlen(pp) + 1;
				seq_printf(m, " %s", pp);
				plen -= l;
				pp += l;
			}
			seq_printf(m, "\n");
		}
150
		of_node_put(np);
151 152 153 154 155 156 157 158
	} else
		seq_printf(m, "PowerMac\n");

	/* print parsed model */
	seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname);
	seq_printf(m, "pmac flags\t: %08x\n", mbflags);

	/* find l2 cache info */
159 160 161 162
	np = of_find_node_by_name(NULL, "l2-cache");
	if (np == NULL)
		np = of_find_node_by_type(NULL, "cache");
	if (np != NULL) {
163 164 165 166
		const unsigned int *ic =
			of_get_property(np, "i-cache-size", NULL);
		const unsigned int *dc =
			of_get_property(np, "d-cache-size", NULL);
167 168
		seq_printf(m, "L2 cache\t:");
		has_l2cache = 1;
169
		if (of_get_property(np, "cache-unified", NULL) != 0 && dc) {
170 171 172 173 174 175 176 177
			seq_printf(m, " %dK unified", *dc / 1024);
		} else {
			if (ic)
				seq_printf(m, " %dK instruction", *ic / 1024);
			if (dc)
				seq_printf(m, "%s %dK data",
					   (ic? " +": ""), *dc / 1024);
		}
178
		pp = of_get_property(np, "ram-type", NULL);
179 180 181
		if (pp)
			seq_printf(m, " %s", pp);
		seq_printf(m, "\n");
182
		of_node_put(np);
183 184 185 186 187 188 189
	}

	/* Indicate newworld/oldworld */
	seq_printf(m, "pmac-generation\t: %s\n",
		   pmac_newworld ? "NewWorld" : "OldWorld");
}

190 191 192
#ifndef CONFIG_ADB_CUDA
int find_via_cuda(void)
{
193 194 195
	struct device_node *dn = of_find_node_by_name(NULL, "via-cuda");

	if (!dn)
196
		return 0;
197
	of_node_put(dn);
198 199 200 201 202
	printk("WARNING ! Your machine is CUDA-based but your kernel\n");
	printk("          wasn't compiled with CONFIG_ADB_CUDA option !\n");
	return 0;
}
#endif
203

204 205
#ifndef CONFIG_ADB_PMU
int find_via_pmu(void)
206
{
207 208 209
	struct device_node *dn = of_find_node_by_name(NULL, "via-pmu");

	if (!dn)
210
		return 0;
211
	of_node_put(dn);
212 213
	printk("WARNING ! Your machine is PMU-based but your kernel\n");
	printk("          wasn't compiled with CONFIG_ADB_PMU option !\n");
P
Paul Mackerras 已提交
214
	return 0;
215 216
}
#endif
217

218 219 220 221 222 223 224
#ifndef CONFIG_PMAC_SMU
int smu_init(void)
{
	/* should check and warn if SMU is present */
	return 0;
}
#endif
225

226 227
#ifdef CONFIG_PPC32
static volatile u32 *sysctrl_regs;
228

229 230
static void __init ohare_init(void)
{
231 232
	struct device_node *dn;

233 234 235 236
	/* this area has the CPU identification register
	   and some registers used by smp boards */
	sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000);

237 238 239 240 241
	/*
	 * Turn on the L2 cache.
	 * We assume that we have a PSX memory controller iff
	 * we have an ohare I/O controller.
	 */
242 243 244
	dn = of_find_node_by_name(NULL, "ohare");
	if (dn) {
		of_node_put(dn);
245 246 247 248 249 250 251 252 253 254
		if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) {
			if (sysctrl_regs[4] & 0x10)
				sysctrl_regs[4] |= 0x04000020;
			else
				sysctrl_regs[4] |= 0x04000000;
			if(has_l2cache)
				printk(KERN_INFO "Level 2 cache enabled\n");
		}
	}
}
255

256 257
static void __init l2cr_init(void)
{
258 259
	/* Checks "l2cr-value" property in the registry */
	if (cpu_has_feature(CPU_FTR_L2CR)) {
260
		struct device_node *np = of_find_node_by_name(NULL, "cpus");
261
		if (np == 0)
262
			np = of_find_node_by_type(NULL, "cpu");
263
		if (np != 0) {
264
			const unsigned int *l2cr =
265
				of_get_property(np, "l2cr-value", NULL);
266 267 268 269 270 271
			if (l2cr != 0) {
				ppc_override_l2cr = 1;
				ppc_override_l2cr_value = *l2cr;
				_set_L2CR(0);
				_set_L2CR(ppc_override_l2cr_value);
			}
272
			of_node_put(np);
273 274 275 276
		}
	}

	if (ppc_override_l2cr)
277 278 279 280
		printk(KERN_INFO "L2CR overridden (0x%x), "
		       "backside cache is %s\n",
		       ppc_override_l2cr_value,
		       (ppc_override_l2cr_value & 0x80000000)
281
				? "enabled" : "disabled");
282 283 284
}
#endif

285
static void __init pmac_setup_arch(void)
286
{
P
Paul Mackerras 已提交
287
	struct device_node *cpu, *ic;
288
	const int *fp;
289 290 291 292 293 294 295 296 297
	unsigned long pvr;

	pvr = PVR_VER(mfspr(SPRN_PVR));

	/* Set loops_per_jiffy to a half-way reasonable value,
	   for use until calibrate_delay gets called. */
	loops_per_jiffy = 50000000 / HZ;
	cpu = of_find_node_by_type(NULL, "cpu");
	if (cpu != NULL) {
298
		fp = of_get_property(cpu, "clock-frequency", NULL);
299 300 301 302 303 304 305 306 307 308 309 310 311 312
		if (fp != NULL) {
			if (pvr >= 0x30 && pvr < 0x80)
				/* PPC970 etc. */
				loops_per_jiffy = *fp / (3 * HZ);
			else if (pvr == 4 || pvr >= 8)
				/* 604, G3, G4 etc. */
				loops_per_jiffy = *fp / HZ;
			else
				/* 601, 603, etc. */
				loops_per_jiffy = *fp / (2 * HZ);
		}
		of_node_put(cpu);
	}

P
Paul Mackerras 已提交
313
	/* See if newworld or oldworld */
314
	for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; )
315
		if (of_get_property(ic, "interrupt-controller", NULL))
316
			break;
317 318
	if (ic) {
		pmac_newworld = 1;
P
Paul Mackerras 已提交
319
		of_node_put(ic);
320
	}
P
Paul Mackerras 已提交
321

322 323 324 325 326 327 328 329
	/* Lookup PCI hosts */
	pmac_pci_init();

#ifdef CONFIG_PPC32
	ohare_init();
	l2cr_init();
#endif /* CONFIG_PPC32 */

330 331
	find_via_cuda();
	find_via_pmu();
332 333
	smu_init();

334 335
#if defined(CONFIG_NVRAM) || defined(CONFIG_NVRAM_MODULE) || \
    defined(CONFIG_PPC64)
336 337
	pmac_nvram_init();
#endif
338 339

#ifdef CONFIG_PPC32
340 341 342 343 344 345
#ifdef CONFIG_BLK_DEV_INITRD
	if (initrd_start)
		ROOT_DEV = Root_RAM0;
	else
#endif
		ROOT_DEV = DEFAULT_ROOT_DEVICE;
346
#endif
347 348 349

#ifdef CONFIG_SMP
	/* Check for Core99 */
350 351 352 353 354 355 356
	ic = of_find_node_by_name(NULL, "uni-n");
	if (!ic)
		ic = of_find_node_by_name(NULL, "u3");
	if (!ic)
		ic = of_find_node_by_name(NULL, "u4");
	if (ic) {
		of_node_put(ic);
357
		smp_ops = &core99_smp_ops;
358
	}
359
#ifdef CONFIG_PPC32
360 361 362 363 364 365 366 367 368 369 370
	else {
		/*
		 * We have to set bits in cpu_possible_map here since the
		 * secondary CPU(s) aren't in the device tree, and
		 * setup_per_cpu_areas only allocates per-cpu data for
		 * CPUs in the cpu_possible_map.
		 */
		int cpu;

		for (cpu = 1; cpu < 4 && cpu < NR_CPUS; ++cpu)
			cpu_set(cpu, cpu_possible_map);
371
		smp_ops = &psurge_smp_ops;
372
	}
373
#endif
374
#endif /* CONFIG_SMP */
375 376 377 378 379 380 381

#ifdef CONFIG_ADB
	if (strstr(cmd_line, "adb_sync")) {
		extern int __adb_probe_sync;
		__adb_probe_sync = 1;
	}
#endif /* CONFIG_ADB */
382 383 384
}

#ifdef CONFIG_SCSI
385
void note_scsi_host(struct device_node *node, void *host)
386 387
{
}
388
EXPORT_SYMBOL(note_scsi_host);
389 390
#endif

391 392
static int initializing = 1;

393 394 395
static int pmac_late_init(void)
{
	initializing = 0;
396 397 398
	/* this is udbg (which is __init) and we can later use it during
	 * cpu hotplug (in smp_core99_kick_cpu) */
	ppc_md.progress = NULL;
399 400
	return 0;
}
401
machine_late_initcall(powermac, pmac_late_init);
402

403 404 405 406 407 408 409
/*
 * This is __init_refok because we check for "initializing" before
 * touching any of the __init sensitive things and "initializing"
 * will be false after __init time. This can't be __init because it
 * can be called whenever a disk is first accessed.
 */
void __init_refok note_bootable_part(dev_t dev, int part, int goodness)
410 411 412 413 414 415 416 417
{
	char *p;

	if (!initializing)
		return;
	if ((goodness <= current_root_goodness) &&
	    ROOT_DEV != DEFAULT_ROOT_DEVICE)
		return;
418 419
	p = strstr(boot_command_line, "root=");
	if (p != NULL && (p == boot_command_line || p[-1] == ' '))
420 421
		return;

422 423
	ROOT_DEV = dev + part;
	current_root_goodness = goodness;
424 425 426
}

#ifdef CONFIG_ADB_CUDA
427 428
static void cuda_restart(void)
{
429 430
	struct adb_request req;

431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461
	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_RESET_SYSTEM);
	for (;;)
		cuda_poll();
}

static void cuda_shutdown(void)
{
	struct adb_request req;

	cuda_request(&req, NULL, 2, CUDA_PACKET, CUDA_POWERDOWN);
	for (;;)
		cuda_poll();
}

#else
#define cuda_restart()
#define cuda_shutdown()
#endif

#ifndef CONFIG_ADB_PMU
#define pmu_restart()
#define pmu_shutdown()
#endif

#ifndef CONFIG_PMAC_SMU
#define smu_restart()
#define smu_shutdown()
#endif

static void pmac_restart(char *cmd)
{
462 463
	switch (sys_ctrler) {
	case SYS_CTRLER_CUDA:
464
		cuda_restart();
465 466 467 468
		break;
	case SYS_CTRLER_PMU:
		pmu_restart();
		break;
469 470 471
	case SYS_CTRLER_SMU:
		smu_restart();
		break;
472 473 474 475
	default: ;
	}
}

476
static void pmac_power_off(void)
477 478 479
{
	switch (sys_ctrler) {
	case SYS_CTRLER_CUDA:
480
		cuda_shutdown();
481 482 483 484
		break;
	case SYS_CTRLER_PMU:
		pmu_shutdown();
		break;
485 486 487
	case SYS_CTRLER_SMU:
		smu_shutdown();
		break;
488 489 490 491 492 493 494 495 496 497
	default: ;
	}
}

static void
pmac_halt(void)
{
	pmac_power_off();
}

498 499 500 501 502
/* 
 * Early initialization.
 */
static void __init pmac_init_early(void)
{
503 504 505 506
	/* Enable early btext debug if requested */
	if (strstr(cmd_line, "btextdbg")) {
		udbg_adb_init_early();
		register_early_udbg_console();
507 508
	}

509 510 511 512 513 514 515 516
	/* Probe motherboard chipset */
	pmac_feature_init();

	/* Initialize debug stuff */
	udbg_scc_init(!!strstr(cmd_line, "sccdbg"));
	udbg_adb_init(!!strstr(cmd_line, "btextdbg"));

#ifdef CONFIG_PPC64
517
	iommu_init_early_dart();
518 519 520 521
#endif
}

static int __init pmac_declare_of_platform_devices(void)
522
{
523
	struct device_node *np;
524

525 526 527
	if (machine_is(chrp))
		return -1;

528
	np = of_find_node_by_name(NULL, "valkyrie");
529 530
	if (np)
		of_platform_device_create(np, "valkyrie", NULL);
531
	np = of_find_node_by_name(NULL, "platinum");
532 533 534 535 536 537 538
	if (np)
		of_platform_device_create(np, "platinum", NULL);
        np = of_find_node_by_type(NULL, "smu");
        if (np) {
		of_platform_device_create(np, "smu", NULL);
		of_node_put(np);
	}
539 540 541

	return 0;
}
542
machine_device_initcall(powermac, pmac_declare_of_platform_devices);
543 544 545 546

/*
 * Called very early, MMU is off, device-tree isn't unflattened
 */
547
static int __init pmac_probe(void)
548
{
549 550 551 552
	unsigned long root = of_get_flat_dt_root();

	if (!of_flat_dt_is_compatible(root, "Power Macintosh") &&
	    !of_flat_dt_is_compatible(root, "MacRISC"))
553 554
		return 0;

555
#ifdef CONFIG_PPC64
556 557 558 559 560 561
	/*
	 * On U3, the DART (iommu) must be allocated now since it
	 * has an impact on htab_initialize (due to the large page it
	 * occupies having to be broken up so the DART itself is not
	 * part of the cacheable linar mapping
	 */
562
	alloc_dart_table();
563 564

	hpte_init_native();
565 566
#endif

567 568 569 570 571 572 573
#ifdef CONFIG_PPC32
	/* isa_io_base gets set in pmac_pci_init */
	ISA_DMA_THRESHOLD = ~0L;
	DMA_MODE_READ = 1;
	DMA_MODE_WRITE = 2;
#endif /* CONFIG_PPC32 */

574 575 576 577 578 579 580 581 582 583 584 585 586
#ifdef CONFIG_PMAC_SMU
	/*
	 * SMU based G5s need some memory below 2Gb, at least the current
	 * driver needs that. We have to allocate it now. We allocate 4k
	 * (1 small page) for now.
	 */
	smu_cmdbuf_abs = lmb_alloc_base(4096, 4096, 0x80000000UL);
#endif /* CONFIG_PMAC_SMU */

	return 1;
}

#ifdef CONFIG_PPC64
587 588
/* Move that to pci.c */
static int pmac_pci_probe_mode(struct pci_bus *bus)
589 590 591 592
{
	struct device_node *node = bus->sysdata;

	/* We need to use normal PCI probing for the AGP bus,
593
	 * since the device for the AGP bridge isn't in the tree.
594
	 * Same for the PCIe host on U4 and the HT host bridge.
595
	 */
596
	if (bus->self == NULL && (of_device_is_compatible(node, "u3-agp") ||
597 598
				  of_device_is_compatible(node, "u4-pcie") ||
				  of_device_is_compatible(node, "u3-ht")))
599 600 601
		return PCI_PROBE_NORMAL;
	return PCI_PROBE_DEVTREE;
}
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647

#ifdef CONFIG_HOTPLUG_CPU
/* access per cpu vars from generic smp.c */
DECLARE_PER_CPU(int, cpu_state);

static void pmac_cpu_die(void)
{
	/*
	 * turn off as much as possible, we'll be
	 * kicked out as this will only be invoked
	 * on core99 platforms for now ...
	 */

	printk(KERN_INFO "CPU#%d offline\n", smp_processor_id());
	__get_cpu_var(cpu_state) = CPU_DEAD;
	smp_wmb();

	/*
	 * during the path that leads here preemption is disabled,
	 * reenable it now so that when coming up preempt count is
	 * zero correctly
	 */
	preempt_enable();

	/*
	 * hard-disable interrupts for the non-NAP case, the NAP code
	 * needs to re-enable interrupts (but soft-disables them)
	 */
	hard_irq_disable();

	while (1) {
		/* let's not take timer interrupts too often ... */
		set_dec(0x7fffffff);

		/* should always be true at this point */
		if (cpu_has_feature(CPU_FTR_CAN_NAP))
			power4_cpu_offline_powersave();
		else {
			HMT_low();
			HMT_very_low();
		}
	}
}
#endif /* CONFIG_HOTPLUG_CPU */

#endif /* CONFIG_PPC64 */
648

649 650
define_machine(powermac) {
	.name			= "PowerMac",
651 652 653 654 655
	.probe			= pmac_probe,
	.setup_arch		= pmac_setup_arch,
	.init_early		= pmac_init_early,
	.show_cpuinfo		= pmac_show_cpuinfo,
	.init_IRQ		= pmac_pic_init,
656
	.get_irq		= NULL,	/* changed later */
657
	.pci_irq_fixup		= pmac_pci_irq_fixup,
658 659 660 661 662 663 664 665 666
	.restart		= pmac_restart,
	.power_off		= pmac_power_off,
	.halt			= pmac_halt,
	.time_init		= pmac_time_init,
	.get_boot_time		= pmac_get_boot_time,
	.set_rtc_time		= pmac_set_rtc_time,
	.get_rtc_time		= pmac_get_rtc_time,
	.calibrate_decr		= pmac_calibrate_decr,
	.feature_call		= pmac_do_feature_call,
667
	.progress		= udbg_progress,
668
#ifdef CONFIG_PPC64
669
	.pci_probe_mode		= pmac_pci_probe_mode,
670
	.power_save		= power4_idle,
671
	.enable_pmcs		= power4_enable_pmcs,
M
Michael Ellerman 已提交
672 673 674
#ifdef CONFIG_KEXEC
	.machine_kexec		= default_machine_kexec,
	.machine_kexec_prepare	= default_machine_kexec_prepare,
675
	.machine_crash_shutdown	= default_machine_crash_shutdown,
676
#endif
M
Michael Ellerman 已提交
677
#endif /* CONFIG_PPC64 */
678 679 680 681 682
#ifdef CONFIG_PPC32
	.pcibios_enable_device_hook = pmac_pci_enable_device_hook,
	.pcibios_after_init	= pmac_pcibios_after_init,
	.phys_mem_access_prot	= pci_phys_mem_access_prot,
#endif
683
#if defined(CONFIG_HOTPLUG_CPU) && defined(CONFIG_PPC64)
684
	.cpu_die		= pmac_cpu_die,
685
#endif
686
};