/*
 * 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/config.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;

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 inline int 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:
		prom_printf("Unknown SOC type %x\n", soc_type);
		ret = 1;
		break;
	}
	return ret;
}

static inline int 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 {
			prom_printf("Unknown BCM1250 rev %x\n", soc_pass);
			ret = 1;
		}
		break;
	}
	return ret;
}

static inline int 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:
		prom_printf("Unknown %s rev %x\n", soc_str, soc_pass);
		ret = 1;
	}
	return ret;
}

void 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()) {
		prom_printf("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);

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

	switch(war_pass) {
	case K_SYS_REVISION_BCM1250_PASS1:
#ifndef CONFIG_SB1_PASS_1_WORKAROUNDS
		prom_printf("@@@@ 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)
		prom_printf("@@@@ 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
		prom_printf("@@@@ 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
		prom_printf("@@@@ 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)
		prom_printf("@@@@ This is a BCM1250 B1/B2, but the kernel is conservatively configured for an 'A' stepping. @@@@\n");
#endif
		break;
	default:
		break;
	}
	if (bad_config) {
		prom_printf("Invalid configuration for this chip.\n");
		machine_restart(NULL);
	}
}
