/*
 * (C) Copyright 2000-2004
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 *
 * (C) Copyright 2002
 * Torsten Demke, FORCE Computers GmbH. torsten.demke@fci.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 <mpc824x.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <pci.h>
#include <ide.h>
#include "piix_pci.h"
#include "eXalion.h"

int checkboard (void)
{
	ulong busfreq = get_bus_freq (0);
	char buf[32];

	printf ("Board: eXalion MPC824x - CHRP (MAP B)\n");
	printf ("Built: %s at %s\n", __DATE__, __TIME__);
	printf ("Local Bus:  %s MHz\n", strmhz (buf, busfreq));

	return 0;
}

int checkflash (void)
{
	printf ("checkflash\n");
	flash_init ();
	return (0);
}

phys_size_t initdram (int board_type)
{
	int i, cnt;
	volatile uchar *base = CFG_SDRAM_BASE;
	volatile ulong *addr;
	ulong save[32];
	ulong val, ret = 0;

	for (i = 0, cnt = (CFG_MAX_RAM_SIZE / sizeof (long)) >> 1; cnt > 0;
	     cnt >>= 1) {
		addr = (volatile ulong *) base + cnt;
		save[i++] = *addr;
		*addr = ~cnt;
	}

	addr = (volatile ulong *) base;
	save[i] = *addr;
	*addr = 0;

	if (*addr != 0) {
		*addr = save[i];
		goto Done;
	}

	for (cnt = 1; cnt <= CFG_MAX_RAM_SIZE / sizeof (long); cnt <<= 1) {
		addr = (volatile ulong *) base + cnt;
		val = *addr;
		*addr = save[--i];
		if (val != ~cnt) {
			ulong new_bank0_end = cnt * sizeof (long) - 1;
			ulong mear1 = mpc824x_mpc107_getreg (MEAR1);
			ulong emear1 = mpc824x_mpc107_getreg (EMEAR1);

			mear1 = (mear1 & 0xFFFFFF00) |
				((new_bank0_end & MICR_ADDR_MASK) >>
				 MICR_ADDR_SHIFT);
			emear1 = (emear1 & 0xFFFFFF00) |
				((new_bank0_end & MICR_ADDR_MASK) >>
				 MICR_EADDR_SHIFT);
			mpc824x_mpc107_setreg (MEAR1, mear1);
			mpc824x_mpc107_setreg (EMEAR1, emear1);

			ret = cnt * sizeof (long);
			goto Done;
		}
	}

	ret = CFG_MAX_RAM_SIZE;
      Done:
	return ret;
}

int misc_init_r (void)
{
	pci_dev_t bdf;
	u32 val32;
	u8 val8;

	puts ("ISA:   ");
	bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_ISA_DEV_ID, 0);
	if (bdf == -1) {
		puts ("Unable to find PIIX4 ISA bridge !\n");
		hang ();
	}

	/* set device for normal ISA instead EIO */
	pci_read_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, &val32);
	val32 |= 0x00000001;
	pci_write_config_dword (bdf, PCI_CFG_PIIX4_GENCFG, val32);
	printf ("PIIX4 ISA bridge (%d,%d,%d)\n", PCI_BUS (bdf),
		PCI_DEV (bdf), PCI_FUNC (bdf));

	puts ("ISA:   ");
	bdf = pci_find_device (PIIX4_VENDOR_ID, PIIX4_IDE_DEV_ID, 0);
	if (bdf == -1) {
		puts ("Unable to find PIIX4 IDE controller !\n");
		hang ();
	}

	/* Init BMIBA register  */
	/* pci_read_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, &val32); */
	/* val32 |= 0x1000; */
	/* pci_write_config_dword(bdf, PCI_CFG_PIIX4_BMIBA, val32); */

	/* Enable BUS master and IO access  */
	val32 = PCI_COMMAND_MASTER | PCI_COMMAND_IO;
	pci_write_config_dword (bdf, PCI_COMMAND, val32);

	/* Set latency  */
	pci_read_config_byte (bdf, PCI_LATENCY_TIMER, &val8);
	val8 = 0x40;
	pci_write_config_byte (bdf, PCI_LATENCY_TIMER, val8);

	/* Enable Primary ATA/IDE  */
	pci_read_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, &val32);
	/* val32 = 0xa307a307; */
	val32 = 0x00008000;
	pci_write_config_dword (bdf, PCI_CFG_PIIX4_IDETIM, val32);


	printf ("PIIX4 IDE controller (%d,%d,%d)\n", PCI_BUS (bdf),
		PCI_DEV (bdf), PCI_FUNC (bdf));

	/* Try to get FAT working... */
	/* fat_register_read(ide_read); */


	return (0);
}

