/*
 * (C) Copyright 2001-2003
 * Stefan Roese, esd gmbh germany, stefan.roese@esd-electronics.com
 *
 * 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 <asm/processor.h>
#include <asm/io.h>
#include <command.h>
#include <malloc.h>

DECLARE_GLOBAL_DATA_PTR;

extern void lxt971_no_sleep(void);

int board_revision(void)
{
	unsigned long osrl_reg;
	unsigned long isr1l_reg;
	unsigned long tcr_reg;
	unsigned long value;

	/*
	 * Get version of HUB405 board from GPIO's
	 */

	/*
	 * Setup GPIO pin(s) (IRQ6/GPIO23)
	 */
	osrl_reg = in_be32((void *)GPIO0_OSRH);
	isr1l_reg = in_be32((void *)GPIO0_ISR1H);
	tcr_reg = in_be32((void *)GPIO0_TCR);
	out_be32((void *)GPIO0_OSRH, osrl_reg & ~0x00030000);     /* output select */
	out_be32((void *)GPIO0_ISR1H, isr1l_reg | 0x00030000);    /* input select  */
	out_be32((void *)GPIO0_TCR, tcr_reg & ~0x00000100);       /* select input  */

	udelay(1000);            /* wait some time before reading input */
	value = in_be32((void *)GPIO0_IR) & 0x00000100;         /* get config bits */

	/*
	 * Restore GPIO settings
	 */
	out_be32((void *)GPIO0_OSRH, osrl_reg);                   /* output select */
	out_be32((void *)GPIO0_ISR1H, isr1l_reg);                 /* input select  */
	out_be32((void *)GPIO0_TCR, tcr_reg);  /* enable output driver for outputs */

	if (value & 0x00000100) {
		/* Revision 1.1 or 1.2 detected */
		return 1;
	}

	/* Revision 1.0 */
	return 0;
}


int board_early_init_f (void)
{
	/*
	 * IRQ 0-15  405GP internally generated; active high; level sensitive
	 * IRQ 16    405GP internally generated; active low; level sensitive
	 * IRQ 17-24 RESERVED
	 * IRQ 25 (EXT IRQ 0) CAN0; active low; level sensitive
	 * IRQ 26 (EXT IRQ 1) SER0 ; active low; level sensitive
	 * IRQ 27 (EXT IRQ 2) SER1; active low; level sensitive
	 * IRQ 28 (EXT IRQ 3) FPGA 0; active low; level sensitive
	 * IRQ 29 (EXT IRQ 4) FPGA 1; active low; level sensitive
	 * IRQ 30 (EXT IRQ 5) PCI INTA; active low; level sensitive
	 * IRQ 31 (EXT IRQ 6) COMPACT FLASH; active high; level sensitive
	 */
	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */
	mtdcr(uicer, 0x00000000);       /* disable all ints */
	mtdcr(uiccr, 0x00000000);       /* set all to be non-critical*/
	mtdcr(uicpr, 0xFFFFFF9F);       /* set int polarities */
	mtdcr(uictr, 0x10000000);       /* set int trigger levels */
	mtdcr(uicvcr, 0x00000001);      /* set vect base=0,INT0 highest priority*/
	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */

	/*
	 * EBC Configuration Register: set ready timeout to 512 ebc-clks -> ca. 15 us
	 */
	mtebc (EBC0_CFG, 0xa8400000); /* ebc always driven */

	return 0;
}

#define LED_REG (DUART0_BA + 0x20)
int misc_init_r (void)
{
	unsigned long val;
	int delay, flashcnt;
	char *str;
	char hw_rev[4];

	/*
	 * Enable interrupts in exar duart mcr[3]
	 */
	out_8((void *)(DUART0_BA + 4), 0x08);
	out_8((void *)(DUART1_BA + 4), 0x08);
	out_8((void *)(DUART2_BA + 4), 0x08);
	out_8((void *)(DUART3_BA + 4), 0x08);

	/*
	 * Set RS232/RS422 control (RS232 = high on GPIO)
	 */
	val = in_be32((void *)GPIO0_OR);
	val &= ~(CONFIG_SYS_UART2_RS232 | CONFIG_SYS_UART3_RS232 |
		 CONFIG_SYS_UART4_RS232 | CONFIG_SYS_UART5_RS232);

	str = getenv("phys0");
	if (!str || (str && (str[0] == '0')))
		val |= CONFIG_SYS_UART2_RS232;

	str = getenv("phys1");
	if (!str || (str && (str[0] == '0')))
		val |= CONFIG_SYS_UART3_RS232;

	str = getenv("phys2");
	if (!str || (str && (str[0] == '0')))
		val |= CONFIG_SYS_UART4_RS232;

	str = getenv("phys3");
	if (!str || (str && (str[0] == '0')))
		val |= CONFIG_SYS_UART5_RS232;

	out_be32((void *)GPIO0_OR, val);

	/*
	 * check board type and setup AP power
	 */
	str = getenv("bd_type"); /* this is only set on non prototype hardware */
	if (str != NULL) {
		if ((strcmp(str, "swch405") == 0) || ((!strcmp(str, "hub405") && (gd->board_type >= 1)))) {
			unsigned char led_reg_default = 0;
			str = getenv("ap_pwr");
			if (!str || (str && (str[0] == '1')))
				led_reg_default = 0x04 | 0x02 ; /* U2_LED | AP_PWR */

			/*
			 * Flash LEDs
			 */
			for (flashcnt = 0; flashcnt < 3; flashcnt++) {
				/* LED_A..D off */
				out_8((void *)LED_REG, led_reg_default);
				for (delay = 0; delay < 100; delay++)
					udelay(1000);
				/* LED_A..D on */
				out_8((void *)LED_REG, led_reg_default | 0xf0);
				for (delay = 0; delay < 50; delay++)
					udelay(1000);
			}
			out_8((void *)LED_REG, led_reg_default);
		}
	}

	/*
	 * Reset external DUARTs
	 */
	out_be32((void *)GPIO0_OR,
		 in_be32((void *)GPIO0_OR) | CONFIG_SYS_DUART_RST); /* set reset to high */
	udelay(10); /* wait 10us */
	out_be32((void *)GPIO0_OR,
		 in_be32((void *)GPIO0_OR) & ~CONFIG_SYS_DUART_RST); /* set reset to low */
	udelay(1000); /* wait 1ms */

	/*
	 * Store hardware revision in environment for further processing
	 */
	sprintf(hw_rev, "1.%ld", gd->board_type);
	setenv("hw_rev", hw_rev);
	return (0);
}


/*
 * Check Board Identity:
 */
int checkboard (void)
{
	char str[64];
	int i = getenv_r ("serial#", str, sizeof(str));

	puts ("Board: ");

	if (i == -1) {
		puts ("### No HW ID - assuming HUB405");
	} else {
		puts(str);
	}

	if (getenv_r("bd_type", str, sizeof(str)) != -1) {
		printf(" (%s", str);
	} else {
		puts(" (Missing bd_type!");
	}

	gd->board_type = board_revision();
	printf(", Rev 1.%ld)\n", gd->board_type);

	/*
	 * Disable sleep mode in LXT971
	 */
	lxt971_no_sleep();

	return 0;
}
