blob: 4212d1abbeae65b47c11fd70a2d35ec8314591a5 [file] [log] [blame]
Stefan Reinauer8e073822012-04-04 00:07:22 +02001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation; version 2 of
9 * 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.
Stefan Reinauer8e073822012-04-04 00:07:22 +020015 */
16
17#include <console/console.h>
18#include <device/device.h>
19#include <device/pci.h>
20#include <device/pci_ids.h>
21#include <pc80/mc146818rtc.h>
22#include <pc80/isa-dma.h>
23#include <pc80/i8259.h>
24#include <arch/io.h>
25#include <arch/ioapic.h>
26#include <arch/acpi.h>
27#include <cpu/cpu.h>
Duncan Laurie800e9502012-06-23 17:06:47 -070028#include <elog.h>
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +020029#include <arch/acpigen.h>
30#include <drivers/intel/gma/i915.h>
Vladimir Serbinenko5b044ae2014-10-25 15:20:55 +020031#include <cpu/x86/smm.h>
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +020032#include <cbmem.h>
Vladimir Serbinenko7309c642014-10-05 11:07:33 +020033#include <string.h>
Vladimir Serbinenko5b044ae2014-10-25 15:20:55 +020034#include <cpu/x86/smm.h>
Arthur Heymansd2d2aef2018-01-16 14:19:37 +010035#include <southbridge/intel/common/rcba.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020036#include "pch.h"
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +020037#include "nvs.h"
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +010038#include <southbridge/intel/common/pciehp.h>
Tobias Diedrich7f5efd92017-12-14 00:29:01 +010039#include <southbridge/intel/common/acpi_pirq_gen.h>
Stefan Reinauer8e073822012-04-04 00:07:22 +020040
41#define NMI_OFF 0
42
43#define ENABLE_ACPI_MODE_IN_COREBOOT 0
Stefan Reinauer8e073822012-04-04 00:07:22 +020044
45typedef struct southbridge_intel_bd82x6x_config config_t;
46
Paul Menzel9c50e6a2013-05-03 12:23:39 +020047/**
48 * Set miscellanous static southbridge features.
49 *
50 * @param dev PCI device with I/O APIC control registers
51 */
52static void pch_enable_ioapic(struct device *dev)
Stefan Reinauer8e073822012-04-04 00:07:22 +020053{
Stefan Reinauer8e073822012-04-04 00:07:22 +020054 u32 reg32;
Stefan Reinauer8e073822012-04-04 00:07:22 +020055
Nico Huberb2dae792015-10-26 12:34:02 +010056 /* Assign unique bus/dev/fn for I/O APIC */
57 pci_write_config16(dev, LPC_IBDF,
58 PCH_IOAPIC_PCI_BUS << 8 | PCH_IOAPIC_PCI_SLOT << 3);
59
Paul Menzel9c50e6a2013-05-03 12:23:39 +020060 /* Enable ACPI I/O range decode */
61 pci_write_config8(dev, ACPI_CNTL, ACPI_EN);
Stefan Reinauer8e073822012-04-04 00:07:22 +020062
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080063 set_ioapic_id(VIO_APIC_VADDR, 0x02);
Stefan Reinauer8e073822012-04-04 00:07:22 +020064
65 /* affirm full set of redirection table entries ("write once") */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080066 reg32 = io_apic_read(VIO_APIC_VADDR, 0x01);
67 io_apic_write(VIO_APIC_VADDR, 0x01, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +020068
Paul Menzel9c50e6a2013-05-03 12:23:39 +020069 /*
70 * Select Boot Configuration register (0x03) and
71 * use Processor System Bus (0x01) to deliver interrupts.
72 */
Kevin Paul Herbertbde6d302014-12-24 18:43:20 -080073 io_apic_write(VIO_APIC_VADDR, 0x03, 0x01);
Stefan Reinauer8e073822012-04-04 00:07:22 +020074}
75
76static void pch_enable_serial_irqs(struct device *dev)
77{
78 /* Set packet length and toggle silent mode bit for one frame. */
79 pci_write_config8(dev, SERIRQ_CNTL,
80 (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0));
Martin Roth7a1a3ad2017-06-24 21:29:38 -060081#if !IS_ENABLED(CONFIG_SERIRQ_CONTINUOUS_MODE)
Stefan Reinauer8e073822012-04-04 00:07:22 +020082 pci_write_config8(dev, SERIRQ_CNTL,
83 (1 << 7) | (0 << 6) | ((21 - 17) << 2) | (0 << 0));
84#endif
85}
86
87/* PIRQ[n]_ROUT[3:0] - PIRQ Routing Control
88 * 0x00 - 0000 = Reserved
89 * 0x01 - 0001 = Reserved
90 * 0x02 - 0010 = Reserved
91 * 0x03 - 0011 = IRQ3
92 * 0x04 - 0100 = IRQ4
93 * 0x05 - 0101 = IRQ5
94 * 0x06 - 0110 = IRQ6
95 * 0x07 - 0111 = IRQ7
96 * 0x08 - 1000 = Reserved
97 * 0x09 - 1001 = IRQ9
98 * 0x0A - 1010 = IRQ10
99 * 0x0B - 1011 = IRQ11
100 * 0x0C - 1100 = IRQ12
101 * 0x0D - 1101 = Reserved
102 * 0x0E - 1110 = IRQ14
103 * 0x0F - 1111 = IRQ15
104 * PIRQ[n]_ROUT[7] - PIRQ Routing Control
105 * 0x80 - The PIRQ is not routed.
106 */
107
108static void pch_pirq_init(device_t dev)
109{
110 device_t irq_dev;
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +0200111 /* Interrupt 11 is not used by legacy devices and so can always be used for
112 PCI interrupts. Full legacy IRQ routing is complicated and hard to
113 get right. Fortunately all modern OS use MSI and so it's not that big of
114 an issue anyway. Still we have to provide a reasonable default. Using
115 interrupt 11 for it everywhere is a working default. ACPI-aware OS can
116 move it to any interrupt and others will just leave them at default.
Stefan Reinauer8e073822012-04-04 00:07:22 +0200117 */
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +0200118 const u8 pirq_routing = 11;
119
120 pci_write_config8(dev, PIRQA_ROUT, pirq_routing);
121 pci_write_config8(dev, PIRQB_ROUT, pirq_routing);
122 pci_write_config8(dev, PIRQC_ROUT, pirq_routing);
123 pci_write_config8(dev, PIRQD_ROUT, pirq_routing);
124
125 pci_write_config8(dev, PIRQE_ROUT, pirq_routing);
126 pci_write_config8(dev, PIRQF_ROUT, pirq_routing);
127 pci_write_config8(dev, PIRQG_ROUT, pirq_routing);
128 pci_write_config8(dev, PIRQH_ROUT, pirq_routing);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200129
Elyes HAOUASba28e8d2016-08-31 19:22:16 +0200130 for (irq_dev = all_devices; irq_dev; irq_dev = irq_dev->next) {
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +0200131 u8 int_pin=0;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200132
133 if (!irq_dev->enabled || irq_dev->path.type != DEVICE_PATH_PCI)
134 continue;
135
136 int_pin = pci_read_config8(irq_dev, PCI_INTERRUPT_PIN);
137
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +0200138 if (int_pin == 0)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200139 continue;
140
Vladimir Serbinenko33b535f2014-10-19 10:13:14 +0200141 pci_write_config8(irq_dev, PCI_INTERRUPT_LINE, pirq_routing);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200142 }
143}
144
145static void pch_gpi_routing(device_t dev)
146{
147 /* Get the chip configuration */
148 config_t *config = dev->chip_info;
149 u32 reg32 = 0;
150
151 /* An array would be much nicer here, or some
152 * other method of doing this.
153 */
154 reg32 |= (config->gpi0_routing & 0x03) << 0;
155 reg32 |= (config->gpi1_routing & 0x03) << 2;
156 reg32 |= (config->gpi2_routing & 0x03) << 4;
157 reg32 |= (config->gpi3_routing & 0x03) << 6;
158 reg32 |= (config->gpi4_routing & 0x03) << 8;
159 reg32 |= (config->gpi5_routing & 0x03) << 10;
160 reg32 |= (config->gpi6_routing & 0x03) << 12;
161 reg32 |= (config->gpi7_routing & 0x03) << 14;
162 reg32 |= (config->gpi8_routing & 0x03) << 16;
163 reg32 |= (config->gpi9_routing & 0x03) << 18;
164 reg32 |= (config->gpi10_routing & 0x03) << 20;
165 reg32 |= (config->gpi11_routing & 0x03) << 22;
166 reg32 |= (config->gpi12_routing & 0x03) << 24;
167 reg32 |= (config->gpi13_routing & 0x03) << 26;
168 reg32 |= (config->gpi14_routing & 0x03) << 28;
169 reg32 |= (config->gpi15_routing & 0x03) << 30;
170
Kyösti Mälkkib85a87b2014-12-29 11:32:27 +0200171 pci_write_config32(dev, GPIO_ROUT, reg32);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200172}
173
174static void pch_power_options(device_t dev)
175{
176 u8 reg8;
177 u16 reg16, pmbase;
178 u32 reg32;
179 const char *state;
180 /* Get the chip configuration */
181 config_t *config = dev->chip_info;
182
183 int pwr_on=CONFIG_MAINBOARD_POWER_ON_AFTER_POWER_FAIL;
184 int nmi_option;
185
186 /* Which state do we want to goto after g3 (power restored)?
187 * 0 == S0 Full On
188 * 1 == S5 Soft Off
189 *
190 * If the option is not existent (Laptops), use Kconfig setting.
191 */
192 get_option(&pwr_on, "power_on_after_fail");
193
194 reg16 = pci_read_config16(dev, GEN_PMCON_3);
195 reg16 &= 0xfffe;
196 switch (pwr_on) {
197 case MAINBOARD_POWER_OFF:
198 reg16 |= 1;
199 state = "off";
200 break;
201 case MAINBOARD_POWER_ON:
202 reg16 &= ~1;
203 state = "on";
204 break;
205 case MAINBOARD_POWER_KEEP:
206 reg16 &= ~1;
207 state = "state keep";
208 break;
209 default:
210 state = "undefined";
211 }
212
213 reg16 &= ~(3 << 4); /* SLP_S4# Assertion Stretch 4s */
214 reg16 |= (1 << 3); /* SLP_S4# Assertion Stretch Enable */
215
216 reg16 &= ~(1 << 10);
217 reg16 |= (1 << 11); /* SLP_S3# Min Assertion Width 50ms */
218
219 reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */
220
221 pci_write_config16(dev, GEN_PMCON_3, reg16);
222 printk(BIOS_INFO, "Set power %s after power failure.\n", state);
223
224 /* Set up NMI on errors. */
225 reg8 = inb(0x61);
226 reg8 &= 0x0f; /* Higher Nibble must be 0 */
227 reg8 &= ~(1 << 3); /* IOCHK# NMI Enable */
228 // reg8 &= ~(1 << 2); /* PCI SERR# Enable */
229 reg8 |= (1 << 2); /* PCI SERR# Disable for now */
230 outb(reg8, 0x61);
231
232 reg8 = inb(0x70);
233 nmi_option = NMI_OFF;
234 get_option(&nmi_option, "nmi");
235 if (nmi_option) {
236 printk(BIOS_INFO, "NMI sources enabled.\n");
237 reg8 &= ~(1 << 7); /* Set NMI. */
238 } else {
239 printk(BIOS_INFO, "NMI sources disabled.\n");
240 reg8 |= ( 1 << 7); /* Can't mask NMI from PCI-E and NMI_NOW */
241 }
242 outb(reg8, 0x70);
243
244 /* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
245 reg16 = pci_read_config16(dev, GEN_PMCON_1);
246 reg16 &= ~(3 << 0); // SMI# rate 1 minute
247 reg16 &= ~(1 << 10); // Disable BIOS_PCI_EXP_EN for native PME
248#if DEBUG_PERIODIC_SMIS
249 /* Set DEBUG_PERIODIC_SMIS in pch.h to debug using
250 * periodic SMIs.
251 */
252 reg16 |= (3 << 0); // Periodic SMI every 8s
253#endif
254 pci_write_config16(dev, GEN_PMCON_1, reg16);
255
256 // Set the board's GPI routing.
257 pch_gpi_routing(dev);
258
259 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
260
261 outl(config->gpe0_en, pmbase + GPE0_EN);
262 outw(config->alt_gp_smi_en, pmbase + ALT_GP_SMI_EN);
263
264 /* Set up power management block and determine sleep mode */
265 reg32 = inl(pmbase + 0x04); // PM1_CNT
266 reg32 &= ~(7 << 10); // SLP_TYP
267 reg32 |= (1 << 0); // SCI_EN
268 outl(reg32, pmbase + 0x04);
269
270 /* Clear magic status bits to prevent unexpected wake */
271 reg32 = RCBA32(0x3310);
272 reg32 |= (1 << 4)|(1 << 5)|(1 << 0);
273 RCBA32(0x3310) = reg32;
274
275 reg32 = RCBA32(0x3f02);
276 reg32 &= ~0xf;
277 RCBA32(0x3f02) = reg32;
278}
279
280static void pch_rtc_init(struct device *dev)
281{
Aaron Durbin976200382017-09-15 15:19:32 -0600282 int rtc_failed = rtc_failure();
Stefan Reinauer8e073822012-04-04 00:07:22 +0200283
Stefan Reinauer8e073822012-04-04 00:07:22 +0200284 if (rtc_failed) {
Aaron Durbin976200382017-09-15 15:19:32 -0600285 if (IS_ENABLED(CONFIG_ELOG))
286 elog_add_event(ELOG_TYPE_RTC_RESET);
287 pci_update_config8(dev, GEN_PMCON_3, ~RTC_BATTERY_DEAD, 0);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200288 }
Aaron Durbin976200382017-09-15 15:19:32 -0600289
Stefan Reinauer8e073822012-04-04 00:07:22 +0200290 printk(BIOS_DEBUG, "rtc_failed = 0x%x\n", rtc_failed);
291
Gabe Blackb3f08c62014-04-30 17:12:25 -0700292 cmos_init(rtc_failed);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200293}
294
Duncan Laurie3f6a4d72012-06-28 13:03:40 -0700295/* CougarPoint PCH Power Management init */
296static void cpt_pm_init(struct device *dev)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200297{
Duncan Laurie3f6a4d72012-06-28 13:03:40 -0700298 printk(BIOS_DEBUG, "CougarPoint PM init\n");
Stefan Reinauer8e073822012-04-04 00:07:22 +0200299 pci_write_config8(dev, 0xa9, 0x47);
300 RCBA32_AND_OR(0x2238, ~0UL, (1 << 6)|(1 << 0));
301 RCBA32_AND_OR(0x228c, ~0UL, (1 << 0));
302 RCBA16_AND_OR(0x1100, ~0UL, (1 << 13)|(1 << 14));
303 RCBA16_AND_OR(0x0900, ~0UL, (1 << 14));
304 RCBA32(0x2304) = 0xc0388400;
305 RCBA32_AND_OR(0x2314, ~0UL, (1 << 5)|(1 << 18));
306 RCBA32_AND_OR(0x2320, ~0UL, (1 << 15)|(1 << 1));
307 RCBA32_AND_OR(0x3314, ~0x1f, 0xf);
308 RCBA32(0x3318) = 0x050f0000;
309 RCBA32(0x3324) = 0x04000000;
310 RCBA32_AND_OR(0x3340, ~0UL, 0xfffff);
311 RCBA32_AND_OR(0x3344, ~0UL, (1 << 1));
312 RCBA32(0x3360) = 0x0001c000;
313 RCBA32(0x3368) = 0x00061100;
314 RCBA32(0x3378) = 0x7f8fdfff;
315 RCBA32(0x337c) = 0x000003fc;
316 RCBA32(0x3388) = 0x00001000;
317 RCBA32(0x3390) = 0x0001c000;
318 RCBA32(0x33a0) = 0x00000800;
319 RCBA32(0x33b0) = 0x00001000;
320 RCBA32(0x33c0) = 0x00093900;
321 RCBA32(0x33cc) = 0x24653002;
322 RCBA32(0x33d0) = 0x062108fe;
323 RCBA32_AND_OR(0x33d4, 0xf000f000, 0x00670060);
324 RCBA32(0x3a28) = 0x01010000;
325 RCBA32(0x3a2c) = 0x01010404;
326 RCBA32(0x3a80) = 0x01041041;
327 RCBA32_AND_OR(0x3a84, ~0x0000ffff, 0x00001001);
328 RCBA32_AND_OR(0x3a84, ~0UL, (1 << 24)); /* SATA 2/3 disabled */
329 RCBA32_AND_OR(0x3a88, ~0UL, (1 << 0)); /* SATA 4/5 disabled */
330 RCBA32(0x3a6c) = 0x00000001;
331 RCBA32_AND_OR(0x2344, 0x00ffff00, 0xff00000c);
332 RCBA32_AND_OR(0x80c, ~(0xff << 20), 0x11 << 20);
333 RCBA32(0x33c8) = 0;
334 RCBA32_AND_OR(0x21b0, ~0UL, 0xf);
335}
336
Duncan Laurie3f6a4d72012-06-28 13:03:40 -0700337/* PantherPoint PCH Power Management init */
338static void ppt_pm_init(struct device *dev)
339{
340 printk(BIOS_DEBUG, "PantherPoint PM init\n");
341 pci_write_config8(dev, 0xa9, 0x47);
342 RCBA32_AND_OR(0x2238, ~0UL, (1 << 0));
343 RCBA32_AND_OR(0x228c, ~0UL, (1 << 0));
344 RCBA16_AND_OR(0x1100, ~0UL, (1 << 13)|(1 << 14));
345 RCBA16_AND_OR(0x0900, ~0UL, (1 << 14));
346 RCBA32(0x2304) = 0xc03b8400;
347 RCBA32_AND_OR(0x2314, ~0UL, (1 << 5)|(1 << 18));
348 RCBA32_AND_OR(0x2320, ~0UL, (1 << 15)|(1 << 1));
349 RCBA32_AND_OR(0x3314, ~0x1f, 0xf);
350 RCBA32(0x3318) = 0x054f0000;
351 RCBA32(0x3324) = 0x04000000;
352 RCBA32_AND_OR(0x3340, ~0UL, 0xfffff);
353 RCBA32_AND_OR(0x3344, ~0UL, (1 << 1)|(1 << 0));
354 RCBA32(0x3360) = 0x0001c000;
355 RCBA32(0x3368) = 0x00061100;
356 RCBA32(0x3378) = 0x7f8fdfff;
357 RCBA32(0x337c) = 0x000003fd;
358 RCBA32(0x3388) = 0x00001000;
359 RCBA32(0x3390) = 0x0001c000;
360 RCBA32(0x33a0) = 0x00000800;
361 RCBA32(0x33b0) = 0x00001000;
362 RCBA32(0x33c0) = 0x00093900;
363 RCBA32(0x33cc) = 0x24653002;
364 RCBA32(0x33d0) = 0x067388fe;
365 RCBA32_AND_OR(0x33d4, 0xf000f000, 0x00670060);
366 RCBA32(0x3a28) = 0x01010000;
367 RCBA32(0x3a2c) = 0x01010404;
368 RCBA32(0x3a80) = 0x01040000;
369 RCBA32_AND_OR(0x3a84, ~0x0000ffff, 0x00001001);
370 RCBA32_AND_OR(0x3a84, ~0UL, (1 << 24)); /* SATA 2/3 disabled */
371 RCBA32_AND_OR(0x3a88, ~0UL, (1 << 0)); /* SATA 4/5 disabled */
372 RCBA32(0x3a6c) = 0x00000001;
373 RCBA32_AND_OR(0x2344, 0x00ffff00, 0xff00000c);
374 RCBA32_AND_OR(0x80c, ~(0xff << 20), 0x11 << 20);
375 RCBA32_AND_OR(0x33a4, ~0UL, (1 << 0));
376 RCBA32(0x33c8) = 0;
377 RCBA32_AND_OR(0x21b0, ~0UL, 0xf);
378}
379
Nico Huberb2dae792015-10-26 12:34:02 +0100380static void enable_hpet(struct device *const dev)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200381{
382 u32 reg32;
Nico Huberb2dae792015-10-26 12:34:02 +0100383 size_t i;
384
385 /* Assign unique bus/dev/fn for each HPET */
386 for (i = 0; i < 8; ++i)
387 pci_write_config16(dev, LPC_HnBDF(i),
388 PCH_HPET_PCI_BUS << 8 | PCH_HPET_PCI_SLOT << 3 | i);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200389
390 /* Move HPET to default address 0xfed00000 and enable it */
391 reg32 = RCBA32(HPTC);
392 reg32 |= (1 << 7); // HPET Address Enable
393 reg32 &= ~(3 << 0);
394 RCBA32(HPTC) = reg32;
395}
396
397static void enable_clock_gating(device_t dev)
398{
399 u32 reg32;
400 u16 reg16;
401
402 RCBA32_AND_OR(0x2234, ~0UL, 0xf);
403
404 reg16 = pci_read_config16(dev, GEN_PMCON_1);
405 reg16 |= (1 << 2) | (1 << 11);
406 pci_write_config16(dev, GEN_PMCON_1, reg16);
407
408 pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
409 pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
410 pch_iobp_update(0xEC007F07, ~0UL, (1 << 31));
411 pch_iobp_update(0xEC004000, ~0UL, (1 << 7));
412
413 reg32 = RCBA32(CG);
414 reg32 |= (1 << 31);
415 reg32 |= (1 << 29) | (1 << 28);
416 reg32 |= (1 << 27) | (1 << 26) | (1 << 25) | (1 << 24);
417 reg32 |= (1 << 16);
418 reg32 |= (1 << 17);
419 reg32 |= (1 << 18);
420 reg32 |= (1 << 22);
421 reg32 |= (1 << 23);
422 reg32 &= ~(1 << 20);
423 reg32 |= (1 << 19);
424 reg32 |= (1 << 0);
425 reg32 |= (0xf << 1);
426 RCBA32(CG) = reg32;
427
428 RCBA32_OR(0x38c0, 0x7);
429 RCBA32_OR(0x36d4, 0x6680c004);
430 RCBA32_OR(0x3564, 0x3);
431}
432
Vladimir Serbinenkoa3e41c02015-05-28 16:04:17 +0200433static void pch_set_acpi_mode(void)
Stefan Reinauer8e073822012-04-04 00:07:22 +0200434{
Vladimir Serbinenkoa3e41c02015-05-28 16:04:17 +0200435 if (!acpi_is_wakeup_s3() && CONFIG_HAVE_SMI_HANDLER) {
Stefan Reinauer8e073822012-04-04 00:07:22 +0200436#if ENABLE_ACPI_MODE_IN_COREBOOT
Duncan Laurie95be1d62012-04-09 12:31:43 -0700437 printk(BIOS_DEBUG, "Enabling ACPI via APMC:\n");
Vladimir Serbinenkoa3e41c02015-05-28 16:04:17 +0200438 outb(APM_CNT_ACPI_ENABLE, APM_CNT); // Enable ACPI mode
Duncan Laurie95be1d62012-04-09 12:31:43 -0700439 printk(BIOS_DEBUG, "done.\n");
Stefan Reinauer8e073822012-04-04 00:07:22 +0200440#else
Duncan Laurie95be1d62012-04-09 12:31:43 -0700441 printk(BIOS_DEBUG, "Disabling ACPI via APMC:\n");
Vladimir Serbinenkoa3e41c02015-05-28 16:04:17 +0200442 outb(APM_CNT_ACPI_DISABLE, APM_CNT); // Disable ACPI mode
Duncan Laurie95be1d62012-04-09 12:31:43 -0700443 printk(BIOS_DEBUG, "done.\n");
Stefan Reinauer8e073822012-04-04 00:07:22 +0200444#endif
Duncan Laurie95be1d62012-04-09 12:31:43 -0700445 }
Stefan Reinauer8e073822012-04-04 00:07:22 +0200446}
Stefan Reinauer8e073822012-04-04 00:07:22 +0200447
448static void pch_disable_smm_only_flashing(struct device *dev)
449{
450 u8 reg8;
451
452 printk(BIOS_SPEW, "Enabling BIOS updates outside of SMM... ");
453 reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
454 reg8 &= ~(1 << 5);
455 pci_write_config8(dev, 0xdc, reg8);
456}
457
458static void pch_fixups(struct device *dev)
459{
460 u8 gen_pmcon_2;
461
462 /* Indicate DRAM init done for MRC S3 to know it can resume */
463 gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2);
464 gen_pmcon_2 |= (1 << 7);
465 pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
466
467 /*
468 * Enable DMI ASPM in the PCH
469 */
470 RCBA32_AND_OR(0x2304, ~(1 << 10), 0);
471 RCBA32_OR(0x21a4, (1 << 11)|(1 << 10));
472 RCBA32_OR(0x21a8, 0x3);
473}
474
475static void pch_decode_init(struct device *dev)
476{
477 config_t *config = dev->chip_info;
478
479 printk(BIOS_DEBUG, "pch_decode_init\n");
480
481 pci_write_config32(dev, LPC_GEN1_DEC, config->gen1_dec);
482 pci_write_config32(dev, LPC_GEN2_DEC, config->gen2_dec);
483 pci_write_config32(dev, LPC_GEN3_DEC, config->gen3_dec);
484 pci_write_config32(dev, LPC_GEN4_DEC, config->gen4_dec);
485}
486
Nico Huber7b2f9f62015-10-01 19:00:51 +0200487static void pch_spi_init(const struct device *const dev)
488{
489 const config_t *const config = dev->chip_info;
490
491 printk(BIOS_DEBUG, "pch_spi_init\n");
492
493 if (config->spi_uvscc)
494 RCBA32(0x3800 + 0xc8) = config->spi_uvscc;
495 if (config->spi_lvscc)
496 RCBA32(0x3800 + 0xc4) = config->spi_lvscc;
497
498 if (config->spi_uvscc || config->spi_lvscc)
499 RCBA32_OR(0x3800 + 0xc4, 1 << 23); /* lock both UVSCC + LVSCC */
500}
501
Stefan Reinauer8e073822012-04-04 00:07:22 +0200502static void lpc_init(struct device *dev)
503{
504 printk(BIOS_DEBUG, "pch: lpc_init\n");
505
506 /* Set the value for PCI command register. */
507 pci_write_config16(dev, PCI_COMMAND, 0x000f);
508
509 /* IO APIC initialization. */
Paul Menzel9c50e6a2013-05-03 12:23:39 +0200510 pch_enable_ioapic(dev);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200511
512 pch_enable_serial_irqs(dev);
513
514 /* Setup the PIRQ. */
515 pch_pirq_init(dev);
516
517 /* Setup power options. */
518 pch_power_options(dev);
519
520 /* Initialize power management */
Duncan Laurie3f6a4d72012-06-28 13:03:40 -0700521 switch (pch_silicon_type()) {
522 case PCH_TYPE_CPT: /* CougarPoint */
523 cpt_pm_init(dev);
524 break;
525 case PCH_TYPE_PPT: /* PantherPoint */
526 ppt_pm_init(dev);
527 break;
528 default:
529 printk(BIOS_ERR, "Unknown Chipset: 0x%04x\n", dev->device);
530 }
Stefan Reinauer8e073822012-04-04 00:07:22 +0200531
532 /* Set the state of the GPIO lines. */
533 //gpio_init(dev);
534
535 /* Initialize the real time clock. */
536 pch_rtc_init(dev);
537
538 /* Initialize ISA DMA. */
539 isa_dma_init();
540
541 /* Initialize the High Precision Event Timers, if present. */
Nico Huberb2dae792015-10-26 12:34:02 +0100542 enable_hpet(dev);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200543
544 /* Initialize Clock Gating */
545 enable_clock_gating(dev);
546
547 setup_i8259();
548
549 /* The OS should do this? */
550 /* Interrupt 9 should be level triggered (SCI) */
551 i8259_configure_irq_trigger(9, 1);
552
553 pch_disable_smm_only_flashing(dev);
554
Vladimir Serbinenkoa3e41c02015-05-28 16:04:17 +0200555 pch_set_acpi_mode();
Stefan Reinauer8e073822012-04-04 00:07:22 +0200556
557 pch_fixups(dev);
Nico Huber7b2f9f62015-10-01 19:00:51 +0200558
559 pch_spi_init(dev);
Stefan Reinauer8e073822012-04-04 00:07:22 +0200560}
561
562static void pch_lpc_read_resources(device_t dev)
563{
564 struct resource *res;
Marc Jonesa0bec172012-07-13 14:14:34 -0600565 config_t *config = dev->chip_info;
566 u8 io_index = 0;
Stefan Reinauer8e073822012-04-04 00:07:22 +0200567
568 /* Get the normal PCI resources of this device. */
569 pci_dev_read_resources(dev);
570
571 /* Add an extra subtractive resource for both memory and I/O. */
Marc Jonesa0bec172012-07-13 14:14:34 -0600572 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
Stefan Reinauer8e073822012-04-04 00:07:22 +0200573 res->base = 0;
574 res->size = 0x1000;
575 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
576 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
577
Marc Jonesa0bec172012-07-13 14:14:34 -0600578 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
Vladimir Serbinenko0650cd02014-02-05 15:03:50 +0100579 res->base = 0xff000000;
580 /* Some systems (e.g. X230) have 12 MiB flash.
581 SPI controller supports up to 2 x 16 MiB of flash but
582 address map limits this to 16MiB. */
583 res->size = 0x01000000; /* 16 MB for flash */
Stefan Reinauer8e073822012-04-04 00:07:22 +0200584 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE |
585 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
586
587 res = new_resource(dev, 3); /* IOAPIC */
588 res->base = IO_APIC_ADDR;
589 res->size = 0x00001000;
590 res->flags = IORESOURCE_MEM | IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
Marc Jonesa0bec172012-07-13 14:14:34 -0600591
592 /* Set PCH IO decode ranges if required.*/
593 if ((config->gen1_dec & 0xFFFC) > 0x1000) {
594 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
595 res->base = config->gen1_dec & 0xFFFC;
596 res->size = (config->gen1_dec >> 16) & 0xFC;
597 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
598 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
599 }
600
601 if ((config->gen2_dec & 0xFFFC) > 0x1000) {
602 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
603 res->base = config->gen2_dec & 0xFFFC;
604 res->size = (config->gen2_dec >> 16) & 0xFC;
605 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
606 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
607 }
608
609 if ((config->gen3_dec & 0xFFFC) > 0x1000) {
610 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
611 res->base = config->gen3_dec & 0xFFFC;
612 res->size = (config->gen3_dec >> 16) & 0xFC;
613 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE |
614 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
615 }
616
617 if ((config->gen4_dec & 0xFFFC) > 0x1000) {
618 res = new_resource(dev, IOINDEX_SUBTRACTIVE(io_index++, 0));
619 res->base = config->gen4_dec & 0xFFFC;
620 res->size = (config->gen4_dec >> 16) & 0xFC;
621 res->flags = IORESOURCE_IO| IORESOURCE_SUBTRACTIVE |
622 IORESOURCE_ASSIGNED | IORESOURCE_FIXED;
623 }
Stefan Reinauer8e073822012-04-04 00:07:22 +0200624}
625
626static void pch_lpc_enable_resources(device_t dev)
627{
628 pch_decode_init(dev);
629 return pci_dev_enable_resources(dev);
630}
631
632static void pch_lpc_enable(device_t dev)
633{
634 /* Enable PCH Display Port */
635 RCBA16(DISPBDF) = 0x0010;
636 RCBA32_OR(FD2, PCH_ENABLE_DBDF);
637
638 pch_enable(dev);
639}
640
641static void set_subsystem(device_t dev, unsigned vendor, unsigned device)
642{
643 if (!vendor || !device) {
644 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
645 pci_read_config32(dev, PCI_VENDOR_ID));
646 } else {
647 pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
648 ((device & 0xffff) << 16) | (vendor & 0xffff));
649 }
650}
651
Alexander Couzensa90dad12015-04-12 21:49:46 +0200652static void southbridge_inject_dsdt(device_t dev)
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200653{
Elyes HAOUAS035df002016-10-03 21:54:16 +0200654 global_nvs_t *gnvs = cbmem_add (CBMEM_ID_ACPI_GNVS, sizeof(*gnvs));
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200655
656 if (gnvs) {
Vladimir Serbinenkodd2bc3f2014-10-31 09:16:31 +0100657 const struct i915_gpu_controller_info *gfx = intel_gma_get_controller_info();
Elyes HAOUAS035df002016-10-03 21:54:16 +0200658 memset(gnvs, 0, sizeof(*gnvs));
Vladimir Serbinenko7309c642014-10-05 11:07:33 +0200659
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200660 acpi_create_gnvs(gnvs);
Vladimir Serbinenko06c788d2014-10-12 00:17:11 +0200661
662 gnvs->apic = 1;
663 gnvs->mpen = 1; /* Enable Multi Processing */
664 gnvs->pcnt = dev_count_cpu();
665
Vladimir Serbinenkodd2bc3f2014-10-31 09:16:31 +0100666 gnvs->ndid = gfx->ndid;
667 memcpy(gnvs->did, gfx->did, sizeof(gnvs->did));
668
Martin Roth7a1a3ad2017-06-24 21:29:38 -0600669#if IS_ENABLED(CONFIG_CHROMEOS)
Vladimir Serbinenko06c788d2014-10-12 00:17:11 +0200670 chromeos_init_vboot(&(gnvs->chromeos));
671#endif
672
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200673 /* And tell SMI about it */
674 smm_setup_structures(gnvs, NULL, NULL);
675
Vladimir Serbinenko334fd8e2014-10-05 11:10:35 +0200676 /* Add it to DSDT. */
Vladimir Serbinenko226d7842014-11-04 21:09:23 +0100677 acpigen_write_scope("\\");
678 acpigen_write_name_dword("NVSA", (u32) gnvs);
679 acpigen_pop_len();
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200680 }
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200681}
682
Vladimir Serbinenko5b044ae2014-10-25 15:20:55 +0200683void acpi_fill_fadt(acpi_fadt_t *fadt)
684{
685 device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
686 config_t *chip = dev->chip_info;
687 u16 pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
688 int c2_latency;
689
690 fadt->model = 1;
691
692 fadt->sci_int = 0x9;
693 fadt->smi_cmd = APM_CNT;
694 fadt->acpi_enable = APM_CNT_ACPI_ENABLE;
695 fadt->acpi_disable = APM_CNT_ACPI_DISABLE;
696 fadt->s4bios_req = 0x0;
697 fadt->pstate_cnt = 0;
698
699 fadt->pm1a_evt_blk = pmbase;
700 fadt->pm1b_evt_blk = 0x0;
701 fadt->pm1a_cnt_blk = pmbase + 0x4;
702 fadt->pm1b_cnt_blk = 0x0;
703 fadt->pm2_cnt_blk = pmbase + 0x50;
704 fadt->pm_tmr_blk = pmbase + 0x8;
705 fadt->gpe0_blk = pmbase + 0x20;
706 fadt->gpe1_blk = 0;
707
708 fadt->pm1_evt_len = 4;
709 fadt->pm1_cnt_len = 2;
710 fadt->pm2_cnt_len = 1;
711 fadt->pm_tmr_len = 4;
712 fadt->gpe0_blk_len = 16;
713 fadt->gpe1_blk_len = 0;
714 fadt->gpe1_base = 0;
715 fadt->cst_cnt = 0;
716 c2_latency = chip->c2_latency;
717 if (!c2_latency) {
718 c2_latency = 101; /* c2 unsupported */
719 }
720 fadt->p_lvl2_lat = c2_latency;
721 fadt->p_lvl3_lat = 87;
722 fadt->flush_size = 1024;
723 fadt->flush_stride = 16;
724 fadt->duty_offset = 1;
725 if (chip->p_cnt_throttling_supported) {
726 fadt->duty_width = 3;
727 } else {
728 fadt->duty_width = 0;
729 }
730 fadt->day_alrm = 0xd;
731 fadt->mon_alrm = 0x00;
732 fadt->century = 0x00;
733 fadt->iapc_boot_arch = ACPI_FADT_LEGACY_DEVICES | ACPI_FADT_8042;
734
735 fadt->flags = ACPI_FADT_WBINVD |
736 ACPI_FADT_C1_SUPPORTED |
737 ACPI_FADT_SLEEP_BUTTON |
738 ACPI_FADT_RESET_REGISTER |
739 ACPI_FADT_SEALED_CASE |
740 ACPI_FADT_S4_RTC_WAKE |
741 ACPI_FADT_PLATFORM_CLOCK;
742 if (chip->docking_supported) {
743 fadt->flags |= ACPI_FADT_DOCKING_SUPPORTED;
744 }
745 if (c2_latency < 100) {
746 fadt->flags |= ACPI_FADT_C2_MP_SUPPORTED;
747 }
748
749 fadt->reset_reg.space_id = 1;
750 fadt->reset_reg.bit_width = 8;
751 fadt->reset_reg.bit_offset = 0;
752 fadt->reset_reg.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
753 fadt->reset_reg.addrl = 0xcf9;
754 fadt->reset_reg.addrh = 0;
755
756 fadt->reset_value = 6;
757
758 fadt->x_pm1a_evt_blk.space_id = 1;
759 fadt->x_pm1a_evt_blk.bit_width = 32;
760 fadt->x_pm1a_evt_blk.bit_offset = 0;
761 fadt->x_pm1a_evt_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
762 fadt->x_pm1a_evt_blk.addrl = pmbase;
763 fadt->x_pm1a_evt_blk.addrh = 0x0;
764
765 fadt->x_pm1b_evt_blk.space_id = 1;
766 fadt->x_pm1b_evt_blk.bit_width = 0;
767 fadt->x_pm1b_evt_blk.bit_offset = 0;
768 fadt->x_pm1b_evt_blk.access_size = 0;
769 fadt->x_pm1b_evt_blk.addrl = 0x0;
770 fadt->x_pm1b_evt_blk.addrh = 0x0;
771
772 fadt->x_pm1a_cnt_blk.space_id = 1;
773 fadt->x_pm1a_cnt_blk.bit_width = 16;
774 fadt->x_pm1a_cnt_blk.bit_offset = 0;
775 fadt->x_pm1a_cnt_blk.access_size = ACPI_ACCESS_SIZE_WORD_ACCESS;
776 fadt->x_pm1a_cnt_blk.addrl = pmbase + 0x4;
777 fadt->x_pm1a_cnt_blk.addrh = 0x0;
778
779 fadt->x_pm1b_cnt_blk.space_id = 1;
780 fadt->x_pm1b_cnt_blk.bit_width = 0;
781 fadt->x_pm1b_cnt_blk.bit_offset = 0;
782 fadt->x_pm1b_cnt_blk.access_size = 0;
783 fadt->x_pm1b_cnt_blk.addrl = 0x0;
784 fadt->x_pm1b_cnt_blk.addrh = 0x0;
785
786 fadt->x_pm2_cnt_blk.space_id = 1;
787 fadt->x_pm2_cnt_blk.bit_width = 8;
788 fadt->x_pm2_cnt_blk.bit_offset = 0;
789 fadt->x_pm2_cnt_blk.access_size = ACPI_ACCESS_SIZE_BYTE_ACCESS;
790 fadt->x_pm2_cnt_blk.addrl = pmbase + 0x50;
791 fadt->x_pm2_cnt_blk.addrh = 0x0;
792
793 fadt->x_pm_tmr_blk.space_id = 1;
794 fadt->x_pm_tmr_blk.bit_width = 32;
795 fadt->x_pm_tmr_blk.bit_offset = 0;
796 fadt->x_pm_tmr_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
797 fadt->x_pm_tmr_blk.addrl = pmbase + 0x8;
798 fadt->x_pm_tmr_blk.addrh = 0x0;
799
800 fadt->x_gpe0_blk.space_id = 1;
801 fadt->x_gpe0_blk.bit_width = 128;
802 fadt->x_gpe0_blk.bit_offset = 0;
803 fadt->x_gpe0_blk.access_size = ACPI_ACCESS_SIZE_DWORD_ACCESS;
804 fadt->x_gpe0_blk.addrl = pmbase + 0x20;
805 fadt->x_gpe0_blk.addrh = 0x0;
806
807 fadt->x_gpe1_blk.space_id = 1;
808 fadt->x_gpe1_blk.bit_width = 0;
809 fadt->x_gpe1_blk.bit_offset = 0;
810 fadt->x_gpe1_blk.access_size = 0;
811 fadt->x_gpe1_blk.addrl = 0x0;
812 fadt->x_gpe1_blk.addrh = 0x0;
813}
814
Aaron Durbinaa090cb2017-09-13 16:01:52 -0600815static const char *lpc_acpi_name(const struct device *dev)
Patrick Rudolph604f6982017-06-07 09:46:52 +0200816{
817 return "LPCB";
818}
819
Alexander Couzens5eea4582015-04-12 22:18:55 +0200820static void southbridge_fill_ssdt(device_t device)
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +0100821{
822 device_t dev = dev_find_slot(0, PCI_DEVFN(0x1f,0));
823 config_t *chip = dev->chip_info;
824
825 intel_acpi_pcie_hotplug_generator(chip->pcie_hotplug_map, 8);
Tobias Diedrich7f5efd92017-12-14 00:29:01 +0100826 intel_acpi_gen_def_acpi_pirq(dev);
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +0100827}
828
Vladimir Serbinenkob06a2492015-05-21 10:32:59 +0200829static void lpc_final(struct device *dev)
830{
Bill XIEd533b162017-08-22 16:26:22 +0800831 /* Call SMM finalize() handlers before resume */
832 if (IS_ENABLED(CONFIG_HAVE_SMI_HANDLER)) {
833 if (IS_ENABLED(CONFIG_INTEL_CHIPSET_LOCKDOWN) ||
834 acpi_is_wakeup_s3()) {
835 outb(APM_CNT_FINALIZE, APM_CNT);
836 }
Vladimir Serbinenkob06a2492015-05-21 10:32:59 +0200837 }
838}
839
Stefan Reinauer8e073822012-04-04 00:07:22 +0200840static struct pci_operations pci_ops = {
841 .set_subsystem = set_subsystem,
842};
843
844static struct device_operations device_ops = {
845 .read_resources = pch_lpc_read_resources,
846 .set_resources = pci_dev_set_resources,
847 .enable_resources = pch_lpc_enable_resources,
Vladimir Serbinenko35c0f432014-09-02 22:25:36 +0200848 .write_acpi_tables = acpi_write_hpet,
Vladimir Serbinenko334fd8e2014-10-05 11:10:35 +0200849 .acpi_inject_dsdt_generator = southbridge_inject_dsdt,
Vladimir Serbinenko36fa5b82014-10-28 23:43:20 +0100850 .acpi_fill_ssdt_generator = southbridge_fill_ssdt,
Patrick Rudolph604f6982017-06-07 09:46:52 +0200851 .acpi_name = lpc_acpi_name,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200852 .init = lpc_init,
Vladimir Serbinenkob06a2492015-05-21 10:32:59 +0200853 .final = lpc_final,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200854 .enable = pch_lpc_enable,
Kyösti Mälkkid0e212c2015-02-26 20:47:47 +0200855 .scan_bus = scan_lpc_bus,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200856 .ops_pci = &pci_ops,
857};
858
859
Kimarie Hoote6f459c2012-07-14 08:26:08 -0600860/* IDs for LPC device of Intel 6 Series Chipset, Intel 7 Series Chipset, and
861 * Intel C200 Series Chipset
Stefan Reinauer8e073822012-04-04 00:07:22 +0200862 */
863
Vladimir Serbinenko42d55e02016-01-02 01:47:26 +0100864static const unsigned short pci_device_ids[] = {
865 0x1c40, 0x1c41, 0x1c42, 0x1c43, 0x1c44, 0x1c45, 0x1c46, 0x1c47, 0x1c48,
866 0x1c49, 0x1c4a, 0x1c4b, 0x1c4c, 0x1c4d, 0x1c4e, 0x1c4f, 0x1c50, 0x1c51,
867 0x1c52, 0x1c53, 0x1c54, 0x1c55, 0x1c56, 0x1c57, 0x1c58, 0x1c59, 0x1c5a,
868 0x1c5b, 0x1c5c, 0x1c5d, 0x1c5e, 0x1c5f,
869
870 0x1e41, 0x1e42, 0x1e43, 0x1e44, 0x1e45, 0x1e46, 0x1e47, 0x1e48, 0x1e49,
871 0x1e4a, 0x1e4b, 0x1e4c, 0x1e4d, 0x1e4e, 0x1e4f, 0x1e50, 0x1e51, 0x1e52,
872 0x1e53, 0x1e54, 0x1e55, 0x1e56, 0x1e57, 0x1e58, 0x1e59, 0x1e5a, 0x1e5b,
873 0x1e5c, 0x1e5d, 0x1e5e, 0x1e5f,
874
875 0 };
Stefan Reinauer9a380ab2012-06-22 13:16:11 -0700876
877static const struct pci_driver pch_lpc __pci_driver = {
878 .ops = &device_ops,
879 .vendor = PCI_VENDOR_ID_INTEL,
880 .devices = pci_device_ids,
Stefan Reinauer8e073822012-04-04 00:07:22 +0200881};