/*
 * (C) Copyright 2007
 * Matthias Fuchs, esd Gmbh, matthias.fuchs@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 <command.h>
#include <asm/io.h>
#include <asm/cache.h>
#include <asm/processor.h>

#include "pmc440.h"

int is_monarch(void);
int bootstrap_eeprom_write(unsigned dev_addr, unsigned offset, uchar *buffer, unsigned cnt);
int eeprom_write_enable(unsigned dev_addr, int state);

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_CMD_BSP)

static int got_fifoirq;
static int got_hcirq;

int fpga_interrupt(u32 arg)
{
	pmc440_fpga_t *fpga = (pmc440_fpga_t *)arg;
	int rc = -1; /* not for us */
	u32 status = FPGA_IN32(&fpga->status);

	/* check for interrupt from fifo module */
	if (status & STATUS_FIFO_ISF) {
		/* disable this int source */
		FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_FIFOIE_GATE);
		rc = 0;
		got_fifoirq = 1; /* trigger backend */
	}

	if (status & STATUS_HOST_ISF) {
		FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_HCINT_GATE);
		rc = 0;
		got_hcirq = 1;
	}

	return rc;
}


int do_waithci(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;

	got_hcirq = 0;

	FPGA_CLRBITS(&fpga->ctrla, CTRL_HOST_IE);
	FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_HCINT_GATE);

	irq_install_handler(IRQ0_FPGA,
			    (interrupt_handler_t *)fpga_interrupt,
			    fpga);

	FPGA_SETBITS(&fpga->ctrla, CTRL_HOST_IE);

	while (!got_hcirq) {
		/* Abort if ctrl-c was pressed */
		if (ctrlc()) {
			puts("\nAbort\n");
			break;
		}
	}
	if (got_hcirq)
		printf("Got interrupt!\n");

	FPGA_CLRBITS(&fpga->ctrla, CTRL_HOST_IE);
	irq_free_handler(IRQ0_FPGA);
	return 0;
}
U_BOOT_CMD(
	waithci,	1,	1,	do_waithci,
	"waithci - Wait for host control interrupt\n",
	NULL
	);


void dump_fifo(pmc440_fpga_t *fpga, int f, int *n)
{
	u32 ctrl;

	while (!((ctrl = FPGA_IN32(&fpga->fifo[f].ctrl)) & FIFO_EMPTY)) {
		printf("%5d  %d    %3d  %08x",
		       (*n)++, f, ctrl & (FIFO_LEVEL_MASK | FIFO_FULL),
		       FPGA_IN32(&fpga->fifo[f].data));
		if (ctrl & FIFO_OVERFLOW) {
			printf(" OVERFLOW\n");
			FPGA_CLRBITS(&fpga->fifo[f].ctrl, FIFO_OVERFLOW);
		} else
			printf("\n");
	}
}


