/*
 * (C) Copyright 2006
 * 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 <asm/arch/ixp425.h>

DECLARE_GLOBAL_DATA_PTR;

/* Prototypes */
int gunzip(void *, int, unsigned char *, unsigned long *);
int do_reset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[]);

/* predefine these here for FPGA programming (before including fpga.c) */
#define SET_FPGA(data)	*IXP425_GPIO_GPOUTR = (data)
#define FPGA_DONE_STATE (*IXP425_GPIO_GPINR & CFG_FPGA_DONE)
#define FPGA_INIT_STATE (*IXP425_GPIO_GPINR & CFG_FPGA_INIT)
#define OLD_VAL		old_val

static unsigned long old_val = 0;

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

/*
 * Miscelaneous platform dependent initialisations
 */
int board_post_init(void)
{
	return (0);
}

int board_init(void)
{
	/* arch number of PDNB3 */
	gd->bd->bi_arch_number = MACH_TYPE_PDNB3;

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

	GPIO_OUTPUT_SET(CFG_GPIO_FPGA_RESET);
	GPIO_OUTPUT_ENABLE(CFG_GPIO_FPGA_RESET);

	GPIO_OUTPUT_SET(CFG_GPIO_SYS_RUNNING);
	GPIO_OUTPUT_ENABLE(CFG_GPIO_SYS_RUNNING);

	/*
	 * Setup GPIO's for FPGA programming
	 */
	GPIO_OUTPUT_CLEAR(CFG_GPIO_PRG);
	GPIO_OUTPUT_CLEAR(CFG_GPIO_CLK);
	GPIO_OUTPUT_CLEAR(CFG_GPIO_DATA);
	GPIO_OUTPUT_ENABLE(CFG_GPIO_PRG);
	GPIO_OUTPUT_ENABLE(CFG_GPIO_CLK);
	GPIO_OUTPUT_ENABLE(CFG_GPIO_DATA);
	GPIO_OUTPUT_DISABLE(CFG_GPIO_INIT);
	GPIO_OUTPUT_DISABLE(CFG_GPIO_DONE);

	/*
	 * Setup GPIO's for interrupts
	 */
	GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTA);
	GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTA);
	GPIO_OUTPUT_DISABLE(CFG_GPIO_PCI_INTB);
	GPIO_INT_ACT_LOW_SET(CFG_GPIO_PCI_INTB);
	GPIO_OUTPUT_DISABLE(CFG_GPIO_RESTORE_INT);
	GPIO_INT_ACT_LOW_SET(CFG_GPIO_RESTORE_INT);
	GPIO_OUTPUT_DISABLE(CFG_GPIO_RESTART_INT);
	GPIO_INT_ACT_LOW_SET(CFG_GPIO_RESTART_INT);

	/*
	 * Setup GPIO's for 33MHz clock output
	 */
	*IXP425_GPIO_GPCLKR = 0x01FF0000;
	GPIO_OUTPUT_ENABLE(CFG_GPIO_CLK_33M);

	/*
	 * Setup other chip select's
	 */
	*IXP425_EXP_CS1 = CFG_EXP_CS1;

	return 0;
}

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

	puts("Board: PDNB3");

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

	return (0);
}

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

	return (0);
}

int do_fpga_boot(unsigned char *fpgadata)
{
	unsigned char *dst;
	int status;
	int index;
	int i;
	ulong len = CFG_MALLOC_LEN;

	/*
	 * Setup GPIO's for FPGA programming
	 */
	GPIO_OUTPUT_CLEAR(CFG_GPIO_PRG);
	GPIO_OUTPUT_CLEAR(CFG_GPIO_CLK);
	GPIO_OUTPUT_CLEAR(CFG_GPIO_DATA);

	/*
	 * Save value so no readback is required upon programming
	 */
	old_val = *IXP425_GPIO_GPOUTR;

	/*
	 * First try to decompress fpga image (gzip compressed?)
	 */
	dst = malloc(CFG_FPGA_MAX_SIZE);
	if (gunzip(dst, CFG_FPGA_MAX_SIZE, (uchar *)fpgadata, &len) != 0) {
		printf("Error: Image has to be gzipp'ed!\n");
		return -1;
	}

	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=5; 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);
	}

	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
	 */
	GPIO_OUTPUT_CLEAR(CFG_GPIO_FPGA_RESET);
	udelay(10);
	GPIO_OUTPUT_SET(CFG_GPIO_FPGA_RESET);

	return (0);
}

int do_fpga(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong addr;

	if (argc < 2) {
		printf ("Usage:\n%s\n", cmdtp->usage);
		return 1;
	}

	addr = simple_strtoul(argv[1], NULL, 16);

	return do_fpga_boot((unsigned char *)addr);
}

U_BOOT_CMD(
	fpga,     2,     0,      do_fpga,
	"fpga    - boot FPGA\n",
	"address size\n    - boot FPGA with gzipped image at <address>\n"
);

#if (CONFIG_COMMANDS & CFG_CMD_PCI) || defined(CONFIG_PCI)
extern struct pci_controller hose;
extern void pci_ixp_init(struct pci_controller * hose);

void pci_init_board(void)
{
	extern void pci_ixp_init (struct pci_controller *hose);

	pci_ixp_init(&hose);
}
#endif
