diff options
Diffstat (limited to 'arch/x86/cpu/ivybridge')
-rw-r--r-- | arch/x86/cpu/ivybridge/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/Makefile | 5 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/bd82x6x.c | 256 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/cpu.c | 146 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/early_init.c | 147 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/early_me.c | 70 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/gma.c | 114 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/lpc.c | 295 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/model_206ax.c | 126 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/northbridge.c | 126 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/pch.c | 123 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/pci.c | 67 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/report_platform.c | 11 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/sata.c | 132 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/sdram.c | 64 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/usb_ehci.c | 29 | ||||
-rw-r--r-- | arch/x86/cpu/ivybridge/usb_xhci.c | 32 |
17 files changed, 792 insertions, 952 deletions
diff --git a/arch/x86/cpu/ivybridge/Kconfig b/arch/x86/cpu/ivybridge/Kconfig index 56abd8fae3..1768a26a35 100644 --- a/arch/x86/cpu/ivybridge/Kconfig +++ b/arch/x86/cpu/ivybridge/Kconfig @@ -48,7 +48,6 @@ config DCACHE_RAM_MRC_VAR_SIZE config CPU_SPECIFIC_OPTIONS def_bool y select SMM_TSEG - select HAVE_INTEL_ME select X86_RAMTEST config SMM_TSEG_SIZE diff --git a/arch/x86/cpu/ivybridge/Makefile b/arch/x86/cpu/ivybridge/Makefile index 0c7efaec7c..45ef14187e 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 434dfd649f..2b172d49ba 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 343bfb4e98..948833c028 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, ®8); - 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 9ca008e345..0000000000 --- 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 711470f364..b1df77d571 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 85a09c64b6..3b6291e905 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, ®16); + 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, ®16); + 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, ®8); + 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, ®32); @@ -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 af5d4a8908..9ab5ed3ff9 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, ®16); 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, ®16); 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, ®8); 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, ®16); 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, ®8); /* 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, ®8); + 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 fd7db97cbd..9654600cf1 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 e3d8c139df..a066607a18 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, ®8); + 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 bbab64699e..0000000000 --- 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 5e90f30e08..0000000000 --- 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 44938709c9..c78322aef9 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 e7bf03c1dc..a59d9edce5 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, ®16); 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, ®16); 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, ®16); 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 4372a5caf2..e23c422cd0 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 da11aee94d..0000000000 --- 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 f77b80489b..0000000000 --- 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"); -} |