int do_fifo(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;
	int i;
	int n = 0;
	u32 ctrl, data, f;
	char str[] = "\\|/-";
	int abort = 0;
	int count = 0;
	int count2 = 0;

	switch (argc) {
	case 1:
		/* print all fifos status information */
		printf("fifo level status\n");
		printf("______________________________\n");
		for (i=0; i<FIFO_COUNT; i++) {
			ctrl = FPGA_IN32(&fpga->fifo[i].ctrl);
			printf(" %d    %3d  %s%s%s %s\n",
			       i, ctrl & (FIFO_LEVEL_MASK | FIFO_FULL),
			       ctrl & FIFO_FULL ? "FULL     " : "",
			       ctrl & FIFO_EMPTY ? "EMPTY    " : "",
			       ctrl & (FIFO_FULL|FIFO_EMPTY) ? "" : "NOT EMPTY",
			       ctrl & FIFO_OVERFLOW ? "OVERFLOW" : "");
		}
		break;

	case 2:
		/* completely read out fifo 'n' */
		if (!strcmp(argv[1],"read")) {
			printf("  #   fifo level data\n");
			printf("______________________________\n");

			for (i=0; i<FIFO_COUNT; i++)
				dump_fifo(fpga, i, &n);

		} else if (!strcmp(argv[1],"wait")) {
			got_fifoirq = 0;

			irq_install_handler(IRQ0_FPGA,
					    (interrupt_handler_t *)fpga_interrupt,
					    fpga);

			printf("  #   fifo level data\n");
			printf("______________________________\n");

			/* enable all fifo interrupts */
			FPGA_OUT32(&fpga->hostctrl,
				   HOSTCTRL_FIFOIE_GATE | HOSTCTRL_FIFOIE_FLAG);
			for (i=0; i<FIFO_COUNT; i++) {
				/* enable interrupts from all fifos */
				FPGA_SETBITS(&fpga->fifo[i].ctrl, FIFO_IE);
			}

			while (1) {
				/* wait loop */
				while (!got_fifoirq) {
					count++;
					if (!(count % 100)) {
						count2++;
						putc(0x08); /* backspace */
						putc(str[count2 % 4]);
					}

					/* Abort if ctrl-c was pressed */
					if ((abort = ctrlc())) {
						puts("\nAbort\n");
						break;
					}
					udelay(1000);
				}
				if (abort)
					break;

				/* simple fifo backend */
				if (got_fifoirq) {
					for (i=0; i<FIFO_COUNT; i++)
						dump_fifo(fpga, i, &n);

					got_fifoirq = 0;
					/* unmask global fifo irq */
					FPGA_OUT32(&fpga->hostctrl,
						   HOSTCTRL_FIFOIE_GATE | HOSTCTRL_FIFOIE_FLAG);
				}
			}

			/* disable all fifo interrupts */
			FPGA_OUT32(&fpga->hostctrl, HOSTCTRL_FIFOIE_GATE);
			for (i=0; i<FIFO_COUNT; i++)
				FPGA_CLRBITS(&fpga->fifo[i].ctrl, FIFO_IE);

			irq_free_handler(IRQ0_FPGA);

		} else {
			printf("Usage:\nfifo %s\n", cmdtp->help);
			return 1;
		}
		break;

	case 4:
	case 5:
		if (!strcmp(argv[1],"write")) {
			/* get fifo number or fifo address */
			f = simple_strtoul(argv[2], NULL, 16);

			/* data paramter */
			data = simple_strtoul(argv[3], NULL, 16);

			/* get optional count parameter */
			n = 1;
			if (argc >= 5)
				n = (int)simple_strtoul(argv[4], NULL, 10);

			if (f < FIFO_COUNT) {
				printf("writing %d x %08x to fifo %d\n",
				       n, data, f);
				for (i=0; i<n; i++)
					FPGA_OUT32(&fpga->fifo[f].data, data);
			} else {
				printf("writing %d x %08x to fifo port at address %08x\n",
				       n, data, f);
				for (i=0; i<n; i++)
					out32(f, data);
			}
		} else {
			printf("Usage:\nfifo %s\n", cmdtp->help);
			return 1;
		}
		break;

	default:
		printf("Usage:\nfifo %s\n", cmdtp->help);
		return 1;
	}
	return 0;
}
U_BOOT_CMD(
	fifo,	5,	1,	do_fifo,
	"fifo    - Fifo module operations\n",
	"wait\nfifo read\n"
	"fifo write fifo(0..3) data [cnt=1]\n"
	"fifo write address(>=4) data [cnt=1]\n"
	"  - without arguments: print all fifo's status\n"
	"  - with 'wait' argument: interrupt driven read from all fifos\n"
	"  - with 'read' argument: read current contents from all fifos\n"
	"  - with 'write' argument: write 'data' 'cnt' times to 'fifo' or 'address'\n"
	);


