/*
 * (C) Copyright 2002
 * Sysgo Real-Time Solutions, GmbH <www.elinos.com>
 * Marius Groeger <mgroeger@sysgo.de>
 *
 * (C) Copyright 2002
 * David Mueller, ELSOFT AG, <d.mueller@elsoft.ch>
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * 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 <common.h>
#include <s3c2410.h>
#include <i2c.h>

#include "vcma9.h"
#include "../common/common_util.h"

DECLARE_GLOBAL_DATA_PTR;

#define FCLK_SPEED 1

#if FCLK_SPEED==0		/* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV	0xC3
#define M_PDIV	0x4
#define M_SDIV	0x1
#elif FCLK_SPEED==1		/* Fout = 202.8MHz */
#define M_MDIV	0xA1
#define M_PDIV	0x3
#define M_SDIV	0x1
#endif

#define USB_CLOCK 1

#if USB_CLOCK==0
#define U_M_MDIV	0xA1
#define U_M_PDIV	0x3
#define U_M_SDIV	0x1
#elif USB_CLOCK==1
#define U_M_MDIV	0x48
#define U_M_PDIV	0x3
#define U_M_SDIV	0x2
#endif

static inline void delay(unsigned long loops)
{
	__asm__ volatile ("1:\n"
	  "subs %0, %1, #1\n"
	  "bne 1b":"=r" (loops):"0" (loops));
}

/*
 * Miscellaneous platform dependent initialisations
 */

