Thu Jul 16 12:39:11 2020 UTC ()
Pull up the following revisions, requested by msaitoh in ticket #1017:

	sys/dev/pci/piixpm.c			1.57-1.59, 1.61-1.63 via patch
	sys/dev/pci/piixpmreg.h			1.9-1.12

- Fix number of port for Hudson rev. 0x1f and newer.
- Read SB800_SMB_HOSTC correctly. This register is not in the PCI
  config space but in the I/O space.
- The bit 0 of SB800_SMB_HOSTC is 0 on SMI and 1 on IRQ, so invert the
  check.
- Don't force using SMBUS0SEL register.
- Acquire/release host semaphore to share SMBus between the host and
  the embedded controller (IMC). Without this change, "shutdown -r"
  does power off and not boot on some machines.
- Save/restore port number before selecting port.
- Modify comment.
- Whitespace fix.


(martin)
diff -r1.54 -r1.54.2.1 src/sys/dev/pci/piixpm.c
diff -r1.8 -r1.8.2.1 src/sys/dev/pci/piixpmreg.h

cvs diff -r1.54 -r1.54.2.1 src/sys/dev/pci/piixpm.c (expand / switch to unified diff)

--- src/sys/dev/pci/piixpm.c 2019/07/13 09:24:17 1.54
+++ src/sys/dev/pci/piixpm.c 2020/07/16 12:39:11 1.54.2.1
@@ -1,38 +1,38 @@ @@ -1,38 +1,38 @@
1/* $NetBSD: piixpm.c,v 1.54 2019/07/13 09:24:17 msaitoh Exp $ */ 1/* $NetBSD: piixpm.c,v 1.54.2.1 2020/07/16 12:39:11 martin Exp $ */
2/* $OpenBSD: piixpm.c,v 1.39 2013/10/01 20:06:02 sf Exp $ */ 2/* $OpenBSD: piixpm.c,v 1.39 2013/10/01 20:06:02 sf Exp $ */
3 3
4/* 4/*
5 * Copyright (c) 2005, 2006 Alexander Yurchenko <grange@openbsd.org> 5 * Copyright (c) 2005, 2006 Alexander Yurchenko <grange@openbsd.org>
6 * 6 *
7 * Permission to use, copy, modify, and distribute this software for any 7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above 8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies. 9 * copyright notice and this permission notice appear in all copies.
10 * 10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */ 18 */
19 19
20/* 20/*
21 * Intel PIIX and compatible Power Management controller driver. 21 * Intel PIIX and compatible Power Management controller driver.
22 */ 22 */
23 23
24#include <sys/cdefs.h> 24#include <sys/cdefs.h>
25__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.54 2019/07/13 09:24:17 msaitoh Exp $"); 25__KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.54.2.1 2020/07/16 12:39:11 martin Exp $");
26 26
27#include <sys/param.h> 27#include <sys/param.h>
28#include <sys/systm.h> 28#include <sys/systm.h>
29#include <sys/device.h> 29#include <sys/device.h>
30#include <sys/kernel.h> 30#include <sys/kernel.h>
31#include <sys/mutex.h> 31#include <sys/mutex.h>
32#include <sys/proc.h> 32#include <sys/proc.h>
33 33
34#include <sys/bus.h> 34#include <sys/bus.h>
35 35
36#include <dev/pci/pcidevs.h> 36#include <dev/pci/pcidevs.h>
37#include <dev/pci/pcireg.h> 37#include <dev/pci/pcireg.h>
38#include <dev/pci/pcivar.h> 38#include <dev/pci/pcivar.h>
@@ -60,42 +60,46 @@ __KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1 @@ -60,42 +60,46 @@ __KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1
60 ((PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_ATI_SB600_SMB) && \ 60 ((PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_ATI_SB600_SMB) && \
61 ((sc)->sc_rev >= 0x40))) 61 ((sc)->sc_rev >= 0x40)))
62 62
63#define PIIXPM_IS_HUDSON(sc) \ 63#define PIIXPM_IS_HUDSON(sc) \
64 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \ 64 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \
65 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_HUDSON_SMB)) 65 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_HUDSON_SMB))
66 66
67#define PIIXPM_IS_KERNCZ(sc) \ 67#define PIIXPM_IS_KERNCZ(sc) \
68 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \ 68 ((PCI_VENDOR((sc)->sc_id) == PCI_VENDOR_AMD) && \
69 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_KERNCZ_SMB)) 69 (PCI_PRODUCT((sc)->sc_id) == PCI_PRODUCT_AMD_KERNCZ_SMB))
70 70
71#define PIIXPM_IS_FCHGRP(sc) (PIIXPM_IS_HUDSON(sc) || PIIXPM_IS_KERNCZ(sc)) 71#define PIIXPM_IS_FCHGRP(sc) (PIIXPM_IS_HUDSON(sc) || PIIXPM_IS_KERNCZ(sc))
72 72
 73#define PIIX_SB800_TIMEOUT 500
 74