int do_setup_bootstrap_eeprom(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong sdsdp[5];
	ulong delay;
	int count=16;

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

	if (argc > 1) {
		if (!strcmp(argv[1], "400")) {
			/* PLB=133MHz, PLB/PCI=3 */
			printf("Bootstrapping for 400MHz\n");
			sdsdp[0]=0x8678624e;
			sdsdp[1]=0x095fa030;
			sdsdp[2]=0x40082350;
			sdsdp[3]=0x0d050000;
		} else if (!strcmp(argv[1], "533")) {
			/* PLB=133MHz, PLB/PCI=3 */
			printf("Bootstrapping for 533MHz\n");
			sdsdp[0]=0x87788252;
			sdsdp[1]=0x095fa030;
			sdsdp[2]=0x40082350;
			sdsdp[3]=0x0d050000;
		} else if (!strcmp(argv[1], "667")) {
			/* PLB=133MHz, PLB/PCI=4 */
			printf("Bootstrapping for 667MHz\n");
			sdsdp[0]=0x8778a256;
			sdsdp[1]=0x0947a030;
			sdsdp[2]=0x40082350;
			sdsdp[3]=0x0d050000;
		} else if (!strcmp(argv[1], "test")) {
			/* TODO: this will replace the 667 MHz config above.
			 * But it needs some more testing on a real 667 MHz CPU.
			 */
			printf("Bootstrapping for test (667MHz PLB=133PLB PLB/PCI=3)\n");
			sdsdp[0]=0x8778a256;
			sdsdp[1]=0x095fa030;
			sdsdp[2]=0x40082350;
			sdsdp[3]=0x0d050000;
		} else {
			printf("Usage:\nsbe %s\n", cmdtp->help);
			return -1;
		}
	}

	if (argc > 2) {
		sdsdp[4] = 0;
		if (argv[2][0]=='1')
			sdsdp[4]=0x19750100;
		else if (argv[2][0]=='0')
			sdsdp[4]=0x19750000;
		if (sdsdp[4])
			count += 4;
	}

	if (argc > 3) {
		delay = simple_strtoul(argv[3], NULL, 10);
		if (delay > 20)
			delay = 20;
		sdsdp[4] |= delay;
	}

	printf("Writing boot EEPROM ...\n");
	if (bootstrap_eeprom_write(CFG_I2C_BOOT_EEPROM_ADDR,
				   0, (uchar*)sdsdp, count) != 0)
		printf("bootstrap_eeprom_write failed\n");
	else
		printf("done (dump via 'i2c md 52 0.1 14')\n");

	return 0;
}
U_BOOT_CMD(
	sbe, 4, 0, do_setup_bootstrap_eeprom,
	"sbe     - setup bootstrap eeprom\n",
	"<cpufreq:400|533|667> [<console-uart:0|1> [<bringup delay (0..20s)>]]"
	);


#if defined(CONFIG_PRAM)
#include <environment.h>
extern env_t *env_ptr;

int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	u32 memsize;
	u32 pram, env_base;
	char *v;
	u32 param;
	ulong *lptr;

	memsize = gd->bd->bi_memsize;

	v = getenv("pram");
	if (v)
		pram = simple_strtoul(v, NULL, 10);
	else {
		printf("Error: pram undefined. Please define pram in KiB\n");
		return 1;
	}

	param = memsize - (pram << 10);
	printf("PARAM: @%08x\n", param);

	memset((void*)param, 0, (pram << 10));
	env_base = memsize - 4096 - ((CFG_ENV_SIZE + 4096) & ~(4096-1));
	memcpy((void*)env_base, env_ptr, CFG_ENV_SIZE);

	lptr = (ulong*)memsize;
	*(--lptr) = CFG_ENV_SIZE;
	*(--lptr) = memsize - env_base;
	*(--lptr) = crc32(0, (void*)(memsize - 0x08), 0x08);
	*(--lptr) = 0;

	/* make sure data can be accessed through PCI */
	flush_dcache_range(param, param + (pram << 10) - 1);
	return 0;
}
U_BOOT_CMD(
	painit,	1,	1,	do_painit,
	"painit  - prepare PciAccess system\n",
	NULL
	);
#endif /* CONFIG_PRAM */


int do_selfreset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	if (argc > 1) {
		if (argv[1][0] == '0') {
			/* assert */
			printf("self-reset# asserted\n");
			out_be32((void*)GPIO0_TCR,
				 in_be32((void*)GPIO0_TCR) | GPIO0_SELF_RST);
		} else {
			/* deassert */
			printf("self-reset# deasserted\n");
			out_be32((void*)GPIO0_TCR,
				 in_be32((void*)GPIO0_TCR) & ~GPIO0_SELF_RST);
		}
	} else {
		printf("self-reset# is %s\n",
		       in_be32((void*)GPIO0_TCR) & GPIO0_SELF_RST ?
		       "active" : "inactive");
	}

	return 0;
}
U_BOOT_CMD(
	selfreset,	2,	1,	do_selfreset,
	"selfreset- assert self-reset# signal\n",
	NULL
	);


