]> git.sur5r.net Git - u-boot/blobdiff - arch/x86/cpu/ivybridge/bd82x6x.c
x86: ivybridge: Move lpc_early_init() to probe()
[u-boot] / arch / x86 / cpu / ivybridge / bd82x6x.c
index 1a3c0368504fb4ae2b75e7de48b780ea6de2fc7c..72f2ed4d712c929210450ff6d5383eaed899cbc5 100644 (file)
@@ -3,11 +3,12 @@
  *
  * 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 <asm/lapic.h>
 #include <asm/pci.h>
 #include <asm/arch/bd82x6x.h>
@@ -15,6 +16,8 @@
 #include <asm/arch/pch.h>
 #include <asm/arch/sandybridge.h>
 
+#define BIOS_CTRL      0xdc
+
 void bd82x6x_pci_init(pci_dev_t dev)
 {
        u16 reg16;
@@ -22,76 +25,48 @@ void bd82x6x_pci_init(pci_dev_t dev)
 
        debug("bd82x6x PCI init.\n");
        /* Enable Bus Master */
-       reg16 = pci_read_config16(dev, PCI_COMMAND);
+       reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
        reg16 |= PCI_COMMAND_MASTER;
-       pci_write_config16(dev, PCI_COMMAND, reg16);
+       x86_pci_write_config16(dev, PCI_COMMAND, reg16);
 
        /* This device has no interrupt */
-       pci_write_config8(dev, INTR, 0xff);
+       x86_pci_write_config8(dev, INTR, 0xff);
 
        /* disable parity error response and SERR */
-       reg16 = pci_read_config16(dev, BCTRL);
+       reg16 = x86_pci_read_config16(dev, BCTRL);
        reg16 &= ~(1 << 0);
        reg16 &= ~(1 << 1);
-       pci_write_config16(dev, BCTRL, reg16);
+       x86_pci_write_config16(dev, BCTRL, reg16);
 
        /* Master Latency Count must be set to 0x04! */
-       reg8 = pci_read_config8(dev, SMLT);
+       reg8 = x86_pci_read_config8(dev, SMLT);
        reg8 &= 0x07;
        reg8 |= (0x04 << 3);
-       pci_write_config8(dev, SMLT, reg8);
+       x86_pci_write_config8(dev, SMLT, reg8);
 
        /* Will this improve throughput of bus masters? */
-       pci_write_config8(dev, PCI_MIN_GNT, 0x06);
+       x86_pci_write_config8(dev, PCI_MIN_GNT, 0x06);
 
        /* Clear errors in status registers */
-       reg16 = pci_read_config16(dev, PSTS);
+       reg16 = x86_pci_read_config16(dev, PSTS);
        /* reg16 |= 0xf900; */
-       pci_write_config16(dev, PSTS, reg16);
+       x86_pci_write_config16(dev, PSTS, reg16);
 
-       reg16 = pci_read_config16(dev, SECSTS);
+       reg16 = x86_pci_read_config16(dev, SECSTS);
        /* reg16 |= 0xf900; */
-       pci_write_config16(dev, SECSTS, reg16);
-}
-
-#define PCI_BRIDGE_UPDATE_COMMAND
-void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
-{
-       uint16_t command;
-
-       command = pci_read_config16(dev, PCI_COMMAND);
-       command |= PCI_COMMAND_IO;
-#ifdef PCI_BRIDGE_UPDATE_COMMAND
-       /*
-        * If we write to PCI_COMMAND, on some systems this will cause the
-        * ROM and APICs to become invisible.
-        */
-       debug("%x cmd <- %02x\n", dev, command);
-       pci_write_config16(dev, PCI_COMMAND, command);
-#else
-       printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
-#endif
-}
-
-void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
-{
-       uint16_t ctrl;
-
-       ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
-       ctrl |= PCI_COMMAND_IO;
-       ctrl |= PCI_BRIDGE_CTL_VGA;
-       debug("%x bridge ctrl <- %04x\n", dev, ctrl);
-       pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
-
-       bd82x6x_pci_dev_enable_resources(dev);
+       x86_pci_write_config16(dev, SECSTS, reg16);
 }
 
-int bd82x6x_init_pci_devices(void)
+static int bd82x6x_probe(struct udevice *dev)
 {
        const void *blob = gd->fdt_blob;
        struct pci_controller *hose;
        struct x86_cpu_priv *cpu;
-       int sata_node;
+       int sata_node, gma_node;
+       int ret;
+
+       if (!(gd->flags & GD_FLG_RELOC))
+               return 0;
 
        hose = pci_bus_to_hose(0);
        lpc_enable(PCH_LPC_DEV);
@@ -111,9 +86,22 @@ int bd82x6x_init_pci_devices(void)
                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;
+       }
+       ret = dm_pci_bus_find_bdf(PCH_VIDEO_DEV, &dev);
+       if (ret)
+               return ret;
+       ret = gma_func0_init(dev, blob, gma_node);
+       if (ret)
+               return ret;
+
        return 0;
 }
 
+/* TODO(sjg@chromium.org): Move this to the PCH init() method */
 int bd82x6x_init(void)
 {
        const void *blob = gd->fdt_blob;
@@ -128,6 +116,62 @@ int bd82x6x_init(void)
 
        bd82x6x_pci_init(PCH_DEV);
        bd82x6x_sata_enable(PCH_SATA_DEV, blob, sata_node);
+       northbridge_enable(PCH_DEV);
+       northbridge_init(PCH_DEV);
 
        return 0;
 }
+
+static int bd82x6x_pch_get_sbase(struct udevice *dev, ulong *sbasep)
+{
+       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;
+}
+
+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" },
+       { }
+};
+
+U_BOOT_DRIVER(bd82x6x_drv) = {
+       .name           = "bd82x6x",
+       .id             = UCLASS_PCH,
+       .of_match       = bd82x6x_ids,
+       .probe          = bd82x6x_probe,
+       .ops            = &bd82x6x_pch_ops,
+};