Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev/pci Add PCI power management control. If the power ...
details: https://anonhg.NetBSD.org/src/rev/6b36494251ab
branches: trunk
changeset: 516921:6b36494251ab
user: haya <haya%NetBSD.org@localhost>
date: Fri Nov 02 03:32:33 2001 +0000
description:
Add PCI power management control. If the power state of a bridge is
not D0 at device attaching or resuming, set the bridge D0 mode.
diffstat:
sys/dev/pci/pccbb.c | 47 +++++++++++++++++++++++++++++++++++++++++++++--
sys/dev/pci/pccbbvar.h | 4 +++-
2 files changed, 48 insertions(+), 3 deletions(-)
diffs (100 lines):
diff -r 458f670af839 -r 6b36494251ab sys/dev/pci/pccbb.c
--- a/sys/dev/pci/pccbb.c Fri Nov 02 03:12:48 2001 +0000
+++ b/sys/dev/pci/pccbb.c Fri Nov 02 03:32:33 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pccbb.c,v 1.69 2001/10/17 10:25:51 haya Exp $ */
+/* $NetBSD: pccbb.c,v 1.70 2001/11/02 03:32:33 haya Exp $ */
/*
* Copyright (c) 1998, 1999 and 2000
@@ -422,6 +422,7 @@
bus_addr_t sockbase;
char devinfo[256];
int flags;
+ int pwrmgt_offs;
sc->sc_chipset = cb_chipset(pa->pa_id, &flags);
@@ -447,6 +448,22 @@
sc->sc_base_memh = 0;
+ /* power management: set D0 state */
+ sc->sc_pwrmgt_offs = 0;
+ if (pci_get_capability(pc, pa->pa_tag, PCI_CAP_PWRMGMT,
+ &pwrmgt_offs, 0)) {
+ reg = pci_conf_read(pc, pa->pa_tag, pwrmgt_offs + 4);
+ if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0 ||
+ reg & 0x100 /* PCI_PMCSR_PME_EN */) {
+ reg &= ~PCI_PMCSR_STATE_MASK;
+ reg |= PCI_PMCSR_STATE_D0;
+ reg &= ~(0x100 /* PCI_PMCSR_PME_EN */);
+ pci_conf_write(pc, pa->pa_tag, pwrmgt_offs + 4, reg);
+ }
+
+ sc->sc_pwrmgt_offs = pwrmgt_offs;
+ }
+
/*
* MAP socket registers and ExCA registers on memory-space
* When no valid address is set on socket base registers (on pci
@@ -3253,7 +3270,7 @@
void *arg;
{
struct pccbb_softc *sc = arg;
- u_int32_t reg;
+ pcireg_t reg;
bus_space_tag_t base_memt = sc->sc_base_memt; /* socket regs memory */
bus_space_handle_t base_memh = sc->sc_base_memh;
@@ -3271,6 +3288,32 @@
}
if (why == PWR_RESUME) {
+ if (sc->sc_pwrmgt_offs != 0) {
+ reg = pci_conf_read(sc->sc_pc, sc->sc_tag,
+ sc->sc_pwrmgt_offs + 4);
+ if ((reg & PCI_PMCSR_STATE_MASK) != PCI_PMCSR_STATE_D0 ||
+ reg & 0x100) {
+ /* powrstate != D0 */
+
+ printf("%s going back to D0 mode\n",
+ sc->sc_dev.dv_xname);
+ reg &= ~PCI_PMCSR_STATE_MASK;
+ reg |= PCI_PMCSR_STATE_D0;
+ reg &= ~(0x100 /* PCI_PMCSR_PME_EN */);
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ sc->sc_pwrmgt_offs + 4, reg);
+
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ PCI_SOCKBASE, sc->sc_sockbase);
+ pci_conf_write(sc->sc_pc, sc->sc_tag,
+ PCI_BUSNUM, sc->sc_busnum);
+ pccbb_chipinit(sc);
+ /* setup memory and io space window for CB */
+ pccbb_winset(0x1000, sc, sc->sc_memt);
+ pccbb_winset(0x04, sc, sc->sc_iot);
+ }
+ }
+
if (pci_conf_read (sc->sc_pc, sc->sc_tag, PCI_SOCKBASE) == 0)
/* BIOS did not recover this register */
pci_conf_write (sc->sc_pc, sc->sc_tag,
diff -r 458f670af839 -r 6b36494251ab sys/dev/pci/pccbbvar.h
--- a/sys/dev/pci/pccbbvar.h Fri Nov 02 03:12:48 2001 +0000
+++ b/sys/dev/pci/pccbbvar.h Fri Nov 02 03:32:33 2001 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pccbbvar.h,v 1.16 2001/07/06 18:07:00 mcr Exp $ */
+/* $NetBSD: pccbbvar.h,v 1.17 2001/11/02 03:32:34 haya Exp $ */
/*
* Copyright (c) 1999 HAYAKAWA Koichi. All rights reserved.
*
@@ -160,6 +160,8 @@
/* interrupt handler list on the bridge */
struct pccbb_intrhand_list *sc_pil;
int sc_pil_intr_enable; /* can i call intr handler for child device? */
+
+ int sc_pwrmgt_offs; /* Offset for power management capability */
};
/*
Home |
Main Index |
Thread Index |
Old Index