73struct piixpm_smbus { 75struct piixpm_smbus {
74 int sda; 76 int sda;
 77 int sda_save;
75 struct piixpm_softc *softc; 78 struct piixpm_softc *softc;
76}; 79};
77 80
78struct piixpm_softc { 81struct piixpm_softc {
79 device_t sc_dev; 82 device_t sc_dev;
80 83
81 bus_space_tag_t sc_iot; 84 bus_space_tag_t sc_iot;
82#define sc_pm_iot sc_iot 85#define sc_pm_iot sc_iot
83#define sc_smb_iot sc_iot 86#define sc_smb_iot sc_iot
84 bus_space_handle_t sc_pm_ioh; 87 bus_space_handle_t sc_pm_ioh;
85 bus_space_handle_t sc_sb800_ioh; 88 bus_space_handle_t sc_sb800_ioh;
86 bus_space_handle_t sc_smb_ioh; 89 bus_space_handle_t sc_smb_ioh;
87 void * sc_smb_ih; 90 void * sc_smb_ih;
88 int sc_poll; 91 int sc_poll;
 92 bool sc_sb800_selen; /* Use SMBUS0SEL */
89 93
90 pci_chipset_tag_t sc_pc; 94 pci_chipset_tag_t sc_pc;
91 pcitag_t sc_pcitag; 95 pcitag_t sc_pcitag;
92 pcireg_t sc_id; 96 pcireg_t sc_id;
93 pcireg_t sc_rev; 97 pcireg_t sc_rev;
94 98
95 int sc_numbusses; 99 int sc_numbusses;
96 device_t sc_i2c_device[4]; 100 device_t sc_i2c_device[4];
97 struct piixpm_smbus sc_busses[4]; 101 struct piixpm_smbus sc_busses[4];
98 struct i2c_controller sc_i2c_tags[4]; 102 struct i2c_controller sc_i2c_tags[4];
99 103
100 kmutex_t sc_i2c_mutex; 104 kmutex_t sc_i2c_mutex;
101 struct { 105 struct {
@@ -109,28 +113,28 @@ struct piixpm_softc { @@ -109,28 +113,28 @@ struct piixpm_softc {
109 pcireg_t sc_devact[2]; 113 pcireg_t sc_devact[2];
110}; 114};
111 115
112static int piixpm_match(device_t, cfdata_t, void *); 116static int piixpm_match(device_t, cfdata_t, void *);
113static void piixpm_attach(device_t, device_t, void *); 117static void piixpm_attach(device_t, device_t, void *);
114static int piixpm_rescan(device_t, const char *, const int *); 118static int piixpm_rescan(device_t, const char *, const int *);
115static void piixpm_chdet(device_t, device_t); 119static void piixpm_chdet(device_t, device_t);
116 120
117static bool piixpm_suspend(device_t, const pmf_qual_t *); 121static bool piixpm_suspend(device_t, const pmf_qual_t *);
118static bool piixpm_resume(device_t, const pmf_qual_t *); 122static bool piixpm_resume(device_t, const pmf_qual_t *);
119 123
120static int piixpm_sb800_init(struct piixpm_softc *); 124static int piixpm_sb800_init(struct piixpm_softc *);
121static void piixpm_csb5_reset(void *); 125static void piixpm_csb5_reset(void *);
122static int piixpm_i2c_acquire_bus(void *, int); 126static int piixpm_i2c_sb800_acquire_bus(void *, int);
123static void piixpm_i2c_release_bus(void *, int); 127static void piixpm_i2c_sb800_release_bus(void *, int);
124static int piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *, 128static int piixpm_i2c_exec(void *, i2c_op_t, i2c_addr_t, const void *,
125 size_t, void *, size_t, int); 129 size_t, void *, size_t, int);
126 130
127static int piixpm_intr(void *); 131static int piixpm_intr(void *);
128 132
129CFATTACH_DECL3_NEW(piixpm, sizeof(struct piixpm_softc), 133CFATTACH_DECL3_NEW(piixpm, sizeof(struct piixpm_softc),
130 piixpm_match, piixpm_attach, NULL, NULL, piixpm_rescan, piixpm_chdet, 0); 134 piixpm_match, piixpm_attach, NULL, NULL, piixpm_rescan, piixpm_chdet, 0);
131 135
132static int 136static int
133piixpm_match(device_t parent, cfdata_t match, void *aux) 137piixpm_match(device_t parent, cfdata_t match, void *aux)
134{ 138{
135 struct pci_attach_args *pa; 139 struct pci_attach_args *pa;
136 140
@@ -221,35 +225,30 @@ piixpm_attach(device_t parent, device_t  @@ -221,35 +225,30 @@ piixpm_attach(device_t parent, device_t
221 /* 225 /*
222 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. 226 * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M.
223 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 227 * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20
224 * in the "Specification update" (document #297738). 228 * in the "Specification update" (document #297738).
225 */ 229 */
226 acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, 230 acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR,
227 (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0); 231 (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0);
228 232
229nopowermanagement: 233nopowermanagement:
230 234
231 /* SB800 rev 0x40+, AMD HUDSON and newer need special initialization */ 235 /* SB800 rev 0x40+, AMD HUDSON and newer need special initialization */
232 if (PIIXPM_IS_FCHGRP(sc) || PIIXPM_IS_SB800GRP(sc)) { 236 if (PIIXPM_IS_FCHGRP(sc) || PIIXPM_IS_SB800GRP(sc)) {
233 if (piixpm_sb800_init(sc) == 0) { 237 if (piixpm_sb800_init(sc) == 0) {
234 sc->sc_numbusses = 4; 
235 
236 /* Read configuration */ 238 /* Read configuration */
237 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, 239 conf = bus_space_read_1(sc->sc_iot,
238 SB800_SMB_HOSTC); 240 sc->sc_smb_ioh, SB800_SMB_HOSTC);
239 DPRINTF(("%s: conf 0x%08x\n", device_xname(self), 241 usesmi = ((conf & SB800_SMB_HOSTC_IRQ) == 0);
240 conf)); 
241 
242 usesmi = conf & SB800_SMB_HOSTC_SMI; 
243 goto setintr; 242 goto setintr;
244 } 243 }
245 aprint_normal_dev(self, "SMBus initialization failed\n"); 244 aprint_normal_dev(self, "SMBus initialization failed\n");
246 return; 245 return;
247 } 246 }
248 247
249 /* Read configuration */ 248 /* Read configuration */
250 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC); 249 conf = pci_conf_read(pa->pa_pc, pa->pa_tag, PIIX_SMB_HOSTC);
251 DPRINTF(("%s: conf 0x%08x\n", device_xname(self), conf)); 250 DPRINTF(("%s: conf 0x%08x\n", device_xname(self), conf));
252 251
253 if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) { 252 if ((conf & PIIX_SMB_HOSTC_HSTEN) == 0) {
254 aprint_normal_dev(self, "SMBus disabled\n"); 253 aprint_normal_dev(self, "SMBus disabled\n");
255 return; 254 return;
@@ -318,37 +317,44 @@ piixpm_iicbus_print(void *aux, const cha @@ -318,37 +317,44 @@ piixpm_iicbus_print(void *aux, const cha
318static int 317static int
319piixpm_rescan(device_t self, const char *ifattr, const int *flags) 318piixpm_rescan(device_t self, const char *ifattr, const int *flags)
320{ 319{
321 struct piixpm_softc *sc = device_private(self); 320 struct piixpm_softc *sc = device_private(self);
322 struct i2cbus_attach_args iba; 321 struct i2cbus_attach_args iba;
323 int i; 322 int i;
324 323
325 if (!ifattr_match(ifattr, "i2cbus")) 324 if (!ifattr_match(ifattr, "i2cbus"))
326 return 0; 325 return 0;
327 326
328 /* Attach I2C bus */ 327 /* Attach I2C bus */
329 328
330 for (i = 0; i < sc->sc_numbusses; i++) { 329 for (i = 0; i < sc->sc_numbusses; i++) {
 330 struct i2c_controller *tag = &sc->sc_i2c_tags[i];
 331
331 if (sc->sc_i2c_device[i]) 332 if (sc->sc_i2c_device[i])
332 continue; 333 continue;
333 sc->sc_busses[i].sda = i; 334 sc->sc_busses[i].sda = i;
334 sc->sc_busses[i].softc = sc; 335 sc->sc_busses[i].softc = sc;
335 sc->sc_i2c_tags[i].ic_cookie = &sc->sc_busses[i]; 336 tag->ic_cookie = &sc->sc_busses[i];
336 sc->sc_i2c_tags[i].ic_acquire_bus = piixpm_i2c_acquire_bus; 337 if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_FCHGRP(sc)) {
337 sc->sc_i2c_tags[i].ic_release_bus = piixpm_i2c_release_bus; 338 tag->ic_acquire_bus = piixpm_i2c_sb800_acquire_bus;
338 sc->sc_i2c_tags[i].ic_exec = piixpm_i2c_exec; 339 tag->ic_release_bus = piixpm_i2c_sb800_release_bus;
 340 } else {
 341 tag->ic_acquire_bus = NULL;
 342 tag->ic_release_bus = NULL;
 343 }
 344 tag->ic_exec = piixpm_i2c_exec;
339 memset(&iba, 0, sizeof(iba)); 345 memset(&iba, 0, sizeof(iba));
340 iba.iba_type = I2C_TYPE_SMBUS; 346 iba.iba_type = I2C_TYPE_SMBUS;
341 iba.iba_tag = &sc->sc_i2c_tags[i]; 347 iba.iba_tag = tag;
342 sc->sc_i2c_device[i] = config_found_ia(self, ifattr, &iba, 348 sc->sc_i2c_device[i] = config_found_ia(self, ifattr, &iba,
343 piixpm_iicbus_print); 349 piixpm_iicbus_print);
344 } 350 }
345 351
346 return 0; 352 return 0;
347} 353}
348 354
349static void 355static void
350piixpm_chdet(device_t self, device_t child) 356piixpm_chdet(device_t self, device_t child)
351{ 357{
352 struct piixpm_softc *sc = device_private(self); 358 struct piixpm_softc *sc = device_private(self);
353 int i; 359 int i;
354 360
@@ -391,68 +397,77 @@ piixpm_resume(device_t dv, const pmf_qua @@ -391,68 +397,77 @@ piixpm_resume(device_t dv, const pmf_qua
391 * Extract SMBus base address from SB800 Power Management (PM) registers. 397 * Extract SMBus base address from SB800 Power Management (PM) registers.
392 * The PM registers can be accessed either through indirect I/O (CD6/CD7) or 398 * The PM registers can be accessed either through indirect I/O (CD6/CD7) or
393 * direct mapping if AcpiMMioDecodeEn is enabled. Since this function is only 399 * direct mapping if AcpiMMioDecodeEn is enabled. Since this function is only
394 * called once it uses indirect I/O for simplicity. 400 * called once it uses indirect I/O for simplicity.
395 */ 401 */
396static int 402static int
397piixpm_sb800_init(struct piixpm_softc *sc) 403piixpm_sb800_init(struct piixpm_softc *sc)
398{ 404{
399 bus_space_tag_t iot = sc->sc_iot; 405 bus_space_tag_t iot = sc->sc_iot;
400 bus_space_handle_t ioh; /* indirect I/O handle */ 406 bus_space_handle_t ioh; /* indirect I/O handle */
401 uint16_t val, base_addr; 407 uint16_t val, base_addr;
402 bool enabled; 408 bool enabled;
403 409
 410 if (PIIXPM_IS_KERNCZ(sc) ||
 411 (PIIXPM_IS_HUDSON(sc) && (sc->sc_rev >= 0x1f)))
 412 sc->sc_numbusses = 2;
 413 else
 414 sc->sc_numbusses = 4;
 415
404 /* Fetch SMB base address */ 416 /* Fetch SMB base address */
405 if (bus_space_map(iot, 417 if (bus_space_map(iot,
406 SB800_INDIRECTIO_BASE, SB800_INDIRECTIO_SIZE, 0, &ioh)) { 418 SB800_INDIRECTIO_BASE, SB800_INDIRECTIO_SIZE, 0, &ioh)) {
407 device_printf(sc->sc_dev, "couldn't map indirect I/O space\n"); 419 device_printf(sc->sc_dev, "couldn't map indirect I/O space\n");
408 return EBUSY; 420 return EBUSY;
409 } 421 }
410 if (PIIXPM_IS_FCHGRP(sc)) { 422 if (PIIXPM_IS_FCHGRP(sc)) {
411 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 423 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX,
412 AMDFCH41_PM_DECODE_EN0); 424 AMDFCH41_PM_DECODE_EN0);
413 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); 425 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA);
414 enabled = val & AMDFCH41_SMBUS_EN; 426 enabled = val & AMDFCH41_SMBUS_EN;
415 if (!enabled) 427 if (!enabled)
416 return ENOENT; 428 return ENOENT;
417 429
418 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 430 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX,
419 AMDFCH41_PM_DECODE_EN1); 431 AMDFCH41_PM_DECODE_EN1);
420 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8; 432 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8;
421 base_addr = val; 433 base_addr = val;
422 } else { 434 } else {
 435 uint8_t data;
 436
423 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 437 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX,
424 SB800_PM_SMBUS0EN_LO); 438 SB800_PM_SMBUS0EN_LO);
425 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); 439 val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA);
426 enabled = val & SB800_PM_SMBUS0EN_ENABLE; 440 enabled = val & SB800_PM_SMBUS0EN_ENABLE;
427 if (!enabled) 441 if (!enabled)
428 return ENOENT; 442 return ENOENT;
429 443
430 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 444 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX,
431 SB800_PM_SMBUS0EN_HI); 445 SB800_PM_SMBUS0EN_HI);
432 val |= bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8; 446 val |= bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA) << 8;
433 base_addr = val & SB800_PM_SMBUS0EN_BADDR; 447 base_addr = val & SB800_PM_SMBUS0EN_BADDR;
434 448
435 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, 449 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX,
436 SB800_PM_SMBUS0SELEN); 450 SB800_PM_SMBUS0SELEN);
437 bus_space_write_1(iot, ioh, SB800_INDIRECTIO_DATA, 451 data = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA);
438 SB800_PM_SMBUS0EN_ENABLE); 452 if ((data & SB800_PM_USE_SMBUS0SEL) != 0)
 453 sc->sc_sb800_selen = true;
