/*
 * (C) Copyright 2009
 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd.eu
 *
 * 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 <libfdt.h>
#include <fdt_support.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/4xx_pci.h>
#include <command.h>
#include <malloc.h>

/*
 * PMC405-DE cpld registers
 * - all registers are 8 bit
 * - all registers are on 32 bit addesses
 */
struct pmc405de_cpld {
	/* cpld design version */
	u8 version;
	u8 reserved0[3];

	/* misc. status lines */
	u8 status;
	u8 reserved1[3];

	/*
	 * gated control flags
	 * gate bit(s) must be written with '1' to
	 * access control flag
	 */
	u8 control;
	u8 reserved2[3];
};

#define CPLD_VERSION_MASK		0x0f
#define CPLD_CONTROL_POSTLED_N		0x01
#define CPLD_CONTROL_POSTLED_GATE	0x02
#define CPLD_CONTROL_RESETOUT_N		0x40
#define CPLD_CONTROL_RESETOUT_N_GATE	0x80

DECLARE_GLOBAL_DATA_PTR;

extern void __ft_board_setup(void *blob, bd_t *bd);
extern void pll_write(u32 a, u32 b);

static int wait_for_pci_ready_done;

static int is_monarch(void);
static int pci_is_66mhz(void);
static int board_revision(void);
static int cpld_revision(void);
static void upd_plb_pci_div(u32 pllmr0, u32 pllmr1, u32 div);

int board_early_init_f(void)
{
	u32 pllmr0, pllmr1;

	/*
	 * check M66EN and patch PLB:PCI divider for 66MHz PCI
	 *
	 * fCPU==333MHz && fPCI==66MHz (PLBDiv==3 && M66EN==1): PLB/PCI=1
	 * fCPU==333MHz && fPCI==33MHz (PLBDiv==3 && M66EN==0): PLB/PCI=2
	 * fCPU==133|266MHz && fPCI==66MHz (PLBDiv==1|2 && M66EN==1): PLB/PCI=2
	 * fCPU==133|266MHz && fPCI==33MHz (PLBDiv==1|2 && M66EN==0): PLB/PCI=3
	 *
	 * calling upd_plb_pci_div() may end in calling pll_write() which will
	 * do a chip reset and never return.
	 */
	pllmr0 = mfdcr(CPC0_PLLMR0);
	pllmr1 = mfdcr(CPC0_PLLMR1);

	if ((pllmr0 & PLLMR0_CPU_TO_PLB_MASK) == PLLMR0_CPU_PLB_DIV_3) {
		/* fCPU=333MHz, fPLB=111MHz */
		if (pci_is_66mhz())
			upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_1);
		else
			upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_2);
	} else {
		/* fCPU=133|266MHz, fPLB=133MHz */
		if (pci_is_66mhz())
			upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_2);
		else
			upd_plb_pci_div(pllmr0, pllmr1, PLLMR0_PCI_PLB_DIV_3);
	}

	/*
	 * IRQ 25 (EXT IRQ 0) PCI-INTA#; active low; level sensitive
	 * IRQ 26 (EXT IRQ 1) PCI-INTB#; active low; level sensitive
	 * IRQ 27 (EXT IRQ 2) PCI-INTC#; active low; level sensitive
	 * IRQ 28 (EXT IRQ 3) PCI-INTD#; active low; level sensitive
	 * IRQ 29 (EXT IRQ 4) ETH0-PHY-IRQ#; active low; level sensitive
	 * IRQ 30 (EXT IRQ 5) ETH1-PHY-IRQ#; active low; level sensitive
	 * IRQ 31 (EXT IRQ 6) PLD-IRQ#; active low; 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, 0xFFFFFF80);       /* set int polarities */
	mtdcr(uictr, 0x10000000);       /* set int trigger levels */
	mtdcr(uicvcr, 0x00000001);      /* set vect base=0, INT0 highest prio */
	mtdcr(uicsr, 0xFFFFFFFF);       /* clear all ints */

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

	return 0;
}

static void upd_plb_pci_div(u32 pllmr0, u32 pllmr1, u32 div)
{
	if ((pllmr0 & PLLMR0_PCI_TO_PLB_MASK) != div)
		pll_write((pllmr0 & ~PLLMR0_PCI_TO_PLB_MASK) | div, pllmr1);
}

