| @@ -1,38 +1,38 @@ | | | @@ -1,38 +1,38 @@ |
1 | /* $NetBSD: piixpm.c,v 1.56 2019/12/23 15:41:34 thorpej Exp $ */ | | 1 | /* $NetBSD: piixpm.c,v 1.57 2019/12/23 23:31:23 msaitoh 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.56 2019/12/23 15:41:34 thorpej Exp $"); | | 25 | __KERNEL_RCSID(0, "$NetBSD: piixpm.c,v 1.57 2019/12/23 23:31:23 msaitoh 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> |
| @@ -220,28 +220,26 @@ piixpm_attach(device_t parent, device_t | | | @@ -220,28 +220,26 @@ piixpm_attach(device_t parent, device_t |
220 | /* | | 220 | /* |
221 | * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. | | 221 | * Revision 0 and 1 are PIIX4, 2 is PIIX4E, 3 is PIIX4M. |
222 | * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 | | 222 | * PIIX4 and PIIX4E have a bug in the timer latch, see Errata #20 |
223 | * in the "Specification update" (document #297738). | | 223 | * in the "Specification update" (document #297738). |
224 | */ | | 224 | */ |
225 | acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, | | 225 | acpipmtimer_attach(self, sc->sc_pm_iot, sc->sc_pm_ioh, PIIX_PM_PMTMR, |
226 | (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0); | | 226 | (PCI_REVISION(pa->pa_class) < 3) ? ACPIPMT_BADLATCH : 0); |
227 | | | 227 | |
228 | nopowermanagement: | | 228 | nopowermanagement: |
229 | | | 229 | |
230 | /* SB800 rev 0x40+, AMD HUDSON and newer need special initialization */ | | 230 | /* SB800 rev 0x40+, AMD HUDSON and newer need special initialization */ |
231 | if (PIIXPM_IS_FCHGRP(sc) || PIIXPM_IS_SB800GRP(sc)) { | | 231 | if (PIIXPM_IS_FCHGRP(sc) || PIIXPM_IS_SB800GRP(sc)) { |
232 | if (piixpm_sb800_init(sc) == 0) { | | 232 | if (piixpm_sb800_init(sc) == 0) { |
233 | sc->sc_numbusses = 4; | | | |
234 | | | | |
235 | /* Read configuration */ | | 233 | /* Read configuration */ |
236 | conf = pci_conf_read(pa->pa_pc, pa->pa_tag, | | 234 | conf = pci_conf_read(pa->pa_pc, pa->pa_tag, |
237 | SB800_SMB_HOSTC); | | 235 | SB800_SMB_HOSTC); |
238 | DPRINTF(("%s: conf 0x%08x\n", device_xname(self), | | 236 | DPRINTF(("%s: conf 0x%08x\n", device_xname(self), |
239 | conf)); | | 237 | conf)); |
240 | | | 238 | |
241 | usesmi = conf & SB800_SMB_HOSTC_SMI; | | 239 | usesmi = conf & SB800_SMB_HOSTC_SMI; |
242 | goto setintr; | | 240 | goto setintr; |
243 | } | | 241 | } |
244 | aprint_normal_dev(self, "SMBus initialization failed\n"); | | 242 | aprint_normal_dev(self, "SMBus initialization failed\n"); |
245 | return; | | 243 | return; |
246 | } | | 244 | } |
247 | | | 245 | |
| @@ -389,26 +387,32 @@ piixpm_resume(device_t dv, const pmf_qua | | | @@ -389,26 +387,32 @@ piixpm_resume(device_t dv, const pmf_qua |
389 | * Extract SMBus base address from SB800 Power Management (PM) registers. | | 387 | * Extract SMBus base address from SB800 Power Management (PM) registers. |
390 | * The PM registers can be accessed either through indirect I/O (CD6/CD7) or | | 388 | * The PM registers can be accessed either through indirect I/O (CD6/CD7) or |
391 | * direct mapping if AcpiMMioDecodeEn is enabled. Since this function is only | | 389 | * direct mapping if AcpiMMioDecodeEn is enabled. Since this function is only |
392 | * called once it uses indirect I/O for simplicity. | | 390 | * called once it uses indirect I/O for simplicity. |
393 | */ | | 391 | */ |
394 | static int | | 392 | static int |
395 | piixpm_sb800_init(struct piixpm_softc *sc) | | 393 | piixpm_sb800_init(struct piixpm_softc *sc) |
396 | { | | 394 | { |
397 | bus_space_tag_t iot = sc->sc_iot; | | 395 | bus_space_tag_t iot = sc->sc_iot; |
398 | bus_space_handle_t ioh; /* indirect I/O handle */ | | 396 | bus_space_handle_t ioh; /* indirect I/O handle */ |
399 | uint16_t val, base_addr; | | 397 | uint16_t val, base_addr; |
400 | bool enabled; | | 398 | bool enabled; |
401 | | | 399 | |
| | | 400 | if (PIIXPM_IS_KERNCZ(sc) || |
| | | 401 | (PIIXPM_IS_HUDSON(sc) && (sc->sc_rev >= 0x1f))) |
| | | 402 | sc->sc_numbusses = 2; |
| | | 403 | else |
| | | 404 | sc->sc_numbusses = 4; |
| | | 405 | |
402 | /* Fetch SMB base address */ | | 406 | /* Fetch SMB base address */ |
403 | if (bus_space_map(iot, | | 407 | if (bus_space_map(iot, |
404 | SB800_INDIRECTIO_BASE, SB800_INDIRECTIO_SIZE, 0, &ioh)) { | | 408 | SB800_INDIRECTIO_BASE, SB800_INDIRECTIO_SIZE, 0, &ioh)) { |
405 | device_printf(sc->sc_dev, "couldn't map indirect I/O space\n"); | | 409 | device_printf(sc->sc_dev, "couldn't map indirect I/O space\n"); |
406 | return EBUSY; | | 410 | return EBUSY; |
407 | } | | 411 | } |
408 | if (PIIXPM_IS_FCHGRP(sc)) { | | 412 | if (PIIXPM_IS_FCHGRP(sc)) { |
409 | bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, | | 413 | bus_space_write_1(iot, ioh, SB800_INDIRECTIO_INDEX, |
410 | AMDFCH41_PM_DECODE_EN0); | | 414 | AMDFCH41_PM_DECODE_EN0); |
411 | val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); | | 415 | val = bus_space_read_1(iot, ioh, SB800_INDIRECTIO_DATA); |
412 | enabled = val & AMDFCH41_SMBUS_EN; | | 416 | enabled = val & AMDFCH41_SMBUS_EN; |
413 | if (!enabled) | | 417 | if (!enabled) |
414 | return ENOENT; | | 418 | return ENOENT; |