/*
 * The generic setup file for PMC-Sierra MSP processors
 *
 * Copyright 2005-2007 PMC-Sierra, Inc,
 * Author: Jun Sun, 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.
 */

#include <linux/delay.h>

#include <asm/bootinfo.h>
#include <asm/cacheflush.h>
#include <asm/idle.h>
#include <asm/r4kcache.h>
#include <asm/reboot.h>
#include <asm/smp-ops.h>
#include <asm/time.h>

#include <msp_prom.h>
#include <msp_regs.h>

#if defined(CONFIG_PMC_MSP7120_GW)
#include <msp_regops.h>
#define MSP_BOARD_RESET_GPIO	9
#endif

extern void msp_serial_setup(void);

#if defined(CONFIG_PMC_MSP7120_EVAL) || \
    defined(CONFIG_PMC_MSP7120_GW) || \
    defined(CONFIG_PMC_MSP7120_FPGA)
/*
 * Performs the reset for MSP7120-based boards
 */
void msp7120_reset(void)
{
	void *start, *end, *iptr;

	/* Diasble all interrupts */
	local_irq_disable();
#ifdef CONFIG_SYS_SUPPORTS_MULTITHREADING
	dvpe();
#endif

	/* Cache the reset code of this function */
	__asm__ __volatile__ (
		"	.set	push				\n"
		"	.set	arch=r4000			\n"
		"	la	%0,startpoint			\n"
		"	la	%1,endpoint			\n"
		"	.set	pop				\n"
		: "=r" (start), "=r" (end)
		:
	);

	for (iptr = (void *)((unsigned int)start & ~(L1_CACHE_BYTES - 1));
	     iptr < end; iptr += L1_CACHE_BYTES)
		cache_op(Fill, iptr);

	__asm__ __volatile__ (
		"startpoint:					\n"
	);

	/* Put the DDRC into self-refresh mode */
	DDRC_INDIRECT_WRITE(DDRC_CTL(10), 0xb, 1 << 16);

	/*
	 * IMPORTANT!
	 * DO NOT do anything from here on out that might even
	 * think about fetching from RAM - i.e., don't call any
	 * non-inlined functions, and be VERY sure that any inline
	 * functions you do call do NOT access any sort of RAM
	 * anywhere!
	 */

	/* Wait a bit for the DDRC to settle */
	mdelay(125);

#if defined(CONFIG_PMC_MSP7120_GW)
	/*
	 * Set GPIO 9 HI, (tied to board reset logic)
	 * GPIO 9 is the 4th GPIO of register 3
	 *
	 * NOTE: We cannot use the higher-level msp_gpio_mode()/out()
	 * as GPIO char driver may not be enabled and it would look up
	 * data inRAM!
	 */
	set_value_reg32(GPIO_CFG3_REG, 0xf000, 0x8000);
	set_reg32(GPIO_DATA3_REG, 8);

	/*
	 * In case GPIO9 doesn't reset the board (jumper configurable!)
	 * fallback to device reset below.
	 */
#endif
	/* Set bit 1 of the MSP7120 reset register */
	*RST_SET_REG = 0x00000001;

	__asm__ __volatile__ (
		"endpoint:					\n"
	);
}
#endif

void msp_restart(char *command)
{
	printk(KERN_WARNING "Now rebooting .......\n");

#if defined(CONFIG_PMC_MSP7120_EVAL) || \
    defined(CONFIG_PMC_MSP7120_GW) || \
    defined(CONFIG_PMC_MSP7120_FPGA)
	msp7120_reset();
#else
	/* No chip-specific reset code, just jump to the ROM reset vector */
	set_c0_status(ST0_BEV | ST0_ERL);
	change_c0_config(CONF_CM_CMASK, CONF_CM_UNCACHED);
	flush_cache_all();
	write_c0_wired(0);

	__asm__ __volatile__("jr\t%0"::"r"(0xbfc00000));
#endif
}

void msp_halt(void)
{
	printk(KERN_WARNING "\n** You can safely turn off the power\n");
	while (1)
		/* If possible call official function to get CPU WARs */
		if (cpu_wait)
			(*cpu_wait)();
		else
			__asm__(".set\tmips3\n\t" "wait\n\t" ".set\tmips0");
}

void msp_power_off(void)
{
	msp_halt();
}

void __init plat_mem_setup(void)
{
	_machine_restart = msp_restart;
	_machine_halt = msp_halt;
	pm_power_off = msp_power_off;
}

void __init prom_init(void)
{
	unsigned long family;
	unsigned long revision;

	prom_argc = fw_arg0;
	prom_argv = (char **)fw_arg1;
	prom_envp = (char **)fw_arg2;

	/*
	 * Someday we can use this with PMON2000 to get a
	 * platform call prom routines for output etc. without
	 * having to use grody hacks.  For now it's unused.
	 *
	 * struct callvectors *cv = (struct callvectors *) fw_arg3;
	 */
	family = identify_family();
	revision = identify_revision();

	switch (family) {
	case FAMILY_FPGA:
		if (FPGA_IS_MSP4200(revision)) {
			/* Old-style revision ID */
			mips_machtype = MACH_MSP4200_FPGA;
		} else {
			mips_machtype = MACH_MSP_OTHER;
		}
		break;

	case FAMILY_MSP4200:
#if defined(CONFIG_PMC_MSP4200_EVAL)
		mips_machtype  = MACH_MSP4200_EVAL;
#elif defined(CONFIG_PMC_MSP4200_GW)
		mips_machtype  = MACH_MSP4200_GW;
#else
		mips_machtype = MACH_MSP_OTHER;
#endif
		break;

	case FAMILY_MSP4200_FPGA:
		mips_machtype  = MACH_MSP4200_FPGA;
		break;

	case FAMILY_MSP7100:
#if defined(CONFIG_PMC_MSP7120_EVAL)
		mips_machtype = MACH_MSP7120_EVAL;
#elif defined(CONFIG_PMC_MSP7120_GW)
		mips_machtype = MACH_MSP7120_GW;
#else
		mips_machtype = MACH_MSP_OTHER;
#endif
		break;

	case FAMILY_MSP7100_FPGA:
		mips_machtype  = MACH_MSP7120_FPGA;
		break;

	default:
		/* we don't recognize the machine */
		mips_machtype  = MACH_UNKNOWN;
		panic("***Bogosity factor five***, exiting");
		break;
	}

	prom_init_cmdline();

	prom_meminit();

	/*
	 * Sub-system setup follows.
	 * Setup functions can	either be called here or using the
	 * subsys_initcall mechanism (i.e. see msp_pci_setup). The
	 * order in which they are called can be changed by using the
	 * link order in arch/mips/pmc-sierra/msp71xx/Makefile.
	 *
	 * NOTE: Please keep sub-system specific initialization code
	 * in separate specific files.
	 */
	msp_serial_setup();

	register_vsmp_smp_ops();
}
