/*
 * 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 = bus_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(bus_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);
	}
}
