/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2007-2009 coresystems GmbH
 * Copyright (C) 2011 Sven Schnelle <svens@stackframe.org>
 *
 * 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; version 2 of
 * the License.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston,
 * MA 02110-1301 USA
 */

#include <stdint.h>
#include <string.h>
#include <arch/io.h>
#include <device/pci_def.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <lib.h>
#include <console/console.h>
#include <cpu/x86/bist.h>
#include <superio/winbond/w83627hf/early_serial.c>
#include <northbridge/intel/i5000/raminit.h>
#include "northbridge/intel/i3100/i3100.h"
#include "southbridge/intel/i3100/i3100.h"
#include <southbridge/intel/i3100/early_smbus.c>

#define DEVPRES_CONFIG  (DEVPRES_D1F0 | DEVPRES_D2F0 | DEVPRES_D3F0)
#define DEVPRES1_CONFIG (DEVPRES1_D0F1 | DEVPRES1_D8F0)

#define RCBA_RPC   0x0224 /* 32 bit */
#define RCBA_HPTC  0x3404 /* 32 bit */
#define RCBA_GCS   0x3410 /* 32 bit */
#define RCBA_FD    0x3418 /* 32 bit */

static void early_config(void)
{
	u32 gcs, rpc, fd;

	/* Enable RCBA */
	pci_write_config32(PCI_DEV(0, 0x1F, 0), RCBA, DEFAULT_RCBA | 1);

	/* Disable watchdog */
	gcs = read32(DEFAULT_RCBA + RCBA_GCS);
	gcs |= (1 << 5); /* No reset */
	write32(DEFAULT_RCBA + RCBA_GCS, gcs);

	/* Configure PCIe port B as 4x */
	rpc = read32(DEFAULT_RCBA + RCBA_RPC);
	rpc |= (3 << 0);
	write32(DEFAULT_RCBA + RCBA_RPC, rpc);

	/* Disable Modem, Audio, PCIe ports 2/3/4 */
	fd = read32(DEFAULT_RCBA + RCBA_FD);
	fd |= (1 << 19) | (1 << 18) | (1 << 17) | (1 << 6) | (1 << 5);
	write32(DEFAULT_RCBA + RCBA_FD, fd);

	/* Enable HPET */
	write32(DEFAULT_RCBA + RCBA_HPTC, (1 << 7));

	/* Setup sata mode */
	pci_write_config8(PCI_DEV(0, 0x1F, 2), SATA_MAP, 0x40);
}

#define DEFAULT_GPIOBASE 0x1180
static void setup_gpio(void)
{
	pci_write_config32(PCI_DEV(0, 31, 0), 0x48, DEFAULT_GPIOBASE | 1);
	pci_write_config8(PCI_DEV(0, 31, 0), 0x4c, (1 << 4));

        outl(0x1b0ce7c0, DEFAULT_GPIOBASE + 0x00); /* GPIO_USE_SEL */
        outl(0xec00ffff, DEFAULT_GPIOBASE + 0x04); /* GP_IO_SEL */
        outl(0xff350000, DEFAULT_GPIOBASE + 0x0c); /* GP_LVL */
        outl(0x0000e742, DEFAULT_GPIOBASE + 0x2c); /* GPI_INV */
        outl(0x00000006, DEFAULT_GPIOBASE + 0x30); /* GPIO_USE_SEL2 */
        outl(0x00000300, DEFAULT_GPIOBASE + 0x34); /* GP_IO_SEL2 */
        outl(0x00030301, DEFAULT_GPIOBASE + 0x38); /* GPIO_LVL2 */

}

static void i5000_lpc_config(void)
{
	pci_write_config16(PCI_DEV(0, 0x1f, 0), 0x82, 0x3f0f);
}

int mainboard_set_fbd_clock(int speed)
{
	switch(speed) {
		case 533:
			smbus_write_byte(0x6f, 0x80, 0x21);
			return 0;
		case 667:
			smbus_write_byte(0x6f, 0x80, 0x23);
			return 0;
		default:
			printk(BIOS_ERR, "Invalid clock: %dMHz\n", speed);
			die("");
			return -1;
	}
}

void main(unsigned long bist)
{
	if (bist == 0)
		enable_lapic();

	i5000_lpc_config();

	w83627hf_enable_serial(PNP_DEV(0x2e, 2), 0x3f8);

	console_init();

	/* Halt if there was a built in self test failure */
	report_bist_failure(bist);

	early_config();

	setup_gpio();

	enable_smbus();

	/* setup PCIe MMCONF base address */
	pci_write_config32(PCI_DEV(0, 16, 0), 0x64,
			   CONFIG_MMCONF_BASE_ADDRESS >> 16);

        smbus_write_byte(0x6f, 0x00, 0x63);
        smbus_write_byte(0x6f, 0x01, 0x04);
        smbus_write_byte(0x6f, 0x02, 0x53);
        smbus_write_byte(0x6f, 0x03, 0x39);
        smbus_write_byte(0x6f, 0x08, 0x06);
        smbus_write_byte(0x6f, 0x09, 0x00);

	pci_write_config32(PCI_DEV(0, 0x1f, 0), 0xf0, DEFAULT_RCBA | 1);
	i5000_fbdimm_init();
	smbus_write_byte(0x69, 0x01, 0x01);
}
