/*
 * BRIEF MODULE DESCRIPTION
 * Momentum Computer Ocelot-G (CP7000G) - board dependent boot routines
 *
 * Copyright (C) 1996, 1997, 2001  Ralf Baechle
 * Copyright (C) 2000 RidgeRun, Inc.
 * Copyright (C) 2001 Red Hat, Inc.
 * Copyright (C) 2002 Momentum Computer
 *
 * Author: Matthew Dharm, Momentum Computer
 *   mdharm@momenco.com
 *
 * Author: RidgeRun, Inc.
 *   glonnon@ridgerun.com, skranz@ridgerun.com, stevej@ridgerun.com
 *
 * Copyright 2001 MontaVista Software Inc.
 * Author: jsun@mvista.com or jsun@junsun.net
 *
 *  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/kernel.h>
#include <linux/types.h>
#include <linux/mm.h>
#include <linux/swap.h>
#include <linux/ioport.h>
#include <linux/sched.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/timex.h>
#include <linux/vmalloc.h>

#include <asm/time.h>
#include <asm/bootinfo.h>
#include <asm/page.h>
#include <asm/io.h>
#include <asm/gt64240.h>
#include <asm/irq.h>
#include <asm/pci.h>
#include <asm/pgtable.h>
#include <asm/processor.h>
#include <asm/reboot.h>
#include <linux/bootmem.h>

#include "ocelot_pld.h"

#ifdef CONFIG_GALILEO_GT64240_ETH
extern unsigned char prom_mac_addr_base[6];
#endif

unsigned long marvell_base;

/* These functions are used for rebooting or halting the machine*/
extern void momenco_ocelot_restart(char *command);
extern void momenco_ocelot_halt(void);
extern void momenco_ocelot_power_off(void);

extern void gt64240_time_init(void);
extern void momenco_ocelot_irq_setup(void);

static char reset_reason;

static unsigned long ENTRYLO(unsigned long paddr)
{
	return ((paddr & PAGE_MASK) |
	       (_PAGE_PRESENT | __READABLE | __WRITEABLE | _PAGE_GLOBAL |
		_CACHE_UNCACHED)) >> 6;
}

/* setup code for a handoff from a version 2 PMON 2000 PROM */
void PMON_v2_setup(void)
{
	/* A wired TLB entry for the GT64240 and the serial port. The
	   GT64240 is going to be hit on every IRQ anyway - there's
	   absolutely no point in letting it be a random TLB entry, as
	   it'll just cause needless churning of the TLB. And we use
	   the other half for the serial port, which is just a PITA
	   otherwise :)

		Device			Physical	Virtual
		GT64240 Internal Regs	0xf4000000	0xe0000000
		UARTs (CS2)		0xfd000000	0xe0001000
	*/
	add_wired_entry(ENTRYLO(0xf4000000), ENTRYLO(0xf4010000),
	                0xf4000000, PM_64K);
	add_wired_entry(ENTRYLO(0xfd000000), ENTRYLO(0xfd001000),
	                0xfd000000, PM_4K);

	/* Also a temporary entry to let us talk to the Ocelot PLD and NVRAM
	   in the CS[012] region. We can't use ioremap() yet. The NVRAM
	   is a ST M48T37Y, which includes NVRAM, RTC, and Watchdog functions.

		Ocelot PLD (CS0)	0xfc000000	0xe0020000
		NVRAM (CS1)		0xfc800000	0xe0030000
	*/
	add_temporary_entry(ENTRYLO(0xfc000000), ENTRYLO(0xfc010000),
	                    0xfc000000, PM_64K);
	add_temporary_entry(ENTRYLO(0xfc800000), ENTRYLO(0xfc810000),
	                    0xfc800000, PM_64K);

	marvell_base = 0xf4000000;
}

extern int rm7k_tcache_enabled;

/*
 * This runs in KSEG1. See the verbiage in rm7k.c::probe_scache()
 */
#define Page_Invalidate_T 0x16
static void __init setup_l3cache(unsigned long size)
{
	int register i;

	printk("Enabling L3 cache...");

	/* Enable the L3 cache in the GT64120A's CPU Configuration register */
	MV_WRITE(0, MV_READ(0) | (1<<14));

	/* Enable the L3 cache in the CPU */
	set_c0_config(1<<12 /* CONF_TE */);

	/* Clear the cache */
	write_c0_taglo(0);
	write_c0_taghi(0);

	for (i=0; i < size; i+= 4096) {
		__asm__ __volatile__ (
			".set noreorder\n\t"
			".set mips3\n\t"
			"cache %1, (%0)\n\t"
			".set mips0\n\t"
			".set reorder"
			:
			: "r" (KSEG0ADDR(i)),
			  "i" (Page_Invalidate_T));
	}

	/* Let the RM7000 MM code know that the tertiary cache is enabled */
	rm7k_tcache_enabled = 1;

	printk("Done\n");
}

