/*
 * (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 <stdio_dev.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)
{
	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();
	stdio_print_current_devices();
	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)
{
	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]);
	}
}