int board_init(void)
{
	S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
	S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();

	/* to reduce PLL lock time, adjust the LOCKTIME register */
	clk_power->LOCKTIME = 0xFFFFFF;

	/* configure MPLL */
	clk_power->MPLLCON = ((M_MDIV << 12) + (M_PDIV << 4) + M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (4000);

	/* configure UPLL */
	clk_power->UPLLCON = ((U_M_MDIV << 12) + (U_M_PDIV << 4) + U_M_SDIV);

	/* some delay between MPLL and UPLL */
	delay (8000);

	/* set up the I/O ports */
	gpio->GPACON = 0x007FFFFF;
	gpio->GPBCON = 0x002AAAAA;
	gpio->GPBUP = 0x000002BF;
	gpio->GPCCON = 0xAAAAAAAA;
	gpio->GPCUP = 0x0000FFFF;
	gpio->GPDCON = 0xAAAAAAAA;
	gpio->GPDUP = 0x0000FFFF;
	gpio->GPECON = 0xAAAAAAAA;
	gpio->GPEUP = 0x000037F7;
	gpio->GPFCON = 0x00000000;
	gpio->GPFUP = 0x00000000;
	gpio->GPGCON = 0xFFEAFF5A;
	gpio->GPGUP = 0x0000F0DC;
	gpio->GPHCON = 0x0028AAAA;
	gpio->GPHUP = 0x00000656;

	/* setup correct IRQ modes for NIC */
	gpio->EXTINT2 = (gpio->EXTINT2 & ~(7<<8)) | (4<<8); /* rising edge mode */

	/* select USB port 2 to be host or device (fix to host for now) */
	gpio->MISCCR |= 0x08;

	/* init serial */
	gd->baudrate = CONFIG_BAUDRATE;
	gd->have_console = 1;
	serial_init();

	/* arch number of VCMA9-Board */
	gd->bd->bi_arch_number = MACH_TYPE_MPL_VCMA9;

	/* adress of boot parameters */
	gd->bd->bi_boot_params = 0x30000100;

	icache_enable();
	dcache_enable();

	return 0;
}

/*
 * NAND flash initialization.
 */
#if defined(CONFIG_CMD_NAND)
extern ulong
nand_probe(ulong physadr);


static inline void NF_Reset(void)
{
    int i;

    NF_SetCE(NFCE_LOW);
    NF_Cmd(0xFF);		/* reset command */
    for(i = 0; i < 10; i++);	/* tWB = 100ns. */
    NF_WaitRB();		/* wait 200~500us; */
    NF_SetCE(NFCE_HIGH);
}


static inline void NF_Init(void)
{
#if 0 /* a little bit too optimistic */
#define TACLS   0
#define TWRPH0  3
#define TWRPH1  0
#else
#define TACLS   0
#define TWRPH0  4
#define TWRPH1  2
#endif

    NF_Conf((1<<15)|(0<<14)|(0<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0));
    /*nand->NFCONF = (1<<15)|(1<<14)|(1<<13)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0); */
    /* 1  1    1     1,   1      xxx,  r xxx,   r xxx */
    /* En 512B 4step ECCR nFCE=H tACLS   tWRPH0   tWRPH1 */

    NF_Reset();
}

void
nand_init(void)
{
	S3C2410_NAND * const nand = S3C2410_GetBase_NAND();

	NF_Init();
#ifdef DEBUG
	printf("NAND flash probing at 0x%.8lX\n", (ulong)nand);
#endif
	printf ("%4lu MB\n", nand_probe((ulong)nand) >> 20);
}
#endif

/*
 * Get some Board/PLD Info
 */

static u8 Get_PLD_ID(void)
{
	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();

	return(pld->ID);
}

static u8 Get_PLD_BOARD(void)
{
	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();

	return(pld->BOARD);
}

static u8 Get_PLD_SDRAM(void)
{
	VCMA9_PLD * const pld = VCMA9_GetBase_PLD();

	return(pld->SDRAM);
}

static u8 Get_PLD_Version(void)
{
	return((Get_PLD_ID() >> 4) & 0x0F);
}

static u8 Get_PLD_Revision(void)
{
	return(Get_PLD_ID() & 0x0F);
}

#if 0	/* not used */
static int Get_Board_Config(void)
{
	u8 config = Get_PLD_BOARD() & 0x03;

	if (config == 3)
	    return 1;
	else
	    return 0;
}
#endif

static uchar Get_Board_PCB(void)
{
	return(((Get_PLD_BOARD() >> 4) & 0x03) + 'A');
}

static u8 Get_SDRAM_ChipNr(void)
{
	switch ((Get_PLD_SDRAM() >> 4) & 0x0F) {
		case 0: return 4;
		case 1: return 1;
		case 2: return 2;
		default: return 0;
	}
}

static ulong Get_SDRAM_ChipSize(void)
{
	switch (Get_PLD_SDRAM() & 0x0F) {
		case 0: return 16 * (1024*1024);
		case 1: return 32 * (1024*1024);
		case 2: return  8 * (1024*1024);
		case 3: return  8 * (1024*1024);
		default: return 0;
	}
}
static const char * Get_SDRAM_ChipGeom(void)
{
	switch (Get_PLD_SDRAM() & 0x0F) {
		case 0: return "4Mx8x4";
		case 1: return "8Mx8x4";
		case 2: return "2Mx8x4";
		case 3: return "4Mx8x2";
		default: return "unknown";
	}
}

static void Show_VCMA9_Info(char *board_name, char *serial)
{
	printf("Board: %s SN: %s  PCB Rev: %c PLD(%d,%d)\n",
		board_name, serial, Get_Board_PCB(), Get_PLD_Version(), Get_PLD_Revision());
	printf("SDRAM: %d chips %s\n", Get_SDRAM_ChipNr(), Get_SDRAM_ChipGeom());
}

int dram_init(void)
{
	gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
	gd->bd->bi_dram[0].size = Get_SDRAM_ChipSize() * Get_SDRAM_ChipNr();

	return 0;
}

/* ------------------------------------------------------------------------- */

/*
 * Check Board Identity:
 */

int checkboard(void)
{
	unsigned char s[50];
	int i;
	backup_t *b = (backup_t *) s;

	i = getenv_r("serial#", s, 32);
	if ((i < 0) || strncmp (s, "VCMA9", 5)) {
		get_backup_values (b);
		if (strncmp (b->signature, "MPL\0", 4) != 0) {
			puts ("### No HW ID - assuming VCMA9");
		} else {
			b->serial_name[5] = 0;
			Show_VCMA9_Info(b->serial_name, &b->serial_name[6]);
		}
	} else {
		s[5] = 0;
		Show_VCMA9_Info(s, &s[6]);
	}
	/*printf("\n");*/
	return(0);
}


extern void mem_test_reloc(void);

int last_stage_init(void)
{
	mem_test_reloc();
	checkboard();
	show_stdio_dev();
	check_env();
	return 0;
}

/***************************************************************************
 * some helping routines
 */
#if !CONFIG_USB_KEYBOARD
int overwrite_console(void)
{
	/* return TRUE if console should be overwritten */
	return 0;
}
#endif

/************************************************************************
* Print VCMA9 Info
************************************************************************/
void print_vcma9_info(void)
{
	unsigned char s[50];
	int i;

	if ((i = getenv_r("serial#", s, 32)) < 0) {
		puts ("### No HW ID - assuming VCMA9");
		printf("i %d", i*24);
	} else {
		s[5] = 0;
		Show_VCMA9_Info(s, &s[6]);
	}
}
