/*
 * (C) Copyright 2008-2009
 * Andreas Pfefferle, DENX Software Engineering, ap@denx.de.
 *
 * (C) Copyright 2009
 * Detlev Zundel, DENX Software Engineering, dzu@denx.de.
 *
 * (C) Copyright 2004
 * Mark Jonas, Freescale Semiconductor, mark.jonas@motorola.com.
 *
 * (C) Copyright 2004
 * Martin Krause, TQ-Systems GmbH, martin.krause@tqs.de
 *
 * (C) Copyright 2003-2004
 * Wolfgang Denk, DENX Software Engineering, wd@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 <asm/io.h>
#include <common.h>
#include <mpc5xxx.h>
#include <pci.h>

#if defined(CONFIG_DDR_MT46V16M16)
#include "mt46v16m16-75.h"
#elif defined(CONFIG_SDR_MT48LC16M16A2)
#include "mt48lc16m16a2-75.h"
#elif defined(CONFIG_DDR_MT46V32M16)
#include "mt46v32m16.h"
#elif defined(CONFIG_DDR_HYB25D512160BF)
#include "hyb25d512160bf.h"
#elif defined(CONFIG_DDR_K4H511638C)
#include "k4h511638c.h"
#else
#error "INKA4x0 SDRAM: invalid chip type specified!"
#endif

#ifndef CONFIG_SYS_RAMBOOT
static void sdram_start (int hi_addr)
{
	volatile struct mpc5xxx_sdram *sdram =
		(struct mpc5xxx_sdram *)MPC5XXX_SDRAM;
	long hi_addr_bit = hi_addr ? 0x01000000 : 0;

	/* unlock mode register */
	out_be32(&sdram->ctrl, SDRAM_CONTROL | 0x80000000 | hi_addr_bit);

	/* precharge all banks */
	out_be32(&sdram->ctrl, SDRAM_CONTROL | 0x80000002 | hi_addr_bit);

#if SDRAM_DDR
	/* set mode register: extended mode */
	out_be32(&sdram->mode, SDRAM_EMODE);

	/* set mode register: reset DLL */
	out_be32(&sdram->mode, SDRAM_MODE | 0x04000000);
#endif

	/* precharge all banks */
	out_be32(&sdram->ctrl, SDRAM_CONTROL | 0x80000002 | hi_addr_bit);

	/* auto refresh */
	out_be32(&sdram->ctrl, SDRAM_CONTROL | 0x80000004 | hi_addr_bit);

	/* set mode register */
	out_be32(&sdram->mode, SDRAM_MODE);

	/* normal operation */
	out_be32(&sdram->ctrl, SDRAM_CONTROL | hi_addr_bit);
}
#endif

/*
 * ATTENTION: Although partially referenced initdram does NOT make real use
 *	      use of CONFIG_SYS_SDRAM_BASE. The code does not work if CONFIG_SYS_SDRAM_BASE
 *	      is something else than 0x00000000.
 */

phys_size_t initdram (int board_type)
{
	volatile struct mpc5xxx_mmap_ctl *mm =
		(struct mpc5xxx_mmap_ctl *) CONFIG_SYS_MBAR;
	volatile struct mpc5xxx_cdm     *cdm =
		(struct mpc5xxx_cdm *)      MPC5XXX_CDM;
	volatile struct mpc5xxx_sdram *sdram =
		(struct mpc5xxx_sdram *)    MPC5XXX_SDRAM;
	ulong dramsize = 0;
#ifndef CONFIG_SYS_RAMBOOT
	long test1, test2;

	/* setup SDRAM chip selects */
	out_be32(&mm->sdram0, 0x0000001c);	/* 512MB at 0x0 */
	out_be32(&mm->sdram1, 0x40000000);	/* disabled */

	/* setup config registers */
	out_be32(&sdram->config1, SDRAM_CONFIG1);
	out_be32(&sdram->config2, SDRAM_CONFIG2);

#if SDRAM_DDR
	/* set tap delay */
	out_be32(&cdm->porcfg, SDRAM_TAPDELAY);
#endif

	/* find RAM size using SDRAM CS0 only */
	sdram_start(0);
	test1 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
	sdram_start(1);
	test2 = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE, 0x20000000);
	if (test1 > test2) {
		sdram_start(0);
		dramsize = test1;
	} else {
		dramsize = test2;
	}

	/* memory smaller than 1MB is impossible */
	if (dramsize < (1 << 20)) {
		dramsize = 0;
	}

	/* set SDRAM CS0 size according to the amount of RAM found */
	if (dramsize > 0) {
		out_be32(&mm->sdram0, 0x13 +
			 __builtin_ffs(dramsize >> 20) - 1);
	} else {
		out_be32(&mm->sdram0, 0); /* disabled */
	}

	out_be32(&mm->sdram1, dramsize); /* disabled */
#else /* CONFIG_SYS_RAMBOOT */

	/* retrieve size of memory connected to SDRAM CS0 */
	dramsize = in_be32(&mm->sdram0) & 0xFF;
	if (dramsize >= 0x13) {
		dramsize = (1 << (dramsize - 0x13)) << 20;
	} else {
		dramsize = 0;
	}
#endif /* CONFIG_SYS_RAMBOOT */

	return dramsize;
}

int checkboard (void)
{
	puts ("Board: INKA 4X0\n");
	return 0;
}

