/*
 * (C) Copyright 2005-2008
 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd-electronics.com
 *
 * (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>
#include <flash.h>
#include <asm/4xx_pci.h>
#include <pci.h>

DECLARE_GLOBAL_DATA_PTR;

#undef FPGA_DEBUG

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

int flash_banks = CFG_MAX_FLASH_BANKS_DETECT;

/* fpga configuration data - gzip compressed and generated by bin2c */
const unsigned char fpgadata[] =
{
#include "fpgadata.c"
};

/*
 * include common fpga code (for esd boards)
 */
#include "../common/fpga.c"

/* Prototypes */
int gunzip(void *, int, unsigned char *, unsigned long *);

#ifdef CONFIG_LCD_USED
/* logo bitmap data - gzip compressed and generated by bin2c */
unsigned char logo_bmp[] =
{
#include "logo_640_480_24bpp.c"
};

/*
 * include common lcd code (for esd boards)
 */
#include "../common/lcd.c"
#include "../common/s1d13505_640_480_16bpp.h"
#include "../common/s1d13806_640_480_16bpp.h"
#endif /* CONFIG_LCD_USED */

/*
 * include common auto-update code (for esd boards)
 */
#include "../common/auto_update.h"

au_image_t au_image[] = {
	{"preinst.img", 0, -1, AU_SCRIPT},
	{"u-boot.img", 0xfff80000, 0x00080000, AU_FIRMWARE | AU_PROTECT},
	{"pImage", 0xfe000000, 0x00100000, AU_NOR | AU_PROTECT},
	{"pImage.initrd", 0xfe100000, 0x00400000, AU_NOR | AU_PROTECT},
	{"work.img", 0xfe500000, 0x01400000, AU_NOR},
	{"data.img", 0xff900000, 0x00580000, AU_NOR},
	{"logo.img", 0xffe80000, 0x00100000, AU_NOR | AU_PROTECT},
	{"postinst.img", 0, 0, AU_SCRIPT},
};

int N_AU_IMAGES = (sizeof(au_image) / sizeof(au_image[0]));

int board_revision(void)
{
	unsigned long cntrl0Reg;
	volatile unsigned long value;

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

	/* Setup GPIO pins (CS2/GPIO11, CS3/GPIO12 and CS4/GPIO13 as GPIO) */
	cntrl0Reg = mfdcr(cntrl0);
	mtdcr(cntrl0, cntrl0Reg | 0x03800000);
	out_be32((void*)GPIO0_ODR, in_be32((void*)GPIO0_ODR) & ~0x001c0000);
	out_be32((void*)GPIO0_TCR, in_be32((void*)GPIO0_TCR) & ~0x001c0000);

	/* wait some time before reading input */
	udelay(1000);

	/* get config bits */
	value = in_be32((void*)GPIO0_IR) & 0x001c0000;
	/*
	 * Restore GPIO settings
	 */
	mtdcr(cntrl0, cntrl0Reg);

	switch (value) {
	case 0x001c0000:
		/* CS2==1 && CS3==1 && CS4==1 -> version <= 1.2 */
		return 2;
	case 0x000c0000:
		/* CS2==0 && CS3==1 && CS4==1 -> version 1.3 */
		return 3;
	case 0x00180000:
		/* CS2==1 && CS3==1 && CS4==0 -> version 1.6 */
		return 6;
	case 0x00140000:
		/* CS2==1 && CS3==0 && CS4==1 -> version 1.8 */
		return 8;
	default:
		/* should not be reached! */
		return 0;
	}
}

int board_early_init_f (void)
{
	/*
	 * First pull fpga-prg pin low, to disable fpga logic
	 */
	out_be32((void*)GPIO0_ODR, 0x00000000);        /* no open drain pins */
	out_be32((void*)GPIO0_TCR, CFG_FPGA_PRG);      /* setup for output   */
	out_be32((void*)GPIO0_OR, 0);                  /* pull prg low       */

	/*
	 * 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, 0xFFFFFF81);       /* set int polarities */
	mtdcr(uictr, 0x10000000);       /* set int trigger levels */
	mtdcr(uicvcr, 0x00000001);      /* set vect base=0 */
	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */

	/*
	 * EBC Configuration Register: set ready timeout to 512 ebc-clks
	 */
	mtebc(epcr, 0xa8400000); /* ebc always driven */

	/*
	 * New boards have a single 32MB flash connected to CS0
	 * instead of two 16MB flashes on CS0+1.
	 */
	if (board_revision() >= 8) {
		/* disable CS1 */
		mtebc(pb1ap, 0);
		mtebc(pb1cr, 0);

		/* resize CS0 to 32MB */
		mtebc(pb0ap, CFG_EBC_PB0AP_HWREV8);
		mtebc(pb0cr, CFG_EBC_PB0CR_HWREV8);
	}

	return 0;
}