int misc_init_r(void)
{
	int i;
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	struct pmc405de_cpld *cpld =
		(struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE;

	if (!is_monarch()) {
		/* PCI configuration done: release EREADY */
		setbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EREADY);
		setbits_be32(&gpio0->tcr, CONFIG_SYS_GPIO_EREADY);
	}

	/* turn off POST LED */
	out_8(&cpld->control,
	      CPLD_CONTROL_POSTLED_N | CPLD_CONTROL_POSTLED_GATE);

	/* turn on LEDs: RUN, A, B */
	clrbits_be32(&gpio0->or,
		     CONFIG_SYS_GPIO_LEDRUN_N |
		     CONFIG_SYS_GPIO_LEDA_N |
		     CONFIG_SYS_GPIO_LEDB_N);

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

	/* turn off LEDs: A, B */
	setbits_be32(&gpio0->or,
		     CONFIG_SYS_GPIO_LEDA_N |
		     CONFIG_SYS_GPIO_LEDB_N);

	return (0);
}

static int is_monarch(void)
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	return (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_MONARCH_N) == 0;
}

static int pci_is_66mhz(void)
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	return (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_M66EN);
}

static int board_revision(void)
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	return ((in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_HWREV_MASK) >>
		CONFIG_SYS_GPIO_HWREV_SHIFT);
}

static int cpld_revision(void)
{
	struct pmc405de_cpld *cpld =
		(struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE;
	return ((in_8(&cpld->version) & CPLD_VERSION_MASK));
}

/*
 * Check Board Identity
 */
int checkboard(void)
{
	puts("Board: esd GmbH - PMC-CPU/405-DE");

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

	if (!is_monarch())
		puts("non-");

	printf("monarch, PCI=%s MHz, PLD-Rev 1.%d\n",
	       pci_is_66mhz() ? "66" : "33", cpld_revision());

	return 0;
}


static void wait_for_pci_ready(void)
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	int i;
	char *s = getenv("pcidelay");

	/* only wait once */
	if (wait_for_pci_ready_done)
		return;

	/*
	 * We have our own handling of the pcidelay variable.
	 * Using CONFIG_PCI_BOOTDELAY enables pausing for host
	 * and adapter devices. For adapter devices we do not
	 * want this.
	 */
	if (s) {
		int ms = simple_strtoul(s, NULL, 10);
		printf("PCI:   Waiting for %d ms\n", ms);
		for (i=0; i<ms; i++)
			udelay(1000);
	}

	if (!(in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_EREADY)) {
		printf("PCI:   Waiting for EREADY (CTRL-C to skip) ... ");
		while (1) {
			if (ctrlc()) {
				puts("abort\n");
				break;
			}
			if (in_be32(&gpio0->ir) & CONFIG_SYS_GPIO_EREADY) {
				printf("done\n");
				break;
			}
		}
	}

	wait_for_pci_ready_done = 1;
}

/*
 * Overwrite weak is_pci_host()
 *
 * This routine is called to determine if a pci scan should be
 * performed. With various hardware environments (especially cPCI and
 * PPMC) it's insufficient to depend on the state of the arbiter enable
 * bit in the strap register, or generic host/adapter assumptions.
 *
 * Return 0 for adapter mode, non-zero for host (monarch) mode.
 */
int is_pci_host(struct pci_controller *hose)
{
	char *s;

	if (!is_monarch()) {
		/*
		 * Overwrite PCI identification when running in
		 * non-monarch mode
		 * This should be moved into pci_target_init()
		 * when it is sometimes available for 405 CPUs
		 */
		pci_write_config_word(PCIDEVID_405GP,
				      PCI_SUBSYSTEM_ID,
				      CONFIG_SYS_PCI_SUBSYS_ID_NONMONARCH);
		pci_write_config_word(PCIDEVID_405GP,
				      PCI_CLASS_SUB_CODE,
				      CONFIG_SYS_PCI_CLASSCODE_NONMONARCH);
	}

	s = getenv("pciscan");
	if (s == NULL) {
		if (is_monarch()) {
			wait_for_pci_ready();
			return 1;
		} else {
			return 0;
		}
	} else {
		if (!strcmp(s, "yes"))
			return 1;
	}

	return 0;
}

/*
 * Overwrite weak pci_pre_init()
 *
 * The default implementation enables the 405EP
 * internal PCI arbiter. We do not want that
 * on a PMC module.
 */
int pci_pre_init(struct pci_controller *hose)
{
	return 1;
}

#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP)
void ft_board_setup(void *blob, bd_t *bd)
{
	int rc;

	__ft_board_setup(blob, bd);

	/*
	 * Disable PCI in non-monarch mode.
	 */
	if (!is_monarch()) {
		rc = fdt_find_and_setprop(blob, "/plb/pci@ec000000", "status",
					  "disabled", sizeof("disabled"), 1);
		if (rc) {
			printf("Unable to update property status in PCI node, "
			       "err=%s\n",
			       fdt_strerror(rc));
		}
	}
}
#endif /* defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) */

