summaryrefslogtreecommitdiff
path: root/arch/x86/cpu/ivybridge
diff options
context:
space:
mode:
Diffstat (limited to 'arch/x86/cpu/ivybridge')
-rw-r--r--arch/x86/cpu/ivybridge/Makefile5
-rw-r--r--arch/x86/cpu/ivybridge/bd82x6x.c256
-rw-r--r--arch/x86/cpu/ivybridge/cpu.c146
-rw-r--r--arch/x86/cpu/ivybridge/early_init.c147
-rw-r--r--arch/x86/cpu/ivybridge/early_me.c70
-rw-r--r--arch/x86/cpu/ivybridge/gma.c114
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c295
-rw-r--r--arch/x86/cpu/ivybridge/model_206ax.c126
-rw-r--r--arch/x86/cpu/ivybridge/northbridge.c126
-rw-r--r--arch/x86/cpu/ivybridge/pch.c123
-rw-r--r--arch/x86/cpu/ivybridge/pci.c67
-rw-r--r--arch/x86/cpu/ivybridge/report_platform.c11
-rw-r--r--arch/x86/cpu/ivybridge/sata.c132
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c64
-rw-r--r--arch/x86/cpu/ivybridge/usb_ehci.c29
-rw-r--r--arch/x86/cpu/ivybridge/usb_xhci.c32
16 files changed, 792 insertions, 951 deletions
diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile
index 0c7efae..45ef141 100644
--- a/arch/x86/cpu/ivybridge/Makefile
+++ b/arch/x86/cpu/ivybridge/Makefile
@@ -7,7 +7,6 @@
obj-y += bd82x6x.o
obj-y += car.o
obj-y += cpu.o
-obj-y += early_init.o
obj-y += early_me.o
obj-y += gma.o
obj-y += lpc.o
@@ -15,10 +14,6 @@ obj-y += me_status.o
obj-y += model_206ax.o
obj-y += microcode_intel.o
obj-y += northbridge.o
-obj-y += pch.o
-obj-y += pci.o
obj-y += report_platform.o
obj-y += sata.o
obj-y += sdram.o
-obj-y += usb_ehci.o
-obj-y += usb_xhci.o
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 434dfd6..2b172d4 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -3,12 +3,15 @@
*
* SPDX-License-Identifier: GPL-2.0+
*/
-
#include <common.h>
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
+#include <pch.h>
+#include <syscon.h>
+#include <asm/cpu.h>
+#include <asm/io.h>
#include <asm/lapic.h>
#include <asm/pci.h>
#include <asm/arch/bd82x6x.h>
@@ -16,106 +19,198 @@
#include <asm/arch/pch.h>
#include <asm/arch/sandybridge.h>
-void bd82x6x_pci_init(pci_dev_t dev)
+#define BIOS_CTRL 0xdc
+
+static int pch_revision_id = -1;
+static int pch_type = -1;
+
+/**
+ * pch_silicon_revision() - Read silicon revision ID from the PCH
+ *
+ * @dev: PCH device
+ * @return silicon revision ID
+ */
+static int pch_silicon_revision(struct udevice *dev)
{
- u16 reg16;
- u8 reg8;
-
- debug("bd82x6x PCI init.\n");
- /* Enable Bus Master */
- reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
- reg16 |= PCI_COMMAND_MASTER;
- x86_pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /* This device has no interrupt */
- x86_pci_write_config8(dev, INTR, 0xff);
-
- /* disable parity error response and SERR */
- reg16 = x86_pci_read_config16(dev, BCTRL);
- reg16 &= ~(1 << 0);
- reg16 &= ~(1 << 1);
- x86_pci_write_config16(dev, BCTRL, reg16);
-
- /* Master Latency Count must be set to 0x04! */
- reg8 = x86_pci_read_config8(dev, SMLT);
- reg8 &= 0x07;
- reg8 |= (0x04 << 3);
- x86_pci_write_config8(dev, SMLT, reg8);
-
- /* Will this improve throughput of bus masters? */
- x86_pci_write_config8(dev, PCI_MIN_GNT, 0x06);
-
- /* Clear errors in status registers */
- reg16 = x86_pci_read_config16(dev, PSTS);
- /* reg16 |= 0xf900; */
- x86_pci_write_config16(dev, PSTS, reg16);
-
- reg16 = x86_pci_read_config16(dev, SECSTS);
- /* reg16 |= 0xf900; */
- x86_pci_write_config16(dev, SECSTS, reg16);
+ u8 val;
+
+ if (pch_revision_id < 0) {
+ dm_pci_read_config8(dev, PCI_REVISION_ID, &val);
+ pch_revision_id = val;
+ }
+
+ return pch_revision_id;
}
-static int bd82x6x_probe(struct udevice *dev)
+int pch_silicon_type(struct udevice *dev)
{
- const void *blob = gd->fdt_blob;
- struct pci_controller *hose;
- struct x86_cpu_priv *cpu;
- int sata_node, gma_node;
- int ret;
+ u8 val;
- hose = pci_bus_to_hose(0);
- lpc_enable(PCH_LPC_DEV);
- lpc_init(hose, PCH_LPC_DEV);
- sata_node = fdtdec_next_compatible(blob, 0,
- COMPAT_INTEL_PANTHERPOINT_AHCI);
- if (sata_node < 0) {
- debug("%s: Cannot find SATA node\n", __func__);
- return -EINVAL;
+ if (pch_type < 0) {
+ dm_pci_read_config8(dev, PCI_DEVICE_ID + 1, &val);
+ pch_type = val;
}
- bd82x6x_sata_init(PCH_SATA_DEV, blob, sata_node);
- bd82x6x_usb_ehci_init(PCH_EHCI1_DEV);
- bd82x6x_usb_ehci_init(PCH_EHCI2_DEV);
-
- cpu = calloc(1, sizeof(*cpu));
- if (!cpu)
- return -ENOMEM;
- model_206ax_init(cpu);
-
- gma_node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_GMA);
- if (gma_node < 0) {
- debug("%s: Cannot find GMA node\n", __func__);
- return -EINVAL;
+
+ return pch_type;
+}
+
+/**
+ * pch_silicon_supported() - Check if a certain revision is supported
+ *
+ * @dev: PCH device
+ * @type: PCH type
+ * @rev: Minimum required resion
+ * @return 0 if not supported, 1 if supported
+ */
+static int pch_silicon_supported(struct udevice *dev, int type, int rev)
+{
+ int cur_type = pch_silicon_type(dev);
+ int cur_rev = pch_silicon_revision(dev);
+
+ switch (type) {
+ case PCH_TYPE_CPT:
+ /* CougarPoint minimum revision */
+ if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
+ return 1;
+ /* PantherPoint any revision */
+ if (cur_type == PCH_TYPE_PPT)
+ return 1;
+ break;
+
+ case PCH_TYPE_PPT:
+ /* PantherPoint minimum revision */
+ if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
+ return 1;
+ break;
+ }
+
+ return 0;
+}
+
+#define IOBP_RETRY 1000
+static inline int iobp_poll(void)
+{
+ unsigned try = IOBP_RETRY;
+ u32 data;
+
+ while (try--) {
+ data = readl(RCB_REG(IOBPS));
+ if ((data & 1) == 0)
+ return 1;
+ udelay(10);
}
- ret = dm_pci_bus_find_bdf(PCH_VIDEO_DEV, &dev);
+
+ printf("IOBP timeout\n");
+ return 0;
+}
+
+void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue,
+ u32 orvalue)
+{
+ u32 data;
+
+ /* Set the address */
+ writel(address, RCB_REG(IOBPIRI));
+
+ /* READ OPCODE */
+ if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0))
+ writel(IOBPS_RW_BX, RCB_REG(IOBPS));
+ else
+ writel(IOBPS_READ_AX, RCB_REG(IOBPS));
+ if (!iobp_poll())
+ return;
+
+ /* Read IOBP data */
+ data = readl(RCB_REG(IOBPD));
+ if (!iobp_poll())
+ return;
+
+ /* Check for successful transaction */
+ if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) {
+ printf("IOBP read 0x%08x failed\n", address);
+ return;
+ }
+
+ /* Update the data */
+ data &= andvalue;
+ data |= orvalue;
+
+ /* WRITE OPCODE */
+ if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0))
+ writel(IOBPS_RW_BX, RCB_REG(IOBPS));
+ else
+ writel(IOBPS_WRITE_AX, RCB_REG(IOBPS));
+ if (!iobp_poll())
+ return;
+
+ /* Write IOBP data */
+ writel(data, RCB_REG(IOBPD));
+ if (!iobp_poll())
+ return;
+}
+
+static int bd82x6x_probe(struct udevice *dev)
+{
+ struct udevice *gma_dev;
+ int ret;
+
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+
+ /* Cause the SATA device to do its init */
+ uclass_first_device(UCLASS_DISK, &dev);
+
+ ret = syscon_get_by_driver_data(X86_SYSCON_GMA, &gma_dev);
if (ret)
return ret;
- ret = gma_func0_init(dev, blob, gma_node);
+ ret = gma_func0_init(gma_dev);
if (ret)
return ret;
return 0;
}
-int bd82x6x_init(void)
+static int bd82x6x_pch_get_sbase(struct udevice *dev, ulong *sbasep)
{
- const void *blob = gd->fdt_blob;
- int sata_node;
-
- sata_node = fdtdec_next_compatible(blob, 0,
- COMPAT_INTEL_PANTHERPOINT_AHCI);
- if (sata_node < 0) {
- debug("%s: Cannot find SATA node\n", __func__);
- return -EINVAL;
- }
+ u32 rcba;
+
+ dm_pci_read_config32(dev, PCH_RCBA, &rcba);
+ /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */
+ rcba = rcba & 0xffffc000;
+ *sbasep = rcba + 0x3800;
+
+ return 0;
+}
+
+static enum pch_version bd82x6x_pch_get_version(struct udevice *dev)
+{
+ return PCHV_9;
+}
- bd82x6x_pci_init(PCH_DEV);
- bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
- northbridge_enable(PCH_DEV);
- northbridge_init(PCH_DEV);
+static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect)
+{
+ uint8_t bios_cntl;
+
+ /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */
+ dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl);
+ if (protect) {
+ bios_cntl &= ~BIOS_CTRL_BIOSWE;
+ bios_cntl |= BIT(5);
+ } else {
+ bios_cntl |= BIOS_CTRL_BIOSWE;
+ bios_cntl &= ~BIT(5);
+ }
+ dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl);
return 0;
}
+static const struct pch_ops bd82x6x_pch_ops = {
+ .get_sbase = bd82x6x_pch_get_sbase,
+ .get_version = bd82x6x_pch_get_version,
+ .set_spi_protect = bd82x6x_set_spi_protect,
+};
+
static const struct udevice_id bd82x6x_ids[] = {
{ .compatible = "intel,bd82x6x" },
{ }
@@ -126,4 +221,5 @@ U_BOOT_DRIVER(bd82x6x_drv) = {
.id = UCLASS_PCH,
.of_match = bd82x6x_ids,
.probe = bd82x6x_probe,
+ .ops = &bd82x6x_pch_ops,
};
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index 343bfb4..948833c 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -15,6 +15,7 @@
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
+#include <pch.h>
#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/lapic.h>
@@ -30,26 +31,6 @@
DECLARE_GLOBAL_DATA_PTR;
-static void enable_port80_on_lpc(struct pci_controller *hose, pci_dev_t dev)
-{
- /* Enable port 80 POST on LPC */
- pci_hose_write_config_dword(hose, dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
- clrbits_le32(RCB_REG(GCS), 4);
-}
-
-/*
- * Enable Prefetching and Caching.
- */
-static void enable_spi_prefetch(struct pci_controller *hose, pci_dev_t dev)
-{
- u8 reg8;
-
- pci_hose_read_config_byte(hose, dev, 0xdc, &reg8);
- reg8 &= ~(3 << 2);
- reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
- pci_hose_write_config_byte(hose, dev, 0xdc, reg8);
-}
-
static int set_flex_ratio_to_tdp_nominal(void)
{
msr_t flex_ratio, msr;
@@ -99,22 +80,6 @@ static int set_flex_ratio_to_tdp_nominal(void)
return -EINVAL;
}
-static void set_spi_speed(void)
-{
- u32 fdod;
-
- /* Observe SPI Descriptor Component Section 0 */
- writel(0x1000, RCB_REG(SPI_DESC_COMP0));
-
- /* Extract the1 Write/Erase SPI Frequency from descriptor */
- fdod = readl(RCB_REG(SPI_FREQ_WR_ERA));
- fdod >>= 24;
- fdod &= 7;
-
- /* Set Software Sequence frequency to match */
- clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod);
-}
-
int arch_cpu_init(void)
{
post_code(POST_CPU_INIT);
@@ -124,10 +89,8 @@ int arch_cpu_init(void)
int arch_cpu_init_dm(void)
{
- const void *blob = gd->fdt_blob;
struct pci_controller *hose;
- struct udevice *bus;
- int node;
+ struct udevice *bus, *dev;
int ret;
post_code(0x70);
@@ -141,19 +104,9 @@ int arch_cpu_init_dm(void)
/* TODO(sjg@chromium.org): Get rid of gd->hose */
gd->hose = hose;
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
- if (node < 0)
- return -ENOENT;
- ret = lpc_early_init(gd->fdt_blob, node, PCH_LPC_DEV);
- if (ret)
- return ret;
-
- enable_spi_prefetch(hose, PCH_LPC_DEV);
-
- /* This is already done in start.S, but let's do it in C */
- enable_port80_on_lpc(hose, PCH_LPC_DEV);
-
- set_spi_speed();
+ ret = uclass_first_device(UCLASS_LPC, &dev);
+ if (!dev)
+ return -ENODEV;
/*
* We should do as little as possible before the serial console is
@@ -167,41 +120,6 @@ int arch_cpu_init_dm(void)
return 0;
}
-static int enable_smbus(void)
-{
- pci_dev_t dev;
- uint16_t value;
-
- /* Set the SMBus device statically. */
- dev = PCI_BDF(0x0, 0x1f, 0x3);
-
- /* Check to make sure we've got the right device. */
- value = x86_pci_read_config16(dev, 0x0);
- if (value != 0x8086) {
- printf("SMBus controller not found\n");
- return -ENOSYS;
- }
-
- /* Set SMBus I/O base. */
- x86_pci_write_config32(dev, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
-
- /* Set SMBus enable. */
- x86_pci_write_config8(dev, HOSTC, HST_EN);
-
- /* Set SMBus I/O space enable. */
- x86_pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
-
- /* Disable interrupt generation. */
- outb(0, SMBUS_IO_BASE + SMBHSTCTL);
-
- /* Clear any lingering errors, so transactions can run. */
- outb(inb(SMBUS_IO_BASE + SMBHSTSTAT), SMBUS_IO_BASE + SMBHSTSTAT);
- debug("SMBus controller enabled\n");
-
- return 0;
-}
-
#define PCH_EHCI0_TEMP_BAR0 0xe8000000
#define PCH_EHCI1_TEMP_BAR0 0xe8000400
#define PCH_XHCI_TEMP_BAR0 0xe8001000
@@ -215,33 +133,33 @@ static int enable_smbus(void)
*
* This is used to speed up the resume path.
*/
-static void enable_usb_bar(void)
+static void enable_usb_bar(struct udevice *bus)
{
pci_dev_t usb0 = PCH_EHCI1_DEV;
pci_dev_t usb1 = PCH_EHCI2_DEV;
pci_dev_t usb3 = PCH_XHCI_DEV;
- u32 cmd;
+ ulong cmd;
/* USB Controller 1 */
- x86_pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
- PCH_EHCI0_TEMP_BAR0);
- cmd = x86_pci_read_config32(usb0, PCI_COMMAND);
+ pci_bus_write_config(bus, usb0, PCI_BASE_ADDRESS_0,
+ PCH_EHCI0_TEMP_BAR0, PCI_SIZE_32);
+ pci_bus_read_config(bus, usb0, PCI_COMMAND, &cmd, PCI_SIZE_32);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- x86_pci_write_config32(usb0, PCI_COMMAND, cmd);
+ pci_bus_write_config(bus, usb0, PCI_COMMAND, cmd, PCI_SIZE_32);
- /* USB Controller 1 */
- x86_pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
- PCH_EHCI1_TEMP_BAR0);
- cmd = x86_pci_read_config32(usb1, PCI_COMMAND);
+ /* USB Controller 2 */
+ pci_bus_write_config(bus, usb1, PCI_BASE_ADDRESS_0,
+ PCH_EHCI1_TEMP_BAR0, PCI_SIZE_32);
+ pci_bus_read_config(bus, usb1, PCI_COMMAND, &cmd, PCI_SIZE_32);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- x86_pci_write_config32(usb1, PCI_COMMAND, cmd);
+ pci_bus_write_config(bus, usb1, PCI_COMMAND, cmd, PCI_SIZE_32);
- /* USB3 Controller */
- x86_pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
- PCH_XHCI_TEMP_BAR0);
- cmd = x86_pci_read_config32(usb3, PCI_COMMAND);
+ /* USB3 Controller 1 */
+ pci_bus_write_config(bus, usb3, PCI_BASE_ADDRESS_0,
+ PCH_XHCI_TEMP_BAR0, PCI_SIZE_32);
+ pci_bus_read_config(bus, usb3, PCI_COMMAND, &cmd, PCI_SIZE_32);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- x86_pci_write_config32(usb3, PCI_COMMAND, cmd);
+ pci_bus_write_config(bus, usb3, PCI_COMMAND, cmd, PCI_SIZE_32);
}
static int report_bist_failure(void)
@@ -259,6 +177,7 @@ int print_cpuinfo(void)
{
enum pei_boot_mode_t boot_mode = PEI_BOOT_NONE;
char processor_name[CPU_MAX_NAME_LEN];
+ struct udevice *dev, *lpc;
const char *name;
uint32_t pm1_cnt;
uint16_t pm1_sts;
@@ -289,7 +208,16 @@ int print_cpuinfo(void)
}
/* Early chipset init required before RAM init can work */
- sandybridge_early_init(SANDYBRIDGE_MOBILE);
+ uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
+
+ ret = uclass_first_device(UCLASS_LPC, &lpc);
+ if (ret)
+ return ret;
+ if (!dev)
+ return -ENODEV;
+
+ /* Cause the SATA device to do its early init */
+ uclass_first_device(UCLASS_DISK, &dev);
/* Check PM1_STS[15] to see if we are waking from Sx */
pm1_sts = inw(DEFAULT_PMBASE + PM1_STS);
@@ -308,20 +236,18 @@ int print_cpuinfo(void)
post_code(POST_EARLY_INIT);
/* Enable SPD ROMs and DDR-III DRAM */
- ret = enable_smbus();
+ ret = uclass_first_device(UCLASS_I2C, &dev);
if (ret)
return ret;
+ if (!dev)
+ return -ENODEV;
/* Prepare USB controller early in S3 resume */
if (boot_mode == PEI_BOOT_RESUME)
- enable_usb_bar();
+ enable_usb_bar(pci_get_controller(lpc->parent));
gd->arch.pei_boot_mode = boot_mode;
- /* TODO: Move this to the board or driver */
- x86_pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
- x86_pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
-
/* Print processor name */
name = cpu_get_name(processor_name);
printf("CPU: %s\n", name);
diff --git a/arch/x86/cpu/ivybridge/early_init.c b/arch/x86/cpu/ivybridge/early_init.c
deleted file mode 100644
index 9ca008e..0000000
--- a/arch/x86/cpu/ivybridge/early_init.c
+++ /dev/null
@@ -1,147 +0,0 @@
-/*
- * From Coreboot
- *
- * Copyright (C) 2007-2010 coresystems GmbH
- * Copyright (C) 2011 Google Inc
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/arch/pch.h>
-#include <asm/arch/sandybridge.h>
-
-static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev)
-{
- /* Setting up Southbridge. In the northbridge code. */
- debug("Setting up static southbridge registers\n");
- x86_pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
-
- x86_pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1);
- x86_pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */
-
- debug("Disabling watchdog reboot\n");
- setbits_le32(RCB_REG(GCS), 1 >> 5); /* No reset */
- outw(1 << 11, DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */
-
- /* Set up all hardcoded northbridge BARs */
- debug("Setting up static registers\n");
- x86_pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1);
- x86_pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
- x86_pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1);
- x86_pci_write_config32(pch_dev, MCHBAR + 4,
- (0LL + DEFAULT_MCHBAR) >> 32);
- /* 64MB - busses 0-63 */
- x86_pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
- x86_pci_write_config32(pch_dev, PCIEXBAR + 4,
- (0LL + DEFAULT_PCIEXBAR) >> 32);
- x86_pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1);
- x86_pci_write_config32(pch_dev, DMIBAR + 4,
- (0LL + DEFAULT_DMIBAR) >> 32);
-
- /* Set C0000-FFFFF to access RAM on both reads and writes */
- x86_pci_write_config8(pch_dev, PAM0, 0x30);
- x86_pci_write_config8(pch_dev, PAM1, 0x33);
- x86_pci_write_config8(pch_dev, PAM2, 0x33);
- x86_pci_write_config8(pch_dev, PAM3, 0x33);
- x86_pci_write_config8(pch_dev, PAM4, 0x33);
- x86_pci_write_config8(pch_dev, PAM5, 0x33);
- x86_pci_write_config8(pch_dev, PAM6, 0x33);
-}
-
-static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
-{
- u32 reg32;
- u16 reg16;
- u8 reg8;
-
- reg16 = x86_pci_read_config16(video_dev, PCI_DEVICE_ID);
- switch (reg16) {
- case 0x0102: /* GT1 Desktop */
- case 0x0106: /* GT1 Mobile */
- case 0x010a: /* GT1 Server */
- case 0x0112: /* GT2 Desktop */
- case 0x0116: /* GT2 Mobile */
- case 0x0122: /* GT2 Desktop >=1.3GHz */
- case 0x0126: /* GT2 Mobile >=1.3GHz */
- case 0x0156: /* IvyBridge */
- case 0x0166: /* IvyBridge */
- break;
- default:
- debug("Graphics not supported by this CPU/chipset\n");
- return;
- }
-
- debug("Initialising Graphics\n");
-
- /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */
- reg16 = x86_pci_read_config16(pch_dev, GGC);
- reg16 &= ~0x00f8;
- reg16 |= 1 << 3;
- /* Program GTT memory by setting GGC[9:8] = 2MB */
- reg16 &= ~0x0300;
- reg16 |= 2 << 8;
- /* Enable VGA decode */
- reg16 &= ~0x0002;
- x86_pci_write_config16(pch_dev, GGC, reg16);
-
- /* Enable 256MB aperture */
- reg8 = x86_pci_read_config8(video_dev, MSAC);
- reg8 &= ~0x06;
- reg8 |= 0x02;
- x86_pci_write_config8(video_dev, MSAC, reg8);
-
- /* Erratum workarounds */
- reg32 = readl(MCHBAR_REG(0x5f00));
- reg32 |= (1 << 9) | (1 << 10);
- writel(reg32, MCHBAR_REG(0x5f00));
-
- /* Enable SA Clock Gating */
- reg32 = readl(MCHBAR_REG(0x5f00));
- writel(reg32 | 1, MCHBAR_REG(0x5f00));
-
- /* GPU RC6 workaround for sighting 366252 */
- reg32 = readl(MCHBAR_REG(0x5d14));
- reg32 |= (1 << 31);
- writel(reg32, MCHBAR_REG(0x5d14));
-
- /* VLW */
- reg32 = readl(MCHBAR_REG(0x6120));
- reg32 &= ~(1 << 0);
- writel(reg32, MCHBAR_REG(0x6120));
-
- reg32 = readl(MCHBAR_REG(0x5418));
- reg32 |= (1 << 4) | (1 << 5);
- writel(reg32, MCHBAR_REG(0x5418));
-}
-
-void sandybridge_early_init(int chipset_type)
-{
- pci_dev_t pch_dev = PCH_DEV;
- pci_dev_t video_dev = PCH_VIDEO_DEV;
- pci_dev_t lpc_dev = PCH_LPC_DEV;
- u32 capid0_a;
- u8 reg8;
-
- /* Device ID Override Enable should be done very early */
- capid0_a = x86_pci_read_config32(pch_dev, 0xe4);
- if (capid0_a & (1 << 10)) {
- reg8 = x86_pci_read_config8(pch_dev, 0xf3);
- reg8 &= ~7; /* Clear 2:0 */
-
- if (chipset_type == SANDYBRIDGE_MOBILE)
- reg8 |= 1; /* Set bit 0 */
-
- x86_pci_write_config8(pch_dev, 0xf3, reg8);
- }
-
- /* Setup all BARs required for early PCIe and raminit */
- sandybridge_setup_bars(pch_dev, lpc_dev);
-
- /* Device Enable */
- x86_pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
-
- sandybridge_setup_graphics(pch_dev, video_dev);
-}
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index 711470f..b1df77d 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -7,8 +7,10 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <asm/pci.h>
+#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/arch/me.h>
#include <asm/arch/pch.h>
@@ -25,33 +27,36 @@ static const char *const me_ack_values[] = {
[ME_HFS_ACK_CONTINUE] = "Continue to boot"
};
-static inline void pci_read_dword_ptr(void *ptr, int offset)
+static inline void pci_read_dword_ptr(struct udevice *me_dev, void *ptr,
+ int offset)
{
u32 dword;
- dword = x86_pci_read_config32(PCH_ME_DEV, offset);
+ dm_pci_read_config32(me_dev, offset, &dword);
memcpy(ptr, &dword, sizeof(dword));
}
-static inline void pci_write_dword_ptr(void *ptr, int offset)
+static inline void pci_write_dword_ptr(struct udevice *me_dev, void *ptr,
+ int offset)
{
u32 dword = 0;
+
memcpy(&dword, ptr, sizeof(dword));
- x86_pci_write_config32(PCH_ME_DEV, offset, dword);
+ dm_pci_write_config32(me_dev, offset, dword);
}
-void intel_early_me_status(void)
+void intel_early_me_status(struct udevice *me_dev)
{
struct me_hfs hfs;
struct me_gmes gmes;
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
- pci_read_dword_ptr(&gmes, PCI_ME_GMES);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &gmes, PCI_ME_GMES);
intel_me_status(&hfs, &gmes);
}
-int intel_early_me_init(void)
+int intel_early_me_init(struct udevice *me_dev)
{
int count;
struct me_uma uma;
@@ -61,7 +66,7 @@ int intel_early_me_init(void)
/* Wait for ME UMA SIZE VALID bit to be set */
for (count = ME_RETRY; count > 0; --count) {
- pci_read_dword_ptr(&uma, PCI_ME_UMA);
+ pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
if (uma.valid)
break;
udelay(ME_DELAY);
@@ -72,7 +77,7 @@ int intel_early_me_init(void)
}
/* Check for valid firmware */
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
if (hfs.fpt_bad) {
printf("WARNING: ME has bad firmware\n");
return -EBADF;
@@ -83,11 +88,11 @@ int intel_early_me_init(void)
return 0;
}
-int intel_early_me_uma_size(void)
+int intel_early_me_uma_size(struct udevice *me_dev)
{
struct me_uma uma;
- pci_read_dword_ptr(&uma, PCI_ME_UMA);
+ pci_read_dword_ptr(me_dev, &uma, PCI_ME_UMA);
if (uma.valid) {
debug("ME: Requested %uMB UMA\n", uma.size);
return uma.size;
@@ -97,11 +102,11 @@ int intel_early_me_uma_size(void)
return -EINVAL;
}
-static inline void set_global_reset(int enable)
+static inline void set_global_reset(struct udevice *dev, int enable)
{
u32 etr3;
- etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3);
+ dm_pci_read_config32(dev, ETR3, &etr3);
/* Clear CF9 Without Resume Well Reset Enable */
etr3 &= ~ETR3_CWORWRE;
@@ -112,10 +117,11 @@ static inline void set_global_reset(int enable)
else
etr3 &= ~ETR3_CF9GR;
- x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
+ dm_pci_write_config32(dev, ETR3, etr3);
}
-int intel_early_me_init_done(u8 status)
+int intel_early_me_init_done(struct udevice *dev, struct udevice *me_dev,
+ uint status)
{
int count;
u32 mebase_l, mebase_h;
@@ -126,8 +132,8 @@ int intel_early_me_init_done(u8 status)
};
/* MEBASE from MESEG_BASE[35:20] */
- mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
- mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
+ dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L, &mebase_l);
+ dm_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H, &mebase_h);
mebase_h &= 0xf;
did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
@@ -135,25 +141,25 @@ int intel_early_me_init_done(u8 status)
debug("ME: Sending Init Done with status: %d, UMA base: 0x%04x\n",
status, did.uma_base);
- pci_write_dword_ptr(&did, PCI_ME_H_GS);
+ pci_write_dword_ptr(me_dev, &did, PCI_ME_H_GS);
/* Must wait for ME acknowledgement */
for (count = ME_RETRY; count > 0; --count) {
- pci_read_dword_ptr(&hfs, PCI_ME_HFS);
+ pci_read_dword_ptr(me_dev, &hfs, PCI_ME_HFS);
if (hfs.bios_msg_ack)
break;
udelay(ME_DELAY);
}
if (!count) {
printf("ERROR: ME failed to respond\n");
- return -1;
+ return -ETIMEDOUT;
}
/* Return the requested BIOS action */
debug("ME: Requested BIOS Action: %s\n", me_ack_values[hfs.ack_data]);
/* Check status after acknowledgement */
- intel_early_me_status();
+ intel_early_me_status(me_dev);
switch (hfs.ack_data) {
case ME_HFS_ACK_CONTINUE:
@@ -161,17 +167,17 @@ int intel_early_me_init_done(u8 status)
return 0;
case ME_HFS_ACK_RESET:
/* Non-power cycle reset */
- set_global_reset(0);
+ set_global_reset(dev, 0);
reset_cpu(0);
break;
case ME_HFS_ACK_PWR_CYCLE:
/* Power cycle reset */
- set_global_reset(0);
+ set_global_reset(dev, 0);
x86_full_reset();
break;
case ME_HFS_ACK_GBL_RESET:
/* Global reset */
- set_global_reset(1);
+ set_global_reset(dev, 1);
x86_full_reset();
break;
case ME_HFS_ACK_S3:
@@ -180,5 +186,17 @@ int intel_early_me_init_done(u8 status)
break;
}
- return -1;
+ return -EINVAL;
}
+
+static const struct udevice_id ivybridge_syscon_ids[] = {
+ { .compatible = "intel,me", .data = X86_SYSCON_ME },
+ { .compatible = "intel,gma", .data = X86_SYSCON_GMA },
+ { }
+};
+
+U_BOOT_DRIVER(syscon_intel_me) = {
+ .name = "intel_me_syscon",
+ .id = UCLASS_SYSCON,
+ .of_match = ivybridge_syscon_ids,
+};
diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c
index 85a09c6..3b6291e 100644
--- a/arch/x86/cpu/ivybridge/gma.c
+++ b/arch/x86/cpu/ivybridge/gma.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <bios_emul.h>
+#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <pci_rom.h>
@@ -352,14 +353,13 @@ static int gtt_poll(void *bar, u32 reg, u32 mask, u32 value)
return 0;
}
-static int gma_pm_init_pre_vbios(void *gtt_bar)
+static int gma_pm_init_pre_vbios(void *gtt_bar, int rev)
{
u32 reg32;
- debug("GT Power Management Init, silicon = %#x\n",
- bridge_silicon_revision());
+ debug("GT Power Management Init, silicon = %#x\n", rev);
- if (bridge_silicon_revision() < IVB_STEP_C0) {
+ if (rev < IVB_STEP_C0) {
/* 1: Enable force wake */
gtt_write(gtt_bar, 0xa18c, 0x00000001);
gtt_poll(gtt_bar, 0x130090, (1 << 0), (1 << 0));
@@ -369,14 +369,14 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
gtt_poll(gtt_bar, 0x130040, (1 << 0), (1 << 0));
}
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
+ if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
/* 1d: Set GTT+0x42004 [15:14]=11 (SnB C1+) */
reg32 = gtt_read(gtt_bar, 0x42004);
reg32 |= (1 << 14) | (1 << 15);
gtt_write(gtt_bar, 0x42004, reg32);
}
- if (bridge_silicon_revision() >= IVB_STEP_A0) {
+ if (rev >= IVB_STEP_A0) {
/* Display Reset Acknowledge Settings */
reg32 = gtt_read(gtt_bar, 0x45010);
reg32 |= (1 << 1) | (1 << 0);
@@ -385,7 +385,7 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
/* 2: Get GT SKU from GTT+0x911c[13] */
reg32 = gtt_read(gtt_bar, 0x911c);
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
+ if ((rev & BASE_REV_MASK) == BASE_REV_SNB) {
if (reg32 & (1 << 13)) {
debug("SNB GT1 Power Meter Weights\n");
gtt_write_powermeter(gtt_bar, snb_pm_gt1);
@@ -434,13 +434,13 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
reg32 = gtt_read(gtt_bar, 0xa180);
reg32 |= (1 << 26) | (1 << 31);
/* (bit 20=1 for SNB step D1+ / IVB A0+) */
- if (bridge_silicon_revision() >= SNB_STEP_D1)
+ if (rev >= SNB_STEP_D1)
reg32 |= (1 << 20);
gtt_write(gtt_bar, 0xa180, reg32);
/* 6a: for SnB step D2+ only */
- if (((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) &&
- (bridge_silicon_revision() >= SNB_STEP_D2)) {
+ if (((rev & BASE_REV_MASK) == BASE_REV_SNB) &&
+ (rev >= SNB_STEP_D2)) {
reg32 = gtt_read(gtt_bar, 0x9400);
reg32 |= (1 << 7);
gtt_write(gtt_bar, 0x9400, reg32);
@@ -452,7 +452,7 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
gtt_poll(gtt_bar, 0x941c, (1 << 1), (0 << 1));
}
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
+ if ((rev & BASE_REV_MASK) == BASE_REV_IVB) {
reg32 = gtt_read(gtt_bar, 0x907c);
reg32 |= (1 << 16);
gtt_write(gtt_bar, 0x907c, reg32);
@@ -504,7 +504,7 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
gtt_write(gtt_bar, 0xa070, 0x0000000a); /* RP Idle Hysteresis */
/* 11a: Enable Render Standby (RC6) */
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
+ if ((rev & BASE_REV_MASK) == BASE_REV_IVB) {
/*
* IvyBridge should also support DeepRenderStandby.
*
@@ -538,14 +538,16 @@ static int gma_pm_init_pre_vbios(void *gtt_bar)
return 0;
}
-int gma_pm_init_post_vbios(void *gtt_bar, const void *blob, int node)
+int gma_pm_init_post_vbios(struct udevice *dev, int rev, void *gtt_bar)
{
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
u32 reg32, cycle_delay;
debug("GT Power Management Init (post VBIOS)\n");
/* 15: Deassert Force Wake */
- if (bridge_silicon_revision() < IVB_STEP_C0) {
+ if (rev < IVB_STEP_C0) {
gtt_write(gtt_bar, 0xa18c, gtt_read(gtt_bar, 0xa18c) & ~1);
gtt_poll(gtt_bar, 0x130090, (1 << 0), (0 << 0));
} else {
@@ -728,15 +730,93 @@ static int int15_handler(void)
return res;
}
-int gma_func0_init(struct udevice *dev, const void *blob, int node)
+void sandybridge_setup_graphics(struct udevice *dev, struct udevice *video_dev)
+{
+ u32 reg32;
+ u16 reg16;
+ u8 reg8;
+
+ dm_pci_read_config16(video_dev, PCI_DEVICE_ID, &reg16);
+ switch (reg16) {
+ case 0x0102: /* GT1 Desktop */
+ case 0x0106: /* GT1 Mobile */
+ case 0x010a: /* GT1 Server */
+ case 0x0112: /* GT2 Desktop */
+ case 0x0116: /* GT2 Mobile */
+ case 0x0122: /* GT2 Desktop >=1.3GHz */
+ case 0x0126: /* GT2 Mobile >=1.3GHz */
+ case 0x0156: /* IvyBridge */
+ case 0x0166: /* IvyBridge */
+ break;
+ default:
+ debug("Graphics not supported by this CPU/chipset\n");
+ return;
+ }
+
+ debug("Initialising Graphics\n");
+
+ /* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */
+ dm_pci_read_config16(dev, GGC, &reg16);
+ reg16 &= ~0x00f8;
+ reg16 |= 1 << 3;
+ /* Program GTT memory by setting GGC[9:8] = 2MB */
+ reg16 &= ~0x0300;
+ reg16 |= 2 << 8;
+ /* Enable VGA decode */
+ reg16 &= ~0x0002;
+ dm_pci_write_config16(dev, GGC, reg16);
+
+ /* Enable 256MB aperture */
+ dm_pci_read_config8(video_dev, MSAC, &reg8);
+ reg8 &= ~0x06;
+ reg8 |= 0x02;
+ dm_pci_write_config8(video_dev, MSAC, reg8);
+
+ /* Erratum workarounds */
+ reg32 = readl(MCHBAR_REG(0x5f00));
+ reg32 |= (1 << 9) | (1 << 10);
+ writel(reg32, MCHBAR_REG(0x5f00));
+
+ /* Enable SA Clock Gating */
+ reg32 = readl(MCHBAR_REG(0x5f00));
+ writel(reg32 | 1, MCHBAR_REG(0x5f00));
+
+ /* GPU RC6 workaround for sighting 366252 */
+ reg32 = readl(MCHBAR_REG(0x5d14));
+ reg32 |= (1 << 31);
+ writel(reg32, MCHBAR_REG(0x5d14));
+
+ /* VLW */
+ reg32 = readl(MCHBAR_REG(0x6120));
+ reg32 &= ~(1 << 0);
+ writel(reg32, MCHBAR_REG(0x6120));
+
+ reg32 = readl(MCHBAR_REG(0x5418));
+ reg32 |= (1 << 4) | (1 << 5);
+ writel(reg32, MCHBAR_REG(0x5418));
+}
+
+int gma_func0_init(struct udevice *dev)
{
#ifdef CONFIG_VIDEO
ulong start;
#endif
+ struct udevice *nbridge;
void *gtt_bar;
ulong base;
u32 reg32;
int ret;
+ int rev;
+
+ /* Enable PCH Display Port */
+ writew(0x0010, RCB_REG(DISPBDF));
+ setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
+
+ ret = uclass_first_device(UCLASS_NORTHBRIDGE, &nbridge);
+ if (!nbridge)
+ return -ENODEV;
+ rev = bridge_silicon_revision(nbridge);
+ sandybridge_setup_graphics(nbridge, dev);
/* IGD needs to be Bus Master */
dm_pci_read_config32(dev, PCI_COMMAND, &reg32);
@@ -750,7 +830,7 @@ int gma_func0_init(struct udevice *dev, const void *blob, int node)
gtt_bar = (void *)dm_pci_read_bar32(dev, 0);
debug("GT bar %p\n", gtt_bar);
- ret = gma_pm_init_pre_vbios(gtt_bar);
+ ret = gma_pm_init_pre_vbios(gtt_bar, rev);
if (ret)
return ret;
@@ -761,7 +841,7 @@ int gma_func0_init(struct udevice *dev, const void *blob, int node)
debug("BIOS ran in %lums\n", get_timer(start));
#endif
/* Post VBIOS init */
- ret = gma_pm_init_post_vbios(gtt_bar, blob, node);
+ ret = gma_pm_init_post_vbios(dev, rev, gtt_bar);
if (ret)
return ret;
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index af5d4a8..9ab5ed3 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -24,13 +24,13 @@
#define ENABLE_ACPI_MODE_IN_COREBOOT 0
#define TEST_SMM_FLASH_LOCKDOWN 0
-static int pch_enable_apic(pci_dev_t dev)
+static int pch_enable_apic(struct udevice *pch)
{
u32 reg32;
int i;
/* Enable ACPI I/O and power management. Set SCI IRQ to IRQ9 */
- x86_pci_write_config8(dev, ACPI_CNTL, 0x80);
+ dm_pci_write_config8(pch, ACPI_CNTL, 0x80);
writel(0, IO_APIC_INDEX);
writel(1 << 25, IO_APIC_DATA);
@@ -66,36 +66,36 @@ static int pch_enable_apic(pci_dev_t dev)
return 0;
}
-static void pch_enable_serial_irqs(pci_dev_t dev)
+static void pch_enable_serial_irqs(struct udevice *pch)
{
u32 value;
/* Set packet length and toggle silent mode bit for one frame. */
value = (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0);
#ifdef CONFIG_SERIRQ_CONTINUOUS_MODE
- x86_pci_write_config8(dev, SERIRQ_CNTL, value);
+ dm_pci_write_config8(pch, SERIRQ_CNTL, value);
#else
- x86_pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
+ dm_pci_write_config8(pch, SERIRQ_CNTL, value | (1 << 6));
#endif
}
-static int pch_pirq_init(const void *blob, int node, pci_dev_t dev)
+static int pch_pirq_init(struct udevice *pch)
{
uint8_t route[8], *ptr;
- if (fdtdec_get_byte_array(blob, node, "intel,pirq-routing", route,
- sizeof(route)))
+ if (fdtdec_get_byte_array(gd->fdt_blob, pch->of_offset,
+ "intel,pirq-routing", route, sizeof(route)))
return -EINVAL;
ptr = route;
- x86_pci_write_config8(dev, PIRQA_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQB_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQC_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQD_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQA_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQB_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQC_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQD_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQE_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQF_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQG_ROUT, *ptr++);
- x86_pci_write_config8(dev, PIRQH_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQE_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQF_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQG_ROUT, *ptr++);
+ dm_pci_write_config8(pch, PIRQH_ROUT, *ptr++);
/*
* TODO(sjg@chromium.org): U-Boot does not set up the interrupts
@@ -104,26 +104,28 @@ static int pch_pirq_init(const void *blob, int node, pci_dev_t dev)
return 0;
}
-static int pch_gpi_routing(const void *blob, int node, pci_dev_t dev)
+static int pch_gpi_routing(struct udevice *pch)
{
u8 route[16];
u32 reg;
int gpi;
- if (fdtdec_get_byte_array(blob, node, "intel,gpi-routing", route,
- sizeof(route)))
+ if (fdtdec_get_byte_array(gd->fdt_blob, pch->of_offset,
+ "intel,gpi-routing", route, sizeof(route)))
return -EINVAL;
for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++)
reg |= route[gpi] << (gpi * 2);
- x86_pci_write_config32(dev, 0xb8, reg);
+ dm_pci_write_config32(pch, 0xb8, reg);
return 0;
}
-static int pch_power_options(const void *blob, int node, pci_dev_t dev)
+static int pch_power_options(struct udevice *pch)
{
+ const void *blob = gd->fdt_blob;
+ int node = pch->of_offset;
u8 reg8;
u16 reg16, pmbase;
u32 reg32;
@@ -142,7 +144,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
*/
pwr_on = MAINBOARD_POWER_ON;
- reg16 = x86_pci_read_config16(dev, GEN_PMCON_3);
+ dm_pci_read_config16(pch, GEN_PMCON_3, &reg16);
reg16 &= 0xfffe;
switch (pwr_on) {
case MAINBOARD_POWER_OFF:
@@ -169,7 +171,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */
- x86_pci_write_config16(dev, GEN_PMCON_3, reg16);
+ dm_pci_write_config16(pch, GEN_PMCON_3, reg16);
debug("Set power %s after power failure.\n", state);
/* Set up NMI on errors. */
@@ -193,21 +195,22 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
outb(reg8, 0x70);
/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
- reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
+ dm_pci_read_config16(pch, GEN_PMCON_1, &reg16);
reg16 &= ~(3 << 0); /* SMI# rate 1 minute */
reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */
#if DEBUG_PERIODIC_SMIS
/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */
reg16 |= (3 << 0); /* Periodic SMI every 8s */
#endif
- x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
+ dm_pci_write_config16(pch, GEN_PMCON_1, reg16);
/* Set the board's GPI routing. */
- ret = pch_gpi_routing(blob, node, dev);
+ ret = pch_gpi_routing(pch);
if (ret)
return ret;
- pmbase = x86_pci_read_config16(dev, 0x40) & 0xfffe;
+ dm_pci_read_config16(pch, 0x40, &pmbase);
+ pmbase &= 0xfffe;
writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node,
"intel,gpe0-enable", 0));
@@ -227,16 +230,16 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
return 0;
}
-static void pch_rtc_init(pci_dev_t dev)
+static void pch_rtc_init(struct udevice *pch)
{
int rtc_failed;
u8 reg8;
- reg8 = x86_pci_read_config8(dev, GEN_PMCON_3);
+ dm_pci_read_config8(pch, GEN_PMCON_3, &reg8);
rtc_failed = reg8 & RTC_BATTERY_DEAD;
if (rtc_failed) {
reg8 &= ~RTC_BATTERY_DEAD;
- x86_pci_write_config8(dev, GEN_PMCON_3, reg8);
+ dm_pci_write_config8(pch, GEN_PMCON_3, reg8);
}
debug("rtc_failed = 0x%x\n", rtc_failed);
@@ -246,10 +249,10 @@ static void pch_rtc_init(pci_dev_t dev)
}
/* CougarPoint PCH Power Management init */
-static void cpt_pm_init(pci_dev_t dev)
+static void cpt_pm_init(struct udevice *pch)
{
debug("CougarPoint PM init\n");
- x86_pci_write_config8(dev, 0xa9, 0x47);
+ dm_pci_write_config8(pch, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), (1 << 6) | (1 << 0));
setbits_le32(RCB_REG(0x228c), 1 << 0);
@@ -290,10 +293,10 @@ static void cpt_pm_init(pci_dev_t dev)
}
/* PantherPoint PCH Power Management init */
-static void ppt_pm_init(pci_dev_t dev)
+static void ppt_pm_init(struct udevice *pch)
{
debug("PantherPoint PM init\n");
- x86_pci_write_config8(dev, 0xa9, 0x47);
+ dm_pci_write_config8(pch, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), 1 << 0);
setbits_le32(RCB_REG(0x228c), 1 << 0);
setbits_le16(RCB_REG(0x1100), (1 << 13) | (1 << 14));
@@ -340,21 +343,21 @@ static void enable_hpet(void)
clrsetbits_le32(RCB_REG(HPTC), 3 << 0, 1 << 7);
}
-static void enable_clock_gating(pci_dev_t dev)
+static void enable_clock_gating(struct udevice *pch)
{
u32 reg32;
u16 reg16;
setbits_le32(RCB_REG(0x2234), 0xf);
- reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
+ dm_pci_read_config16(pch, GEN_PMCON_1, &reg16);
reg16 |= (1 << 2) | (1 << 11);
- x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
+ dm_pci_write_config16(pch, GEN_PMCON_1, reg16);
- pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
- pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
- pch_iobp_update(0xEC007F07, ~0UL, (1 << 31));
- pch_iobp_update(0xEC004000, ~0UL, (1 << 7));
+ pch_iobp_update(pch, 0xEB007F07, ~0UL, (1 << 31));
+ pch_iobp_update(pch, 0xEB004000, ~0UL, (1 << 7));
+ pch_iobp_update(pch, 0xEC007F07, ~0UL, (1 << 31));
+ pch_iobp_update(pch, 0xEC004000, ~0UL, (1 << 7));
reg32 = readl(RCB_REG(CG));
reg32 |= (1 << 31);
@@ -376,77 +379,24 @@ static void enable_clock_gating(pci_dev_t dev)
setbits_le32(RCB_REG(0x3564), 0x3);
}
-#if CONFIG_HAVE_SMI_HANDLER
-static void pch_lock_smm(pci_dev_t dev)
-{
-#if TEST_SMM_FLASH_LOCKDOWN
- u8 reg8;
-#endif
-
- if (acpi_slp_type != 3) {
-#if ENABLE_ACPI_MODE_IN_COREBOOT
- debug("Enabling ACPI via APMC:\n");
- outb(0xe1, 0xb2); /* Enable ACPI mode */
- debug("done.\n");
-#else
- debug("Disabling ACPI via APMC:\n");
- outb(0x1e, 0xb2); /* Disable ACPI mode */
- debug("done.\n");
-#endif
- }
-
- /* Don't allow evil boot loaders, kernels, or
- * userspace applications to deceive us:
- */
- smm_lock();
-
-#if TEST_SMM_FLASH_LOCKDOWN
- /* Now try this: */
- debug("Locking BIOS to RO... ");
- reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
- (reg8 & 1) ? "rw" : "ro");
- reg8 &= ~(1 << 0); /* clear BIOSWE */
- x86_pci_write_config8(dev, 0xdc, reg8);
- reg8 |= (1 << 1); /* set BLE */
- x86_pci_write_config8(dev, 0xdc, reg8);
- debug("ok.\n");
- reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
- (reg8 & 1) ? "rw" : "ro");
-
- debug("Writing:\n");
- writeb(0, 0xfff00000);
- debug("Testing:\n");
- reg8 |= (1 << 0); /* set BIOSWE */
- x86_pci_write_config8(dev, 0xdc, reg8);
-
- reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
- debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
- (reg8 & 1) ? "rw" : "ro");
- debug("Done.\n");
-#endif
-}
-#endif
-
-static void pch_disable_smm_only_flashing(pci_dev_t dev)
+static void pch_disable_smm_only_flashing(struct udevice *pch)
{
u8 reg8;
debug("Enabling BIOS updates outside of SMM... ");
- reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ dm_pci_read_config8(pch, 0xdc, &reg8); /* BIOS_CNTL */
reg8 &= ~(1 << 5);
- x86_pci_write_config8(dev, 0xdc, reg8);
+ dm_pci_write_config8(pch, 0xdc, reg8);
}
-static void pch_fixups(pci_dev_t dev)
+static void pch_fixups(struct udevice *pch)
{
u8 gen_pmcon_2;
/* Indicate DRAM init done for MRC S3 to know it can resume */
- gen_pmcon_2 = x86_pci_read_config8(dev, GEN_PMCON_2);
+ dm_pci_read_config8(pch, GEN_PMCON_2, &gen_pmcon_2);
gen_pmcon_2 |= (1 << 7);
- x86_pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
+ dm_pci_write_config8(pch, GEN_PMCON_2, gen_pmcon_2);
/* Enable DMI ASPM in the PCH */
clrbits_le32(RCB_REG(0x2304), 1 << 10);
@@ -454,7 +404,49 @@ static void pch_fixups(pci_dev_t dev)
setbits_le32(RCB_REG(0x21a8), 0x3);
}
-int lpc_early_init(const void *blob, int node, pci_dev_t dev)
+/*
+ * Enable Prefetching and Caching.
+ */
+static void enable_spi_prefetch(struct udevice *pch)
+{
+ u8 reg8;
+
+ dm_pci_read_config8(pch, 0xdc, &reg8);
+ reg8 &= ~(3 << 2);
+ reg8 |= (2 << 2); /* Prefetching and Caching Enabled */
+ dm_pci_write_config8(pch, 0xdc, reg8);
+}
+
+static void enable_port80_on_lpc(struct udevice *pch)
+{
+ /* Enable port 80 POST on LPC */
+ dm_pci_write_config32(pch, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
+ clrbits_le32(RCB_REG(GCS), 4);
+}
+
+static void set_spi_speed(void)
+{
+ u32 fdod;
+
+ /* Observe SPI Descriptor Component Section 0 */
+ writel(0x1000, RCB_REG(SPI_DESC_COMP0));
+
+ /* Extract the1 Write/Erase SPI Frequency from descriptor */
+ fdod = readl(RCB_REG(SPI_FREQ_WR_ERA));
+ fdod >>= 24;
+ fdod &= 7;
+
+ /* Set Software Sequence frequency to match */
+ clrsetbits_8(RCB_REG(SPI_FREQ_SWSEQ), 7, fdod);
+}
+
+/**
+ * lpc_early_init() - set up LPC serial ports and other early things
+ *
+ * @dev: LPC device
+ * @return 0 if OK, -ve on error
+ */
+static int lpc_early_init(struct udevice *dev)
{
struct reg_info {
u32 base;
@@ -463,17 +455,18 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
int count;
int i;
- count = fdtdec_get_int_array_count(blob, node, "intel,gen-dec",
- (u32 *)values, sizeof(values) / sizeof(u32));
+ count = fdtdec_get_int_array_count(gd->fdt_blob, dev->of_offset,
+ "intel,gen-dec", (u32 *)values,
+ sizeof(values) / sizeof(u32));
if (count < 0)
return -EINVAL;
/* Set COM1/COM2 decode range */
- x86_pci_write_config16(dev, LPC_IO_DEC, 0x0010);
+ dm_pci_write_config16(dev->parent, LPC_IO_DEC, 0x0010);
/* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
- x86_pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
- GAMEL_LPC_EN | COMA_LPC_EN);
+ dm_pci_write_config16(dev->parent, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
+ GAMEL_LPC_EN | COMA_LPC_EN);
/* Write all registers but use 0 if we run out of data */
count = count * sizeof(u32) / sizeof(values[0]);
@@ -482,81 +475,114 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
if (i < count)
reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16);
- x86_pci_write_config32(dev, LPC_GENX_DEC(i), reg);
+ dm_pci_write_config32(dev->parent, LPC_GENX_DEC(i), reg);
}
+ enable_spi_prefetch(dev->parent);
+
+ /* This is already done in start.S, but let's do it in C */
+ enable_port80_on_lpc(dev->parent);
+
+ set_spi_speed();
+
return 0;
}
-int lpc_init(struct pci_controller *hose, pci_dev_t dev)
+static int lpc_init_extra(struct udevice *dev)
{
+ struct udevice *pch = dev->parent;
const void *blob = gd->fdt_blob;
int node;
debug("pch: lpc_init\n");
- pci_write_bar32(hose, dev, 0, 0);
- pci_write_bar32(hose, dev, 1, 0xff800000);
- pci_write_bar32(hose, dev, 2, 0xfec00000);
- pci_write_bar32(hose, dev, 3, 0x800);
- pci_write_bar32(hose, dev, 4, 0x900);
+ dm_pci_write_bar32(pch, 0, 0);
+ dm_pci_write_bar32(pch, 1, 0xff800000);
+ dm_pci_write_bar32(pch, 2, 0xfec00000);
+ dm_pci_write_bar32(pch, 3, 0x800);
+ dm_pci_write_bar32(pch, 4, 0x900);
node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
if (node < 0)
return -ENOENT;
/* Set the value for PCI command register. */
- x86_pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ dm_pci_write_config16(pch, PCI_COMMAND, 0x000f);
/* IO APIC initialization. */
- pch_enable_apic(dev);
+ pch_enable_apic(pch);
- pch_enable_serial_irqs(dev);
+ pch_enable_serial_irqs(pch);
/* Setup the PIRQ. */
- pch_pirq_init(blob, node, dev);
+ pch_pirq_init(pch);
/* Setup power options. */
- pch_power_options(blob, node, dev);
+ pch_power_options(pch);
/* Initialize power management */
- switch (pch_silicon_type()) {
+ switch (pch_silicon_type(pch)) {
case PCH_TYPE_CPT: /* CougarPoint */
- cpt_pm_init(dev);
+ cpt_pm_init(pch);
break;
case PCH_TYPE_PPT: /* PantherPoint */
- ppt_pm_init(dev);
+ ppt_pm_init(pch);
break;
default:
- printf("Unknown Chipset: %#02x.%dx\n", PCI_DEV(dev),
- PCI_FUNC(dev));
+ printf("Unknown Chipset: %s\n", pch->name);
return -ENOSYS;
}
/* Initialize the real time clock. */
- pch_rtc_init(dev);
+ pch_rtc_init(pch);
/* Initialize the High Precision Event Timers, if present. */
enable_hpet();
/* Initialize Clock Gating */
- enable_clock_gating(dev);
+ enable_clock_gating(pch);
- pch_disable_smm_only_flashing(dev);
+ pch_disable_smm_only_flashing(pch);
-#if CONFIG_HAVE_SMI_HANDLER
- pch_lock_smm(dev);
-#endif
+ pch_fixups(pch);
- pch_fixups(dev);
+ return 0;
+}
+
+static int bd82x6x_lpc_early_init(struct udevice *dev)
+{
+ /* Setting up Southbridge. In the northbridge code. */
+ debug("Setting up static southbridge registers\n");
+ dm_pci_write_config32(dev->parent, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
+ dm_pci_write_config32(dev->parent, PMBASE, DEFAULT_PMBASE | 1);
+
+ /* Enable ACPI BAR */
+ dm_pci_write_config8(dev->parent, ACPI_CNTL, 0x80);
+
+ debug("Disabling watchdog reboot\n");
+ setbits_le32(RCB_REG(GCS), 1 >> 5); /* No reset */
+ outw(1 << 11, DEFAULT_PMBASE | 0x60 | 0x08); /* halt timer */
+
+ dm_pci_write_config32(dev->parent, GPIO_BASE, DEFAULT_GPIOBASE | 1);
+ dm_pci_write_config32(dev->parent, GPIO_CNTL, 0x10);
return 0;
}
-void lpc_enable(pci_dev_t dev)
+static int bd82x6x_lpc_probe(struct udevice *dev)
{
- /* Enable PCH Display Port */
- writew(0x0010, RCB_REG(DISPBDF));
- setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
+ int ret;
+
+ if (!(gd->flags & GD_FLG_RELOC)) {
+ ret = lpc_early_init(dev);
+ if (ret) {
+ debug("%s: lpc_early_init() failed\n", __func__);
+ return ret;
+ }
+
+ return bd82x6x_lpc_early_init(dev);
+ }
+
+ return lpc_init_extra(dev);
}
static const struct udevice_id bd82x6x_lpc_ids[] = {
@@ -568,4 +594,5 @@ U_BOOT_DRIVER(bd82x6x_lpc_drv) = {
.name = "lpc",
.id = UCLASS_LPC,
.of_match = bd82x6x_lpc_ids,
+ .probe = bd82x6x_lpc_probe,
};
diff --git a/arch/x86/cpu/ivybridge/model_206ax.c b/arch/x86/cpu/ivybridge/model_206ax.c
index fd7db97..9654600 100644
--- a/arch/x86/cpu/ivybridge/model_206ax.c
+++ b/arch/x86/cpu/ivybridge/model_206ax.c
@@ -8,10 +8,13 @@
*/
#include <common.h>
+#include <cpu.h>
+#include <dm.h>
#include <fdtdec.h>
#include <malloc.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
+#include <asm/cpu_x86.h>
#include <asm/lapic.h>
#include <asm/msr.h>
#include <asm/mtrr.h>
@@ -280,18 +283,13 @@ static void configure_c_states(void)
msr_write(MSR_PP1_CURRENT_CONFIG, msr);
}
-static int configure_thermal_target(void)
+static int configure_thermal_target(struct udevice *dev)
{
int tcc_offset;
msr_t msr;
- int node;
- /* Find pointer to CPU configuration */
- node = fdtdec_next_compatible(gd->fdt_blob, 0,
- COMPAT_INTEL_MODEL_206AX);
- if (node < 0)
- return -ENOENT;
- tcc_offset = fdtdec_get_int(gd->fdt_blob, node, "tcc-offset", 0);
+ tcc_offset = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "tcc-offset",
+ 0);
/* Set TCC activaiton offset if supported */
msr = msr_read(MSR_PLATFORM_INFO);
@@ -400,56 +398,7 @@ static void configure_mca(void)
static unsigned ehci_debug_addr;
#endif
-/*
- * Initialize any extra cores/threads in this package.
- */
-static int intel_cores_init(struct x86_cpu_priv *cpu)
-{
- struct cpuid_result result;
- unsigned threads_per_package, threads_per_core, i;
-
- /* Logical processors (threads) per core */
- result = cpuid_ext(0xb, 0);
- threads_per_core = result.ebx & 0xffff;
-
- /* Logical processors (threads) per package */
- result = cpuid_ext(0xb, 1);
- threads_per_package = result.ebx & 0xffff;
-
- debug("CPU: %u has %u cores, %u threads per core\n",
- cpu->apic_id, threads_per_package / threads_per_core,
- threads_per_core);
-
- for (i = 1; i < threads_per_package; ++i) {
- struct x86_cpu_priv *new_cpu;
-
- new_cpu = calloc(1, sizeof(*new_cpu));
- if (!new_cpu)
- return -ENOMEM;
-
- new_cpu->apic_id = cpu->apic_id + i;
-
- /* Update APIC ID if no hyperthreading */
- if (threads_per_core == 1)
- new_cpu->apic_id <<= 1;
-
- debug("CPU: %u has core %u\n", cpu->apic_id, new_cpu->apic_id);
-
-#if 0 && CONFIG_SMP && CONFIG_MAX_CPUS > 1
- /* TODO(sjg@chromium.org): Start the new cpu */
- if (!start_cpu(new_cpu)) {
- /* Record the error in cpu? */
- printk(BIOS_ERR, "CPU %u would not start!\n",
- new_cpu->apic_id);
- new_cpu->start_err = 1;
- }
-#endif
- }
-
- return 0;
-}
-
-int model_206ax_init(struct x86_cpu_priv *cpu)
+static int model_206ax_init(struct udevice *dev)
{
int ret;
@@ -463,16 +412,6 @@ int model_206ax_init(struct x86_cpu_priv *cpu)
set_ehci_debug(0);
#endif
- /* Setup MTRRs based on physical address size */
-#if 0 /* TODO: Implement this */
- struct cpuid_result cpuid_regs;
-
- cpuid_regs = cpuid(0x80000008);
- x86_setup_fixed_mtrrs();
- x86_setup_var_mtrrs(cpuid_regs.eax & 0xff, 2);
- x86_mtrr_check();
-#endif
-
#if CONFIG_USBDEBUG
set_ehci_debug(ehci_debug_addr);
#endif
@@ -491,9 +430,11 @@ int model_206ax_init(struct x86_cpu_priv *cpu)
configure_misc();
/* Thermal throttle activation offset */
- ret = configure_thermal_target();
- if (ret)
+ ret = configure_thermal_target(dev);
+ if (ret) {
+ debug("Cannot set thermal target\n");
return ret;
+ }
/* Enable Direct Cache Access */
configure_dca_cap();
@@ -507,8 +448,49 @@ int model_206ax_init(struct x86_cpu_priv *cpu)
/* Enable Turbo */
turbo_enable();
- /* Start up extra cores */
- intel_cores_init(cpu);
+ return 0;
+}
+
+static int model_206ax_get_info(struct udevice *dev, struct cpu_info *info)
+{
+ msr_t msr;
+
+ msr = msr_read(IA32_PERF_CTL);
+ info->cpu_freq = ((msr.lo >> 8) & 0xff) * SANDYBRIDGE_BCLK * 1000000;
+ info->features = 1 << CPU_FEAT_L1_CACHE | 1 << CPU_FEAT_MMU;
+
+ return 0;
+}
+
+static int model_206ax_get_count(struct udevice *dev)
+{
+ return 4;
+}
+
+static int cpu_x86_model_206ax_probe(struct udevice *dev)
+{
+ if (dev->seq == 0)
+ model_206ax_init(dev);
return 0;
}
+
+static const struct cpu_ops cpu_x86_model_206ax_ops = {
+ .get_desc = cpu_x86_get_desc,
+ .get_info = model_206ax_get_info,
+ .get_count = model_206ax_get_count,
+};
+
+static const struct udevice_id cpu_x86_model_206ax_ids[] = {
+ { .compatible = "intel,core-gen3" },
+ { }
+};
+
+U_BOOT_DRIVER(cpu_x86_model_206ax_drv) = {
+ .name = "cpu_x86_model_206ax",
+ .id = UCLASS_CPU,
+ .of_match = cpu_x86_model_206ax_ids,
+ .bind = cpu_x86_bind,
+ .probe = cpu_x86_model_206ax_probe,
+ .ops = &cpu_x86_model_206ax_ops,
+};
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index e3d8c13..a066607 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <asm/msr.h>
#include <asm/acpi.h>
#include <asm/cpu.h>
@@ -18,23 +19,17 @@
#include <asm/arch/model_206ax.h>
#include <asm/arch/sandybridge.h>
-static int bridge_revision_id = -1;
-
-int bridge_silicon_revision(void)
+int bridge_silicon_revision(struct udevice *dev)
{
- if (bridge_revision_id < 0) {
- struct cpuid_result result;
- uint8_t stepping, bridge_id;
- pci_dev_t dev;
-
- result = cpuid(1);
- stepping = result.eax & 0xf;
- dev = PCI_BDF(0, 0, 0);
- bridge_id = x86_pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
- bridge_revision_id = bridge_id | stepping;
- }
-
- return bridge_revision_id;
+ 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;
}
/*
@@ -47,15 +42,14 @@ int bridge_silicon_revision(void)
static const int legacy_hole_base_k = 0xa0000 / 1024;
static const int legacy_hole_size_k = 384;
-static int get_pcie_bar(u32 *base, u32 *len)
+static int get_pcie_bar(struct udevice *dev, u32 *base, u32 *len)
{
- pci_dev_t dev = PCI_BDF(0, 0, 0);
u32 pciexbar_reg;
*base = 0;
*len = 0;
- pciexbar_reg = x86_pci_read_config32(dev, PCIEXBAR);
+ dm_pci_read_config32(dev, PCIEXBAR, &pciexbar_reg);
if (!(pciexbar_reg & (1 << 0)))
return 0;
@@ -81,55 +75,55 @@ static int get_pcie_bar(u32 *base, u32 *len)
return 0;
}
-static void add_fixed_resources(pci_dev_t dev, int index)
+static void add_fixed_resources(struct udevice *dev, int index)
{
u32 pcie_config_base, pcie_config_size;
- if (get_pcie_bar(&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(pci_dev_t dev)
+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 ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB) {
+ 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 (bridge_silicon_revision() >= SNB_STEP_D0) {
+ if (rev >= SNB_STEP_D0) {
setbits_le32(DMIBAR_REG(0x1f8), 1 << 16);
- } else if (bridge_silicon_revision() >= SNB_STEP_D1) {
+ } 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 ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_SNB)
+ if ((rev & BASE_REV_MASK) == BASE_REV_SNB)
setbits_le32(DMIBAR_REG(0xd04), 1 << 4);
setbits_le32(DMIBAR_REG(0x88), (1 << 1) | (1 << 0));
}
-void northbridge_init(pci_dev_t dev)
+static void northbridge_init(struct udevice *dev, int rev)
{
u32 bridge_type;
add_fixed_resources(dev, 6);
- northbridge_dmi_init(dev);
+ northbridge_dmi_init(dev, rev);
bridge_type = readl(MCHBAR_REG(0x5f10));
bridge_type &= ~0xff;
- if ((bridge_silicon_revision() & BASE_REV_MASK) == BASE_REV_IVB) {
+ if ((rev & BASE_REV_MASK) == BASE_REV_IVB) {
/* Enable Power Aware Interrupt Routing - fixed priority */
clrsetbits_8(MCHBAR_REG(0x5418), 0xf, 0x4);
@@ -167,6 +161,78 @@ void northbridge_init(pci_dev_t dev)
writel(0x00100001, MCHBAR_REG(0x5500));
}
-void northbridge_enable(pci_dev_t dev)
+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, DEFAULT_MCHBAR | 1);
+ dm_pci_write_config32(dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 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,
+};
diff --git a/arch/x86/cpu/ivybridge/pch.c b/arch/x86/cpu/ivybridge/pch.c
deleted file mode 100644
index bbab646..0000000
--- a/arch/x86/cpu/ivybridge/pch.c
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * From Coreboot
- * Copyright (C) 2008-2009 coresystems GmbH
- * Copyright (C) 2012 The Chromium OS Authors.
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/arch/pch.h>
-
-static int pch_revision_id = -1;
-static int pch_type = -1;
-
-int pch_silicon_revision(void)
-{
- pci_dev_t dev;
-
- dev = PCH_LPC_DEV;
-
- if (pch_revision_id < 0)
- pch_revision_id = x86_pci_read_config8(dev, PCI_REVISION_ID);
- return pch_revision_id;
-}
-
-int pch_silicon_type(void)
-{
- pci_dev_t dev;
-
- dev = PCH_LPC_DEV;
-
- if (pch_type < 0)
- pch_type = x86_pci_read_config8(dev, PCI_DEVICE_ID + 1);
- return pch_type;
-}
-
-int pch_silicon_supported(int type, int rev)
-{
- int cur_type = pch_silicon_type();
- int cur_rev = pch_silicon_revision();
-
- switch (type) {
- case PCH_TYPE_CPT:
- /* CougarPoint minimum revision */
- if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
- return 1;
- /* PantherPoint any revision */
- if (cur_type == PCH_TYPE_PPT)
- return 1;
- break;
-
- case PCH_TYPE_PPT:
- /* PantherPoint minimum revision */
- if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
- return 1;
- break;
- }
-
- return 0;
-}
-
-#define IOBP_RETRY 1000
-static inline int iobp_poll(void)
-{
- unsigned try = IOBP_RETRY;
- u32 data;
-
- while (try--) {
- data = readl(RCB_REG(IOBPS));
- if ((data & 1) == 0)
- return 1;
- udelay(10);
- }
-
- printf("IOBP timeout\n");
- return 0;
-}
-
-void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
-{
- u32 data;
-
- /* Set the address */
- writel(address, RCB_REG(IOBPIRI));
-
- /* READ OPCODE */
- if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
- writel(IOBPS_RW_BX, RCB_REG(IOBPS));
- else
- writel(IOBPS_READ_AX, RCB_REG(IOBPS));
- if (!iobp_poll())
- return;
-
- /* Read IOBP data */
- data = readl(RCB_REG(IOBPD));
- if (!iobp_poll())
- return;
-
- /* Check for successful transaction */
- if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) {
- printf("IOBP read 0x%08x failed\n", address);
- return;
- }
-
- /* Update the data */
- data &= andvalue;
- data |= orvalue;
-
- /* WRITE OPCODE */
- if (pch_silicon_supported(PCH_TYPE_CPT, PCH_STEP_B0))
- writel(IOBPS_RW_BX, RCB_REG(IOBPS));
- else
- writel(IOBPS_WRITE_AX, RCB_REG(IOBPS));
- if (!iobp_poll())
- return;
-
- /* Write IOBP data */
- writel(data, RCB_REG(IOBPD));
- if (!iobp_poll())
- return;
-}
diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c
deleted file mode 100644
index 5e90f30..0000000
--- a/arch/x86/cpu/ivybridge/pci.c
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2011 The Chromium OS Authors.
- * (C) Copyright 2008,2009
- * Graeme Russ, <graeme.russ@gmail.com>
- *
- * (C) Copyright 2002
- * Daniel Engström, Omicron Ceti AB, <daniel@omicron.se>
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <dm.h>
-#include <pci.h>
-#include <asm/pci.h>
-#include <asm/post.h>
-#include <asm/arch/bd82x6x.h>
-#include <asm/arch/pch.h>
-
-static int pci_ivybridge_probe(struct udevice *bus)
-{
- struct pci_controller *hose = dev_get_uclass_priv(bus);
- pci_dev_t dev;
- u16 reg16;
-
- if (!(gd->flags & GD_FLG_RELOC))
- return 0;
- post_code(0x50);
- bd82x6x_init();
- post_code(0x51);
-
- reg16 = 0xff;
- dev = PCH_DEV;
- reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
- reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- x86_pci_write_config16(dev, PCI_COMMAND, reg16);
-
- /*
- * Clear non-reserved bits in status register.
- */
- pci_hose_write_config_word(hose, dev, PCI_STATUS, 0xffff);
- pci_hose_write_config_byte(hose, dev, PCI_LATENCY_TIMER, 0x80);
- pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
-
- pci_write_bar32(hose, dev, 0, 0xf0000000);
- post_code(0x52);
-
- return 0;
-}
-
-static const struct dm_pci_ops pci_ivybridge_ops = {
- .read_config = pci_x86_read_config,
- .write_config = pci_x86_write_config,
-};
-
-static const struct udevice_id pci_ivybridge_ids[] = {
- { .compatible = "intel,pci-ivybridge" },
- { }
-};
-
-U_BOOT_DRIVER(pci_ivybridge_drv) = {
- .name = "pci_ivybridge",
- .id = UCLASS_PCI,
- .of_match = pci_ivybridge_ids,
- .ops = &pci_ivybridge_ops,
- .probe = pci_ivybridge_probe,
-};
diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/ivybridge/report_platform.c
index 4493870..c78322a 100644
--- a/arch/x86/cpu/ivybridge/report_platform.c
+++ b/arch/x86/cpu/ivybridge/report_platform.c
@@ -10,6 +10,7 @@
#include <asm/cpu.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
+#include <asm/arch/sandybridge.h>
static void report_cpu_info(void)
{
@@ -63,27 +64,27 @@ static struct {
{0x1E5F, "NM70"},
};
-static void report_pch_info(void)
+static void report_pch_info(struct udevice *dev)
{
const char *pch_type = "Unknown";
int i;
u16 dev_id;
uint8_t rev_id;
- dev_id = x86_pci_read_config16(PCH_LPC_DEV, 2);
+ dm_pci_read_config16(dev, 2, &dev_id);
for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
if (pch_table[i].dev_id == dev_id) {
pch_type = pch_table[i].dev_name;
break;
}
}
- rev_id = x86_pci_read_config8(PCH_LPC_DEV, 8);
+ dm_pci_read_config8(dev, 8, &rev_id);
debug("PCH type: %s, device id: %x, rev id %x\n", pch_type, dev_id,
rev_id);
}
-void report_platform_info(void)
+void report_platform_info(struct udevice *dev)
{
report_cpu_info();
- report_pch_info();
+ report_pch_info(dev);
}
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index e7bf03c..a59d9ed 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -6,48 +6,56 @@
*/
#include <common.h>
+#include <dm.h>
#include <fdtdec.h>
#include <asm/io.h>
#include <asm/pci.h>
#include <asm/arch/pch.h>
#include <asm/arch/bd82x6x.h>
-static inline u32 sir_read(pci_dev_t dev, int idx)
+DECLARE_GLOBAL_DATA_PTR;
+
+static inline u32 sir_read(struct udevice *dev, int idx)
{
- x86_pci_write_config32(dev, SATA_SIRI, idx);
- return x86_pci_read_config32(dev, SATA_SIRD);
+ u32 data;
+
+ dm_pci_write_config32(dev, SATA_SIRI, idx);
+ dm_pci_read_config32(dev, SATA_SIRD, &data);
+
+ return data;
}
-static inline void sir_write(pci_dev_t dev, int idx, u32 value)
+static inline void sir_write(struct udevice *dev, int idx, u32 value)
{
- x86_pci_write_config32(dev, SATA_SIRI, idx);
- x86_pci_write_config32(dev, SATA_SIRD, value);
+ dm_pci_write_config32(dev, SATA_SIRI, idx);
+ dm_pci_write_config32(dev, SATA_SIRD, value);
}
-static void common_sata_init(pci_dev_t dev, unsigned int port_map)
+static void common_sata_init(struct udevice *dev, unsigned int port_map)
{
u32 reg32;
u16 reg16;
/* Set IDE I/O Configuration */
reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
- x86_pci_write_config32(dev, IDE_CONFIG, reg32);
+ dm_pci_write_config32(dev, IDE_CONFIG, reg32);
/* Port enable */
- reg16 = x86_pci_read_config16(dev, 0x92);
+ dm_pci_read_config16(dev, 0x92, &reg16);
reg16 &= ~0x3f;
reg16 |= port_map;
- x86_pci_write_config16(dev, 0x92, reg16);
+ dm_pci_write_config16(dev, 0x92, reg16);
/* SATA Initialization register */
port_map &= 0xff;
- x86_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
+ dm_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
}
-void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
+static void bd82x6x_sata_init(struct udevice *dev, struct udevice *pch)
{
unsigned int port_map, speed_support, port_tx;
- struct pci_controller *hose = pci_bus_to_hose(0);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
const char *mode;
u32 reg32;
u16 reg16;
@@ -59,33 +67,27 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
speed_support = fdtdec_get_int(blob, node,
"sata_interface_speed_support", 0);
- /* Enable BARs */
- x86_pci_write_config16(dev, PCI_COMMAND, 0x0007);
-
mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
if (!mode || !strcmp(mode, "ahci")) {
u32 abar;
debug("SATA: Controller in AHCI mode\n");
- /* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
- x86_pci_write_config8(dev, INTR_LN, 0x0a);
-
/* Set timings */
- x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
/* Sync DMA */
- x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
- x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+ dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+ dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
common_sata_init(dev, 0x8000 | port_map);
/* Initialize AHCI memory-mapped space */
- abar = pci_read_bar32(hose, dev, 5);
+ abar = dm_pci_read_bar32(dev, 5);
debug("ABAR: %08X\n", abar);
/* CAP (HBA Capabilities) : enable power management */
reg32 = readl(abar + 0x00);
@@ -113,59 +115,54 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
debug("SATA: Controller in combined mode\n");
/* No AHCI: clear AHCI base */
- pci_write_bar32(hose, dev, 5, 0x00000000);
+ dm_pci_write_bar32(dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
- reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
+ dm_pci_read_config16(dev, PCI_COMMAND, &reg16);
reg16 &= ~PCI_COMMAND_MEMORY;
- x86_pci_write_config16(dev, PCI_COMMAND, reg16);
+ dm_pci_write_config16(dev, PCI_COMMAND, reg16);
- x86_pci_write_config8(dev, 0x09, 0x80);
+ dm_pci_write_config8(dev, 0x09, 0x80);
/* Set timings */
- x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
- x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
- x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
- x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+ dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+ dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
common_sata_init(dev, port_map);
} else {
debug("SATA: Controller in plain-ide mode\n");
/* No AHCI: clear AHCI base */
- pci_write_bar32(hose, dev, 5, 0x00000000);
+ dm_pci_write_bar32(dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
- reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
+ dm_pci_read_config16(dev, PCI_COMMAND, &reg16);
reg16 &= ~PCI_COMMAND_MEMORY;
- x86_pci_write_config16(dev, PCI_COMMAND, reg16);
+ dm_pci_write_config16(dev, PCI_COMMAND, reg16);
/*
* Native mode capable on both primary and secondary (0xa)
* OR'ed with enabled (0x50) = 0xf
*/
- x86_pci_write_config8(dev, 0x09, 0x8f);
-
- /* Set Interrupt Line */
- /* Interrupt Pin is set by D31IP.PIP */
- x86_pci_write_config8(dev, INTR_LN, 0xff);
+ dm_pci_write_config8(dev, 0x09, 0x8f);
/* Set timings */
- x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ dm_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_SITRE | IDE_ISP_3_CLOCKS |
IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
- x86_pci_write_config16(dev, IDE_SDMA_CNT,
- IDE_SSDE0 | IDE_PSDE0);
- x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+ dm_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
+ dm_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
common_sata_init(dev, port_map);
}
@@ -173,11 +170,11 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
/* Set Gen3 Transmitter settings if needed */
port_tx = fdtdec_get_int(blob, node, "intel,sata-port0-gen3-tx", 0);
if (port_tx)
- pch_iobp_update(SATA_IOBP_SP0G3IR, 0, port_tx);
+ pch_iobp_update(pch, SATA_IOBP_SP0G3IR, 0, port_tx);
port_tx = fdtdec_get_int(blob, node, "intel,sata-port1-gen3-tx", 0);
if (port_tx)
- pch_iobp_update(SATA_IOBP_SP1G3IR, 0, port_tx);
+ pch_iobp_update(pch, SATA_IOBP_SP1G3IR, 0, port_tx);
/* Additional Programming Requirements */
sir_write(dev, 0x04, 0x00001600);
@@ -202,12 +199,14 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
sir_write(dev, 0xc8, 0x0c0c0c0c);
sir_write(dev, 0xd4, 0x10000000);
- pch_iobp_update(0xea004001, 0x3fffffff, 0xc0000000);
- pch_iobp_update(0xea00408a, 0xfffffcff, 0x00000100);
+ pch_iobp_update(pch, 0xea004001, 0x3fffffff, 0xc0000000);
+ pch_iobp_update(pch, 0xea00408a, 0xfffffcff, 0x00000100);
}
-void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
+static void bd82x6x_sata_enable(struct udevice *dev)
{
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
unsigned port_map;
const char *mode;
u16 map = 0;
@@ -222,5 +221,36 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
map |= (port_map ^ 0x3f) << 8;
- x86_pci_write_config16(dev, 0x90, map);
+ dm_pci_write_config16(dev, 0x90, map);
}
+
+static int bd82x6x_sata_probe(struct udevice *dev)
+{
+ struct udevice *pch;
+ int ret;
+
+ ret = uclass_first_device(UCLASS_PCH, &pch);
+ if (ret)
+ return ret;
+ if (!pch)
+ return -ENODEV;
+
+ if (!(gd->flags & GD_FLG_RELOC))
+ bd82x6x_sata_enable(dev);
+ else
+ bd82x6x_sata_init(dev, pch);
+
+ return 0;
+}
+
+static const struct udevice_id bd82x6x_ahci_ids[] = {
+ { .compatible = "intel,pantherpoint-ahci" },
+ { }
+};
+
+U_BOOT_DRIVER(ahci_ivybridge_drv) = {
+ .name = "ahci_ivybridge",
+ .id = UCLASS_DISK,
+ .of_match = bd82x6x_ahci_ids,
+ .probe = bd82x6x_sata_probe,
+};
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 4372a5c..e23c422 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -18,6 +18,8 @@
#include <rtc.h>
#include <spi.h>
#include <spi_flash.h>
+#include <syscon.h>
+#include <asm/cpu.h>
#include <asm/processor.h>
#include <asm/gpio.h>
#include <asm/global_data.h>
@@ -283,22 +285,24 @@ static int recovery_mode_enabled(void)
/**
* Find the PEI executable in the ROM and execute it.
*
- * @param pei_data: configuration data for UEFI PEI reference code
+ * @dev: Northbridge device
+ * @pei_data: configuration data for UEFI PEI reference code
*/
-int sdram_initialise(struct pei_data *pei_data)
+int sdram_initialise(struct udevice *dev, struct udevice *me_dev,
+ struct pei_data *pei_data)
{
unsigned version;
const char *data;
uint16_t done;
int ret;
- report_platform_info();
+ report_platform_info(dev);
/* Wait for ME to be ready */
- ret = intel_early_me_init();
+ ret = intel_early_me_init(me_dev);
if (ret)
return ret;
- ret = intel_early_me_uma_size();
+ ret = intel_early_me_uma_size(me_dev);
if (ret < 0)
return ret;
@@ -374,12 +378,12 @@ int sdram_initialise(struct pei_data *pei_data)
* Send ME init done for SandyBridge here. This is done inside the
* SystemAgent binary on IvyBridge
*/
- done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
+ dm_pci_read_config16(dev, PCI_DEVICE_ID, &done);
done &= BASE_REV_MASK;
if (BASE_REV_SNB == done)
- intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
+ intel_early_me_init_done(dev, me_dev, ME_INIT_STATUS_SUCCESS);
else
- intel_early_me_status();
+ intel_early_me_status(me_dev);
post_system_agent_init(pei_data);
report_memory_config();
@@ -495,8 +499,10 @@ static int add_memory_area(struct memory_info *info,
*
* This is a bit complicated since on x86 there are system memory holes all
* over the place. We create a list of available memory blocks
+ *
+ * @dev: Northbridge device
*/
-static int sdram_find(pci_dev_t dev)
+static int sdram_find(struct udevice *dev)
{
struct memory_info *info = &gd->arch.meminfo;
uint32_t tseg_base, uma_size, tolud;
@@ -505,6 +511,7 @@ static int sdram_find(pci_dev_t dev)
uint64_t uma_memory_size;
unsigned long long tomk;
uint16_t ggc;
+ u32 val;
/* Total Memory 2GB example:
*
@@ -533,24 +540,27 @@ static int sdram_find(pci_dev_t dev)
*/
/* Top of Upper Usable DRAM, including remap */
- touud = x86_pci_read_config32(dev, TOUUD+4);
- touud <<= 32;
- touud |= x86_pci_read_config32(dev, TOUUD);
+ dm_pci_read_config32(dev, TOUUD + 4, &val);
+ touud = (uint64_t)val << 32;
+ dm_pci_read_config32(dev, TOUUD, &val);
+ touud |= val;
/* Top of Lower Usable DRAM */
- tolud = x86_pci_read_config32(dev, TOLUD);
+ dm_pci_read_config32(dev, TOLUD, &tolud);
/* Top of Memory - does not account for any UMA */
- tom = x86_pci_read_config32(dev, 0xa4);
- tom <<= 32;
- tom |= x86_pci_read_config32(dev, 0xa0);
+ dm_pci_read_config32(dev, 0xa4, &val);
+ tom = (uint64_t)val << 32;
+ dm_pci_read_config32(dev, 0xa0, &val);
+ tom |= val;
debug("TOUUD %llx TOLUD %08x TOM %llx\n", touud, tolud, tom);
/* ME UMA needs excluding if total memory <4GB */
- me_base = x86_pci_read_config32(dev, 0x74);
- me_base <<= 32;
- me_base |= x86_pci_read_config32(dev, 0x70);
+ dm_pci_read_config32(dev, 0x74, &val);
+ me_base = (uint64_t)val << 32;
+ dm_pci_read_config32(dev, 0x70, &val);
+ me_base |= val;
debug("MEBASE %llx\n", me_base);
@@ -568,7 +578,7 @@ static int sdram_find(pci_dev_t dev)
}
/* Graphics memory comes next */
- ggc = x86_pci_read_config16(dev, GGC);
+ dm_pci_read_config16(dev, GGC, &ggc);
if (!(ggc & 2)) {
debug("IGD decoded, subtracting ");
@@ -588,7 +598,7 @@ static int sdram_find(pci_dev_t dev)
}
/* Calculate TSEG size from its base which must be below GTT */
- tseg_base = x86_pci_read_config32(dev, 0xb8);
+ dm_pci_read_config32(dev, 0xb8, &tseg_base);
uma_size = (uma_memory_base - tseg_base) >> 10;
tomk -= uma_size;
uma_memory_base = tomk * 1024ULL;
@@ -723,15 +733,23 @@ int dram_init(void)
{ 0, 4, 0x0000 }, /* P13= Empty */
},
};
- pci_dev_t dev = PCI_BDF(0, 0, 0);
+ struct udevice *dev, *me_dev;
int ret;
+ ret = uclass_first_device(UCLASS_NORTHBRIDGE, &dev);
+ if (ret)
+ return ret;
+ if (!dev)
+ return -ENODEV;
+ ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev);
+ if (ret)
+ return ret;
debug("Boot mode %d\n", gd->arch.pei_boot_mode);
debug("mrc_input %p\n", pei_data.mrc_input);
pei_data.boot_mode = gd->arch.pei_boot_mode;
ret = copy_spd(&pei_data);
if (!ret)
- ret = sdram_initialise(&pei_data);
+ ret = sdram_initialise(dev, me_dev, &pei_data);
if (ret)
return ret;
diff --git a/arch/x86/cpu/ivybridge/usb_ehci.c b/arch/x86/cpu/ivybridge/usb_ehci.c
deleted file mode 100644
index da11aee..0000000
--- a/arch/x86/cpu/ivybridge/usb_ehci.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * From Coreboot
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/io.h>
-#include <asm/pci.h>
-#include <asm/arch/pch.h>
-
-void bd82x6x_usb_ehci_init(pci_dev_t dev)
-{
- u32 reg32;
-
- /* Disable Wake on Disconnect in RMH */
- reg32 = readl(RCB_REG(0x35b0));
- reg32 |= 0x22;
- writel(reg32, RCB_REG(0x35b0));
-
- debug("EHCI: Setting up controller.. ");
- reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
- reg32 |= PCI_COMMAND_MASTER;
- /* reg32 |= PCI_COMMAND_SERR; */
- x86_pci_write_config32(dev, PCI_COMMAND, reg32);
-
- debug("done.\n");
-}
diff --git a/arch/x86/cpu/ivybridge/usb_xhci.c b/arch/x86/cpu/ivybridge/usb_xhci.c
deleted file mode 100644
index f77b804..0000000
--- a/arch/x86/cpu/ivybridge/usb_xhci.c
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * From Coreboot
- * Copyright (C) 2008-2009 coresystems GmbH
- *
- * SPDX-License-Identifier: GPL-2.0
- */
-
-#include <common.h>
-#include <asm/pci.h>
-#include <asm/arch/pch.h>
-
-void bd82x6x_usb_xhci_init(pci_dev_t dev)
-{
- u32 reg32;
-
- debug("XHCI: Setting up controller.. ");
-
- /* lock overcurrent map */
- reg32 = x86_pci_read_config32(dev, 0x44);
- reg32 |= 1;
- x86_pci_write_config32(dev, 0x44, reg32);
-
- /* Enable clock gating */
- reg32 = x86_pci_read_config32(dev, 0x40);
- reg32 &= ~((1 << 20) | (1 << 21));
- reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
- reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
- reg32 |= (1 << 31); /* lock */
- x86_pci_write_config32(dev, 0x40, reg32);
-
- debug("done.\n");
-}