xref: /openbmc/u-boot/arch/x86/cpu/ivybridge/bd82x6x.c (revision 01a679084b1d98701f73f1344f6802f3d9ee1076)
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