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 support for the per-device power management ...
details: https://anonhg.NetBSD.org/src/rev/35ff9137dae2
branches: trunk
changeset: 532974:35ff9137dae2
user: tshiozak <tshiozak%NetBSD.org@localhost>
date: Tue Jun 18 13:18:37 2002 +0000
description:
add support for the per-device power management capability.
int pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int newstate)
set power state of the device to newstate.
int pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
get current power state of the device.
In the future, these functions will be used for ACPI support.
diffstat:
sys/dev/pci/pci.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++-
sys/dev/pci/pcireg.h | 10 +++++-
sys/dev/pci/pcivar.h | 13 +++++++-
3 files changed, 101 insertions(+), 5 deletions(-)
diffs (154 lines):
diff -r f44138191299 -r 35ff9137dae2 sys/dev/pci/pci.c
--- a/sys/dev/pci/pci.c Tue Jun 18 13:01:30 2002 +0000
+++ b/sys/dev/pci/pci.c Tue Jun 18 13:18:37 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pci.c,v 1.65 2002/05/18 21:40:41 sommerfeld Exp $ */
+/* $NetBSD: pci.c,v 1.66 2002/06/18 13:18:37 tshiozak Exp $ */
/*
* Copyright (c) 1995, 1996, 1997, 1998
@@ -36,7 +36,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.65 2002/05/18 21:40:41 sommerfeld Exp $");
+__KERNEL_RCSID(0, "$NetBSD: pci.c,v 1.66 2002/06/18 13:18:37 tshiozak Exp $");
#include "opt_pci.h"
@@ -448,3 +448,82 @@
}
return (0);
}
+
+/*
+ * Power Management Capability (Rev 2.2)
+ */
+
+int
+pci_set_powerstate(pci_chipset_tag_t pc, pcitag_t tag, int newstate)
+{
+ int offset;
+ pcireg_t value, cap, now;
+
+ if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
+ return (EOPNOTSUPP);
+
+ cap = value >> 16;
+ value = pci_conf_read(pc, tag, offset+PCI_PMCSR);
+ now = value & PCI_PMCSR_STATE_MASK;
+ value &= ~PCI_PMCSR_STATE_MASK;
+ switch (newstate) {
+ case PCI_PWR_D0:
+ if (now == PCI_PMCSR_STATE_D0)
+ return (0);
+ value |= PCI_PMCSR_STATE_D0;
+ break;
+ case PCI_PWR_D1:
+ if (now == PCI_PMCSR_STATE_D1)
+ return (0);
+ if (now == PCI_PMCSR_STATE_D2 || now == PCI_PMCSR_STATE_D3)
+ return (EINVAL);
+ if (!(cap & PCI_PMCR_D1SUPP))
+ return (EOPNOTSUPP);
+ value |= PCI_PMCSR_STATE_D1;
+ break;
+ case PCI_PWR_D2:
+ if (now == PCI_PMCSR_STATE_D2)
+ return (0);
+ if (now == PCI_PMCSR_STATE_D3)
+ return (EINVAL);
+ if (!(cap & PCI_PMCR_D2SUPP))
+ return (EOPNOTSUPP);
+ value |= PCI_PMCSR_STATE_D2;
+ break;
+ case PCI_PWR_D3:
+ if (now == PCI_PMCSR_STATE_D3)
+ return (0);
+ value |= PCI_PMCSR_STATE_D3;
+ break;
+ default:
+ return (EINVAL);
+ }
+ pci_conf_write(pc, tag, offset+PCI_PMCSR, value);
+ DELAY(1000);
+
+ return (0);
+}
+
+int
+pci_get_powerstate(pci_chipset_tag_t pc, pcitag_t tag)
+{
+ int offset;
+ pcireg_t value;
+
+ if (!pci_get_capability(pc, tag, PCI_CAP_PWRMGMT, &offset, &value))
+ return (PCI_PWR_D0);
+ value = pci_conf_read(pc, tag, offset+PCI_PMCSR);
+ value &= PCI_PMCSR_STATE_MASK;
+ switch (value) {
+ case PCI_PMCSR_STATE_D0:
+ return (PCI_PWR_D0);
+ case PCI_PMCSR_STATE_D1:
+ return (PCI_PWR_D1);
+ case PCI_PMCSR_STATE_D2:
+ return (PCI_PWR_D2);
+ case PCI_PMCSR_STATE_D3:
+ return (PCI_PWR_D3);
+ }
+
+ return (PCI_PWR_D0);
+}
diff -r f44138191299 -r 35ff9137dae2 sys/dev/pci/pcireg.h
--- a/sys/dev/pci/pcireg.h Tue Jun 18 13:01:30 2002 +0000
+++ b/sys/dev/pci/pcireg.h Tue Jun 18 13:18:37 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcireg.h,v 1.37 2002/03/22 20:03:20 drochner Exp $ */
+/* $NetBSD: pcireg.h,v 1.38 2002/06/18 13:18:37 tshiozak Exp $ */
/*
* Copyright (c) 1995, 1996, 1999, 2000
@@ -418,9 +418,15 @@
#define PCI_CAP_HOTPLUG 0x0c
/*
- * Power Management Control Status Register; access via capability pointer.
+ * Power Management Capability; access via capability pointer.
*/
+/* Power Management Capability Register */
+#define PCI_PMCR 0x02
+#define PCI_PMCR_D1SUPP 0x0200
+#define PCI_PMCR_D2SUPP 0x0400
+/* Power Management Control Status Register */
+#define PCI_PMCSR 0x04
#define PCI_PMCSR_STATE_MASK 0x03
#define PCI_PMCSR_STATE_D0 0x00
#define PCI_PMCSR_STATE_D1 0x01
diff -r f44138191299 -r 35ff9137dae2 sys/dev/pci/pcivar.h
--- a/sys/dev/pci/pcivar.h Tue Jun 18 13:01:30 2002 +0000
+++ b/sys/dev/pci/pcivar.h Tue Jun 18 13:18:37 2002 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: pcivar.h,v 1.52 2002/05/30 12:06:43 drochner Exp $ */
+/* $NetBSD: pcivar.h,v 1.53 2002/06/18 13:18:37 tshiozak Exp $ */
/*
* Copyright (c) 1996, 1997 Christopher G. Demetriou. All rights reserved.
@@ -210,6 +210,17 @@
int flag, struct proc *));
/*
+ * Power Management (PCI 2.2)
+ */
+
+#define PCI_PWR_D0 0
+#define PCI_PWR_D1 1
+#define PCI_PWR_D2 2
+#define PCI_PWR_D3 3
+int pci_set_powerstate __P((pci_chipset_tag_t, pcitag_t, int));
+int pci_get_powerstate __P((pci_chipset_tag_t, pcitag_t));
+
+/*
* Misc.
*/
char *pci_findvendor __P((pcireg_t));
Home |
Main Index |
Thread Index |
Old Index