#if defined(CONFIG_SYS_EEPROM_WREN)
/* Input: <dev_addr>  I2C address of EEPROM device to enable.
 *         <state>     -1: deliver current state
 *                      0: disable write
 *                      1: enable write
 * Returns:            -1: wrong device address
 *                      0: dis-/en- able done
 *                    0/1: current state if <state> was -1.
 */
int eeprom_write_enable(unsigned dev_addr, int state)
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;

	if (CONFIG_SYS_I2C_EEPROM_ADDR != dev_addr) {
		return -1;
	} else {
		switch (state) {
		case 1:
			/* Enable write access, clear bit GPIO0. */
			clrbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EEPROM_WP);
			state = 0;
			break;
		case 0:
			/* Disable write access, set bit GPIO0. */
			setbits_be32(&gpio0->or, CONFIG_SYS_GPIO_EEPROM_WP);
			state = 0;
			break;
		default:
			/* Read current status back. */
			state = (0 == (in_be32(&gpio0->or) &
				       CONFIG_SYS_GPIO_EEPROM_WP));
			break;
		}
	}
	return state;
}

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(CONFIG_SYS_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",
				CONFIG_SYS_I2C_EEPROM_ADDR,
				state ? "en" : "dis");
			state = 0;
		}
	} else {
		if ('0' == argv[1][0]) {
			/* Disable write access. */
			state = eeprom_write_enable(
				CONFIG_SYS_I2C_EEPROM_ADDR, 0);
		} else {
			/* Enable write access. */
			state = eeprom_write_enable(
				CONFIG_SYS_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,
	"Enable / disable / query EEPROM write access",
	""
);
#endif /* #if defined(CONFIG_SYS_EEPROM_WREN) */

#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 pram, nextbase, base;
	char *v;
	u32 param;
	ulong *lptr;

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

	base = gd->bd->bi_memsize;
#if defined(CONFIG_LOGBUFFER)
	base -= LOGBUFF_LEN + LOGBUFF_OVERHEAD;
#endif
	/*
	 * gd->bd->bi_memsize == physical ram size - CONFIG_SYS_MM_TOP_HIDE
	 */
	param = base - (pram << 10);
	printf("PARAM: @%08x\n", param);
	debug("memsize=0x%08x, base=0x%08x\n", gd->bd->bi_memsize, base);

	/* clear entire PA ram */
	memset((void*)param, 0, (pram << 10));

	/* reserve 4k for pointer field */
	nextbase = base - 4096;
	lptr = (ulong*)(base);

	/*
	 * *(--lptr) = item_size;
	 * *(--lptr) = base - item_base = distance from field top;
	 */

	/* env is first (4k aligned) */
	nextbase -= ((CONFIG_ENV_SIZE + 4096 - 1) & ~(4096 - 1));
	memcpy((void*)nextbase, env_ptr, CONFIG_ENV_SIZE);
	*(--lptr) = CONFIG_ENV_SIZE;     /* size */
	*(--lptr) = base - nextbase;  /* offset | type=0 */

	/* free section */
	*(--lptr) = nextbase - param; /* size */
	*(--lptr) = (base - param) | 126; /* offset | type=126 */

	/* terminate pointer field */
	*(--lptr) = crc32(0, (void*)(base - 0x10), 0x10);
	*(--lptr) = 0;                /* offset=0 -> terminator */
	return 0;
}
U_BOOT_CMD(
	painit,	1,	1,	do_painit,
	"prepare PciAccess system",
	""
);
#endif /* CONFIG_PRAM */

int do_selfreset(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct ppc4xx_gpio *gpio0 = (struct ppc4xx_gpio *)GPIO_BASE;
	setbits_be32(&gpio0->tcr, CONFIG_SYS_GPIO_SELFRST_N);
	return 0;
}
U_BOOT_CMD(
	selfreset,	1,	1,	do_selfreset,
	"assert self-reset# signal",
	""
);

int do_resetout(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
{
	struct pmc405de_cpld *cpld =
		(struct pmc405de_cpld *)CONFIG_SYS_CPLD_BASE;

	if (argc > 1) {
		if (argv[1][0] == '0') {
			/* assert */
			printf("PMC-RESETOUT# asserted\n");
			out_8(&cpld->control,
			      CPLD_CONTROL_RESETOUT_N_GATE);
		} else {
			/* deassert */
			printf("PMC-RESETOUT# deasserted\n");
			out_8(&cpld->control,
			      CPLD_CONTROL_RESETOUT_N |
			      CPLD_CONTROL_RESETOUT_N_GATE);
		}
	} else {
		printf("PMC-RESETOUT# is %s\n",
		       (in_8(&cpld->control) & CPLD_CONTROL_RESETOUT_N) ?
		       "inactive" : "active");
	}
	return 0;
}
U_BOOT_CMD(
	resetout,	2,	1,	do_resetout,
	"assert PMC-RESETOUT# signal",
	""
);