int board_early_init_r(void)
{
	if (gd->board_type >= 8)
		flash_banks = 1;

	return 0;
}

#define FUJI_BASE    0xf0100200
#define LCDBL_PWM    0xa0
#define LCDBL_PWMMIN 0xa4
#define LCDBL_PWMMAX 0xa8

int misc_init_r(void)
{
	u16 *fpga_mode = (u16 *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_CTRL);
	u16 *fpga_ctrl2 =(u16 *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_CTRL2);
	u8 *duart0_mcr = (u8 *)(DUART0_BA + 4);
	u8 *duart1_mcr = (u8 *)(DUART1_BA + 4);
	unsigned char *dst;
	ulong len = sizeof(fpgadata);
	int status;
	int index;
	int i;
	unsigned long cntrl0Reg;
	char *str;
	uchar *logo_addr;
	ulong logo_size;
	ushort minb, maxb;
	int result;

	/*
	 * Setup GPIO pins (CS6+CS7 as GPIO)
	 */
	cntrl0Reg = mfdcr(cntrl0);
	mtdcr(cntrl0, cntrl0Reg | 0x00300000);

	dst = malloc(CFG_FPGA_MAX_SIZE);
	if (gunzip(dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
		printf("GUNZIP ERROR - must RESET board to recover\n");
		do_reset(NULL, 0, 0, NULL);
	}

	status = fpga_boot(dst, len);
	if (status != 0) {
		printf("\nFPGA: Booting failed ");
		switch (status) {
		case ERROR_FPGA_PRG_INIT_LOW:
			printf("(Timeout: "
			       "INIT not low after asserting PROGRAM*)\n ");
			break;
		case ERROR_FPGA_PRG_INIT_HIGH:
			printf("(Timeout: "
			       "INIT not high after deasserting PROGRAM*)\n ");
			break;
		case ERROR_FPGA_PRG_DONE:
			printf("(Timeout: "
			       "DONE not high after programming FPGA)\n ");
			break;
		}

		/* display infos on fpgaimage */
		index = 15;
		for (i = 0; i < 4; i++) {
			len = dst[index];
			printf("FPGA: %s\n", &(dst[index+1]));
			index += len + 3;
		}
		putc('\n');
		/* delayed reboot */
		for (i = 20; i > 0; i--) {
			printf("Rebooting in %2d seconds \r",i);
			for (index = 0; index < 1000; index++)
				udelay(1000);
		}
		putc('\n');
		do_reset(NULL, 0, 0, NULL);
	}

	/* restore gpio/cs settings */
	mtdcr(cntrl0, cntrl0Reg);

	puts("FPGA:  ");

	/* display infos on fpgaimage */
	index = 15;
	for (i = 0; i < 4; i++) {
		len = dst[index];
		printf("%s ", &(dst[index + 1]));
		index += len + 3;
	}
	putc('\n');

	free(dst);

	/*
	 * Reset FPGA via FPGA_DATA pin
	 */
	SET_FPGA(FPGA_PRG | FPGA_CLK);
	udelay(1000); /* wait 1ms */
	SET_FPGA(FPGA_PRG | FPGA_CLK | FPGA_DATA);
	udelay(1000); /* wait 1ms */

	/*
	 * Write board revision in FPGA
	 */
	out_be16(fpga_ctrl2,
		 (in_be16(fpga_ctrl2) & 0xfff0) | (gd->board_type & 0x000f));

	/*
	 * Enable power on PS/2 interface (with reset)
	 */
	out_be16(fpga_mode, in_be16(fpga_mode) | CFG_FPGA_CTRL_PS2_RESET);
	for (i=0;i<100;i++)
		udelay(1000);
	udelay(1000);
	out_be16(fpga_mode, in_be16(fpga_mode) & ~CFG_FPGA_CTRL_PS2_RESET);

	/*
	 * Enable interrupts in exar duart mcr[3]
	 */
	out_8(duart0_mcr, 0x08);
	out_8(duart1_mcr, 0x08);

	/*
	 * Init lcd interface and display logo
	 */
	str = getenv("splashimage");
	if (str) {
		logo_addr = (uchar *)simple_strtoul(str, NULL, 16);
		logo_size = CFG_VIDEO_LOGO_MAX_SIZE;
	} else {
		logo_addr = logo_bmp;
		logo_size = sizeof(logo_bmp);
	}

	if (gd->board_type >= 6) {
		result = lcd_init((uchar *)CFG_LCD_BIG_REG,
				  (uchar *)CFG_LCD_BIG_MEM,
				  regs_13505_640_480_16bpp,
				  sizeof(regs_13505_640_480_16bpp) /
				  sizeof(regs_13505_640_480_16bpp[0]),
				  logo_addr, logo_size);
		if (result && str) {
			/* retry with internal image */
			logo_addr = logo_bmp;
			logo_size = sizeof(logo_bmp);
			lcd_init((uchar *)CFG_LCD_BIG_REG,
				 (uchar *)CFG_LCD_BIG_MEM,
				 regs_13505_640_480_16bpp,
				 sizeof(regs_13505_640_480_16bpp) /
				 sizeof(regs_13505_640_480_16bpp[0]),
				 logo_addr, logo_size);
		}
	} else {
		result = lcd_init((uchar *)CFG_LCD_BIG_REG,
				  (uchar *)CFG_LCD_BIG_MEM,
				  regs_13806_640_480_16bpp,
				  sizeof(regs_13806_640_480_16bpp) /
				  sizeof(regs_13806_640_480_16bpp[0]),
				  logo_addr, logo_size);
		if (result && str) {
			/* retry with internal image */
			logo_addr = logo_bmp;
			logo_size = sizeof(logo_bmp);
			lcd_init((uchar *)CFG_LCD_BIG_REG,
				 (uchar *)CFG_LCD_BIG_MEM,
				 regs_13806_640_480_16bpp,
				 sizeof(regs_13806_640_480_16bpp) /
				 sizeof(regs_13806_640_480_16bpp[0]),
				 logo_addr, logo_size);
		}
	}

	/*
	 * Reset microcontroller and setup backlight PWM controller
	 */
	out_be16(fpga_mode, in_be16(fpga_mode) | 0x0014);
	for (i=0;i<10;i++)
		udelay(1000);
	out_be16(fpga_mode, in_be16(fpga_mode) | 0x001c);

	minb = 0;
	maxb = 0xff;
	str = getenv("lcdbl");
	if (str) {
		minb = (ushort)simple_strtoul(str, &str, 16) & 0x00ff;
		if (str && (*str=',')) {
			str++;
			maxb = (ushort)simple_strtoul(str, NULL, 16) & 0x00ff;
		} else
			minb = 0;

		out_be16((u16 *)(FUJI_BASE + LCDBL_PWMMIN), minb);
		out_be16((u16 *)(FUJI_BASE + LCDBL_PWMMAX), maxb);

		printf("LCDBL: min=0x%02x, max=0x%02x\n", minb, maxb);
	}
	out_be16((u16 *)(FUJI_BASE + LCDBL_PWM), 0xff);

	/*
	 * fix environment for field updated units
	 */
	if (getenv("altbootcmd") == NULL) {
		setenv("usb_load", CFG_USB_LOAD_COMMAND);
		setenv("usbargs", CFG_USB_ARGS);
		setenv("bootcmd", CONFIG_BOOTCOMMAND);
		setenv("usb_self", CFG_USB_SELF_COMMAND);
		setenv("bootlimit", CFG_BOOTLIMIT);
		setenv("altbootcmd", CFG_ALT_BOOTCOMMAND);
		saveenv();
	}

	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 APC405");
	} else {
		puts(str);
	}

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

	return 0;
}