void __init plat_timer_setup(struct irqaction *irq)
{
}

void __init plat_mem_setup(void)
{
	void (*l3func)(unsigned long) = (void *) KSEG1ADDR(setup_l3cache);
	unsigned int tmpword;

	board_time_init = gt64240_time_init;

	_machine_restart = momenco_ocelot_restart;
	_machine_halt = momenco_ocelot_halt;
	pm_power_off = momenco_ocelot_power_off;

	/*
	 * initrd_start = (unsigned long)ocelot_initrd_start;
	 * initrd_end = (unsigned long)ocelot_initrd_start + (ulong)ocelot_initrd_size;
	 * initrd_below_start_ok = 1;
	 */

	/* do handoff reconfiguration */
	PMON_v2_setup();

#ifdef CONFIG_GALILEO_GT64240_ETH
	/* get the mac addr */
	memcpy(prom_mac_addr_base, (void*)0xfc807cf2, 6);
#endif

	/* Turn off the Bit-Error LED */
	OCELOT_PLD_WRITE(0x80, INTCLR);

	tmpword = OCELOT_PLD_READ(BOARDREV);
	if (tmpword < 26)
		printk("Momenco Ocelot-G: Board Assembly Rev. %c\n", 'A'+tmpword);
	else
		printk("Momenco Ocelot-G: Board Assembly Revision #0x%x\n", tmpword);

	tmpword = OCELOT_PLD_READ(PLD1_ID);
	printk("PLD 1 ID: %d.%d\n", tmpword>>4, tmpword&15);
	tmpword = OCELOT_PLD_READ(PLD2_ID);
	printk("PLD 2 ID: %d.%d\n", tmpword>>4, tmpword&15);
	tmpword = OCELOT_PLD_READ(RESET_STATUS);
	printk("Reset reason: 0x%x\n", tmpword);
	reset_reason = tmpword;
	OCELOT_PLD_WRITE(0xff, RESET_STATUS);

	tmpword = OCELOT_PLD_READ(BOARD_STATUS);
	printk("Board Status register: 0x%02x\n", tmpword);
	printk("  - User jumper: %s\n", (tmpword & 0x80)?"installed":"absent");
	printk("  - Boot flash write jumper: %s\n", (tmpword&0x40)?"installed":"absent");
	printk("  - Tulip PHY %s connected\n", (tmpword&0x10)?"is":"not");
	printk("  - L3 Cache size: %d MiB\n", (1<<((tmpword&12) >> 2))&~1);
	printk("  - SDRAM size: %d MiB\n", 1<<(6+(tmpword&3)));

	if (tmpword&12)
		l3func((1<<(((tmpword&12) >> 2)+20)));

	switch(tmpword &3) {
	case 3:
		/* 512MiB -- two banks of 256MiB */
		add_memory_region(  0x0<<20, 0x100<<20, BOOT_MEM_RAM);
/*
		add_memory_region(0x100<<20, 0x100<<20, BOOT_MEM_RAM);
*/
		break;
	case 2:
		/* 256MiB -- two banks of 128MiB */
		add_memory_region( 0x0<<20, 0x80<<20, BOOT_MEM_RAM);
		add_memory_region(0x80<<20, 0x80<<20, BOOT_MEM_RAM);
		break;
	case 1:
		/* 128MiB -- 64MiB per bank */
		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
		add_memory_region(0x40<<20, 0x40<<20, BOOT_MEM_RAM);
		break;
	case 0:
		/* 64MiB */
		add_memory_region( 0x0<<20, 0x40<<20, BOOT_MEM_RAM);
		break;
	}

	/* FIXME: Fix up the DiskOnChip mapping */
	MV_WRITE(0x468, 0xfef73);
}

/* This needs to be one of the first initcalls, because no I/O port access
   can work before this */

static int io_base_ioremap(void)
{
	/* we're mapping PCI accesses from 0xc0000000 to 0xf0000000 */
	unsigned long io_remap_range;

	io_remap_range = (unsigned long) ioremap(0xc0000000, 0x30000000);
	if (!io_remap_range)
		panic("Could not ioremap I/O port range");

	set_io_port_base(io_remap_range - 0xc0000000);

	return 0;
}

module_init(io_base_ioremap);
