xref: /openbmc/u-boot/arch/x86/cpu/ivybridge/bd82x6x.c (revision 17fa0326)
1 /*
2  * Copyright (C) 2014 Google, Inc
3  *
4  * SPDX-License-Identifier:	GPL-2.0+
5  */
6 #include <common.h>
7 #include <dm.h>
8 #include <errno.h>
9 #include <fdtdec.h>
10 #include <malloc.h>
11 #include <pch.h>
12 #include <asm/cpu.h>
13 #include <asm/intel_regs.h>
14 #include <asm/io.h>
15 #include <asm/lapic.h>
16 #include <asm/lpc_common.h>
17 #include <asm/pci.h>
18 #include <asm/arch/model_206ax.h>
19 #include <asm/arch/pch.h>
20 #include <asm/arch/sandybridge.h>
21 
22 #define GPIO_BASE	0x48
23 #define BIOS_CTRL	0xdc
24 
25 #ifndef CONFIG_HAVE_FSP
26 static int pch_revision_id = -1;
27 static int pch_type = -1;
28 
29 /**
30  * pch_silicon_revision() - Read silicon revision ID from the PCH
31  *
32  * @dev:	PCH device
33  * @return silicon revision ID
34  */
35 static int pch_silicon_revision(struct udevice *dev)
36 {
37 	u8 val;
38 
39 	if (pch_revision_id < 0) {
40 		dm_pci_read_config8(dev, PCI_REVISION_ID, &val);
41 		pch_revision_id = val;
42 	}
43 
44 	return pch_revision_id;
45 }
46 
47 int pch_silicon_type(struct udevice *dev)
48 {
49 	u8 val;
50 
51 	if (pch_type < 0) {
52 		dm_pci_read_config8(dev, PCI_DEVICE_ID + 1, &val);
53 		pch_type = val;
54 	}
55 
56 	return pch_type;
57 }
58 
59 /**
60  * pch_silicon_supported() - Check if a certain revision is supported
61  *
62  * @dev:	PCH device
63  * @type:	PCH type
64  * @rev:	Minimum required resion
65  * @return 0 if not supported, 1 if supported
66  */
67 static int pch_silicon_supported(struct udevice *dev, int type, int rev)
68 {
69 	int cur_type = pch_silicon_type(dev);
70 	int cur_rev = pch_silicon_revision(dev);
71 
72 	switch (type) {
73 	case PCH_TYPE_CPT:
74 		/* CougarPoint minimum revision */
75 		if (cur_type == PCH_TYPE_CPT && cur_rev >= rev)
76 			return 1;
77 		/* PantherPoint any revision */
78 		if (cur_type == PCH_TYPE_PPT)
79 			return 1;
80 		break;
81 
82 	case PCH_TYPE_PPT:
83 		/* PantherPoint minimum revision */
84 		if (cur_type == PCH_TYPE_PPT && cur_rev >= rev)
85 			return 1;
86 		break;
87 	}
88 
89 	return 0;
90 }
91 
92 #define IOBP_RETRY 1000
93 static inline int iobp_poll(void)
94 {
95 	unsigned try = IOBP_RETRY;
96 	u32 data;
97 
98 	while (try--) {
99 		data = readl(RCB_REG(IOBPS));
100 		if ((data & 1) == 0)
101 			return 1;
102 		udelay(10);
103 	}
104 
105 	printf("IOBP timeout\n");
106 	return 0;
107 }
108 
109 void pch_iobp_update(struct udevice *dev, u32 address, u32 andvalue,
110 		     u32 orvalue)
111 {
112 	u32 data;
113 
114 	/* Set the address */
115 	writel(address, RCB_REG(IOBPIRI));
116 
117 	/* READ OPCODE */
118 	if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0))
119 		writel(IOBPS_RW_BX, RCB_REG(IOBPS));
120 	else
121 		writel(IOBPS_READ_AX, RCB_REG(IOBPS));
122 	if (!iobp_poll())
123 		return;
124 
125 	/* Read IOBP data */
126 	data = readl(RCB_REG(IOBPD));
127 	if (!iobp_poll())
128 		return;
129 
130 	/* Check for successful transaction */
131 	if ((readl(RCB_REG(IOBPS)) & 0x6) != 0) {
132 		printf("IOBP read 0x%08x failed\n", address);
133 		return;
134 	}
135 
136 	/* Update the data */
137 	data &= andvalue;
138 	data |= orvalue;
139 
140 	/* WRITE OPCODE */
141 	if (pch_silicon_supported(dev, PCH_TYPE_CPT, PCH_STEP_B0))
142 		writel(IOBPS_RW_BX, RCB_REG(IOBPS));
143 	else
144 		writel(IOBPS_WRITE_AX, RCB_REG(IOBPS));
145 	if (!iobp_poll())
146 		return;
147 
148 	/* Write IOBP data */
149 	writel(data, RCB_REG(IOBPD));
150 	if (!iobp_poll())
151 		return;
152 }
153 
154 static int bd82x6x_probe(struct udevice *dev)
155 {
156 	if (!(gd->flags & GD_FLG_RELOC))
157 		return 0;
158 
159 	/* Cause the SATA device to do its init */
160 	uclass_first_device(UCLASS_AHCI, &dev);
161 
162 	return 0;
163 }
164 #endif /* CONFIG_HAVE_FSP */
165 
166 static int bd82x6x_pch_get_spi_base(struct udevice *dev, ulong *sbasep)
167 {
168 	u32 rcba;
169 
170 	dm_pci_read_config32(dev, PCH_RCBA, &rcba);
171 	/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable */
172 	rcba = rcba & 0xffffc000;
173 	*sbasep = rcba + 0x3800;
174 
175 	return 0;
176 }
177 
178 static int bd82x6x_set_spi_protect(struct udevice *dev, bool protect)
179 {
180 	return lpc_set_spi_protect(dev, BIOS_CTRL, protect);
181 }
182 
183 static int bd82x6x_get_gpio_base(struct udevice *dev, u32 *gbasep)
184 {
185 	u32 base;
186 
187 	/*
188 	 * GPIO_BASE moved to its current offset with ICH6, but prior to
189 	 * that it was unused (or undocumented). Check that it looks
190 	 * okay: not all ones or zeros.
191 	 *
192 	 * Note we don't need check bit0 here, because the Tunnel Creek
193 	 * GPIO base address register bit0 is reserved (read returns 0),
194 	 * while on the Ivybridge the bit0 is used to indicate it is an
195 	 * I/O space.
196 	 */
197 	dm_pci_read_config32(dev, GPIO_BASE, &base);
198 	if (base == 0x00000000 || base == 0xffffffff) {
199 		debug("%s: unexpected BASE value\n", __func__);
200 		return -ENODEV;
201 	}
202 
203 	/*
204 	 * Okay, I guess we're looking at the right device. The actual
205 	 * GPIO registers are in the PCI device's I/O space, starting
206 	 * at the offset that we just read. Bit 0 indicates that it's
207 	 * an I/O address, not a memory address, so mask that off.
208 	 */
209 	*gbasep = base & 1 ? base & ~3 : base & ~15;
210 
211 	return 0;
212 }
213 
214 static const struct pch_ops bd82x6x_pch_ops = {
215 	.get_spi_base	= bd82x6x_pch_get_spi_base,
216 	.set_spi_protect = bd82x6x_set_spi_protect,
217 	.get_gpio_base	= bd82x6x_get_gpio_base,
218 };
219 
220 static const struct udevice_id bd82x6x_ids[] = {
221 	{ .compatible = "intel,bd82x6x" },
222 	{ }
223 };
224 
225 U_BOOT_DRIVER(bd82x6x_drv) = {
226 	.name		= "bd82x6x",
227 	.id		= UCLASS_PCH,
228 	.of_match	= bd82x6x_ids,
229 #ifndef CONFIG_HAVE_FSP
230 	.probe		= bd82x6x_probe,
231 #endif
232 	.ops		= &bd82x6x_pch_ops,
233 };
234