/*
 * BRIEF MODULE DESCRIPTION
 *	Galileo EV96100 setup.
 *
 * Copyright 2000 MontaVista Software Inc.
 * Author: MontaVista Software, Inc.
 *         	ppopov@mvista.com or source@mvista.com
 *
 * This file was derived from Carsten Langgaard's
 * arch/mips/mips-boards/atlas/atlas_setup.c.
 *
 * Carsten Langgaard, carstenl@mips.com
 * Copyright (C) 1999,2000 MIPS Technologies, Inc.  All rights reserved.
 *
 *  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  SOFTWARE  IS PROVIDED   ``AS  IS'' AND   ANY  EXPRESS OR IMPLIED
 *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF
 *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN
 *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT, INDIRECT,
 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF
 *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
 *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *  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.,
 *  675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <linux/pci.h>

#include <asm/cpu.h>
#include <asm/bootinfo.h>
#include <asm/mipsregs.h>
#include <asm/irq.h>
#include <asm/delay.h>
#include <asm/gt64120.h>
#include <asm/galileo-boards/ev96100int.h>


extern char *__init prom_getcmdline(void);

extern void mips_reboot_setup(void);

unsigned char mac_0_1[12];

void __init plat_mem_setup(void)
{
	unsigned int config = read_c0_config();
	unsigned int status = read_c0_status();
	unsigned int info = read_c0_info();
	u32 tmp;

	char *argptr;

	clear_c0_status(ST0_FR);

	if (config & 0x8)
		printk("Secondary cache is enabled\n");
	else
		printk("Secondary cache is disabled\n");

	if (status & (1 << 27))
		printk("User-mode cache ops enabled\n");
	else
		printk("User-mode cache ops disabled\n");

	printk("CP0 info reg: %x\n", (unsigned) info);
	if (info & (1 << 28))
		printk("burst mode Scache RAMS\n");
	else
		printk("pipelined Scache RAMS\n");

	if (info & 0x1)
		printk("Atomic Enable is set\n");

	argptr = prom_getcmdline();
#ifdef CONFIG_SERIAL_CONSOLE
	if (strstr(argptr, "console=") == NULL) {
		argptr = prom_getcmdline();
		strcat(argptr, " console=ttyS0,115200");
	}
#endif

	mips_reboot_setup();

	set_io_port_base(KSEG1);
	ioport_resource.start = GT_PCI_IO_BASE;
	ioport_resource.end = GT_PCI_IO_BASE + 0x01ffffff;

#ifdef CONFIG_BLK_DEV_INITRD
	ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
#endif


	/*
	 * Setup GT controller master bit so we can do config cycles
	 */

	/* Clear cause register bits */
	GT_WRITE(GT_INTRCAUSE_OFS, ~(GT_INTRCAUSE_MASABORT0_BIT |
				     GT_INTRCAUSE_TARABORT0_BIT));
	/* Setup address */
	GT_WRITE(GT_PCI0_CFGADDR_OFS,
		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
		 GT_PCI0_CFGADDR_CONFIGEN_BIT);

	udelay(2);
	tmp = GT_READ(GT_PCI0_CFGDATA_OFS);

	tmp |= (PCI_COMMAND_IO | PCI_COMMAND_MEMORY |
		PCI_COMMAND_MASTER | PCI_COMMAND_SERR);
	GT_WRITE(GT_PCI0_CFGADDR_OFS,
		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
		 GT_PCI0_CFGADDR_CONFIGEN_BIT);
	udelay(2);
	GT_WRITE(GT_PCI0_CFGDATA_OFS, tmp);

	/* Setup address */
	GT_WRITE(GT_PCI0_CFGADDR_OFS,
		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
		 ((PCI_COMMAND / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
		 GT_PCI0_CFGADDR_CONFIGEN_BIT);

	udelay(2);
	tmp = GT_READ(GT_PCI0_CFGDATA_OFS);
}

unsigned short get_gt_devid(void)
{
	u32 gt_devid;

	/* Figure out if this is a gt96100 or gt96100A */
	GT_WRITE(GT_PCI0_CFGADDR_OFS,
		 (0 << GT_PCI0_CFGADDR_BUSNUM_SHF) |
		 (0 << GT_PCI0_CFGADDR_FUNCTNUM_SHF) |
		 ((PCI_VENDOR_ID / 4) << GT_PCI0_CFGADDR_REGNUM_SHF) |
		 GT_PCI0_CFGADDR_CONFIGEN_BIT);

	udelay(4);
	gt_devid = GT_READ(GT_PCI0_CFGDATA_OFS);

	return gt_devid >> 16;
}
