/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2007-2010 coresystems GmbH
 * Copyright (C) 2011 Google Inc
 * Copyright (C) 2013 Vladimir Serbinenko
 *
 * 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.
 */

#include <stdint.h>
#include <stdlib.h>
#include <console/console.h>
#include <arch/io.h>
#include <device/pci_def.h>
#include <elog.h>
#include <cpu/x86/msr.h>
#include <cpu/intel/speedstep.h>
#include <cpu/intel/turbo.h>
#include <arch/cpu.h>

#include "nehalem.h"

static void nehalem_setup_bars(void)
{
	/* Setting up Southbridge. In the northbridge code. */
	printk(BIOS_DEBUG, "Setting up static southbridge registers...");
	pci_write_config32(PCI_DEV(0, 0x1f, 0), RCBA, (uintptr_t)DEFAULT_RCBA | 1);

	pci_write_config32(PCI_DEV(0, 0x1f, 0), PMBASE, DEFAULT_PMBASE | 1);
	/* Enable ACPI BAR */
	pci_write_config8(PCI_DEV(0, 0x1f, 0), 0x44 /* ACPI_CNTL */ , 0x80);

	printk(BIOS_DEBUG, " done.\n");

	printk(BIOS_DEBUG, "Disabling Watchdog reboot...");
	/* No reset */
	RCBA32(GCS) = RCBA32(GCS) | (1 << 5);
	/* halt timer */
	outw((1 << 11), DEFAULT_PMBASE | 0x60 | 0x08);
	/* halt timer */
	outw(inw(DEFAULT_PMBASE | 0x60 | 0x06) | 2,
	     DEFAULT_PMBASE | 0x60 | 0x06);
	printk(BIOS_DEBUG, " done.\n");

	printk(BIOS_DEBUG, "Setting up static northbridge registers...");
	/* Set up all hardcoded northbridge BARs */
	pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR, DEFAULT_EPBAR | 1);
	pci_write_config32(PCI_DEV(0, 0x00, 0), EPBAR + 4,
			   (0LL + DEFAULT_EPBAR) >> 32);
	pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR, (uintptr_t)DEFAULT_MCHBAR | 1);
	pci_write_config32(PCI_DEV(0, 0x00, 0), MCHBAR + 4,
			   (0LL + (uintptr_t)DEFAULT_MCHBAR) >> 32);

	pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR, (uintptr_t)DEFAULT_DMIBAR | 1);
	pci_write_config32(PCI_DEV(0, 0x00, 0), DMIBAR + 4,
			   (0LL + (uintptr_t)DEFAULT_DMIBAR) >> 32);

	/* Set C0000-FFFFF to access RAM on both reads and writes */
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(0), 0x30);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(1), 0x33);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(2), 0x33);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(3), 0x33);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(4), 0x33);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(5), 0x33);
	pci_write_config8(PCI_DEV(0xff, 0x00, 1), QPD0F1_PAM(6), 0x33);

#if IS_ENABLED(CONFIG_ELOG_BOOT_COUNT)
	/* Increment Boot Counter for non-S3 resume */
	if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
	    ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) != SLP_TYP_S3)
		boot_count_increment();
#endif

	printk(BIOS_DEBUG, " done.\n");

#if IS_ENABLED(CONFIG_ELOG_BOOT_COUNT)
	/* Increment Boot Counter except when resuming from S3 */
	if ((inw(DEFAULT_PMBASE + PM1_STS) & WAK_STS) &&
	    ((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3)
		return;
	boot_count_increment();
#endif
}

static void early_cpu_init (void)
{
	msr_t m;

	/* bit 0 = disable multicore,
	   bit 1 = disable quadcore,
	   bit 8 = disable hyperthreading.  */
	pci_write_config32(PCI_DEV(0xff, 0x00, 0), 0x80,
			   (pci_read_config32(PCI_DEV(0xff, 0x0, 0x0), 0x80) & 0xfffffefc) | 0x10000);

	u8 reg8;
	struct cpuid_result result;
	result = cpuid_ext(0x6, 0x8b);
	if (!(result.eax & 0x2)) {
		m = rdmsr(MSR_FSB_CLOCK_VCC);
		reg8 = ((m.lo & 0xff00) >> 8) + 1;
		m = rdmsr (IA32_PERF_CTL);
		m.lo = (m.lo & ~0xff) | reg8;
		wrmsr(IA32_PERF_CTL, m);

		m = rdmsr(IA32_MISC_ENABLE);
		m.hi &= ~0x00000040;
		m.lo |= 0x10000;

		wrmsr(IA32_MISC_ENABLE, m);
	}

	m = rdmsr(MSR_FSB_CLOCK_VCC);
	reg8 = ((m.lo & 0xff00) >> 8) + 1;

	m = rdmsr (IA32_PERF_CTL);
	m.lo = (m.lo & ~0xff) | reg8;
	wrmsr(IA32_PERF_CTL, m);

	m = rdmsr(IA32_MISC_ENABLE);
	m.lo |= 0x10000;
	wrmsr(IA32_MISC_ENABLE, m);
}

void nehalem_early_initialization(int chipset_type)
{
	u32 capid0_a;
	u8 reg8;

	/* Device ID Override Enable should be done very early */
	capid0_a = pci_read_config32(PCI_DEV(0, 0, 0), 0xe4);
	if (capid0_a & (1 << 10)) {
		reg8 = pci_read_config8(PCI_DEV(0, 0, 0), 0xf3);
		reg8 &= ~7;	/* Clear 2:0 */

		if (chipset_type == NEHALEM_MOBILE)
			reg8 |= 1;	/* Set bit 0 */

		pci_write_config8(PCI_DEV(0, 0, 0), 0xf3, reg8);
	}

	/* Setup all BARs required for early PCIe and raminit */
	nehalem_setup_bars();

	/* Device Enable */
	pci_write_config32(PCI_DEV(0, 0, 0), D0F0_DEVEN,
			   DEVEN_IGD | DEVEN_PEG10 | DEVEN_HOST);

	early_cpu_init();

	pci_write_config32(PCI_DEV(0, 0x16, 0), 0x10, (uintptr_t)DEFAULT_HECIBAR);
	pci_write_config32(PCI_DEV(0, 0x16, 0), PCI_COMMAND,
			   PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY);

	/* Magic for S3 resume. Must be done early.  */
	if (((inl(DEFAULT_PMBASE + PM1_CNT) >> 10) & 7) == SLP_TYP_S3) {
		MCHBAR32 (0x1e8) = (MCHBAR32(0x1e8) & ~1) | 6;
		MCHBAR32 (0x1e8) = (MCHBAR32(0x1e8) & ~3) | 4;
	}
}
