/*
 * From Coreboot northbridge/intel/sandybridge/northbridge.c
 *
 * Copyright (C) 2007-2009 coresystems GmbH
 * Copyright (C) 2011 The Chromium Authors
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#include <dm.h>
#include <asm/msr.h>
#include <asm/cpu.h>
#include <asm/intel_regs.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/processor.h>
#include <asm/arch/pch.h>
#include <asm/arch/model_206ax.h>
#include <asm/arch/sandybridge.h>

DECLARE_GLOBAL_DATA_PTR;

int bridge_silicon_revision(struct udevice *dev)
{
	struct cpuid_result result;
	u16 bridge_id;
	u8 stepping;

	result = cpuid(1);
	stepping = result.eax & 0xf;
	dm_pci_read_config16(dev, PCI_DEVICE_ID, &bridge_id);
	bridge_id &= 0xf0;
	return bridge_id | stepping;
}

/*
 * Reserve everything between A segment and 1MB:
 *
 * 0xa0000 - 0xbffff: legacy VGA
 * 0xc0000 - 0xcffff: VGA OPROM (needed by kernel)
 * 0xe0000 - 0xfffff: SeaBIOS, if used, otherwise DMI
 */
static const int legacy_hole_base_k = 0xa0000 / 1024;
static const int legacy_hole_size_k = 384;

static int get_pcie_bar(struct udevice *dev, u32 *base, u32 *len)
{
	u32 pciexbar_reg;

	*base = 0;
	*len = 0;

	dm_pci_read_config32(dev, PCIEXBAR, &pciexbar_reg);

	if (!(pciexbar_reg & (1 << 0)))
		return 0;

	switch ((pciexbar_reg >> 1) & 3) {
	case 0: /* 256MB */
		*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
				(1 << 28));
		*len = 256 * 1024 * 1024;
		return 1;
	case 1: /* 128M */
		*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
				(1 << 28) | (1 << 27));
		*len = 128 * 1024 * 1024;
		return 1;
	case 2: /* 64M */
		*base = pciexbar_reg & ((1 << 31) | (1 << 30) | (1 << 29) |
				(1 << 28) | (1 << 27) | (1 << 26));
		*len = 64 * 1024 * 1024;
		return 1;
	}

	return 0;
}

static void add_fixed_resources(struct udevice *dev, int index)
{
	u32 pcie_config_base, pcie_config_size;

	if (get_pcie_bar(dev, &pcie_config_base, &pcie_config_size)) {
		debug("Adding PCIe config bar base=0x%08x size=0x%x\n",
		      pcie_config_base, pcie_config_size);
	}
}

static void northbridge_dmi_init(struct udevice *dev, int rev)
{
	/* Clear error status bits */
	writel(0xffffffff, DMIBAR_REG(0x1c4));
	writel(0xffffffff, DMIBAR_REG(0x1d0));

	/* Steps prior to DMI ASPM */
	if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
		clrsetbits_le32(DMIBAR_REG(0x250), (1 << 22) | (1 << 20),
				1 << 21);
	}

	setbits_le32(DMIBAR_REG(0x238), 1 << 29);

	if (rev >= SNB_STEP_D0) {
		setbits_le32(DMIBAR_REG(0x1f8), 1 << 16);
	} else if (rev >= SNB_STEP_D1) {
		clrsetbits_le32(DMIBAR_REG(0x1f8), 1 << 26, 1 << 16);
		setbits_le32(DMIBAR_REG(0x1fc), (1 << 12) | (1 << 23));
	}

	/* Enable ASPM on SNB link, should happen before PCH link */
	if ((rev & BASE_REV_MASK) == BASE_REV_SNB)
		setbits_le32(DMIBAR_REG(0xd04), 1 << 4);

	setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0));
}

