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