void flash_preinit(void)
{
	volatile struct mpc5xxx_lpb *lpb = (struct mpc5xxx_lpb *)MPC5XXX_LPB;

	/*
	 * Now, when we are in RAM, enable flash write
	 * access for detection process.
	 * Note that CS_BOOT (CS0) cannot be cleared when
	 * executing in flash.
	 */
	clrbits_be32(&lpb->cs0_cfg, 0x1); /* clear RO */
}

int misc_init_r (void) {
	extern int inkadiag_init_r (void);

	/*
	 * The command table used for the subcommands of inkadiag
	 * needs to be relocated manually.
	 */
	return inkadiag_init_r();
}

int misc_init_f (void)
{
	volatile struct mpc5xxx_gpio	*gpio    =
		(struct mpc5xxx_gpio *)   MPC5XXX_GPIO;
	volatile struct mpc5xxx_wu_gpio	*wu_gpio =
		(struct mpc5xxx_wu_gpio *)MPC5XXX_WU_GPIO;
	volatile struct mpc5xxx_gpt	*gpt;
	char tmp[10];
	int i, br;

	i = getenv_r("brightness", tmp, sizeof(tmp));
	br = (i > 0)
		? (int) simple_strtoul (tmp, NULL, 10)
		: CONFIG_SYS_BRIGHTNESS;
	if (br > 255)
		br = 255;

	/* Initialize GPIO output pins.
	 */
	/* Configure GPT as GPIO output (and set them as they control low-active LEDs */
	for (i = 0; i <= 5; i++) {
		gpt = (struct mpc5xxx_gpt *)(MPC5XXX_GPT + (i * 0x10));
		out_be32(&gpt->emsr, 0x34);
	}

	/* Configure GPT7 as PWM timer, 1kHz, no ints. */
	gpt = (struct mpc5xxx_gpt *)(MPC5XXX_GPT + (7 * 0x10));
	out_be32(&gpt->emsr,  0);		/* Disable */
	out_be32(&gpt->cir,   0x020000fe);
	out_be32(&gpt->pwmcr, (br << 16));
	out_be32(&gpt->emsr,  0x3);		/* Enable PWM mode and start */

	/* Configure PSC3_6,7 as GPIO output */
	setbits_be32(&gpio->simple_gpioe, MPC5XXX_GPIO_SIMPLE_PSC3_6 |
					  MPC5XXX_GPIO_SIMPLE_PSC3_7);
	setbits_be32(&gpio->simple_ddr,   MPC5XXX_GPIO_SIMPLE_PSC3_6 |
					  MPC5XXX_GPIO_SIMPLE_PSC3_7);

	/* Configure PSC3_9 and GPIO_WKUP6,7 as GPIO output */
	setbits_8(&wu_gpio->enable,  MPC5XXX_GPIO_WKUP_6 |
				     MPC5XXX_GPIO_WKUP_7 |
				     MPC5XXX_GPIO_WKUP_PSC3_9);
	setbits_8(&wu_gpio->ddr,     MPC5XXX_GPIO_WKUP_6 |
				     MPC5XXX_GPIO_WKUP_7 |
				     MPC5XXX_GPIO_WKUP_PSC3_9);

	/* Set LR mirror bit because it is low-active */
	setbits_8(&wu_gpio->dvo,     MPC5XXX_GPIO_WKUP_7);

	/* Reset Coral-P graphics controller */
	setbits_8(&wu_gpio->dvo,     MPC5XXX_GPIO_WKUP_PSC3_9);

	/* Enable display backlight */
	clrbits_8(&gpio->sint_inten, MPC5XXX_GPIO_SINT_PSC3_8);
	setbits_8(&gpio->sint_gpioe, MPC5XXX_GPIO_SINT_PSC3_8);
	setbits_8(&gpio->sint_ddr,   MPC5XXX_GPIO_SINT_PSC3_8);
	setbits_8(&gpio->sint_dvo,   MPC5XXX_GPIO_SINT_PSC3_8);

	/*
	 * Configure three wire serial interface to RTC (PSC1_4,
	 * PSC2_4, PSC3_4, PSC3_5)
	 */
	setbits_8(&wu_gpio->enable,  MPC5XXX_GPIO_WKUP_PSC1_4 |
				     MPC5XXX_GPIO_WKUP_PSC2_4);
	setbits_8(&wu_gpio->ddr,     MPC5XXX_GPIO_WKUP_PSC1_4 |
				     MPC5XXX_GPIO_WKUP_PSC2_4);
	clrbits_8(&wu_gpio->dvo,     MPC5XXX_GPIO_WKUP_PSC1_4);
	clrbits_8(&gpio->sint_inten, MPC5XXX_GPIO_SINT_PSC3_4 |
				     MPC5XXX_GPIO_SINT_PSC3_5);
	setbits_8(&gpio->sint_gpioe, MPC5XXX_GPIO_SINT_PSC3_4 |
				     MPC5XXX_GPIO_SINT_PSC3_5);
	setbits_8(&gpio->sint_ddr,   MPC5XXX_GPIO_SINT_PSC3_5);
	clrbits_8(&gpio->sint_dvo,   MPC5XXX_GPIO_SINT_PSC3_5);

	return 0;
}

#ifdef	CONFIG_PCI
static struct pci_controller hose;

extern void pci_mpc5xxx_init(struct pci_controller *);

void pci_init_board(void)
{
	pci_mpc5xxx_init(&hose);
}
#endif
