/*
 * (C) Copyright 2009
 * Matthias Fuchs, esd gmbh germany, matthias.fuchs@esd.eu
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */

#include <common.h>
#include <libfdt.h>
#include <fdt_support.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/ppc4xx-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(UIC0SR, 0xFFFFFFFF);       /* clear all ints */
	mtdcr(UIC0ER, 0x00000000);       /* disable all ints */
	mtdcr(UIC0CR, 0x00000000);       /* set all to be non-critical*/
	mtdcr(UIC0PR, 0xFFFFFF80);       /* set int polarities */
	mtdcr(UIC0TR, 0x10000000);       /* set int trigger levels */
	mtdcr(UIC0VCR, 0x00000001);      /* set vect base=0, INT0 highest prio */
	mtdcr(UIC0SR, 0xFFFFFFFF);       /* clear all ints */

	/*
	 * EBC Configuration Register:
	 * - set ready timeout to 512 ebc-clks -> ca. 15 us
	 * - EBC lines are always driven
	 */
	mtebc(EBC0_CFG, 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)
int 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));
		}
	}

	return 0;
}
#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 * const 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>

int do_painit(cmd_tbl_t *cmdtp, int flag, int argc, char * const 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", (u32)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 * const 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 * const 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",
	""
);
