/*
 * Big Endian PROM code for SNI RM machines
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2005-2006 Florian Lohoff (flo@rfc822.org)
 * Copyright (C) 2005-2006 Thomas Bogendoerfer (tsbogend@alpha.franken.de)
 */

#define DEBUG

#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/console.h>

#include <asm/addrspace.h>
#include <asm/sni.h>
#include <asm/mipsprom.h>
#include <asm/mipsregs.h>
#include <asm/bootinfo.h>

/* special SNI prom calls */
/*
 * This does not exist in all proms - SINIX compares
 * the prom env variable "version" against "2.0008"
 * or greater. If lesser it tries to probe interesting
 * registers
 */
#define PROM_GET_MEMCONF	58

#define PROM_VEC		(u64 *)CKSEG1ADDR(0x1fc00000)
#define PROM_ENTRY(x)		(PROM_VEC + (x))


static int *(*__prom_putchar)(int)        = (int *(*)(int))PROM_ENTRY(PROM_PUTCHAR);

void prom_putchar(char c)
{
	__prom_putchar(c);
}

static char *(*__prom_getenv)(char *)     = (char *(*)(char *))PROM_ENTRY(PROM_GETENV);
static void (*__prom_get_memconf)(void *) = (void (*)(void *))PROM_ENTRY(PROM_GET_MEMCONF);

char *prom_getenv (char *s)
{
	return __prom_getenv(s);
}

void __init prom_free_prom_memory(void)
{
}

/*
 * /proc/cpuinfo system type
 *
 */
static const char *systype = "Unknown";
const char *get_system_type(void)
{
	return systype;
}

#define SNI_IDPROM_BASE                0xbff00000
#define SNI_IDPROM_MEMSIZE             (SNI_IDPROM_BASE+0x28)  /* Memsize in 16MB quantities */
#define SNI_IDPROM_BRDTYPE             (SNI_IDPROM_BASE+0x29)  /* Board Type */
#define SNI_IDPROM_CPUTYPE             (SNI_IDPROM_BASE+0x30)  /* CPU Type */

#define SNI_IDPROM_SIZE	0x1000

#ifdef DEBUG
static void __init sni_idprom_dump(void)
{
	int	i;

	pr_debug("SNI IDProm dump:\n");
	for (i = 0; i < 256; i++) {
		if (i%16 == 0)
			pr_debug("%04x ", i);

		printk("%02x ", *(unsigned char *) (SNI_IDPROM_BASE + i));

		if (i % 16 == 15)
			printk("\n");
	}
}
#endif

static void __init sni_mem_init(void )
{
	int i, memsize;
	struct membank {
	        u32		size;
	        u32		base;
	        u32		size2;
	        u32		pad1;
	        u32		pad2;
	} memconf[8];

	/* MemSIZE from prom in 16MByte chunks */
	memsize = *((unsigned char *) SNI_IDPROM_MEMSIZE) * 16;

	pr_debug("IDProm memsize: %lu MByte\n", memsize);

	/* get memory bank layout from prom */
	__prom_get_memconf(&memconf);

	pr_debug("prom_get_mem_conf memory configuration:\n");
	for (i = 0;i < 8 && memconf[i].size; i++) {
		if (sni_brd_type == SNI_BRD_PCI_TOWER ||
		    sni_brd_type == SNI_BRD_PCI_TOWER_CPLUS) {
			if (memconf[i].base >= 0x20000000 &&
			    memconf[i].base <  0x30000000) {
				memconf[i].base -= 0x20000000;
			}
	}
		pr_debug("Bank%d: %08x @ %08x\n", i,
			memconf[i].size, memconf[i].base);
		add_memory_region(memconf[i].base, memconf[i].size, BOOT_MEM_RAM);
	}
}

static void __init sni_console_setup(void)
{
	char *ctype;
	char *cdev;
	char *baud;
	int port;
	static char options[8];

	cdev = prom_getenv ("console_dev");
	if (strncmp (cdev, "tty", 3) == 0) {
		ctype = prom_getenv ("console");
		switch (*ctype) {
		default:
		case 'l':
	                port = 0;
	                baud = prom_getenv("lbaud");
	                break;
		case 'r':
	                port = 1;
	                baud = prom_getenv("rbaud");
	                break;
		}
		if (baud)
			strcpy(options, baud);
		if (strncmp (cdev, "tty552", 6) == 0)
			add_preferred_console("ttyS", port, baud ? options : NULL);
		else
			add_preferred_console("ttySC", port, baud ? options : NULL);
	}
}

void __init prom_init(void)
{
	int argc = fw_arg0;
	char **argv = (void *)fw_arg1;
	int i;
	int cputype;

	sni_brd_type = *(unsigned char *)SNI_IDPROM_BRDTYPE;
	cputype = *(unsigned char *)SNI_IDPROM_CPUTYPE;
	switch (sni_brd_type) {
	case SNI_BRD_TOWER_OASIC:
	        switch (cputype) {
		case SNI_CPU_M8030:
		        systype = "RM400-330";
		        break;
		case SNI_CPU_M8031:
		        systype = "RM400-430";
		        break;
		case SNI_CPU_M8037:
		        systype = "RM400-530";
		        break;
		case SNI_CPU_M8034:
		        systype = "RM400-730";
		        break;
		default:
			systype = "RM400-xxx";
			break;
		}
	        break;
	case SNI_BRD_MINITOWER:
	        switch (cputype) {
		case SNI_CPU_M8021:
		case SNI_CPU_M8043:
		        systype = "RM400-120";
		        break;
		case SNI_CPU_M8040:
		        systype = "RM400-220";
		        break;
		case SNI_CPU_M8053:
		        systype = "RM400-225";
		        break;
		case SNI_CPU_M8050:
		        systype = "RM400-420";
		        break;
		default:
			systype = "RM400-xxx";
			break;
		}
	        break;
	case SNI_BRD_PCI_TOWER:
	        systype = "RM400-Cxx";
	        break;
	case SNI_BRD_RM200:
	        systype = "RM200-xxx";
	        break;
	case SNI_BRD_PCI_MTOWER:
	        systype = "RM300-Cxx";
	        break;
	case SNI_BRD_PCI_DESKTOP:
	        switch (read_c0_prid() & 0xff00) {
		case PRID_IMP_R4600:
		case PRID_IMP_R4700:
		        systype = "RM200-C20";
		        break;
		case PRID_IMP_R5000:
		        systype = "RM200-C40";
		        break;
		default:
		        systype = "RM200-Cxx";
		        break;
		}
	        break;
	case SNI_BRD_PCI_TOWER_CPLUS:
	        systype = "RM400-Exx";
	        break;
	case SNI_BRD_PCI_MTOWER_CPLUS:
	        systype = "RM300-Exx";
	        break;
	}
	pr_debug("Found SNI brdtype %02x name %s\n", sni_brd_type,systype);

#ifdef DEBUG
	sni_idprom_dump();
#endif
	sni_mem_init();
	sni_console_setup();

	/* copy prom cmdline parameters to kernel cmdline */
	for (i = 1; i < argc; i++) {
		strcat(arcs_cmdline, argv[i]);
		if (i < (argc - 1))
			strcat(arcs_cmdline, " ");
	}
}