static void northbridge_init(struct udevice *dev, int rev)
{
	u32 bridge_type;

	add_fixed_resources(dev, 6);
	northbridge_dmi_init(dev, rev);

	bridge_type = readl(MCHBAR_REG(0x5f10));
	bridge_type &= ~0xff;

	if ((rev & BASE_REV_MASK) == BASE_REV_IVB) {
		/* Enable Power Aware Interrupt Routing - fixed priority */
		clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4);

		/* 30h for IvyBridge */
		bridge_type |= 0x30;
	} else {
		/* 20h for Sandybridge */
		bridge_type |= 0x20;
	}
	writel(bridge_type, MCHBAR_REG(0x5f10));

	/*
	 * Set bit 0 of BIOS_RESET_CPL to indicate to the CPU
	 * that BIOS has initialized memory and power management
	 */
	setbits_8(MCHBAR_REG(BIOS_RESET_CPL), 1);
	debug("Set BIOS_RESET_CPL\n");

	/* Configure turbo power limits 1ms after reset complete bit */
	mdelay(1);
	set_power_limits(28);

	/*
	 * CPUs with configurable TDP also need power limits set
	 * in MCHBAR.  Use same values from MSR_PKG_POWER_LIMIT.
	 */
	if (cpu_config_tdp_levels()) {
		msr_t msr = msr_read(MSR_PKG_POWER_LIMIT);

		writel(msr.lo, MCHBAR_REG(0x59A0));
		writel(msr.hi, MCHBAR_REG(0x59A4));
	}

	/* Set here before graphics PM init */
	writel(0x00100001, MCHBAR_REG(0x5500));
}

static void sandybridge_setup_northbridge_bars(struct udevice *dev)
{
	/* Set up all hardcoded northbridge BARs */
	debug("Setting up static registers\n");
	dm_pci_write_config32(dev, EPBAR, DEFAULT_EPBAR | 1);
	dm_pci_write_config32(dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
	dm_pci_write_config32(dev, MCHBAR, MCH_BASE_ADDRESS | 1);
	dm_pci_write_config32(dev, MCHBAR + 4, (0LL + MCH_BASE_ADDRESS) >> 32);
	/* 64MB - busses 0-63 */
	dm_pci_write_config32(dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
	dm_pci_write_config32(dev, PCIEXBAR + 4,
			      (0LL + DEFAULT_PCIEXBAR) >> 32);
	dm_pci_write_config32(dev, DMIBAR, DEFAULT_DMIBAR | 1);
	dm_pci_write_config32(dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32);

	/* Set C0000-FFFFF to access RAM on both reads and writes */
	dm_pci_write_config8(dev, PAM0, 0x30);
	dm_pci_write_config8(dev, PAM1, 0x33);
	dm_pci_write_config8(dev, PAM2, 0x33);
	dm_pci_write_config8(dev, PAM3, 0x33);
	dm_pci_write_config8(dev, PAM4, 0x33);
	dm_pci_write_config8(dev, PAM5, 0x33);
	dm_pci_write_config8(dev, PAM6, 0x33);
}

static int bd82x6x_northbridge_early_init(struct udevice *dev)
{
	const int chipset_type = SANDYBRIDGE_MOBILE;
	u32 capid0_a;
	u8 reg8;

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

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

		dm_pci_write_config8(dev, 0xf3, reg8);
	}

	sandybridge_setup_northbridge_bars(dev);

	/* Device Enable */
	dm_pci_write_config32(dev, DEVEN, DEVEN_HOST | DEVEN_IGD);

	return 0;
}

static int bd82x6x_northbridge_probe(struct udevice *dev)
{
	int rev;

	if (!(gd->flags & GD_FLG_RELOC))
		return bd82x6x_northbridge_early_init(dev);

	rev = bridge_silicon_revision(dev);
	northbridge_init(dev, rev);

	return 0;
}

static const struct udevice_id bd82x6x_northbridge_ids[] = {
	{ .compatible = "intel,bd82x6x-northbridge" },
	{ }
};

U_BOOT_DRIVER(bd82x6x_northbridge_drv) = {
	.name		= "bd82x6x_northbridge",
	.id		= UCLASS_NORTHBRIDGE,
	.of_match	= bd82x6x_northbridge_ids,
	.probe		= bd82x6x_northbridge_probe,
};
