/*
 * ip22-mc.c: Routines for manipulating SGI Memory Controller.
 *
 * Copyright (C) 1996 David S. Miller (dm@engr.sgi.com)
 * Copyright (C) 1999 Andrew R. Baker (andrewb@uab.edu) - Indigo2 changes
 * Copyright (C) 2003 Ladislav Michl  (ladis@linux-mips.org)
 */

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

#include <asm/io.h>
#include <asm/bootinfo.h>
#include <asm/sgialib.h>
#include <asm/sgi/mc.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>

struct sgimc_regs *sgimc;

EXPORT_SYMBOL(sgimc);

static inline unsigned long get_bank_addr(unsigned int memconfig)
{
	return ((memconfig & SGIMC_MCONFIG_BASEADDR) <<
		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 24 : 22));
}

static inline unsigned long get_bank_size(unsigned int memconfig)
{
	return ((memconfig & SGIMC_MCONFIG_RMASK) + 0x0100) <<
		((sgimc->systemid & SGIMC_SYSID_MASKREV) >= 5 ? 16 : 14);
}

static inline unsigned int get_bank_config(int bank)
{
	unsigned int res = bank > 1 ? sgimc->mconfig1 : sgimc->mconfig0;
	return bank % 2 ? res & 0xffff : res >> 16;
}

struct mem {
	unsigned long addr;
	unsigned long size;
};

/*
 * Detect installed memory, do some sanity checks and notify kernel about it
 */
static void __init probe_memory(void)
{
	int i, j, found, cnt = 0;
	struct mem bank[4];
	struct mem space[2] = {{SGIMC_SEG0_BADDR, 0}, {SGIMC_SEG1_BADDR, 0}};

	printk(KERN_INFO "MC: Probing memory configuration:\n");
	for (i = 0; i < ARRAY_SIZE(bank); i++) {
		unsigned int tmp = get_bank_config(i);
		if (!(tmp & SGIMC_MCONFIG_BVALID))
			continue;

		bank[cnt].size = get_bank_size(tmp);
		bank[cnt].addr = get_bank_addr(tmp);
		printk(KERN_INFO " bank%d: %3ldM @ %08lx\n",
			i, bank[cnt].size / 1024 / 1024, bank[cnt].addr);
		cnt++;
	}

	/* And you thought bubble sort is dead algorithm... */
	do {
		unsigned long addr, size;

		found = 0;
		for (i = 1; i < cnt; i++)
			if (bank[i-1].addr > bank[i].addr) {
				addr = bank[i].addr;
				size = bank[i].size;
				bank[i].addr = bank[i-1].addr;
				bank[i].size = bank[i-1].size;
				bank[i-1].addr = addr;
				bank[i-1].size = size;
				found = 1;
			}
	} while (found);

	/* Figure out how are memory banks mapped into spaces */
	for (i = 0; i < cnt; i++) {
		found = 0;
		for (j = 0; j < ARRAY_SIZE(space) && !found; j++)
			if (space[j].addr + space[j].size == bank[i].addr) {
				space[j].size += bank[i].size;
				found = 1;
			}
		/* There is either hole or overlapping memory */
		if (!found)
			printk(KERN_CRIT "MC: Memory configuration mismatch "
					 "(%08lx), expect Bus Error soon\n",
					 bank[i].addr);
	}

	for (i = 0; i < ARRAY_SIZE(space); i++)
		if (space[i].size)
			add_memory_region(space[i].addr, space[i].size,
					  BOOT_MEM_RAM);
}

