/*
 * (C) Copyright 2007
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * 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 <command.h>
#include <malloc.h>
#include <environment.h>
#include <logbuff.h>
#include <post.h>

#include <asm/processor.h>
#include <asm/io.h>
#include <asm/gpio.h>

DECLARE_GLOBAL_DATA_PTR;

#define REBOOT_MAGIC	0x07081967
#define REBOOT_NOP	0x00000000
#define REBOOT_DO_POST	0x00000001

extern flash_info_t flash_info[CFG_MAX_FLASH_BANKS]; /* info for FLASH chips	*/
extern env_t *env_ptr;
extern uchar default_environment[];

ulong flash_get_size(ulong base, int banknum);
void env_crc_update(void);
int do_reset (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

static u32 start_time;

int board_early_init_f(void)
{
	mtdcr(uicsr, 0xFFFFFFFF);	/* clear all ints */
	mtdcr(uicer, 0x00000000);	/* disable all ints */
	mtdcr(uiccr, 0x00000000);
	mtdcr(uicpr, 0xFFFF7F00);	/* set int polarities */
	mtdcr(uictr, 0x00000000);	/* set int trigger levels */
	mtdcr(uicsr, 0xFFFFFFFF);	/* clear all ints */
	mtdcr(uicvcr, 0x00000001);	/* set vect base=0,INT0 highest priority */

	/*
	 * Configure CPC0_PCI to enable PerWE as output
	 */
	mtdcr(cpc0_pci, CPC0_PCI_SPE);

	return 0;
}

int misc_init_r(void)
{
	u32 pbcr;
	int size_val = 0;
	u32 post_magic;
	u32 post_val;

	post_magic = in_be32((void *)CFG_POST_MAGIC);
	post_val = in_be32((void *)CFG_POST_VAL);
	if ((post_magic == REBOOT_MAGIC) && (post_val == REBOOT_DO_POST)) {
		/*
		 * Set special bootline bootparameter to pass this POST boot
		 * mode to Linux to reset the username/password
		 */
		setenv("addmisc", "setenv bootargs \\${bootargs} factory_reset=yes");

		/*
		 * Normally don't run POST tests, only when enabled
		 * via the sw-reset button. So disable further tests
		 * upon next bootup here.
		 */
		out_be32((void *)CFG_POST_VAL, REBOOT_NOP);
	} else {
		/*
		 * Only run POST when initiated via the sw-reset button mechanism
		 */
		post_word_store(0);
	}

	/*
	 * Get current time
	 */
	start_time = get_timer(0);

	/*
	 * FLASH stuff...
	 */

	/* Re-do sizing to get full correct info */

	/* adjust flash start and offset */
	mfebc(pb0cr, pbcr);
	switch (gd->bd->bi_flashsize) {
	case 1 << 20:
		size_val = 0;
		break;
	case 2 << 20:
		size_val = 1;
		break;
	case 4 << 20:
		size_val = 2;
		break;
	case 8 << 20:
		size_val = 3;
		break;
	case 16 << 20:
		size_val = 4;
		break;
	case 32 << 20:
		size_val = 5;
		break;
	case 64 << 20:
		size_val = 6;
		break;
	case 128 << 20:
		size_val = 7;
		break;
	}
	pbcr = (pbcr & 0x0001ffff) | gd->bd->bi_flashstart | (size_val << 17);
	mtebc(pb0cr, pbcr);

	/*
	 * Re-check to get correct base address
	 */
	flash_get_size(gd->bd->bi_flashstart, 0);

	/* Monitor protection ON by default */
	(void)flash_protect(FLAG_PROTECT_SET,
			    -CFG_MONITOR_LEN,
			    0xffffffff,
			    &flash_info[0]);

	/* Env protection ON by default */
	(void)flash_protect(FLAG_PROTECT_SET,
			    CFG_ENV_ADDR_REDUND,
			    CFG_ENV_ADDR_REDUND + 2*CFG_ENV_SECT_SIZE - 1,
			    &flash_info[0]);

	return 0;
}

/*
 * Check Board Identity:
 */
int checkboard(void)
{
	char *s = getenv("serial#");

	puts("Board: Zeus-");

	if (in_be32((void *)GPIO0_IR) & GPIO_VAL(CFG_GPIO_ZEUS_PE))
		puts("PE");
	else
		puts("CE");

	puts(" of BulletEndPoint");

	if (s != NULL) {
		puts(", serial# ");
		puts(s);
	}
	putc('\n');

	/* both LED's off */
	gpio_write_bit(CFG_GPIO_LED_RED, 0);
	gpio_write_bit(CFG_GPIO_LED_GREEN, 0);
	udelay(10000);
	/* and on again */
	gpio_write_bit(CFG_GPIO_LED_RED, 1);
	gpio_write_bit(CFG_GPIO_LED_GREEN, 1);

	return (0);
}

static u32 detect_sdram_size(void)
{
	u32 val;
	u32 size;

	mfsdram(mem_mb0cf, val);
	size = (4 << 20) << ((val & 0x000e0000) >> 17);

	/*
	 * Check if 2nd bank is enabled too
	 */
	mfsdram(mem_mb1cf, val);
	if (val & 1)
		size += (4 << 20) << ((val & 0x000e0000) >> 17);

	return size;
}

long int initdram (int board_type)
{
	return detect_sdram_size();
}

#if defined(CFG_DRAM_TEST)
int testdram(void)
{
	unsigned long *mem = (unsigned long *)0;
	const unsigned long kend = (1024 / sizeof(unsigned long));
	unsigned long k, n;
	unsigned long msr;
	unsigned long total_kbytes;

	total_kbytes = detect_sdram_size();

	msr = mfmsr();
	mtmsr(msr & ~(MSR_EE));

	for (k = 0; k < total_kbytes ;
	     ++k, mem += (1024 / sizeof(unsigned long))) {
		if ((k & 1023) == 0) {
			printf("%3d MB\r", k / 1024);
		}

		memset(mem, 0xaaaaaaaa, 1024);
		for (n = 0; n < kend; ++n) {
			if (mem[n] != 0xaaaaaaaa) {
				printf("SDRAM test fails at: %08x\n",
				       (uint) & mem[n]);
				return 1;
			}
		}

		memset(mem, 0x55555555, 1024);
		for (n = 0; n < kend; ++n) {
			if (mem[n] != 0x55555555) {
				printf("SDRAM test fails at: %08x\n",
				       (uint) & mem[n]);
				return 1;
			}
		}
	}
	printf("SDRAM test passes\n");
	mtmsr(msr);

	return 0;
}
#endif

static int default_env_var(char *buf, char *var)
{
	char *ptr;
	char *val;

	/*
	 * Find env variable
	 */
	ptr = strstr(buf + 4, var);
	if (ptr == NULL) {
		printf("ERROR: %s not found!\n", var);
		return -1;
	}
	ptr += strlen(var) + 1;

	/*
	 * Now the ethaddr needs to be updated in the "normal"
	 * environment storage -> redundant flash.
	 */
	val = ptr;
	setenv(var, val);
	printf("Updated %s from eeprom to %s!\n", var, val);

	return 0;
}

static int restore_default(void)
{
	char *buf;
	char *buf_save;
	u32 crc;

	/*
	 * Unprotect and erase environment area
	 */
	flash_protect(FLAG_PROTECT_CLEAR,
		      CFG_ENV_ADDR_REDUND,
		      CFG_ENV_ADDR_REDUND + 2*CFG_ENV_SECT_SIZE - 1,
		      &flash_info[0]);

	flash_sect_erase(CFG_ENV_ADDR_REDUND,
			 CFG_ENV_ADDR_REDUND + 2*CFG_ENV_SECT_SIZE - 1);

	/*
	 * Now restore default environment from U-Boot image
	 * -> ipaddr, serverip...
	 */
	memset(env_ptr, 0, sizeof(env_t));
	memcpy(env_ptr->data, default_environment, ENV_SIZE);
#ifdef CFG_REDUNDAND_ENVIRONMENT
	env_ptr->flags = 0xFF;
#endif
	env_crc_update();
	gd->env_valid = 1;

	/*
	 * Read board specific values from I2C EEPROM
	 * and set env variables accordingly
	 * -> ethaddr, eth1addr, serial#
	 */
	buf = buf_save = malloc(FACTORY_RESET_ENV_SIZE);
	if (eeprom_read(FACTORY_RESET_I2C_EEPROM, FACTORY_RESET_ENV_OFFS,
			(u8 *)buf, FACTORY_RESET_ENV_SIZE)) {
		puts("\nError reading EEPROM!\n");
	} else {
		crc = crc32(0, (u8 *)(buf + 4), FACTORY_RESET_ENV_SIZE - 4);
		if (crc != *(u32 *)buf) {
			printf("ERROR: crc mismatch %08lx %08lx\n", crc, *(u32 *)buf);
			return -1;
		}

		default_env_var(buf, "ethaddr");
		buf += 8 + 18;
		default_env_var(buf, "eth1addr");
		buf += 9 + 18;
		default_env_var(buf, "serial#");
	}

	/*
	 * Finally save updated env variables back to flash
	 */
	saveenv();

	free(buf_save);

	return 0;
}

int do_set_default(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	char *buf;
	char *buf_save;
	char str[32];
	u32 crc;
	char var[32];

	if (argc < 4) {
		puts("ERROR!\n");
		return -1;
	}

	buf = buf_save = malloc(FACTORY_RESET_ENV_SIZE);
	memset(buf, 0, FACTORY_RESET_ENV_SIZE);

	strcpy(var, "ethaddr");
	printf("Setting %s to %s\n", var, argv[1]);
	sprintf(str, "%s=%s", var, argv[1]);
	strcpy(buf + 4, str);
	buf += strlen(str) + 1;

	strcpy(var, "eth1addr");
	printf("Setting %s to %s\n", var, argv[2]);
	sprintf(str, "%s=%s", var, argv[2]);
	strcpy(buf + 4, str);
	buf += strlen(str) + 1;

	strcpy(var, "serial#");
	printf("Setting %s to %s\n", var, argv[3]);
	sprintf(str, "%s=%s", var, argv[3]);
	strcpy(buf + 4, str);

	crc = crc32(0, (u8 *)(buf_save + 4), FACTORY_RESET_ENV_SIZE - 4);
	*(u32 *)buf_save = crc;

	if (eeprom_write(FACTORY_RESET_I2C_EEPROM, FACTORY_RESET_ENV_OFFS,
			 (u8 *)buf_save, FACTORY_RESET_ENV_SIZE)) {
		puts("\nError writing EEPROM!\n");
		return -1;
	}

	free(buf_save);

	return 0;
}

U_BOOT_CMD(
	setdef,	4,	1,	do_set_default,
	"setdef  - write board-specific values to EEPROM (ethaddr...)\n",
	"ethaddr eth1addr serial#\n    - write board-specific values to EEPROM\n"
	);

static inline int sw_reset_pressed(void)
{
	return !(in_be32((void *)GPIO0_IR) & GPIO_VAL(CFG_GPIO_SW_RESET));
}

int do_chkreset(cmd_tbl_t* cmdtp, int flag, int argc, char* argv[])
{
	int delta;
	int count = 0;
	int post = 0;
	int factory_reset = 0;

	if (!sw_reset_pressed()) {
		printf("SW-Reset already high (Button released)\n");
		printf("-> No action taken!\n");
		return 0;
	}

	printf("Waiting for SW-Reset button to be released.");

	while (1) {
		delta = get_timer(start_time);
		if (!sw_reset_pressed())
			break;

		if ((delta > CFG_TIME_POST) && !post) {
			printf("\nWhen released now, POST tests will be started.");
			gpio_write_bit(CFG_GPIO_LED_GREEN, 0);
			post = 1;
		}

		if ((delta > CFG_TIME_FACTORY_RESET) && !factory_reset) {
			printf("\nWhen released now, factory default values"
			       " will be restored.");
			gpio_write_bit(CFG_GPIO_LED_RED, 0);
			factory_reset = 1;
		}

		udelay(1000);
		if (!(count++ % 1000))
			printf(".");
	}


	printf("\nSW-Reset Button released after %d milli-seconds!\n", delta);

	if (delta > CFG_TIME_FACTORY_RESET) {
		printf("Starting factory reset value restoration...\n");

		/*
		 * Restore default setting
		 */
		restore_default();

		/*
		 * Reset the board for default to become valid
		 */
		do_reset(NULL, 0, 0, NULL);

		return 0;
	}

	if (delta > CFG_TIME_POST) {
		printf("Starting POST configuration...\n");

		/*
		 * Enable POST upon next bootup
		 */
		out_be32((void *)CFG_POST_MAGIC, REBOOT_MAGIC);
		out_be32((void *)CFG_POST_VAL, REBOOT_DO_POST);
		post_bootmode_init();

		/*
		 * Reset the logbuffer for a clean start
		 */
		logbuff_reset();

		do_reset(NULL, 0, 0, NULL);

		return 0;
	}

	return 0;
}

U_BOOT_CMD (
	chkreset, 1, 1, do_chkreset,
	"chkreset- Check for status of SW-reset button and act accordingly\n",
	NULL
);

#if defined(CONFIG_POST)
/*
 * Returns 1 if keys pressed to start the power-on long-running tests
 * Called from board_init_f().
 */
int post_hotkeys_pressed(void)
{
	u32 post_magic;
	u32 post_val;

	post_magic = in_be32((void *)CFG_POST_MAGIC);
	post_val = in_be32((void *)CFG_POST_VAL);

	if ((post_magic == REBOOT_MAGIC) && (post_val == REBOOT_DO_POST))
		return 1;
	else
		return 0;
}
#endif /* CONFIG_POST */
