blob: b7cf4e57183774946f9a213e957be636e1410c7c [file] [log] [blame]
Aaron Durbine18d68f2013-10-24 00:05:31 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 * Copyright (C) 2013 Google Inc.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include <stdint.h>
22#include <arch/io.h>
Aaron Durbind7bc23a2013-10-29 16:37:10 -050023#include <console/console.h>
Aaron Durbine18d68f2013-10-24 00:05:31 -050024#include <device/device.h>
25#include <device/pci.h>
26#include <device/pci_ids.h>
27#include <romstage_handoff.h>
28
29#include <baytrail/iomap.h>
Aaron Durbin3bde3d72013-11-04 21:45:52 -060030#include <baytrail/irq.h>
Aaron Durbine18d68f2013-10-24 00:05:31 -050031#include <baytrail/lpc.h>
32#include <baytrail/nvs.h>
33#include <baytrail/pci_devs.h>
Aaron Durbind7bc23a2013-10-29 16:37:10 -050034#include <baytrail/pmc.h>
Aaron Durbine18d68f2013-10-24 00:05:31 -050035#include <baytrail/ramstage.h>
36
37static inline void
38add_mmio_resource(device_t dev, int i, unsigned long addr, unsigned long size)
39{
40 mmio_resource(dev, i, addr >> 10, size >> 10);
41}
42
43static void sc_add_mmio_resources(device_t dev)
44{
Duncan Laurie7fbe20b2013-11-04 17:00:22 -080045 add_mmio_resource(dev, 0xfeb, ABORT_BASE_ADDRESS, ABORT_BASE_SIZE);
46 add_mmio_resource(dev, PBASE, PMC_BASE_ADDRESS, PMC_BASE_SIZE);
47 add_mmio_resource(dev, IOBASE, IO_BASE_ADDRESS, IO_BASE_SIZE);
48 add_mmio_resource(dev, IBASE, ILB_BASE_ADDRESS, ILB_BASE_SIZE);
49 add_mmio_resource(dev, SBASE, SPI_BASE_ADDRESS, SPI_BASE_SIZE);
50 add_mmio_resource(dev, MPBASE, MPHY_BASE_ADDRESS, MPHY_BASE_SIZE);
51 add_mmio_resource(dev, PUBASE, PUNIT_BASE_ADDRESS, PUNIT_BASE_SIZE);
52 add_mmio_resource(dev, RCBA, RCBA_BASE_ADDRESS, RCBA_BASE_SIZE);
Aaron Durbine18d68f2013-10-24 00:05:31 -050053}
54
55/* Default IO range claimed by the LPC device. The upper bound is exclusive. */
56#define LPC_DEFAULT_IO_RANGE_LOWER 0
57#define LPC_DEFAULT_IO_RANGE_UPPER 0x1000
58
59static inline int io_range_in_default(int base, int size)
60{
61 /* Does it start above the range? */
62 if (base >= LPC_DEFAULT_IO_RANGE_UPPER)
63 return 0;
64
65 /* Is it entirely contained? */
66 if (base >= LPC_DEFAULT_IO_RANGE_LOWER &&
67 (base + size) < LPC_DEFAULT_IO_RANGE_UPPER)
68 return 1;
69
70 /* This will return not in range for partial overlaps. */
71 return 0;
72}
73
74/*
75 * Note: this function assumes there is no overlap with the default LPC device's
76 * claimed range: LPC_DEFAULT_IO_RANGE_LOWER -> LPC_DEFAULT_IO_RANGE_UPPER.
77 */
78static void sc_add_io_resource(device_t dev, int base, int size, int index)
79{
80 struct resource *res;
81
82 if (io_range_in_default(base, size))
83 return;
84
85 res = new_resource(dev, index);
86 res->base = base;
87 res->size = size;
88 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
89}
90
91static void sc_add_io_resources(device_t dev)
92{
93 struct resource *res;
94
95 /* Add the default claimed IO range for the LPC device. */
96 res = new_resource(dev, 0);
97 res->base = LPC_DEFAULT_IO_RANGE_LOWER;
98 res->size = LPC_DEFAULT_IO_RANGE_UPPER - LPC_DEFAULT_IO_RANGE_LOWER;
99 res->flags = IORESOURCE_IO | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
100
101 /* GPIO */
102 sc_add_io_resource(dev, GPIO_BASE_ADDRESS, 256, GBASE);
103
104 /* ACPI */
105 sc_add_io_resource(dev, ACPI_BASE_ADDRESS, 128, ABASE);
106}
107
108static void sc_read_resources(device_t dev)
109{
110 /* Get the normal PCI resources of this device. */
111 pci_dev_read_resources(dev);
112
113 /* Add non-standard MMIO resources. */
114 sc_add_mmio_resources(dev);
115
116 /* Add IO resources. */
117 sc_add_io_resources(dev);
118}
119
Aaron Durbin3bde3d72013-11-04 21:45:52 -0600120static void sc_init(device_t dev)
121{
122 int i;
123 const unsigned long pr_base = ILB_BASE_ADDRESS + 0x08;
124 const unsigned long ir_base = ILB_BASE_ADDRESS + 0x20;
Aaron Durbin1af36632013-11-07 10:42:16 -0600125 const unsigned long actl = ILB_BASE_ADDRESS + ACTL;
Aaron Durbin3bde3d72013-11-04 21:45:52 -0600126 const struct baytrail_irq_route *ir = &global_baytrail_irq_route;
127
128 /* Set up the PIRQ PIC routing based on static config. */
129 for (i = 0; i < NUM_PIRQS; i++) {
130 write8(pr_base + i*sizeof(ir->pic[i]), ir->pic[i]);
131 }
132 /* Set up the per device PIRQ routing base on static config. */
133 for (i = 0; i < NUM_IR_DEVS; i++) {
134 write16(ir_base + i*sizeof(ir->pcidev[i]), ir->pcidev[i]);
135 }
Aaron Durbin1af36632013-11-07 10:42:16 -0600136
137 /* Route SCI to IRQ9 */
138 write32(actl, (read32(actl) & ~SCIS_MASK) | SCIS_IRQ9);
Aaron Durbin3bde3d72013-11-04 21:45:52 -0600139}
140
Aaron Durbind7bc23a2013-10-29 16:37:10 -0500141/*
142 * Common code for the south cluster devices.
143 */
144
145/* Set bit in function disble register to hide this device. */
146static void sc_disable_devfn(device_t dev)
147{
148 const unsigned long func_dis = PMC_BASE_ADDRESS + FUNC_DIS;
149 const unsigned long func_dis2 = PMC_BASE_ADDRESS + FUNC_DIS2;
150 uint32_t mask = 0;
151 uint32_t mask2 = 0;
152
153 switch (dev->path.pci.devfn) {
154 case PCI_DEVFN(SDIO_DEV, SDIO_FUNC):
155 mask |= SDIO_DIS;
156 break;
157 case PCI_DEVFN(SD_DEV, SD_FUNC):
158 mask |= SD_DIS;
159 break;
160 case PCI_DEVFN(SATA_DEV, SATA_FUNC):
161 mask |= SATA_DIS;
162 break;
163 case PCI_DEVFN(XHCI_DEV, XHCI_FUNC):
164 mask |= XHCI_DIS;
165 /* Disable super speed PHY when XHCI is not available. */
166 mask2 |= USH_SS_PHY_DIS;
167 break;
168 case PCI_DEVFN(LPE_DEV, LPE_FUNC):
169 mask |= LPE_DIS;
170 break;
171 case PCI_DEVFN(MMC_DEV, MMC_FUNC):
172 mask |= MMC_DIS;
173 break;
174 case PCI_DEVFN(SIO_DMA1_DEV, SIO_DMA1_FUNC):
175 mask |= SIO_DMA1_DIS;
176 break;
177 case PCI_DEVFN(I2C1_DEV, I2C1_FUNC):
178 mask |= I2C1_DIS;
179 break;
180 case PCI_DEVFN(I2C2_DEV, I2C2_FUNC):
181 mask |= I2C1_DIS;
182 break;
183 case PCI_DEVFN(I2C3_DEV, I2C3_FUNC):
184 mask |= I2C3_DIS;
185 break;
186 case PCI_DEVFN(I2C4_DEV, I2C4_FUNC):
187 mask |= I2C4_DIS;
188 break;
189 case PCI_DEVFN(I2C5_DEV, I2C5_FUNC):
190 mask |= I2C5_DIS;
191 break;
192 case PCI_DEVFN(I2C6_DEV, I2C6_FUNC):
193 mask |= I2C6_DIS;
194 break;
195 case PCI_DEVFN(I2C7_DEV, I2C7_FUNC):
196 mask |= I2C7_DIS;
197 break;
198 case PCI_DEVFN(TXE_DEV, TXE_FUNC):
199 mask |= TXE_DIS;
200 break;
201 case PCI_DEVFN(HDA_DEV, HDA_FUNC):
202 mask |= HDA_DIS;
203 break;
204 case PCI_DEVFN(PCIE_PORT1_DEV, PCIE_PORT1_FUNC):
205 mask |= PCIE_PORT1_DIS;
206 break;
207 case PCI_DEVFN(PCIE_PORT2_DEV, PCIE_PORT2_FUNC):
208 mask |= PCIE_PORT2_DIS;
209 break;
210 case PCI_DEVFN(PCIE_PORT3_DEV, PCIE_PORT3_FUNC):
211 mask |= PCIE_PORT3_DIS;
212 break;
213 case PCI_DEVFN(PCIE_PORT4_DEV, PCIE_PORT4_FUNC):
214 mask |= PCIE_PORT4_DIS;
215 break;
216 case PCI_DEVFN(EHCI_DEV, EHCI_FUNC):
217 mask |= EHCI_DIS;
218 break;
219 case PCI_DEVFN(SIO_DMA2_DEV, SIO_DMA2_FUNC):
220 mask |= SIO_DMA2_DIS;
221 break;
222 case PCI_DEVFN(PWM1_DEV, PWM1_FUNC):
223 mask |= PWM1_DIS;
224 break;
225 case PCI_DEVFN(PWM2_DEV, PWM2_FUNC):
226 mask |= PWM2_DIS;
227 break;
228 case PCI_DEVFN(HSUART1_DEV, HSUART1_FUNC):
229 mask |= HSUART1_DIS;
230 break;
231 case PCI_DEVFN(HSUART2_DEV, HSUART2_FUNC):
232 mask |= HSUART2_DIS;
233 break;
234 case PCI_DEVFN(SPI_DEV, SPI_FUNC):
235 mask |= SPI_DIS;
236 break;
237 case PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC):
238 mask2 |= SMBUS_DIS;
239 break;
240 }
241
242 if (mask != 0) {
243 write32(func_dis, read32(func_dis) | mask);
244 /* Ensure posted write hits. */
245 read32(func_dis);
246 }
247
248 if (mask2 != 0) {
249 write32(func_dis2, read32(func_dis2) | mask2);
250 /* Ensure posted write hits. */
251 read32(func_dis2);
252 }
253}
254
255static inline void set_d3hot_bits(device_t dev, int offset)
256{
257 uint32_t reg8;
258 printk(BIOS_DEBUG, "Power management CAP offset 0x%x.\n", offset);
259 reg8 = pci_read_config8(dev, offset + 4);
260 reg8 |= 0x3;
261 pci_write_config8(dev, offset + 4, reg8);
262}
263
Aaron Durbin46ab8cd2013-10-30 17:07:46 -0500264/* Parts of the audio subsystem are powered by the HDA device. Therefore, one
265 * cannot put HDA into D3Hot. Instead perform this workaround to make some of
266 * the audio paths work for LPE audio. */
267static void hda_work_around(device_t dev)
268{
269 unsigned long gctl = TEMP_BASE_ADDRESS + 0x8;
270
271 /* Need to set magic register 0x43 to 0xd7 in config space. */
272 pci_write_config8(dev, 0x43, 0xd7);
273
274 /* Need to set bit 0 of GCTL to take the device out of reset. However,
275 * that requires setting up the 64-bit BAR. */
276 pci_write_config32(dev, PCI_BASE_ADDRESS_0, TEMP_BASE_ADDRESS);
277 pci_write_config32(dev, PCI_BASE_ADDRESS_1, 0);
278 pci_write_config8(dev, PCI_COMMAND, PCI_COMMAND_MEMORY);
279 write32(gctl, read32(gctl) | 0x1);
280 pci_write_config8(dev, PCI_COMMAND, 0);
281 pci_write_config32(dev, PCI_BASE_ADDRESS_0, 0);
282}
283
Aaron Durbind7bc23a2013-10-29 16:37:10 -0500284static int place_device_in_d3hot(device_t dev)
285{
286 unsigned offset;
287
Aaron Durbin46ab8cd2013-10-30 17:07:46 -0500288 /* Parts of the HDA block are used for LPE audio as well.
289 * Therefore assume the HDA will never be put into D3Hot. */
290 if (dev->path.pci.devfn == PCI_DEVFN(HDA_DEV, HDA_FUNC)) {
291 hda_work_around(dev);
292 return 0;
293 }
294
Aaron Durbind7bc23a2013-10-29 16:37:10 -0500295 offset = pci_find_capability(dev, PCI_CAP_ID_PM);
296
297 if (offset != 0) {
298 set_d3hot_bits(dev, offset);
299 return 0;
300 }
301
302 /* For some reason some of the devices don't have the capability
303 * pointer set correctly. Work around this by hard coding the offset. */
304 switch (dev->path.pci.devfn) {
305 case PCI_DEVFN(SDIO_DEV, SDIO_FUNC):
306 offset = 0x80;
307 break;
308 case PCI_DEVFN(SD_DEV, SD_FUNC):
309 offset = 0x80;
310 break;
311 case PCI_DEVFN(MMC_DEV, MMC_FUNC):
312 offset = 0x80;
313 break;
314 case PCI_DEVFN(LPE_DEV, LPE_FUNC):
315 offset = 0x80;
316 break;
317 case PCI_DEVFN(SIO_DMA1_DEV, SIO_DMA1_FUNC):
318 offset = 0x80;
319 break;
320 case PCI_DEVFN(I2C1_DEV, I2C1_FUNC):
321 offset = 0x80;
322 break;
323 case PCI_DEVFN(I2C2_DEV, I2C2_FUNC):
324 offset = 0x80;
325 break;
326 case PCI_DEVFN(I2C3_DEV, I2C3_FUNC):
327 offset = 0x80;
328 break;
329 case PCI_DEVFN(I2C4_DEV, I2C4_FUNC):
330 offset = 0x80;
331 break;
332 case PCI_DEVFN(I2C5_DEV, I2C5_FUNC):
333 offset = 0x80;
334 break;
335 case PCI_DEVFN(I2C6_DEV, I2C6_FUNC):
336 offset = 0x80;
337 break;
338 case PCI_DEVFN(I2C7_DEV, I2C7_FUNC):
339 offset = 0x80;
340 break;
341 case PCI_DEVFN(SIO_DMA2_DEV, SIO_DMA2_FUNC):
342 offset = 0x80;
343 break;
344 case PCI_DEVFN(PWM1_DEV, PWM1_FUNC):
345 offset = 0x80;
346 break;
347 case PCI_DEVFN(PWM2_DEV, PWM2_FUNC):
348 offset = 0x80;
349 break;
350 case PCI_DEVFN(HSUART1_DEV, HSUART1_FUNC):
351 offset = 0x80;
352 break;
353 case PCI_DEVFN(HSUART2_DEV, HSUART2_FUNC):
354 offset = 0x80;
355 break;
356 case PCI_DEVFN(SPI_DEV, SPI_FUNC):
357 offset = 0x80;
358 break;
359 case PCI_DEVFN(SATA_DEV, SATA_FUNC):
360 offset = 0x70;
361 break;
362 case PCI_DEVFN(XHCI_DEV, XHCI_FUNC):
363 offset = 0x70;
364 break;
365 case PCI_DEVFN(EHCI_DEV, EHCI_FUNC):
366 offset = 0x70;
367 break;
368 case PCI_DEVFN(HDA_DEV, HDA_FUNC):
369 offset = 0x50;
370 break;
371 case PCI_DEVFN(SMBUS_DEV, SMBUS_FUNC):
372 offset = 0x50;
373 break;
374 case PCI_DEVFN(TXE_DEV, TXE_FUNC):
Aaron Durbin1eae3ee2013-10-30 17:08:59 -0500375 /* TXE cannot be placed in D3Hot. */
376 return 0;
Aaron Durbind7bc23a2013-10-29 16:37:10 -0500377 case PCI_DEVFN(PCIE_PORT1_DEV, PCIE_PORT1_FUNC):
378 offset = 0xa0;
379 break;
380 case PCI_DEVFN(PCIE_PORT2_DEV, PCIE_PORT2_FUNC):
381 offset = 0xa0;
382 break;
383 case PCI_DEVFN(PCIE_PORT3_DEV, PCIE_PORT3_FUNC):
384 offset = 0xa0;
385 break;
386 case PCI_DEVFN(PCIE_PORT4_DEV, PCIE_PORT4_FUNC):
387 offset = 0xa0;
388 break;
389 }
390
391 if (offset != 0) {
392 set_d3hot_bits(dev, offset);
393 return 0;
394 }
395
396 return -1;
397}
398
399/* Common PCI device function disable. */
400void southcluster_enable_dev(device_t dev)
401{
402 uint32_t reg32;
403
404 if (!dev->enabled) {
405 int slot = PCI_SLOT(dev->path.pci.devfn);
406 int func = PCI_FUNC(dev->path.pci.devfn);
407 printk(BIOS_DEBUG, "%s: Disabling device: %02x.%01x\n",
408 dev_path(dev), slot, func);
409
410 /* Ensure memory, io, and bus master are all disabled */
411 reg32 = pci_read_config32(dev, PCI_COMMAND);
412 reg32 &= ~(PCI_COMMAND_MASTER |
413 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
414 pci_write_config32(dev, PCI_COMMAND, reg32);
415
416 /* Place device in D3Hot */
417 if (place_device_in_d3hot(dev) < 0) {
418 printk(BIOS_WARNING,
419 "Could not place %02x.%01x into D3Hot. "
420 "Keeping device visible.\n", slot, func);
421 return;
422 }
423 /* Disable this device if possible */
424 sc_disable_devfn(dev);
425 } else {
426 /* Enable SERR */
427 reg32 = pci_read_config32(dev, PCI_COMMAND);
428 reg32 |= PCI_COMMAND_SERR;
429 pci_write_config32(dev, PCI_COMMAND, reg32);
430 }
431}
432
Aaron Durbine18d68f2013-10-24 00:05:31 -0500433static struct device_operations device_ops = {
434 .read_resources = sc_read_resources,
435 .set_resources = pci_dev_set_resources,
436 .enable_resources = NULL,
Aaron Durbin3bde3d72013-11-04 21:45:52 -0600437 .init = sc_init,
Aaron Durbind7bc23a2013-10-29 16:37:10 -0500438 .enable = southcluster_enable_dev,
Duncan Laurie5d535542013-10-31 10:10:20 -0700439 .scan_bus = scan_static_bus,
Aaron Durbine18d68f2013-10-24 00:05:31 -0500440 .ops_pci = &soc_pci_ops,
441};
442
443static const struct pci_driver southcluster __pci_driver = {
444 .ops = &device_ops,
445 .vendor = PCI_VENDOR_ID_INTEL,
446 .device = LPC_DEVID,
447};