void __init sgimc_init(void)
{
	u32 tmp;

	/* ioremap can't fail */
	sgimc = (struct sgimc_regs *)
		ioremap(SGIMC_BASE, sizeof(struct sgimc_regs));

	printk(KERN_INFO "MC: SGI memory controller Revision %d\n",
	       (int) sgimc->systemid & SGIMC_SYSID_MASKREV);

	/* Place the MC into a known state.  This must be done before
	 * interrupts are first enabled etc.
	 */

	/* Step 0: Make sure we turn off the watchdog in case it's
	 *         still running (which might be the case after a
	 *         soft reboot).
	 */
	tmp = sgimc->cpuctrl0;
	tmp &= ~SGIMC_CCTRL0_WDOG;
	sgimc->cpuctrl0 = tmp;

	/* Step 1: The CPU/GIO error status registers will not latch
	 *         up a new error status until the register has been
	 *         cleared by the cpu.  These status registers are
	 *         cleared by writing any value to them.
	 */
	sgimc->cstat = sgimc->gstat = 0;

	/* Step 2: Enable all parity checking in cpu control register
	 *         zero.
	 */
	tmp = sgimc->cpuctrl0;
	tmp |= (SGIMC_CCTRL0_EPERRGIO | SGIMC_CCTRL0_EPERRMEM |
		SGIMC_CCTRL0_R4KNOCHKPARR);
	sgimc->cpuctrl0 = tmp;

	/* Step 3: Setup the MC write buffer depth, this is controlled
	 *         in cpu control register 1 in the lower 4 bits.
	 */
	tmp = sgimc->cpuctrl1;
	tmp &= ~0xf;
	tmp |= 0xd;
	sgimc->cpuctrl1 = tmp;

	/* Step 4: Initialize the RPSS divider register to run as fast
	 *         as it can correctly operate.  The register is laid
	 *         out as follows:
	 *
	 *         ----------------------------------------
	 *         |  RESERVED  |   INCREMENT   | DIVIDER |
	 *         ----------------------------------------
	 *          31        16 15            8 7       0
	 *
	 *         DIVIDER determines how often a 'tick' happens,
	 *         INCREMENT determines by how the RPSS increment
	 *         registers value increases at each 'tick'. Thus,
	 *         for IP22 we get INCREMENT=1, DIVIDER=1 == 0x101
	 */
	sgimc->divider = 0x101;

	/* Step 5: Initialize GIO64 arbitrator configuration register.
	 *
	 * NOTE: HPC init code in sgihpc_init() must run before us because
	 *       we need to know Guiness vs. FullHouse and the board
	 *       revision on this machine. You have been warned.
	 */

	/* First the basic invariants across all GIO64 implementations. */
	tmp = SGIMC_GIOPAR_HPC64;	/* All 1st HPC's interface at 64bits */
	tmp |= SGIMC_GIOPAR_ONEBUS;	/* Only one physical GIO bus exists */

	if (ip22_is_fullhouse()) {
		/* Fullhouse specific settings. */
		if (SGIOC_SYSID_BOARDREV(sgioc->sysid) < 2) {
			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC at 64bits */
			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp0 pipelines */
			tmp |= SGIMC_GIOPAR_MASTEREXP1;	/* exp1 masters */
			tmp |= SGIMC_GIOPAR_RTIMEEXP0;	/* exp0 is realtime */
		} else {
			tmp |= SGIMC_GIOPAR_HPC264;	/* 2nd HPC 64bits */
			tmp |= SGIMC_GIOPAR_PLINEEXP0;	/* exp[01] pipelined */
			tmp |= SGIMC_GIOPAR_PLINEEXP1;
			tmp |= SGIMC_GIOPAR_MASTEREISA;	/* EISA masters */
			tmp |= SGIMC_GIOPAR_GFX64;	/* GFX at 64 bits */
		}
	} else {
		/* Guiness specific settings. */
		tmp |= SGIMC_GIOPAR_EISA64;	/* MC talks to EISA at 64bits */
		tmp |= SGIMC_GIOPAR_MASTEREISA;	/* EISA bus can act as master */
	}
	sgimc->giopar = tmp;	/* poof */

	probe_memory();
}

void __init prom_meminit(void) {}
void __init prom_free_prom_memory(void)
{
}
