/*
 * Copyright (C) 2000, 2001, 2002, 2003 Broadcom Corporation
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 */
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/string.h>

#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
#include <asm/io.h>
#include <asm/sibyte/sb1250.h>
#include <asm/sibyte/sb1250_regs.h>
#include <asm/sibyte/sb1250_scd.h>

unsigned int sb1_pass;
unsigned int soc_pass;
unsigned int soc_type;
unsigned int periph_rev;
unsigned int zbbus_mhz;
EXPORT_SYMBOL(zbbus_mhz);

static char *soc_str;
static char *pass_str;
static unsigned int war_pass;	/* XXXKW don't overload PASS defines? */

static inline int setup_bcm1250(void);
static inline int setup_bcm112x(void);

/* Setup code likely to be common to all SiByte platforms */

static int __init sys_rev_decode(void)
{
	int ret = 0;

	war_pass = soc_pass;
	switch (soc_type) {
	case K_SYS_SOC_TYPE_BCM1250:
	case K_SYS_SOC_TYPE_BCM1250_ALT:
	case K_SYS_SOC_TYPE_BCM1250_ALT2:
		soc_str = "BCM1250";
		ret = setup_bcm1250();
		break;
	case K_SYS_SOC_TYPE_BCM1120:
		soc_str = "BCM1120";
		ret = setup_bcm112x();
		break;
	case K_SYS_SOC_TYPE_BCM1125:
		soc_str = "BCM1125";
		ret = setup_bcm112x();
		break;
	case K_SYS_SOC_TYPE_BCM1125H:
		soc_str = "BCM1125H";
		ret = setup_bcm112x();
		break;
	default:
		printk("Unknown SOC type %x\n", soc_type);
		ret = 1;
		break;
	}
	return ret;
}

static int __init setup_bcm1250(void)
{
	int ret = 0;

	switch (soc_pass) {
	case K_SYS_REVISION_BCM1250_PASS1:
		periph_rev = 1;
		pass_str = "Pass 1";
		break;
	case K_SYS_REVISION_BCM1250_A10:
		periph_rev = 2;
		pass_str = "A8/A10";
		/* XXXKW different war_pass? */
		war_pass = K_SYS_REVISION_BCM1250_PASS2;
		break;
	case K_SYS_REVISION_BCM1250_PASS2_2:
		periph_rev = 2;
		pass_str = "B1";
		break;
	case K_SYS_REVISION_BCM1250_B2:
		periph_rev = 2;
		pass_str = "B2";
		war_pass = K_SYS_REVISION_BCM1250_PASS2_2;
		break;
	case K_SYS_REVISION_BCM1250_PASS3:
		periph_rev = 3;
		pass_str = "C0";
		break;
	case K_SYS_REVISION_BCM1250_C1:
		periph_rev = 3;
		pass_str = "C1";
		break;
	default:
		if (soc_pass < K_SYS_REVISION_BCM1250_PASS2_2) {
			periph_rev = 2;
			pass_str = "A0-A6";
			war_pass = K_SYS_REVISION_BCM1250_PASS2;
		} else {
			printk("Unknown BCM1250 rev %x\n", soc_pass);
			ret = 1;
		}
		break;
	}
	return ret;
}

static int __init setup_bcm112x(void)
{
	int ret = 0;

	switch (soc_pass) {
	case 0:
		/* Early build didn't have revid set */
		periph_rev = 3;
		pass_str = "A1";
		war_pass = K_SYS_REVISION_BCM112x_A1;
		break;
	case K_SYS_REVISION_BCM112x_A1:
		periph_rev = 3;
		pass_str = "A1";
		break;
	case K_SYS_REVISION_BCM112x_A2:
		periph_rev = 3;
		pass_str = "A2";
		break;
	default:
		printk("Unknown %s rev %x\n", soc_str, soc_pass);
		ret = 1;
	}
	return ret;
}

void __init sb1250_setup(void)
{
	uint64_t sys_rev;
	int plldiv;
	int bad_config = 0;

	sb1_pass = read_c0_prid() & 0xff;
	sys_rev = __raw_readq(IOADDR(A_SCD_SYSTEM_REVISION));
	soc_type = SYS_SOC_TYPE(sys_rev);
	soc_pass = G_SYS_REVISION(sys_rev);

	if (sys_rev_decode()) {
		printk("Restart after failure to identify SiByte chip\n");
		machine_restart(NULL);
	}

	plldiv = G_SYS_PLL_DIV(__raw_readq(IOADDR(A_SCD_SYSTEM_CFG)));
	zbbus_mhz = ((plldiv >> 1) * 50) + ((plldiv & 1) * 25);

	printk("Broadcom SiByte %s %s @ %d MHz (SB1 rev %d)\n",
		    soc_str, pass_str, zbbus_mhz * 2, sb1_pass);
	printk("Board type: %s\n", get_system_type());

	switch (war_pass) {
	case K_SYS_REVISION_BCM1250_PASS1:
#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
		printk("@@@@ This is a BCM1250 A0-A2 (Pass 1) board, "
		            "and the kernel doesn't have the proper "
		            "workarounds compiled in. @@@@\n");
		bad_config = 1;
#endif
		break;
	case K_SYS_REVISION_BCM1250_PASS2:
		/* Pass 2 - easiest as default for now - so many numbers */
#if !defined(CONFIG_SB1_PASS_2_WORKAROUNDS) || \
    !defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS)
		printk("@@@@ This is a BCM1250 A3-A10 board, and the "
		            "kernel doesn't have the proper workarounds "
		            "compiled in. @@@@\n");
		bad_config = 1;
#endif
#ifdef CONFIG_CPU_HAS_PREFETCH
		printk("@@@@ Prefetches may be enabled in this kernel, "
		            "but are buggy on this board.  @@@@\n");
		bad_config = 1;
#endif
		break;
	case K_SYS_REVISION_BCM1250_PASS2_2:
#ifndef CONFIG_SB1_PASS_2_WORKAROUNDS
		printk("@@@@ This is a BCM1250 B1/B2. board, and the "
		            "kernel doesn't have the proper workarounds "
		            "compiled in. @@@@\n");
		bad_config = 1;
#endif
#if defined(CONFIG_SB1_PASS_2_1_WORKAROUNDS) || \
    !defined(CONFIG_CPU_HAS_PREFETCH)
		printk("@@@@ This is a BCM1250 B1/B2, but the kernel is "
		            "conservatively configured for an 'A' stepping. "
		            "@@@@\n");
#endif
		break;
	default:
		break;
	}
	if (bad_config) {
		printk("Invalid configuration for this chip.\n");
		machine_restart(NULL);
	}
}
