/*
 * 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;
	bd_t *bd = gd->bd;

	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;

		bd->bi_baudrate &= ~3;
		bd->bi_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
