blob: f13efb0f7fb4096cdb6ade46686b9bfa95b4f287 [file] [log] [blame]
Aaron Durbin76c37002012-10-30 09:03:43 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2008-2009 coresystems GmbH
Duncan Laurie5cc51c02013-03-07 14:06:43 -08005 * Copyright 2013 Google Inc.
Aaron Durbin76c37002012-10-30 09:03:43 -05006 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; version 2 of
10 * the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22#include <console/console.h>
23#include <delay.h>
Duncan Laurie5cc51c02013-03-07 14:06:43 -080024#include <arch/io.h>
Aaron Durbin76c37002012-10-30 09:03:43 -050025#include <device/device.h>
26#include <device/pci.h>
Stefan Reinauer5605f1b2013-03-21 18:43:51 -070027#include <device/pci_def.h>
Aaron Durbin76c37002012-10-30 09:03:43 -050028#include "pch.h"
29
Duncan Laurie5cc51c02013-03-07 14:06:43 -080030static device_t pch_get_lpc_device(void)
31{
32#ifdef __SMM__
33 return PCI_DEV(0, 0x1f, 0);
34#else
35 return dev_find_slot(0, PCI_DEVFN(0x1f, 0));
36#endif
37}
Aaron Durbin76c37002012-10-30 09:03:43 -050038
39int pch_silicon_revision(void)
40{
Duncan Laurie5cc51c02013-03-07 14:06:43 -080041 static int pch_revision_id = -1;
42
Aaron Durbin76c37002012-10-30 09:03:43 -050043 if (pch_revision_id < 0)
Duncan Laurie5cc51c02013-03-07 14:06:43 -080044 pch_revision_id = pci_read_config8(pch_get_lpc_device(),
45 PCI_REVISION_ID);
Aaron Durbin76c37002012-10-30 09:03:43 -050046 return pch_revision_id;
47}
48
49int pch_silicon_type(void)
50{
Duncan Laurie5cc51c02013-03-07 14:06:43 -080051 static int pch_type = -1;
52
Aaron Durbin76c37002012-10-30 09:03:43 -050053 if (pch_type < 0)
Duncan Laurie5cc51c02013-03-07 14:06:43 -080054 pch_type = pci_read_config8(pch_get_lpc_device(),
55 PCI_DEVICE_ID + 1);
Aaron Durbin76c37002012-10-30 09:03:43 -050056 return pch_type;
57}
58
Duncan Laurie5cc51c02013-03-07 14:06:43 -080059int pch_is_lp(void)
Aaron Durbin76c37002012-10-30 09:03:43 -050060{
Duncan Laurie5cc51c02013-03-07 14:06:43 -080061 return pch_silicon_type() == PCH_TYPE_LPT_LP;
Aaron Durbin76c37002012-10-30 09:03:43 -050062}
63
Duncan Laurie1ad55642013-03-07 14:08:04 -080064u16 get_pmbase(void)
65{
66 static u16 pmbase;
67
68 if (!pmbase)
69 pmbase = pci_read_config16(pch_get_lpc_device(),
70 PMBASE) & 0xfffc;
71 return pmbase;
72}
73
74u16 get_gpiobase(void)
75{
76 static u16 gpiobase;
77
78 if (!gpiobase)
79 gpiobase = pci_read_config16(pch_get_lpc_device(),
80 GPIOBASE) & 0xfffc;
81 return gpiobase;
82}
83
Duncan Laurie5cc51c02013-03-07 14:06:43 -080084#ifndef __SMM__
85
Duncan Laurie98c40622013-05-21 16:37:40 -070086/* Put device in D3Hot Power State */
87static void pch_enable_d3hot(device_t dev)
Aaron Durbin76c37002012-10-30 09:03:43 -050088{
Duncan Laurie98c40622013-05-21 16:37:40 -070089 u32 reg32 = pci_read_config32(dev, PCH_PCS);
90 reg32 |= PCH_PCS_PS_D3HOT;
91 pci_write_config32(dev, PCH_PCS, reg32);
92}
93
94/* Set bit in Function Disble register to hide this device */
Aaron Durbin3fcd3562013-06-19 13:20:37 -050095void pch_disable_devfn(device_t dev)
Duncan Laurie98c40622013-05-21 16:37:40 -070096{
97 switch (dev->path.pci.devfn) {
Duncan Laurie26e7dd72012-12-19 09:12:31 -080098 case PCI_DEVFN(19, 0): /* Audio DSP */
99 RCBA32_OR(FD, PCH_DISABLE_ADSPD);
100 break;
101 case PCI_DEVFN(20, 0): /* XHCI */
102 RCBA32_OR(FD, PCH_DISABLE_XHCI);
103 break;
Duncan Laurie71346c02013-01-10 13:20:40 -0800104 case PCI_DEVFN(21, 0): /* DMA */
Duncan Laurie98c40622013-05-21 16:37:40 -0700105 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800106 pch_iobp_update(SIO_IOBP_FUNCDIS0, ~0UL, SIO_IOBP_FUNCDIS_DIS);
107 break;
108 case PCI_DEVFN(21, 1): /* I2C0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700109 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800110 pch_iobp_update(SIO_IOBP_FUNCDIS1, ~0UL, SIO_IOBP_FUNCDIS_DIS);
111 break;
112 case PCI_DEVFN(21, 2): /* I2C1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700113 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800114 pch_iobp_update(SIO_IOBP_FUNCDIS2, ~0UL, SIO_IOBP_FUNCDIS_DIS);
115 break;
116 case PCI_DEVFN(21, 3): /* SPI0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700117 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800118 pch_iobp_update(SIO_IOBP_FUNCDIS3, ~0UL, SIO_IOBP_FUNCDIS_DIS);
119 break;
120 case PCI_DEVFN(21, 4): /* SPI1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700121 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800122 pch_iobp_update(SIO_IOBP_FUNCDIS4, ~0UL, SIO_IOBP_FUNCDIS_DIS);
123 break;
124 case PCI_DEVFN(21, 5): /* UART0 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700125 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800126 pch_iobp_update(SIO_IOBP_FUNCDIS5, ~0UL, SIO_IOBP_FUNCDIS_DIS);
127 break;
128 case PCI_DEVFN(21, 6): /* UART1 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700129 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800130 pch_iobp_update(SIO_IOBP_FUNCDIS6, ~0UL, SIO_IOBP_FUNCDIS_DIS);
131 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500132 case PCI_DEVFN(22, 0): /* MEI #1 */
133 RCBA32_OR(FD2, PCH_DISABLE_MEI1);
134 break;
135 case PCI_DEVFN(22, 1): /* MEI #2 */
136 RCBA32_OR(FD2, PCH_DISABLE_MEI2);
137 break;
138 case PCI_DEVFN(22, 2): /* IDE-R */
139 RCBA32_OR(FD2, PCH_DISABLE_IDER);
140 break;
141 case PCI_DEVFN(22, 3): /* KT */
142 RCBA32_OR(FD2, PCH_DISABLE_KT);
143 break;
Duncan Laurie71346c02013-01-10 13:20:40 -0800144 case PCI_DEVFN(23, 0): /* SDIO */
Duncan Laurie98c40622013-05-21 16:37:40 -0700145 pch_enable_d3hot(dev);
Duncan Laurie71346c02013-01-10 13:20:40 -0800146 pch_iobp_update(SIO_IOBP_FUNCDIS7, ~0UL, SIO_IOBP_FUNCDIS_DIS);
147 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500148 case PCI_DEVFN(25, 0): /* Gigabit Ethernet */
149 RCBA32_OR(BUC, PCH_DISABLE_GBE);
150 break;
151 case PCI_DEVFN(26, 0): /* EHCI #2 */
152 RCBA32_OR(FD, PCH_DISABLE_EHCI2);
153 break;
154 case PCI_DEVFN(27, 0): /* HD Audio Controller */
155 RCBA32_OR(FD, PCH_DISABLE_HD_AUDIO);
156 break;
157 case PCI_DEVFN(28, 0): /* PCI Express Root Port 1 */
158 case PCI_DEVFN(28, 1): /* PCI Express Root Port 2 */
159 case PCI_DEVFN(28, 2): /* PCI Express Root Port 3 */
160 case PCI_DEVFN(28, 3): /* PCI Express Root Port 4 */
161 case PCI_DEVFN(28, 4): /* PCI Express Root Port 5 */
162 case PCI_DEVFN(28, 5): /* PCI Express Root Port 6 */
163 case PCI_DEVFN(28, 6): /* PCI Express Root Port 7 */
164 case PCI_DEVFN(28, 7): /* PCI Express Root Port 8 */
Duncan Laurie98c40622013-05-21 16:37:40 -0700165 RCBA32_OR(FD, PCH_DISABLE_PCIE(PCI_FUNC(dev->path.pci.devfn)));
Aaron Durbin76c37002012-10-30 09:03:43 -0500166 break;
167 case PCI_DEVFN(29, 0): /* EHCI #1 */
168 RCBA32_OR(FD, PCH_DISABLE_EHCI1);
169 break;
Aaron Durbin76c37002012-10-30 09:03:43 -0500170 case PCI_DEVFN(31, 0): /* LPC */
171 RCBA32_OR(FD, PCH_DISABLE_LPC);
172 break;
173 case PCI_DEVFN(31, 2): /* SATA #1 */
174 RCBA32_OR(FD, PCH_DISABLE_SATA1);
175 break;
176 case PCI_DEVFN(31, 3): /* SMBUS */
177 RCBA32_OR(FD, PCH_DISABLE_SMBUS);
178 break;
Duncan Laurie26e7dd72012-12-19 09:12:31 -0800179 case PCI_DEVFN(31, 5): /* SATA #2 */
Aaron Durbin76c37002012-10-30 09:03:43 -0500180 RCBA32_OR(FD, PCH_DISABLE_SATA2);
181 break;
182 case PCI_DEVFN(31, 6): /* Thermal Subsystem */
183 RCBA32_OR(FD, PCH_DISABLE_THERMAL);
184 break;
185 }
186}
187
188#define IOBP_RETRY 1000
189static inline int iobp_poll(void)
190{
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800191 unsigned try;
Aaron Durbin76c37002012-10-30 09:03:43 -0500192
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800193 for (try = IOBP_RETRY; try > 0; try--) {
194 u16 status = RCBA16(IOBPS);
195 if ((status & IOBPS_READY) == 0)
Aaron Durbin76c37002012-10-30 09:03:43 -0500196 return 1;
197 udelay(10);
198 }
199
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800200 printk(BIOS_ERR, "IOBP: timeout waiting for transaction to complete\n");
Aaron Durbin76c37002012-10-30 09:03:43 -0500201 return 0;
202}
203
Aaron Durbinc17aac32013-06-19 13:12:48 -0500204u32 pch_iobp_read(u32 address)
Aaron Durbin76c37002012-10-30 09:03:43 -0500205{
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800206 u16 status;
207
208 if (!iobp_poll())
209 return 0;
Aaron Durbin76c37002012-10-30 09:03:43 -0500210
211 /* Set the address */
212 RCBA32(IOBPIRI) = address;
213
214 /* READ OPCODE */
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800215 status = RCBA16(IOBPS);
216 status &= ~IOBPS_MASK;
217 status |= IOBPS_READ;
218 RCBA16(IOBPS) = status;
Aaron Durbin76c37002012-10-30 09:03:43 -0500219
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800220 /* Undocumented magic */
221 RCBA16(IOBPU) = IOBPU_MAGIC;
222
223 /* Set ready bit */
224 status = RCBA16(IOBPS);
225 status |= IOBPS_READY;
226 RCBA16(IOBPS) = status;
227
Aaron Durbin76c37002012-10-30 09:03:43 -0500228 if (!iobp_poll())
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800229 return 0;
Aaron Durbin76c37002012-10-30 09:03:43 -0500230
231 /* Check for successful transaction */
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800232 status = RCBA16(IOBPS);
233 if (status & IOBPS_TX_MASK) {
234 printk(BIOS_ERR, "IOBP: read 0x%08x failed\n", address);
235 return 0;
Aaron Durbin76c37002012-10-30 09:03:43 -0500236 }
237
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800238 /* Read IOBP data */
239 return RCBA32(IOBPD);
240}
241
Aaron Durbinc17aac32013-06-19 13:12:48 -0500242void pch_iobp_write(u32 address, u32 data)
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800243{
244 u16 status;
Aaron Durbinc17aac32013-06-19 13:12:48 -0500245
246 if (!iobp_poll())
247 return;
248
249 /* Set the address */
250 RCBA32(IOBPIRI) = address;
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800251
252 /* WRITE OPCODE */
253 status = RCBA16(IOBPS);
254 status &= ~IOBPS_MASK;
255 status |= IOBPS_WRITE;
256 RCBA16(IOBPS) = status;
257
Aaron Durbin76c37002012-10-30 09:03:43 -0500258 RCBA32(IOBPD) = data;
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800259
260 /* Undocumented magic */
261 RCBA16(IOBPU) = IOBPU_MAGIC;
262
263 /* Set ready bit */
264 status = RCBA16(IOBPS);
265 status |= IOBPS_READY;
266 RCBA16(IOBPS) = status;
267
Aaron Durbin76c37002012-10-30 09:03:43 -0500268 if (!iobp_poll())
269 return;
Duncan Laurie7302d1e2013-01-10 13:19:23 -0800270
271 /* Check for successful transaction */
272 status = RCBA16(IOBPS);
273 if (status & IOBPS_TX_MASK) {
274 printk(BIOS_ERR, "IOBP: write 0x%08x failed\n", address);
275 return;
276 }
277
278 printk(BIOS_INFO, "IOBP: set 0x%08x to 0x%08x\n", address, data);
Aaron Durbin76c37002012-10-30 09:03:43 -0500279}
280
Aaron Durbinc17aac32013-06-19 13:12:48 -0500281void pch_iobp_update(u32 address, u32 andvalue, u32 orvalue)
282{
283 u32 data = pch_iobp_read(address);
284
285 /* Update the data */
286 data &= andvalue;
287 data |= orvalue;
288
289 pch_iobp_write(address, data);
290}
291
Aaron Durbin76c37002012-10-30 09:03:43 -0500292/* Check if any port in set X to X+3 is enabled */
293static int pch_pcie_check_set_enabled(device_t dev)
294{
295 device_t port;
296 int port_func;
297 int dev_func = PCI_FUNC(dev->path.pci.devfn);
298
299 printk(BIOS_DEBUG, "%s: check set enabled\n", dev_path(dev));
300
301 /* Go through static device tree list of devices
302 * because enumeration is still in progress */
303 for (port = all_devices; port; port = port->next) {
304 /* Only care about PCIe root ports */
305 if (PCI_SLOT(port->path.pci.devfn) !=
306 PCI_SLOT(dev->path.pci.devfn))
307 continue;
308
309 /* Check if port is in range and enabled */
310 port_func = PCI_FUNC(port->path.pci.devfn);
311 if (port_func >= dev_func &&
312 port_func < (dev_func + 4) &&
313 port->enabled)
314 return 1;
315 }
316
317 /* None of the ports in this set are enabled */
318 return 0;
319}
320
321/* RPFN is a write-once register so keep a copy until it is written */
322static u32 new_rpfn;
323
324/* Swap function numbers assigned to two PCIe Root Ports */
325static void pch_pcie_function_swap(u8 old_fn, u8 new_fn)
326{
327 u32 old_rpfn = new_rpfn;
328
329 printk(BIOS_DEBUG, "PCH: Remap PCIe function %d to %d\n",
330 old_fn, new_fn);
331
332 new_rpfn &= ~(RPFN_FNMASK(old_fn) | RPFN_FNMASK(new_fn));
333
334 /* Old function set to new function and disabled */
335 new_rpfn |= RPFN_FNSET(old_fn, RPFN_FNGET(old_rpfn, new_fn));
336 new_rpfn |= RPFN_FNSET(new_fn, RPFN_FNGET(old_rpfn, old_fn));
337}
338
339/* Update devicetree with new Root Port function number assignment */
340static void pch_pcie_devicetree_update(void)
341{
342 device_t dev;
343
344 /* Update the function numbers in the static devicetree */
345 for (dev = all_devices; dev; dev = dev->next) {
346 u8 new_devfn;
347
348 /* Only care about PCH PCIe root ports */
349 if (PCI_SLOT(dev->path.pci.devfn) !=
350 PCH_PCIE_DEV_SLOT)
351 continue;
352
353 /* Determine the new devfn for this port */
354 new_devfn = PCI_DEVFN(PCH_PCIE_DEV_SLOT,
355 RPFN_FNGET(new_rpfn,
356 PCI_FUNC(dev->path.pci.devfn)));
357
358 if (dev->path.pci.devfn != new_devfn) {
359 printk(BIOS_DEBUG,
360 "PCH: PCIe map %02x.%1x -> %02x.%1x\n",
361 PCI_SLOT(dev->path.pci.devfn),
362 PCI_FUNC(dev->path.pci.devfn),
363 PCI_SLOT(new_devfn), PCI_FUNC(new_devfn));
364
365 dev->path.pci.devfn = new_devfn;
366 }
367 }
368}
369
370/* Special handling for PCIe Root Port devices */
371static void pch_pcie_enable(device_t dev)
372{
373 struct southbridge_intel_lynxpoint_config *config = dev->chip_info;
374 u32 reg32;
375
376 /*
377 * Save a copy of the Root Port Function Number map when
378 * starting to walk the list of PCIe Root Ports so it can
379 * be updated locally and written out when the last port
380 * has been processed.
381 */
382 if (PCI_FUNC(dev->path.pci.devfn) == 0) {
383 new_rpfn = RCBA32(RPFN);
384
385 /*
386 * Enable Root Port coalescing if the first port is disabled
387 * or the other devices will not be enumerated by the OS.
388 */
389 if (!dev->enabled)
390 config->pcie_port_coalesce = 1;
391
392 if (config->pcie_port_coalesce)
393 printk(BIOS_INFO,
394 "PCH: PCIe Root Port coalescing is enabled\n");
395 }
396
397 if (!dev->enabled) {
398 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
399
400 /*
401 * PCIE Power Savings for PantherPoint and CougarPoint/B1+
402 *
403 * If PCIe 0-3 disabled set Function 0 0xE2[0] = 1
404 * If PCIe 4-7 disabled set Function 4 0xE2[0] = 1
405 *
406 * This check is done here instead of pcie driver
407 * because the pcie driver enable() handler is not
408 * called unless the device is enabled.
409 */
410 if ((PCI_FUNC(dev->path.pci.devfn) == 0 ||
411 PCI_FUNC(dev->path.pci.devfn) == 4)) {
412 /* Handle workaround for PPT and CPT/B1+ */
413 if (!pch_pcie_check_set_enabled(dev)) {
414 u8 reg8 = pci_read_config8(dev, 0xe2);
415 reg8 |= 1;
416 pci_write_config8(dev, 0xe2, reg8);
417 }
418
419 /*
420 * Enable Clock Gating for shared PCIe resources
421 * before disabling this particular port.
422 */
423 pci_write_config8(dev, 0xe1, 0x3c);
424 }
425
426 /* Ensure memory, io, and bus master are all disabled */
427 reg32 = pci_read_config32(dev, PCI_COMMAND);
428 reg32 &= ~(PCI_COMMAND_MASTER |
429 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
430 pci_write_config32(dev, PCI_COMMAND, reg32);
431
432 /* Do not claim downstream transactions for PCIe ports */
433 new_rpfn |= RPFN_HIDE(PCI_FUNC(dev->path.pci.devfn));
434
Aaron Durbin3fcd3562013-06-19 13:20:37 -0500435 /* Disable this device if possible */
436 pch_disable_devfn(dev);
Aaron Durbin76c37002012-10-30 09:03:43 -0500437 } else {
438 int fn;
439
440 /*
441 * Check if there is a lower disabled port to swap with this
442 * port in order to maintain linear order starting at zero.
443 */
444 if (config->pcie_port_coalesce) {
445 for (fn=0; fn < PCI_FUNC(dev->path.pci.devfn); fn++) {
446 if (!(new_rpfn & RPFN_HIDE(fn)))
447 continue;
448
449 /* Swap places with this function */
450 pch_pcie_function_swap(
451 PCI_FUNC(dev->path.pci.devfn), fn);
452 break;
453 }
454 }
455
456 /* Enable SERR */
457 reg32 = pci_read_config32(dev, PCI_COMMAND);
458 reg32 |= PCI_COMMAND_SERR;
459 pci_write_config32(dev, PCI_COMMAND, reg32);
460 }
461
462 /*
463 * When processing the last PCIe root port we can now
464 * update the Root Port Function Number and Hide register.
465 */
466 if (PCI_FUNC(dev->path.pci.devfn) == 7) {
467 printk(BIOS_SPEW, "PCH: RPFN 0x%08x -> 0x%08x\n",
468 RCBA32(RPFN), new_rpfn);
469 RCBA32(RPFN) = new_rpfn;
470
471 /* Update static devictree with new function numbers */
472 if (config->pcie_port_coalesce)
473 pch_pcie_devicetree_update();
474 }
475}
476
477void pch_enable(device_t dev)
478{
479 u32 reg32;
480
481 /* PCH PCIe Root Ports get special handling */
482 if (PCI_SLOT(dev->path.pci.devfn) == PCH_PCIE_DEV_SLOT)
483 return pch_pcie_enable(dev);
484
485 if (!dev->enabled) {
486 printk(BIOS_DEBUG, "%s: Disabling device\n", dev_path(dev));
487
488 /* Ensure memory, io, and bus master are all disabled */
489 reg32 = pci_read_config32(dev, PCI_COMMAND);
490 reg32 &= ~(PCI_COMMAND_MASTER |
491 PCI_COMMAND_MEMORY | PCI_COMMAND_IO);
492 pci_write_config32(dev, PCI_COMMAND, reg32);
493
Aaron Durbin3fcd3562013-06-19 13:20:37 -0500494 /* Disable this device if possible */
495 pch_disable_devfn(dev);
Aaron Durbin76c37002012-10-30 09:03:43 -0500496 } else {
497 /* Enable SERR */
498 reg32 = pci_read_config32(dev, PCI_COMMAND);
499 reg32 |= PCI_COMMAND_SERR;
500 pci_write_config32(dev, PCI_COMMAND, reg32);
501 }
502}
503
504struct chip_operations southbridge_intel_lynxpoint_ops = {
505 CHIP_NAME("Intel Series 8 (Lynx Point) Southbridge")
506 .enable_dev = pch_enable,
507};
Duncan Laurie5cc51c02013-03-07 14:06:43 -0800508
509#endif /* __SMM__ */