439 } 454 }
440 455
441 sc->sc_sb800_ioh = ioh; 456 sc->sc_sb800_ioh = ioh;
442 aprint_debug_dev(sc->sc_dev, "SMBus @ 0x%04x\n", base_addr); 457 aprint_debug_dev(sc->sc_dev, "SMBus @ 0x%04x\n", base_addr);
443 458
444 if (bus_space_map(iot, PCI_MAPREG_IO_ADDR(base_addr), 459 if (bus_space_map(iot, PCI_MAPREG_IO_ADDR(base_addr),
445 PIIX_SMB_SIZE, 0, &sc->sc_smb_ioh)) { 460 SB800_SMB_SIZE, 0, &sc->sc_smb_ioh)) {
446 aprint_error_dev(sc->sc_dev, "can't map smbus I/O space\n"); 461 aprint_error_dev(sc->sc_dev, "can't map smbus I/O space\n");
447 return EBUSY; 462 return EBUSY;
448 } 463 }
449 464
450 return 0; 465 return 0;
451} 466}
452 467
453static void 468static void
454piixpm_csb5_reset(void *arg) 469piixpm_csb5_reset(void *arg)
455{ 470{
456 struct piixpm_softc *sc = arg; 471 struct piixpm_softc *sc = arg;
457 pcireg_t base, hostc, pmbase; 472 pcireg_t base, hostc, pmbase;
458 473
@@ -462,71 +477,125 @@ piixpm_csb5_reset(void *arg) @@ -462,71 +477,125 @@ piixpm_csb5_reset(void *arg)
462 pmbase = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE); 477 pmbase = pci_conf_read(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE);
463 pmbase |= PIIX_PM_BASE_CSB5_RESET; 478 pmbase |= PIIX_PM_BASE_CSB5_RESET;
464 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase); 479 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase);
465 pmbase &= ~PIIX_PM_BASE_CSB5_RESET; 480 pmbase &= ~PIIX_PM_BASE_CSB5_RESET;
466 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase); 481 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_PM_BASE, pmbase);
467 482
468 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE, base); 483 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_BASE, base);
469 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC, hostc); 484 pci_conf_write(sc->sc_pc, sc->sc_pcitag, PIIX_SMB_HOSTC, hostc);
470 485
471 (void) tsleep(&sc, PRIBIO, "csb5reset", hz/2); 486 (void) tsleep(&sc, PRIBIO, "csb5reset", hz/2);
472} 487}
473 488
474static int 489static int
475piixpm_i2c_acquire_bus(void *cookie, int flags) 490piixpm_i2c_sb800_acquire_bus(void *cookie, int flags)
476{ 491{
477 struct piixpm_smbus *smbus = cookie; 492 struct piixpm_smbus *smbus = cookie;
478 struct piixpm_softc *sc = smbus->softc; 493 struct piixpm_softc *sc = smbus->softc;
 494 uint8_t sctl, old_sda, index, mask, reg;
 495 int i;
 496
479 497
480 if (!cold) 498 if (!cold)
481 mutex_enter(&sc->sc_i2c_mutex); 499 mutex_enter(&sc->sc_i2c_mutex);
482 500
483 if (PIIXPM_IS_KERNCZ(sc)) { 501 sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC);
484 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 502 for (i = 0; i < PIIX_SB800_TIMEOUT; i++) {
485 SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX); 503 /* Try to acquire the host semaphore */
486 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 504 sctl &= ~PIIX_SMB_SC_SEMMASK;
487 SB800_INDIRECTIO_DATA, smbus->sda << 3); 505 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC,
488 } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { 506 sctl | PIIX_SMB_SC_HOSTSEM);
489 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 507
490 SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); 508 sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh,
 509 PIIX_SMB_SC);
 510 if ((sctl & PIIX_SMB_SC_HOSTSEM) != 0)
 511 break;
 512
 513 delay(1000);
 514 }
 515 if (i >= PIIX_SB800_TIMEOUT) {
 516 device_printf(sc->sc_dev,
 517 "Failed to acquire the host semaphore\n");
 518 return -1;
 519 }
 520
 521 if (PIIXPM_IS_KERNCZ(sc) ||
 522 (PIIXPM_IS_HUDSON(sc) && (sc->sc_rev >= 0x1f))) {
 523 index = AMDFCH41_PM_PORT_INDEX;
 524 mask = AMDFCH41_SMBUS_PORTMASK;
 525 } else if (sc->sc_sb800_selen) {
 526 index = SB800_PM_SMBUS0SEL;
 527 mask = SB800_PM_SMBUS0_MASK_E;
 528 } else {
 529 index = SB800_PM_SMBUS0EN_LO;
 530 mask = SB800_PM_SMBUS0_MASK_C;
 531 }
 532
 533 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 534 SB800_INDIRECTIO_INDEX, index);
 535 reg = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh,
 536 SB800_INDIRECTIO_DATA);
 537
 538 old_sda = __SHIFTOUT(reg, mask);
 539 if (smbus->sda != old_sda) {
 540 reg &= ~mask;
 541 reg |= __SHIFTIN(smbus->sda, mask);
491 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 542 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
492 SB800_INDIRECTIO_DATA, smbus->sda << 1); 543 SB800_INDIRECTIO_DATA, reg);
493 } 544 }
494 545
 546 /* Save the old port number */
 547 smbus->sda_save = old_sda;
 548