#ifdef CONFIG_IDE_RESET
void ide_set_reset(int on)
{
	u16 *fpga_mode = (u16 *)(CFG_FPGA_BASE_ADDR + CFG_FPGA_CTRL);

	/*
	 * Assert or deassert CompactFlash Reset Pin
	 */
	if (on) {
		out_be16(fpga_mode,
			 in_be16(fpga_mode) & ~CFG_FPGA_CTRL_CF_RESET);
	} else {
		out_be16(fpga_mode,
			 in_be16(fpga_mode) | CFG_FPGA_CTRL_CF_RESET);
	}
}
#endif /* CONFIG_IDE_RESET */

void reset_phy(void)
{
	/*
	 * Disable sleep mode in LXT971
	 */
	lxt971_no_sleep();
}

#if defined(CONFIG_USB_OHCI_NEW) && defined(CFG_USB_OHCI_BOARD_INIT)
int usb_board_init(void)
{
	return 0;
}

int usb_board_stop(void)
{
	unsigned short tmp;
	int i;

	/*
	 * reset PCI bus
	 * This is required to make some very old Linux OHCI driver
	 * work after U-Boot has used the OHCI controller.
	 */
	pci_read_config_word(PCIDEVID_405GP, PCIBRDGOPT2, &tmp);
	pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, (tmp | 0x1000));

	for (i = 0; i < 100; i++)
		udelay(1000);

	pci_write_config_word(PCIDEVID_405GP, PCIBRDGOPT2, tmp);
	return 0;
}

int usb_board_init_fail(void)
{
	usb_board_stop();
	return 0;
}
#endif /* defined(CONFIG_USB_OHCI) && defined(CFG_USB_OHCI_BOARD_INIT) */
