/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2006 AMD
 * (Written by Yinghai Lu <yinghailu@amd.com> for AMD)
 * Copyright (C) 2006 MSI
 * (Written by Bingxun Shi <bingxunshi@gmail.com> for MSI)
 * Copyright (C) 2007 Rudolf Marek <r.marek@assembler.cz>
 *
 * 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.
 */

unsigned int get_sbdn(unsigned bus);

#include <stdint.h>
#include <string.h>
#include <device/pci_def.h>
#include <arch/io.h>
#include <device/pnp_def.h>
#include <cpu/x86/lapic.h>
#include <pc80/mc146818rtc.h>
#include <console/console.h>
#include <cpu/amd/model_fxx_rev.h>
#include <halt.h>
#include <northbridge/amd/amdk8/raminit.h>
#include <delay.h>
#include <cpu/x86/lapic.h>
#include "northbridge/amd/amdk8/reset_test.c"
#include "northbridge/amd/amdk8/early_ht.c"
#include <superio/winbond/common/winbond.h>
#include <superio/winbond/w83627ehg/w83627ehg.h>
#include "southbridge/via/vt8237r/early_smbus.c"
#include "northbridge/amd/amdk8/debug.c" /* After vt8237r/early_smbus.c! */
#include <cpu/x86/bist.h>
#include "northbridge/amd/amdk8/setup_resource_map.c"
#include <spd.h>

#define SERIAL_DEV PNP_DEV(0x2e, W83627EHG_SP1)
#define GPIO_DEV PNP_DEV(0x2e, W83627EHG_GPIO_SUSLED_V)
#define ACPI_DEV PNP_DEV(0x2e, W83627EHG_ACPI)

static void memreset(int controllers, const struct mem_controller *ctrl) { }
static void activate_spd_rom(const struct mem_controller *ctrl) { }

static inline int spd_read_byte(unsigned device, unsigned address)
{
	return smbus_read_byte(device, address);
}

#include <reset.h>
void soft_reset(void)
{
	uint8_t tmp;

	set_bios_reset();
	printk(BIOS_DEBUG, "soft reset\n");

	/* PCI reset */
	tmp = pci_read_config8(PCI_DEV(0, 0x11, 0), 0x4f);
	tmp |= 0x01;
	pci_write_config8(PCI_DEV(0, 0x11, 0), 0x4f, tmp);

	halt();
}

#include "southbridge/via/k8t890/early_car.c"
#include <northbridge/amd/amdk8/amdk8.h>
#include "northbridge/amd/amdk8/incoherent_ht.c"
#include "northbridge/amd/amdk8/coherent_ht.c"
#include "northbridge/amd/amdk8/raminit.c"
#include "lib/generic_sdram.c"
#include "cpu/amd/dualcore/dualcore.c"
#include "cpu/amd/model_fxx/init_cpus.c"
#include "cpu/amd/model_fxx/fidvid.c"
#include "northbridge/amd/amdk8/resourcemap.c"

unsigned int get_sbdn(unsigned bus)
{
	device_t dev;

	dev = pci_locate_device_on_bus(PCI_ID(PCI_VENDOR_ID_VIA,
					PCI_DEVICE_ID_VIA_VT8237R_LPC), bus);
	return (dev >> 15) & 0x1f;
}