495 return 0; 549 return 0;
496} 550}
497 551
498static void 552static void
499piixpm_i2c_release_bus(void *cookie, int flags) 553piixpm_i2c_sb800_release_bus(void *cookie, int flags)
500{ 554{
501 struct piixpm_smbus *smbus = cookie; 555 struct piixpm_smbus *smbus = cookie;
502 struct piixpm_softc *sc = smbus->softc; 556 struct piixpm_softc *sc = smbus->softc;
 557 uint8_t sctl, index, mask, reg;
503 558
504 if (PIIXPM_IS_KERNCZ(sc)) { 559 if (PIIXPM_IS_KERNCZ(sc) ||
505 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 560 (PIIXPM_IS_HUDSON(sc) && (sc->sc_rev >= 0x1f))) {
506 SB800_INDIRECTIO_INDEX, AMDFCH41_PM_PORT_INDEX); 561 index = AMDFCH41_PM_PORT_INDEX;
507 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 562 mask = AMDFCH41_SMBUS_PORTMASK;
508 SB800_INDIRECTIO_DATA, 0); 563 } else if (sc->sc_sb800_selen) {
509 } else if (PIIXPM_IS_SB800GRP(sc) || PIIXPM_IS_HUDSON(sc)) { 564 index = SB800_PM_SMBUS0SEL;
510 /* 565 mask = SB800_PM_SMBUS0_MASK_E;
511 * HP Microserver hangs after reboot if not set to SDA0. 566 } else {
512 * Also add shutdown hook? 567 index = SB800_PM_SMBUS0EN_LO;
513 */ 568 mask = SB800_PM_SMBUS0_MASK_C;
514 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 569 }
515 SB800_INDIRECTIO_INDEX, SB800_PM_SMBUS0SEL); 570
 571 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
 572 SB800_INDIRECTIO_INDEX, index);
 573 if (smbus->sda != smbus->sda_save) {
 574 /* Restore the port number */
 575 reg = bus_space_read_1(sc->sc_iot, sc->sc_sb800_ioh,
 576 SB800_INDIRECTIO_DATA);
 577 reg &= ~mask;
 578 reg |= __SHIFTIN(smbus->sda_save, mask);
516 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh, 579 bus_space_write_1(sc->sc_iot, sc->sc_sb800_ioh,
517 SB800_INDIRECTIO_DATA, 0); 580 SB800_INDIRECTIO_DATA, reg);
518 } 581 }
519 582
 583 /* Relase the host semaphore */
 584 sctl = bus_space_read_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC);
 585 sctl &= ~PIIX_SMB_SC_SEMMASK;
 586 bus_space_write_1(sc->sc_smb_iot, sc->sc_smb_ioh, PIIX_SMB_SC,
 587 sctl | PIIX_SMB_SC_CLRHOSTSEM);
 588
