11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * ip22-mc.c: Routines for manipulating SGI Memory Controller.
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
479add6277396b91c638f16eb2f1338badc47760dJustin P. Mattock * Copyright (C) 1996 David S. Miller (davem@davemloft.net)
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Ladislav Michl  (ladis@linux-mips.org)
7e2defae5a9b4f8d1acb058be212ef89c8763dc5bThomas Bogendoerfer * Copyright (C) 2004 Peter Fuerst    (pf@net.alphadv.de) - IP28
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h>
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h>
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootinfo.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sgialib.h>
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sgi/mc.h>
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sgi/hpc3.h>
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sgi/ip22.h>
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct sgimc_regs *sgimc;
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(sgimc);
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long get_bank_addr(unsigned int memconfig)
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ((memconfig & SGIMC_MCONFIG_BASEADDR) <<
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned long get_bank_size(unsigned int memconfig)
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) <<
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline unsigned int get_bank_config(int bank)
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return bank % 2 ? res & 0xffff : res >> 16;
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct mem {
441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long addr;
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	unsigned long size;
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Detect installed memory, do some sanity checks and notify kernel about it
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
515bd080f7d21c8f6841d63b8cdb4123a95a311eb9Ralf Baechlestatic void __init probe_memory(void)
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i, j, found, cnt = 0;
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mem bank[4];
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_INFO "MC: Probing memory configuration:\n");
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < ARRAY_SIZE(bank); i++) {
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned int tmp = get_bank_config(i);
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!(tmp & SGIMC_MCONFIG_BVALID))
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			continue;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bank[cnt].size = get_bank_size(tmp);
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		bank[cnt].addr = get_bank_addr(tmp);
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		cnt++;
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* And you thought bubble sort is dead algorithm... */
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	do {
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		unsigned long addr, size;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		found = 0;
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (i = 1; i < cnt; i++)
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (bank[i-1].addr > bank[i].addr) {
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				addr = bank[i].addr;
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				size = bank[i].size;
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				bank[i].addr = bank[i-1].addr;
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				bank[i].size = bank[i-1].size;
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				bank[i-1].addr = addr;
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				bank[i-1].size = size;
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				found = 1;
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} while (found);
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Figure out how are memory banks mapped into spaces */
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < cnt; i++) {
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		found = 0;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			if (space[j].addr + space[j].size == bank[i].addr) {
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				space[j].size += bank[i].size;
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds				found = 1;
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			}
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* There is either hole or overlapping memory */
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (!found)
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk(KERN_CRIT "MC: Memory configuration mismatch "
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 "(%08lx), expect Bus Error soon\n",
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					 bank[i].addr);
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i = 0; i < ARRAY_SIZE(space); i++)
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (space[i].size)
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			add_memory_region(space[i].addr, space[i].size,
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds					  BOOT_MEM_RAM);
1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init sgimc_init(void)
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u32 tmp;
1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* ioremap can't fail */
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc = (struct sgimc_regs *)
1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		ioremap(SGIMC_BASE, sizeof(struct sgimc_regs));
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	       (int) sgimc->systemid & SGIMC_SYSID_MASKREV);
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Place the MC into a known state.  This must be done before
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * interrupts are first enabled etc.
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 0: Make sure we turn off the watchdog in case it's
1247034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   still running (which might be the case after a
1257034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   soft reboot).
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp = sgimc->cpuctrl0;
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp &= ~SGIMC_CCTRL0_WDOG;
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->cpuctrl0 = tmp;
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 1: The CPU/GIO error status registers will not latch
1327034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   up a new error status until the register has been
1337034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   cleared by the cpu.	These status registers are
1347034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   cleared by writing any value to them.
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->cstat = sgimc->gstat = 0;
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 2: Enable all parity checking in cpu control register
1397034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   zero.
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
141e2defae5a9b4f8d1acb058be212ef89c8763dc5bThomas Bogendoerfer	/* don't touch parity settings for IP28 */
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp = sgimc->cpuctrl0;
143e84de0c61905030a0fe66b7210b6f1bb7c3e1eabThomas Bogendoerfer#ifndef CONFIG_SGI_IP28
144e84de0c61905030a0fe66b7210b6f1bb7c3e1eabThomas Bogendoerfer	tmp |= SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM;
145e2defae5a9b4f8d1acb058be212ef89c8763dc5bThomas Bogendoerfer#endif
146e84de0c61905030a0fe66b7210b6f1bb7c3e1eabThomas Bogendoerfer	tmp |= SGIMC_CCTRL0_R4KNOCHKPARR;
1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->cpuctrl0 = tmp;
1481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 3: Setup the MC write buffer depth, this is controlled
1507034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   in cpu control register 1 in the lower 4 bits.
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp = sgimc->cpuctrl1;
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp &= ~0xf;
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp |= 0xd;
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->cpuctrl1 = tmp;
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 4: Initialize the RPSS divider register to run as fast
1587034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   as it can correctly operate.	 The register is laid
1597034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   out as follows:
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
1617034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   ----------------------------------------
1627034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   |  RESERVED	|   INCREMENT	| DIVIDER |
1637034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   ----------------------------------------
1647034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	    31	      16 15	       8 7	 0
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
1667034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   DIVIDER determines how often a 'tick' happens,
1677034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   INCREMENT determines by how the RPSS increment
1687034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   registers value increases at each 'tick'. Thus,
1697034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	   for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->divider = 0x101;
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Step 5: Initialize GIO64 arbitrator configuration register.
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 *
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 * NOTE: HPC init code in sgihpc_init() must run before us because
1767034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	 we need to know Guiness vs. FullHouse and the board
1777034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle	 *	 revision on this machine. You have been warned.
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	 */
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* First the basic invariants across all GIO64 implementations. */
181e84de0c61905030a0fe66b7210b6f1bb7c3e1eabThomas Bogendoerfer	tmp = sgimc->giopar & SGIMC_GIOPAR_GFX64; /* keep gfx 64bit settings */
182e84de0c61905030a0fe66b7210b6f1bb7c3e1eabThomas Bogendoerfer	tmp |= SGIMC_GIOPAR_HPC64;	/* All 1st HPC's interface at 64bits */
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	tmp |= SGIMC_GIOPAR_ONEBUS;	/* Only one physical GIO bus exists */
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (ip22_is_fullhouse()) {
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Fullhouse specific settings. */
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC at 64bits */
1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp0 pipelines */
1907034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle			tmp |= SGIMC_GIOPAR_MASTEREXP1; /* exp1 masters */
1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_RTIMEEXP0;	/* exp0 is realtime */
1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		} else {
1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC 64bits */
1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp[01] pipelined */
1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			tmp |= SGIMC_GIOPAR_PLINEEXP1;
1967034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle			tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA masters */
1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	} else {
1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		/* Guiness specific settings. */
2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		tmp |= SGIMC_GIOPAR_EISA64;	/* MC talks to EISA at 64bits */
2017034228792cc561e79ff8600f02884bd4c80e287Ralf Baechle		tmp |= SGIMC_GIOPAR_MASTEREISA; /* EISA bus can act as master */
2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	sgimc->giopar = tmp;	/* poof */
2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	probe_memory();
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init prom_meminit(void) {}
209c44e8d5e47b8ba672440b92eab0735628469116cAtsushi Nemotovoid __init prom_free_prom_memory(void)
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2117a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer#ifdef CONFIG_SGI_IP28
2127a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	u32 mconfig1;
2137a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	unsigned long flags;
2147a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	spinlock_t lock;
2157a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer
2167a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	/*
2177a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	 * because ARCS accesses memory uncached we wait until ARCS
2187a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	 * isn't needed any longer, before we switch from slow to
2197a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	 * normal mode
2207a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	 */
2217a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	spin_lock_irqsave(&lock, flags);
2227a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	mconfig1 = sgimc->mconfig1;
2237a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	/* map ECC register */
2247a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	sgimc->mconfig1 = (mconfig1 & 0xffff0000) | 0x2060;
2257a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	iob();
2267a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	/* switch to normal mode */
2277a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	*(unsigned long *)PHYS_TO_XKSEG_UNCACHED(0x60000000) = 0;
2287a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	iob();
2297a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	/* reduce WR_COL */
2307a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	sgimc->cmacc = (sgimc->cmacc & ~0xf) | 4;
2317a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	iob();
2327a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	/* restore old config */
2337a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	sgimc->mconfig1 = mconfig1;
2347a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	iob();
2357a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer	spin_unlock_irqrestore(&lock, flags);
2367a2852e49fe2d19296812c0f0f833b0ee3043bbbThomas Bogendoerfer#endif
2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
238