/*
 * GNU General Public License for more details.
 *
 * MATRIX Vision GmbH / June 2002-Nov 2003
 * Andre Schwarz
 */

#include <common.h>
#include <mpc824x.h>
#include <asm/io.h>
#include <ns16550.h>
#include <netdev.h>

#ifdef CONFIG_PCI
#include <pci.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

u32 get_BoardType (void);

#define PCI_CONFIG(b,d,f,r)    cpu_to_le32(0x80000000 | ((b&0xff)<<16) \
						      | ((d&0x1f)<<11) \
						      | ((f&0x7)<<7)   \
						      | (r&0xfc) )

int mv_pci_read (int bus, int dev, int func, int reg)
{
	*(u32 *) (0xfec00cf8) = PCI_CONFIG (bus, dev, func, reg);
	asm ("sync");
	return cpu_to_le32 (*(u32 *) (0xfee00cfc));
}

u32 get_BoardType ()
{
	return (mv_pci_read (0, 0xe, 0, 0) == 0x06801095 ? 0 : 1);
}

void init_2nd_DUART (void)
{
	NS16550_t console = (NS16550_t) CONFIG_SYS_NS16550_COM2;
	int clock_divisor = CONFIG_SYS_NS16550_CLK / 16 / CONFIG_BAUDRATE;

	*(u8 *) (0xfc004511) = 0x1;
	NS16550_init (console, clock_divisor);
}
void hw_watchdog_reset (void)
{
	if (get_BoardType () == 0) {
		*(u32 *) (0xff000005) = 0;
		asm ("sync");
	}
}
int checkboard (void)
{
	ulong busfreq = get_bus_freq (0);
	char buf[32];
	u32 BoardType = get_BoardType ();
	char *BoardName[2] = { "mvBlueBOX", "mvBlueLYNX" };
	char *p;

	hw_watchdog_reset ();

	printf ("U-Boot (%s) running on mvBLUE device.\n", MV_VERSION);
	printf ("       Found %s running at %s MHz memory clock.\n",
		BoardName[BoardType], strmhz (buf, busfreq));

	init_2nd_DUART ();

	if ((p = getenv ("console_nr")) != NULL) {
		unsigned long con_nr = simple_strtoul (p, NULL, 10) & 3;

		gd->baudrate &= ~3;
		gd->baudrate |= con_nr & 3;
	}
	return 0;
}

phys_size_t initdram (int board_type)
{
	long size;
	long new_bank0_end;
	long mear1;
	long emear1;

	size = get_ram_size(CONFIG_SYS_SDRAM_BASE, CONFIG_SYS_MAX_RAM_SIZE);

	new_bank0_end = size - 1;
	mear1 = mpc824x_mpc107_getreg(MEAR1);
	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);

	return (size);
}

/* ------------------------------------------------------------------------- */
u8 *dhcp_vendorex_prep (u8 * e)
{
	char *ptr;

	/* DHCP vendor-class-identifier = 60 */
	if ((ptr = getenv ("dhcp_vendor-class-identifier"))) {
		*e++ = 60;
		*e++ = strlen (ptr);
		while (*ptr)
			*e++ = *ptr++;
	}
	/* my DHCP_CLIENT_IDENTIFIER = 61 */
	if ((ptr = getenv ("dhcp_client_id"))) {
		*e++ = 61;
		*e++ = strlen (ptr);
		while (*ptr)
			*e++ = *ptr++;
	}
	return e;
}

u8 *dhcp_vendorex_proc (u8 * popt)
{
	return NULL;
}

/* ------------------------------------------------------------------------- */

/*
 * Initialize PCI Devices
 */
#ifdef CONFIG_PCI
void pci_mvblue_clear_base (struct pci_controller *hose, pci_dev_t dev)
{
	u32 cnt;

	printf ("clear base @ dev/func 0x%02x/0x%02x ... ", PCI_DEV (dev),
		PCI_FUNC (dev));
	for (cnt = 0; cnt < 6; cnt++)
		pci_hose_write_config_dword (hose, dev, 0x10 + (4 * cnt),
					     0x0);
	printf ("done\n");
}

void duart_setup (u32 base, u16 divisor)
{
	printf ("duart setup ...");
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 3), 0x80);
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 0), divisor & 0xff);
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 1), divisor >> 8);
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 3), 0x03);
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 4), 0x03);
	out_8 ((u8 *) (CONFIG_SYS_ISA_IO + base + 2), 0x07);
	printf ("done\n");
}

void pci_mvblue_fixup_irq_behind_bridge (struct pci_controller *hose,
					 pci_dev_t bridge, unsigned char irq)
{
	pci_dev_t d;
	unsigned char bus;
	unsigned short vendor, class;

	pci_hose_read_config_byte (hose, bridge, PCI_SECONDARY_BUS, &bus);
	for (d = PCI_BDF (bus, 0, 0);
	     d < PCI_BDF (bus, PCI_MAX_PCI_DEVICES - 1,
			  PCI_MAX_PCI_FUNCTIONS - 1);
	     d += PCI_BDF (0, 0, 1)) {
		pci_hose_read_config_word (hose, d, PCI_VENDOR_ID, &vendor);
		if (vendor != 0xffff && vendor != 0x0000) {
			pci_hose_read_config_word (hose, d, PCI_CLASS_DEVICE,
						   &class);
			if (class == PCI_CLASS_BRIDGE_PCI)
				pci_mvblue_fixup_irq_behind_bridge (hose, d,
								    irq);
			else
				pci_hose_write_config_byte (hose, d,
							    PCI_INTERRUPT_LINE,
							    irq);
		}
	}
}

#define MV_MAX_PCI_BUSSES	3
#define SLOT0_IRQ	3
#define SLOT1_IRQ	4
void pci_mvblue_fixup_irq (struct pci_controller *hose, pci_dev_t dev)
{
	unsigned char line = 0xff;
	unsigned short class;

	if (PCI_BUS (dev) == 0) {
		switch (PCI_DEV (dev)) {
		case 0xd:
			if (get_BoardType () == 0) {
				line = 1;
			} else
				/* mvBL */
				line = 2;
			break;
		case 0xe:
			/* mvBB: IDE */
			line = 2;
			pci_hose_write_config_byte (hose, dev, 0x8a, 0x20);
			break;
		case 0xf:
			/* mvBB: Slot0 (Grabber) */
			pci_hose_read_config_word (hose, dev,
						   PCI_CLASS_DEVICE, &class);
			if (class == PCI_CLASS_BRIDGE_PCI) {
				pci_mvblue_fixup_irq_behind_bridge (hose, dev,
								    SLOT0_IRQ);
				line = 0xff;
			} else
				line = SLOT0_IRQ;
			break;
		case 0x10:
			/* mvBB: Slot1 */
			pci_hose_read_config_word (hose, dev,
						   PCI_CLASS_DEVICE, &class);
			if (class == PCI_CLASS_BRIDGE_PCI) {
				pci_mvblue_fixup_irq_behind_bridge (hose, dev,
								    SLOT1_IRQ);
				line = 0xff;
			} else
				line = SLOT1_IRQ;
			break;
		default:
			printf ("***pci_scan: illegal dev = 0x%08x\n",
				PCI_DEV (dev));
			line = 0xff;
			break;
		}
		pci_hose_write_config_byte (hose, dev, PCI_INTERRUPT_LINE,
					    line);
	}
}

struct pci_controller hose = {
	fixup_irq:pci_mvblue_fixup_irq
};

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

int board_eth_init(bd_t *bis)
{
	return pci_eth_init(bis);
}
#endif