520 if (!cold) 589 if (!cold)
521 mutex_exit(&sc->sc_i2c_mutex); 590 mutex_exit(&sc->sc_i2c_mutex);
522} 591}
523 592
524static int 593static int
525piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr, 594piixpm_i2c_exec(void *cookie, i2c_op_t op, i2c_addr_t addr,
526 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags) 595 const void *cmdbuf, size_t cmdlen, void *buf, size_t len, int flags)
527{ 596{
528 struct piixpm_smbus *smbus = cookie; 597 struct piixpm_smbus *smbus = cookie;
529 struct piixpm_softc *sc = smbus->softc; 598 struct piixpm_softc *sc = smbus->softc;
530 const uint8_t *b; 599 const uint8_t *b;
531 uint8_t ctl = 0, st; 600 uint8_t ctl = 0, st;
532 int retries; 601 int retries;

cvs diff -r1.8 -r1.8.2.1 src/sys/dev/pci/piixpmreg.h (expand / switch to unified diff)

--- src/sys/dev/pci/piixpmreg.h 2019/07/13 09:24:17 1.8
+++ src/sys/dev/pci/piixpmreg.h 2020/07/16 12:39:11 1.8.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: piixpmreg.h,v 1.8 2019/07/13 09:24:17 msaitoh Exp $ */ 1/* $NetBSD: piixpmreg.h,v 1.8.2.1 2020/07/16 12:39:11 martin Exp $ */
2/* $OpenBSD: piixreg.h,v 1.3 2006/01/03 22:39:03 grange Exp $ */ 2/* $OpenBSD: piixreg.h,v 1.3 2006/01/03 22:39:03 grange Exp $ */
3 3
4/*- 4/*-
5 * Copyright (c) 2016 Andriy Gapon <avg@FreeBSD.org> 5 * Copyright (c) 2016 Andriy Gapon <avg@FreeBSD.org>
6 * All rights reserved. 6 * All rights reserved.
7 * 7 *
8 * Redistribution and use in source and binary forms, with or without 8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions 9 * modification, are permitted provided that the following conditions
10 * are met: 10 * are met:
11 * 1. Redistributions of source code must retain the above copyright 11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer. 12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright 13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the 14 * notice, this list of conditions and the following disclaimer in the
@@ -56,27 +56,27 @@ @@ -56,27 +56,27 @@
56 * Power management registers. 56 * Power management registers.
57 */ 57 */
58 58
59/* PCI configuration registers */ 59/* PCI configuration registers */
60#define PIIX_PM_BASE 0x40 /* Power management base address */ 60#define PIIX_PM_BASE 0x40 /* Power management base address */
61#define PIIX_PM_BASE_CSB5_RESET 0x10 /* CSB5 PM reset */ 61#define PIIX_PM_BASE_CSB5_RESET 0x10 /* CSB5 PM reset */
62#define PIIX_DEVACTA 0x54 /* Device activity A (function 3) */ 62#define PIIX_DEVACTA 0x54 /* Device activity A (function 3) */
63#define PIIX_DEVACTB 0x58 /* Device activity B (function 3) */ 63#define PIIX_DEVACTB 0x58 /* Device activity B (function 3) */
64#define PIIX_PMREGMISC 0x80 /* Misc. Power management */ 64#define PIIX_PMREGMISC 0x80 /* Misc. Power management */
65#define PIIX_SMB_BASE 0x90 /* SMBus base address */ 65#define PIIX_SMB_BASE 0x90 /* SMBus base address */
66#define PIIX_SMB_HOSTC 0xd0 /* SMBus host configuration */ 66#define PIIX_SMB_HOSTC 0xd0 /* SMBus host configuration */
67#define PIIX_SMB_HOSTC_HSTEN (1 << 16) /* enable host controller */ 67#define PIIX_SMB_HOSTC_HSTEN (1 << 16) /* enable host controller */
68#define PIIX_SMB_HOSTC_SMI (0 << 17) /* SMI */ 68#define PIIX_SMB_HOSTC_SMI (0 << 17) /* SMI */
69#define PIIX_SMB_HOSTC_IRQ (4 << 17) /* IRQ */ 69#define PIIX_SMB_HOSTC_IRQ (4 << 17) /* IRQ 9 */
70#define PIIX_SMB_HOSTC_INTMASK (7 << 17) 70#define PIIX_SMB_HOSTC_INTMASK (7 << 17)
71 71
72/* SMBus I/O registers */ 72/* SMBus I/O registers */
73#define PIIX_SMB_HS 0x00 /* host status */ 73#define PIIX_SMB_HS 0x00 /* host status */
74#define PIIX_SMB_HS_BUSY (1 << 0) /* running a command */ 74#define PIIX_SMB_HS_BUSY (1 << 0) /* running a command */
75#define PIIX_SMB_HS_INTR (1 << 1) /* command completed */ 75#define PIIX_SMB_HS_INTR (1 << 1) /* command completed */
76#define PIIX_SMB_HS_DEVERR (1 << 2) /* command error */ 76#define PIIX_SMB_HS_DEVERR (1 << 2) /* command error */
77#define PIIX_SMB_HS_BUSERR (1 << 3) /* transaction collision */ 77#define PIIX_SMB_HS_BUSERR (1 << 3) /* transaction collision */
78#define PIIX_SMB_HS_FAILED (1 << 4) /* failed bus transaction */ 78#define PIIX_SMB_HS_FAILED (1 << 4) /* failed bus transaction */
79#define PIIX_SMB_HS_BITS "\020\001BUSY\002INTR\003DEVERR\004BUSERR\005FAILED" 79#define PIIX_SMB_HS_BITS "\020\001BUSY\002INTR\003DEVERR\004BUSERR\005FAILED"
80#define PIIX_SMB_HC 0x02 /* host control */ 80#define PIIX_SMB_HC 0x02 /* host control */
81#define PIIX_SMB_HC_INTREN (1 << 0) /* enable interrupts */ 81#define PIIX_SMB_HC_INTREN (1 << 0) /* enable interrupts */
82#define PIIX_SMB_HC_KILL (1 << 1) /* kill current transaction */ 82#define PIIX_SMB_HC_KILL (1 << 1) /* kill current transaction */
@@ -85,65 +85,80 @@ @@ -85,65 +85,80 @@
85#define PIIX_SMB_HC_CMD_BDATA (2 << 2) /* BYTE DATA command */ 85#define PIIX_SMB_HC_CMD_BDATA (2 << 2) /* BYTE DATA command */
86#define PIIX_SMB_HC_CMD_WDATA (3 << 2) /* WORD DATA command */ 86#define PIIX_SMB_HC_CMD_WDATA (3 << 2) /* WORD DATA command */
87#define PIIX_SMB_HC_CMD_BLOCK (5 << 2) /* BLOCK command */ 87#define PIIX_SMB_HC_CMD_BLOCK (5 << 2) /* BLOCK command */
88#define PIIX_SMB_HC_START (1 << 6) /* start transaction */ 88#define PIIX_SMB_HC_START (1 << 6) /* start transaction */
89#define PIIX_SMB_HCMD 0x03 /* host command */ 89#define PIIX_SMB_HCMD 0x03 /* host command */
90#define PIIX_SMB_TXSLVA 0x04 /* transmit slave address */ 90#define PIIX_SMB_TXSLVA 0x04 /* transmit slave address */
91#define PIIX_SMB_TXSLVA_READ (1 << 0) /* read direction */ 91#define PIIX_SMB_TXSLVA_READ (1 << 0) /* read direction */
92#define PIIX_SMB_TXSLVA_ADDR(x) (((x) & 0x7f) << 1) /* 7-bit address */ 92#define PIIX_SMB_TXSLVA_ADDR(x) (((x) & 0x7f) << 1) /* 7-bit address */
93#define PIIX_SMB_HD0 0x05 /* host data 0 */ 93#define PIIX_SMB_HD0 0x05 /* host data 0 */
94#define PIIX_SMB_HD1 0x06 /* host data 1 */ 94#define PIIX_SMB_HD1 0x06 /* host data 1 */
95#define PIIX_SMB_HBDB 0x07 /* host block data byte */ 95#define PIIX_SMB_HBDB 0x07 /* host block data byte */
96#define PIIX_SMB_SC 0x08 /* slave control */ 96#define PIIX_SMB_SC 0x08 /* slave control */
97#define PIIX_SMB_SC_ALERTEN (1 << 3) /* enable SMBALERT# */ 97#define PIIX_SMB_SC_ALERTEN (1 << 3) /* enable SMBALERT# */
 98#define PIIX_SMB_SC_HOSTSEM (1 << 4) /* (W1S) HostSemaphore */
 99#define PIIX_SMB_SC_CLRHOSTSEM (1 << 5) /* (W1C) ClrHostSemaphore */
 100#define PIIX_SMB_SC_ECSEM (1 << 6) /* (W1S) EcSemaphore */
 101#define PIIX_SMB_SC_CLRECSEM (1 << 7) /* (W1C) ClrEcSemaphore */
 102#define PIIX_SMB_SC_SEMMASK 0xf0 /* Semaphore bits */
98 103
99/* Power management I/O registers */ 104/* Power management I/O registers */
100#define PIIX_PM_PMTMR 0x08 /* power management timer */ 105#define PIIX_PM_PMTMR 0x08 /* power management timer */
101 106
102/* Misc */ 107/* Misc */
103#define PIIX_PM_SIZE 0x38 /* Power management I/O space size */ 108#define PIIX_PM_SIZE 0x38 /* Power management I/O space size */
104#define PIIX_SMB_SIZE 0x10 /* SMBus I/O space size */ 109#define PIIX_SMB_SIZE 0x10 /* SMBus I/O space size */
105 110
106/* 111/*
107 * AMD SB800 and compatible chipset's configuration registers. 112 * AMD SB800 and compatible chipset's configuration registers.
108 * See SB8xx RRG 2.3.3, etc. 113 * See SB8xx RRG 2.3.3, etc.
109 */ 114 */
110 115
111/* In the I/O area */ 116/* In the I/O area */
112#define SB800_INDIRECTIO_BASE 0xcd6 117#define SB800_INDIRECTIO_BASE 0xcd6
113#define SB800_INDIRECTIO_SIZE 2  118#define SB800_INDIRECTIO_SIZE 2
114#define SB800_INDIRECTIO_INDEX 0 119#define SB800_INDIRECTIO_INDEX 0
115#define SB800_INDIRECTIO_DATA 1 120#define SB800_INDIRECTIO_DATA 1
116  121
117#define SB800_PM_SMBUS0EN_LO 0x2c 122#define SB800_PM_SMBUS0EN_LO 0x2c
118#define SB800_PM_SMBUS0EN_HI 0x2d 123#define SB800_PM_SMBUS0EN_HI 0x2d
119#define SB800_PM_SMBUS0SEL 0x2e  124#define SB800_PM_SMBUS0EN_ENABLE __BIT(0) /* Function enable */
120#define SB800_PM_SMBUS0SELEN 0x2f  125#define SB800_PM_SMBUS0_MASK_C __BITS(2, 1) /* Port mask (PMIO2C) */
121  126#define SB800_PM_SMBUS0EN_BADDR __BITS(15, 5) /* Base address */
122#define SB800_PM_SMBUS0EN_ENABLE 0x0001 127
123#define SB800_PM_SMBUS0EN_BADDR 0xffe0 128#define SB800_PM_SMBUS0SEL 0x2e
 129#define SB800_PM_SMBUS0_MASK_E __BITS(2, 1) /* Port mask (PMIO2E) */
 130#define SB800_PM_SMBUS0SELEN 0x2f
 131#define SB800_PM_USE_SMBUS0SEL __BIT(0) /*
 132 * If the bit is set, SMBUS0SEL is
 133 * used to select the port.
 134 */
124 135
125/* In the PCI config space */ 136/* In the SMBus I/O space */
126#define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */ 137#define SB800_SMB_HOSTC 0x10 /* I2C bus configuration */
127#define SB800_SMB_HOSTC_SMI (1 << 0) /* SMI */ 138#define SB800_SMB_HOSTC_IRQ (1 << 0) /* 0:SMI 1:IRQ */
 139
 140/* Misc */
 141#define SB800_SMB_SIZE 0x11 /* SMBus I/O space size */
128 142
129/* 143/*
130 * Newer FCH registers in the PMIO space. 144 * Newer FCH registers in the PMIO space.
131 * See BKDG for Family 16h Models 30h-3Fh 3.26.13 PMx00 and PMx04. 145 * See BKDG for Family 16h Models 30h-3Fh 3.26.13 PMx00 and PMx04.
132 */ 146 */
133#define AMDFCH41_PM_DECODE_EN0 0x00 147#define AMDFCH41_PM_DECODE_EN0 0x00
134#define AMDFCH41_SMBUS_EN 0x10 148#define AMDFCH41_SMBUS_EN 0x10
135#define AMDFCH41_WDT_EN 0x80 149#define AMDFCH41_WDT_EN 0x80
136#define AMDFCH41_PM_DECODE_EN1 0x01 150#define AMDFCH41_PM_DECODE_EN1 0x01
137#define AMDFCH41_PM_PORT_INDEX 0x02 151#define AMDFCH41_PM_PORT_INDEX 0x02
 152#define AMDFCH41_SMBUS_PORTMASK 0x18
138#define AMDFCH41_PM_DECODE_EN3 0x03 153#define AMDFCH41_PM_DECODE_EN3 0x03
139#define AMDFCH41_WDT_RES_MASK 0x03 154#define AMDFCH41_WDT_RES_MASK 0x03
140#define AMDFCH41_WDT_RES_32US 0x00 155#define AMDFCH41_WDT_RES_32US 0x00
141#define AMDFCH41_WDT_RES_10MS 0x01 156#define AMDFCH41_WDT_RES_10MS 0x01
142#define AMDFCH41_WDT_RES_100MS 0x02 157#define AMDFCH41_WDT_RES_100MS 0x02
143#define AMDFCH41_WDT_RES_1S 0x03 158#define AMDFCH41_WDT_RES_1S 0x03
144#define AMDFCH41_WDT_EN_MASK 0x0c 159#define AMDFCH41_WDT_EN_MASK 0x0c
145#define AMDFCH41_WDT_ENABLE 0x00 160#define AMDFCH41_WDT_ENABLE 0x00
146#define AMDFCH41_PM_ISA_CTRL 0x04 161#define AMDFCH41_PM_ISA_CTRL 0x04
147#define AMDFCH41_MMIO_EN 0x02 162#define AMDFCH41_MMIO_EN 0x02
148 163
149#endif /* !_DEV_PCI_PIIXREG_H_ */ 164#endif /* !_DEV_PCI_PIIXREG_H_ */