static void sio_init(void)
{
	u8 reg;

	pnp_enter_ext_func_mode(SERIAL_DEV);
	/* We have 24MHz input. */
	reg = pnp_read_config(SERIAL_DEV, 0x24);
	pnp_write_config(SERIAL_DEV, 0x24, (reg & ~0x40));
	/* We have GPIO for KB/MS pin. */
	reg = pnp_read_config(SERIAL_DEV, 0x2a);
	pnp_write_config(SERIAL_DEV, 0x2a, (reg | 1));
	/* We have all RESTOUT and even some reserved bits, too. */
	reg = pnp_read_config(SERIAL_DEV, 0x2c);
	pnp_write_config(SERIAL_DEV, 0x2c, (reg | 0xf0));
	pnp_exit_ext_func_mode(SERIAL_DEV);

	pnp_enter_ext_func_mode(ACPI_DEV);
	pnp_set_logical_device(ACPI_DEV);
	/*
	 * Set the delay rising time from PWROK_LP to PWROK_ST to
	 * 300 - 600ms, and 0 to vice versa.
	 */
	reg = pnp_read_config(ACPI_DEV, 0xe6);
	pnp_write_config(ACPI_DEV, 0xe6, (reg & 0xf0));
	/* 1 Use external suspend clock source 32.768KHz. Undocumented?? */
	reg = pnp_read_config(ACPI_DEV, 0xe4);
	pnp_write_config(ACPI_DEV, 0xe4, (reg | 0x10));
	pnp_exit_ext_func_mode(ACPI_DEV);

	pnp_enter_ext_func_mode(GPIO_DEV);
	pnp_set_logical_device(GPIO_DEV);
	/* Set memory voltage to 2.75V, vcore offset + 100mV, 1.5V chipset voltage. */
	pnp_write_config(GPIO_DEV, 0x30, 0x09);	/* Enable GPIO 2 & GPIO 5. */
	pnp_write_config(GPIO_DEV, 0xe2, 0x00);	/* No inversion */
	pnp_write_config(GPIO_DEV, 0xe5, 0x00);	/* No inversion */
	pnp_write_config(GPIO_DEV, 0xe3, 0x03);	/* 0000 0011, 0=output 1=input */
	pnp_write_config(GPIO_DEV, 0xe0, 0xde);	/* 1101 1110, 0=output 1=input */
	pnp_write_config(GPIO_DEV, 0xe1, 0x01);	/* Set output val. */
	pnp_write_config(GPIO_DEV, 0xe4, 0xb4);	/* Set output val (1011 0100). */
	pnp_exit_ext_func_mode(GPIO_DEV);
}

void cache_as_ram_main(unsigned long bist, unsigned long cpu_init_detectedx)
{
	static const uint16_t spd_addr[] = {
		// Node 0
		DIMM0, DIMM2, 0, 0,
		DIMM1, DIMM3, 0, 0,
		// Node 1
		DIMM4, DIMM6, 0, 0,
		DIMM5, DIMM7, 0, 0,
	};
	unsigned bsp_apicid = 0;
	int needs_reset = 0;
	struct sys_info *sysinfo = &sysinfo_car;

	sio_init();
	winbond_enable_serial(SERIAL_DEV, CONFIG_TTYS0_BASE);
	console_init();
	enable_rom_decode();

	printk(BIOS_INFO, "now booting... romstage\n");

	/* Is this a CPU only reset? Or is this a secondary CPU? */
	if (!cpu_init_detectedx && boot_cpu()) {
		/* Nothing special needs to be done to find bus 0. */
		/* Allow the HT devices to be found. */
		enumerate_ht_chain();
	}

	printk(BIOS_INFO, "now booting... real_main\n");

	if (bist == 0)
		bsp_apicid = init_cpus(cpu_init_detectedx, sysinfo);

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

	setup_default_resource_map();
	setup_coherent_ht_domain();
	wait_all_core0_started();

	printk(BIOS_INFO, "now booting... Core0 started\n");

#if CONFIG_LOGICAL_CPUS
	/* It is said that we should start core1 after all core0 launched. */
	start_other_cores();
	wait_all_other_cores_started(bsp_apicid);
#endif
	init_timer();
	ht_setup_chains_x(sysinfo); /* Init sblnk and sbbusn, nodes, sbdn. */

	needs_reset = optimize_link_coherent_ht();
	needs_reset |= optimize_link_incoherent_ht(sysinfo);
	needs_reset |= k8t890_early_setup_ht();

	if (needs_reset) {
		printk(BIOS_DEBUG, "ht reset -\n");
		soft_reset();
	}

	/* the HT settings needs to be OK, because link freq chnage may cause HT disconnect */
	enable_fid_change();
	init_fidvid_bsp(bsp_apicid);

	/* Stop the APs so we can start them later in init. */
	allow_all_aps_stop(bsp_apicid);

	/* It's the time to set ctrl now. */
	fill_mem_ctrl(sysinfo->nodes, sysinfo->ctrl, spd_addr);

	enable_smbus();
	sdram_initialize(sysinfo->nodes, sysinfo->ctrl, sysinfo);
	post_cache_as_ram();
}
