14e7a6acaSSimon Glass /* 24e7a6acaSSimon Glass * Copyright (C) 2014 Google, Inc 34e7a6acaSSimon Glass * 44e7a6acaSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 54e7a6acaSSimon Glass */ 64e7a6acaSSimon Glass #include <common.h> 7aad78d27SSimon Glass #include <dm.h> 84e7a6acaSSimon Glass #include <errno.h> 94e7a6acaSSimon Glass #include <fdtdec.h> 104e7a6acaSSimon Glass #include <malloc.h> 11f2b85ab5SSimon Glass #include <pch.h> 124e7a6acaSSimon Glass #include <asm/lapic.h> 134e7a6acaSSimon Glass #include <asm/pci.h> 144e7a6acaSSimon Glass #include <asm/arch/bd82x6x.h> 154e7a6acaSSimon Glass #include <asm/arch/model_206ax.h> 164e7a6acaSSimon Glass #include <asm/arch/pch.h> 174e7a6acaSSimon Glass #include <asm/arch/sandybridge.h> 184e7a6acaSSimon Glass 19f2b85ab5SSimon Glass #define BIOS_CTRL 0xdc 20f2b85ab5SSimon Glass 21aad78d27SSimon Glass static int bd82x6x_probe(struct udevice *dev) 224e7a6acaSSimon Glass { 233ac83935SSimon Glass const void *blob = gd->fdt_blob; 2472cd085aSSimon Glass struct pci_controller *hose; 25*01a67908SSimon Glass int gma_node; 26effcf067SSimon Glass int ret; 2772cd085aSSimon Glass 284acc83d4SSimon Glass if (!(gd->flags & GD_FLG_RELOC)) 294acc83d4SSimon Glass return 0; 304acc83d4SSimon Glass 3172cd085aSSimon Glass hose = pci_bus_to_hose(0); 3272cd085aSSimon Glass lpc_enable(PCH_LPC_DEV); 332b27d205SSimon Glass lpc_init_extra(hose, PCH_LPC_DEV); 34*01a67908SSimon Glass 35*01a67908SSimon Glass /* Cause the SATA device to do its init */ 36*01a67908SSimon Glass uclass_first_device(UCLASS_DISK, &dev); 37*01a67908SSimon Glass 389baeca4bSSimon Glass bd82x6x_usb_ehci_init(PCH_EHCI1_DEV); 399baeca4bSSimon Glass bd82x6x_usb_ehci_init(PCH_EHCI2_DEV); 4072cd085aSSimon Glass 41effcf067SSimon Glass gma_node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_GMA); 42effcf067SSimon Glass if (gma_node < 0) { 43effcf067SSimon Glass debug("%s: Cannot find GMA node\n", __func__); 44effcf067SSimon Glass return -EINVAL; 45effcf067SSimon Glass } 469bf727fcSSimon Glass ret = dm_pci_bus_find_bdf(PCH_VIDEO_DEV, &dev); 479bf727fcSSimon Glass if (ret) 489bf727fcSSimon Glass return ret; 499bf727fcSSimon Glass ret = gma_func0_init(dev, blob, gma_node); 50effcf067SSimon Glass if (ret) 51effcf067SSimon Glass return ret; 52effcf067SSimon Glass 534e7a6acaSSimon Glass return 0; 544e7a6acaSSimon Glass } 554e7a6acaSSimon Glass 56f2b85ab5SSimon Glass static int bd82x6x_pch_get_sbase(struct udevice *dev, ulong *sbasep) 57f2b85ab5SSimon Glass { 58f2b85ab5SSimon Glass u32 rcba; 59f2b85ab5SSimon Glass 60f2b85ab5SSimon Glass dm_pci_read_config32(dev, PCH_RCBA, &rcba); 61f2b85ab5SSimon Glass /* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */ 62f2b85ab5SSimon Glass rcba = rcba & 0xffffc000; 63f2b85ab5SSimon Glass *sbasep = rcba + 0x3800; 64f2b85ab5SSimon Glass 65f2b85ab5SSimon Glass return 0; 66f2b85ab5SSimon Glass } 67f2b85ab5SSimon Glass 68f2b85ab5SSimon Glass static enum pch_version bd82x6x_pch_get_version(struct udevice *dev) 69f2b85ab5SSimon Glass { 70f2b85ab5SSimon Glass return PCHV_9; 71f2b85ab5SSimon Glass } 72f2b85ab5SSimon Glass 73f2b85ab5SSimon Glass static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect) 74f2b85ab5SSimon Glass { 75f2b85ab5SSimon Glass uint8_t bios_cntl; 76f2b85ab5SSimon Glass 77f2b85ab5SSimon Glass /* Adjust the BIOS write protect and SMM BIOS Write Protect Disable */ 78f2b85ab5SSimon Glass dm_pci_read_config8(dev, BIOS_CTRL, &bios_cntl); 79f2b85ab5SSimon Glass if (protect) { 80f2b85ab5SSimon Glass bios_cntl &= ~BIOS_CTRL_BIOSWE; 81f2b85ab5SSimon Glass bios_cntl |= BIT(5); 82f2b85ab5SSimon Glass } else { 83f2b85ab5SSimon Glass bios_cntl |= BIOS_CTRL_BIOSWE; 84f2b85ab5SSimon Glass bios_cntl &= ~BIT(5); 85f2b85ab5SSimon Glass } 86f2b85ab5SSimon Glass dm_pci_write_config8(dev, BIOS_CTRL, bios_cntl); 87f2b85ab5SSimon Glass 88f2b85ab5SSimon Glass return 0; 89f2b85ab5SSimon Glass } 90f2b85ab5SSimon Glass 91f2b85ab5SSimon Glass static const struct pch_ops bd82x6x_pch_ops = { 92f2b85ab5SSimon Glass .get_sbase = bd82x6x_pch_get_sbase, 93f2b85ab5SSimon Glass .get_version = bd82x6x_pch_get_version, 94f2b85ab5SSimon Glass .set_spi_protect = bd82x6x_set_spi_protect, 95f2b85ab5SSimon Glass }; 96f2b85ab5SSimon Glass 97aad78d27SSimon Glass static const struct udevice_id bd82x6x_ids[] = { 98aad78d27SSimon Glass { .compatible = "intel,bd82x6x" }, 99aad78d27SSimon Glass { } 100aad78d27SSimon Glass }; 101aad78d27SSimon Glass 102aad78d27SSimon Glass U_BOOT_DRIVER(bd82x6x_drv) = { 103aad78d27SSimon Glass .name = "bd82x6x", 104aad78d27SSimon Glass .id = UCLASS_PCH, 105aad78d27SSimon Glass .of_match = bd82x6x_ids, 106aad78d27SSimon Glass .probe = bd82x6x_probe, 107f2b85ab5SSimon Glass .ops = &bd82x6x_pch_ops, 108aad78d27SSimon Glass }; 109