/*
 * Show/Init PCI devices on the specified bus number.
 */

void pci_eXalion_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
{
	unsigned char line;

	switch (PCI_DEV (dev)) {
	case 16:
		line = PCI_INT_A;
		break;
	case 17:
		line = PCI_INT_B;
		break;
	case 18:
		line = PCI_INT_C;
		break;
	case 19:
		line = PCI_INT_D;
		break;
#if defined (CONFIG_MPC8245)
	case 20:
		line = PCI_INT_A;
		break;
	case 21:
		line = PCI_INT_B;
		break;
	case 22:
		line = PCI_INT_NA;
		break;
#endif
	default:
		line = PCI_INT_A;
		break;
	}
	pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE, line);
}


/*
 * Initialize PCI Devices, report devices found.
 */
#ifndef CONFIG_PCI_PNP
#if defined (CONFIG_MPC8240)
static struct pci_config_table pci_eXalion_config_table[] = {
	{
	 /* Intel 82559ER ethernet controller */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00,
	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
				     PCI_ENET0_MEMADDR,
				     PCI_COMMAND_MEMORY |
				     PCI_COMMAND_MASTER}},
	{
	 /* Intel 82371AB PIIX4 PCI to ISA bridge */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00,
	 pci_cfgfunc_config_device, {0,
				     0,
				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
	{
	 /* Intel 82371AB PIIX4 IDE controller */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x01,
	 pci_cfgfunc_config_device, {0,
				     0,
				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
	{}
};
#elif defined (CONFIG_MPC8245)
static struct pci_config_table pci_eXalion_config_table[] = {
	{
	 /* Intel 82559ER ethernet controller */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 17, 0x00,
	 pci_cfgfunc_config_device, {PCI_ENET0_IOADDR,
				     PCI_ENET0_MEMADDR,
				     PCI_COMMAND_MEMORY |
				     PCI_COMMAND_MASTER}},
	{
	 /* Intel 82559ER ethernet controller */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 18, 0x00,
	 pci_cfgfunc_config_device, {PCI_ENET1_IOADDR,
				     PCI_ENET1_MEMADDR,
				     PCI_COMMAND_MEMORY |
				     PCI_COMMAND_MASTER}},
	{
	 /* Broadcom BCM5690 Gigabit switch */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 20, 0x00,
	 pci_cfgfunc_config_device, {PCI_ENET2_IOADDR,
				     PCI_ENET2_MEMADDR,
				     PCI_COMMAND_MEMORY |
				     PCI_COMMAND_MASTER}},
	{
	 /* Broadcom BCM5690 Gigabit switch */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 21, 0x00,
	 pci_cfgfunc_config_device, {PCI_ENET3_IOADDR,
				     PCI_ENET3_MEMADDR,
				     PCI_COMMAND_MEMORY |
				     PCI_COMMAND_MASTER}},
	{
	 /* Intel 82371AB PIIX4 PCI to ISA bridge */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x00,
	 pci_cfgfunc_config_device, {0,
				     0,
				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
	{
	 /* Intel 82371AB PIIX4 IDE controller */
	 PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, 0x00, 22, 0x01,
	 pci_cfgfunc_config_device, {0,
				     0,
				     PCI_COMMAND_IO | PCI_COMMAND_MASTER}},
	{}
};
#else
#error Specific type of MPC824x must be defined (i.e. CONFIG_MPC8240)
#endif

#endif /* #ifndef CONFIG_PCI_PNP */

struct pci_controller hose = {
#ifndef CONFIG_PCI_PNP
	config_table:pci_eXalion_config_table,
	fixup_irq:pci_eXalion_fixup_irq,
#endif
};

void pci_init_board (void)
{
	pci_mpc824x_init (&hose);
}
