/*
 * (C) Copyright 2007-2008
 * 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=3 */
			printf("Bootstrapping for 667MHz\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 */

		/* PMM1 Mask/Attribute - disabled b4 setting */
		out32r(PCIX0_PMM1MA, 0x00000000);
		/* PMM1 Local Address */
		out32r(PCIX0_PMM1LA, 0xc0000000);
		/* PMM1 PCI Low Address */
		out32r(PCIX0_PMM1PCILA, pciaddr);
		/* PMM1 PCI High Address */
		out32r(PCIX0_PMM1PCIHA, 0x00000000);
		/* 256MB + No prefetching, and enable region */
		out32r(PCIX0_PMM1MA, 0xf0000001);
	} 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 */