int do_resetout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	pmc440_fpga_t *fpga = (pmc440_fpga_t *)FPGA_BA;

	/* requiers bootet FPGA and PLD_IOEN_N active */
	if (in_be32((void*)GPIO1_OR) & GPIO1_IOEN_N) {
		printf("Error: resetout requires a bootet FPGA\n");
		return -1;
	}

	if (argc > 1) {
		if (argv[1][0] == '0') {
			/* assert */
			printf("PMC-RESETOUT# asserted\n");
			FPGA_OUT32(&fpga->hostctrl,
				   HOSTCTRL_PMCRSTOUT_GATE);
		} else {
			/* deassert */
			printf("PMC-RESETOUT# deasserted\n");
			FPGA_OUT32(&fpga->hostctrl,
				   HOSTCTRL_PMCRSTOUT_GATE | HOSTCTRL_PMCRSTOUT_FLAG);
		}
	} else {
		printf("PMC-RESETOUT# is %s\n",
		       FPGA_IN32(&fpga->hostctrl) & HOSTCTRL_PMCRSTOUT_FLAG ?
		       "inactive" : "active");
	}

	return 0;
}
U_BOOT_CMD(
	resetout,	2,	1,	do_resetout,
	"resetout - assert PMC-RESETOUT# signal\n",
	NULL
	);


int do_inta(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	if (is_monarch()) {
		printf("This command is only supported in non-monarch mode\n");
		return -1;
	}

	if (argc > 1) {
		if (argv[1][0] == '0') {
			/* assert */
			printf("inta# asserted\n");
			out_be32((void*)GPIO1_TCR,
				 in_be32((void*)GPIO1_TCR) | GPIO1_INTA_FAKE);
		} else {
			/* deassert */
			printf("inta# deasserted\n");
			out_be32((void*)GPIO1_TCR,
				 in_be32((void*)GPIO1_TCR) & ~GPIO1_INTA_FAKE);
		}
	} else {
		printf("inta# is %s\n", in_be32((void*)GPIO1_TCR) & GPIO1_INTA_FAKE ? "active" : "inactive");
	}
	return 0;
}
U_BOOT_CMD(
	inta,	2,	1,	do_inta,
	"inta    - Assert/Deassert or query INTA# state in non-monarch mode\n",
	NULL
	);


/* test-only */
int do_pmm(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	ulong pciaddr;

	if (argc > 1) {
		pciaddr = simple_strtoul(argv[1], NULL, 16);

		pciaddr &= 0xf0000000;

		/* map PCI address at 0xc0000000 in PLB space */
		out32r(PCIX0_PMM1MA, 0x00000000); /* PMM1 Mask/Attribute - disabled b4 setting */
		out32r(PCIX0_PMM1LA, 0xc0000000); /* PMM1 Local Address */
		out32r(PCIX0_PMM1PCILA, pciaddr); /* PMM1 PCI Low Address */
		out32r(PCIX0_PMM1PCIHA, 0x00000000); /* PMM1 PCI High Address */
		out32r(PCIX0_PMM1MA, 0xf0000001); /* 256MB + No prefetching, and enable region */
	} else {
		printf("Usage:\npmm %s\n", cmdtp->help);
	}
	return 0;
}
U_BOOT_CMD(
	pmm,	2,	1,	do_pmm,
	"pmm     - Setup pmm[1] registers\n",
	"<pciaddr> (pciaddr will be aligned to 256MB)\n"
	);

#if defined(CFG_EEPROM_WREN)
int do_eep_wren(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	int query = argc == 1;
	int state = 0;

	if (query) {
		/* Query write access state. */
		state = eeprom_write_enable(CFG_I2C_EEPROM_ADDR, -1);
		if (state < 0) {
			puts("Query of write access state failed.\n");
		} else {
			printf("Write access for device 0x%0x is %sabled.\n",
			       CFG_I2C_EEPROM_ADDR, state ? "en" : "dis");
			state = 0;
		}
	} else {
		if ('0' == argv[1][0]) {
			/* Disable write access. */
			state = eeprom_write_enable(CFG_I2C_EEPROM_ADDR, 0);
		} else {
			/* Enable write access. */
			state = eeprom_write_enable(CFG_I2C_EEPROM_ADDR, 1);
		}
		if (state < 0) {
			puts("Setup of write access state failed.\n");
		}
	}

	return state;
}
U_BOOT_CMD(eepwren, 2, 0, do_eep_wren,
	   "eepwren - Enable / disable / query EEPROM write access\n",
	   NULL);
#endif /* #if defined(CFG_EEPROM_WREN) */

#endif /* CONFIG_CMD_BSP */
