summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoroga <oga@openbsd.org>2010-08-07 17:44:09 +0000
committeroga <oga@openbsd.org>2010-08-07 17:44:09 +0000
commita1d1974bc90996c62e7545b5e95069b55ba899c4 (patch)
tree30e0fb2678864e1f14767a16baa8085f9b9242b8
parentIn -Thtml output, preserve blank lines at the end of .Bd -literal. (diff)
downloadwireguard-openbsd-a1d1974bc90996c62e7545b5e95069b55ba899c4.tar.xz
wireguard-openbsd-a1d1974bc90996c62e7545b5e95069b55ba899c4.zip
Save and restore registers on suspend/resume.
An earlier iteration of this fixed the "no X, suspend, resume, startx, boom" problem for sthen on his machine. ok deraadt@
-rw-r--r--sys/dev/pci/agp_intel.c120
1 files changed, 118 insertions, 2 deletions
diff --git a/sys/dev/pci/agp_intel.c b/sys/dev/pci/agp_intel.c
index 8d9ae34ca27..f035ff7c2f6 100644
--- a/sys/dev/pci/agp_intel.c
+++ b/sys/dev/pci/agp_intel.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_intel.c,v 1.16 2010/04/08 00:23:53 tedu Exp $ */
+/* $OpenBSD: agp_intel.c,v 1.17 2010/08/07 17:44:09 oga Exp $ */
/* $NetBSD: agp_intel.c,v 1.3 2001/09/15 00:25:00 thorpej Exp $ */
/*-
@@ -63,10 +63,17 @@ struct agp_intel_softc {
CHIP_I850,
CHIP_I865
} chiptype;
+ /* registers saved during a suspend/resume cycle. */
+ pcireg_t savectrl;
+ pcireg_t savecmd;
+ pcireg_t savecfg;
};
void agp_intel_attach(struct device *, struct device *, void *);
+int agp_intel_activate(struct device *, int);
+void agp_intel_save(struct agp_intel_softc *);
+void agp_intel_restore(struct agp_intel_softc *);
int agp_intel_probe(struct device *, void *, void *);
bus_size_t agp_intel_get_aperture(void *);
int agp_intel_set_aperture(void *, bus_size_t);
@@ -75,7 +82,8 @@ void agp_intel_unbind_page(void *, bus_addr_t);
void agp_intel_flush_tlb(void *);
struct cfattach intelagp_ca = {
- sizeof(struct agp_intel_softc), agp_intel_probe, agp_intel_attach
+ sizeof(struct agp_intel_softc), agp_intel_probe, agp_intel_attach,
+ NULL, agp_intel_activate
};
struct cfdriver intelagp_cd = {
@@ -257,6 +265,114 @@ agp_intel_attach(struct device *parent, struct device *self, void *aux)
return;
}
+int
+agp_intel_activate(struct device *arg, int act)
+{
+ struct agp_intel_softc *isc = (struct agp_intel_softc *)arg;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ agp_intel_save(isc);
+ break;
+ case DVACT_RESUME:
+ agp_intel_restore(isc);
+ break;
+ }
+
+ return (0);
+}
+
+void
+agp_intel_save(struct agp_intel_softc *isc)
+{
+
+ if (isc->chiptype != CHIP_I443) {
+ isc->savectrl = pci_conf_read(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_AGPCTRL);
+ }
+
+ switch (isc->chiptype) {
+ case CHIP_I845:
+ case CHIP_I865:
+ isc->savecmd = pci_conf_read(isc->isc_pc, isc->isc_tag,
+ AGP_I840_MCHCFG);
+
+ break;
+ case CHIP_I840:
+ case CHIP_I850:
+ isc->savecmd = pci_conf_read(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_AGPCMD);
+ isc->savecfg = pci_conf_read(isc->isc_pc, isc->isc_tag,
+ AGP_I840_MCHCFG);
+
+ break;
+ default:
+ isc->savecfg = pci_conf_read(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_NBXCFG);
+ }
+}
+
+void
+agp_intel_restore(struct agp_intel_softc *isc)
+{
+ /*
+ * reset size now just in case, if it worked before then sanity
+ * checking will not fail
+ */
+ (void)agp_intel_set_aperture(isc, isc->isc_apsize);
+
+ /* Install the gatt. */
+ pci_conf_write(isc->isc_pc, isc->isc_tag, AGP_INTEL_ATTBASE,
+ isc->gatt->ag_physical);
+
+ /* Enable the GLTB and setup the control register. */
+ switch (isc->chiptype) {
+ case CHIP_I443:
+ pci_conf_write(isc->isc_pc, isc->isc_tag, AGP_INTEL_AGPCTRL,
+ AGPCTRL_AGPRSE | AGPCTRL_GTLB);
+ break;
+ default:
+ pci_conf_write(isc->isc_pc, isc->isc_tag, AGP_INTEL_AGPCTRL,
+ isc->savectrl);
+ }
+
+ /* Enable things, clear errors etc. */
+ switch (isc->chiptype) {
+ case CHIP_I845:
+ case CHIP_I865:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_I840_MCHCFG, isc->savecmd);
+ break;
+ case CHIP_I840:
+ case CHIP_I850:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_AGPCMD, isc->savecmd);
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_I840_MCHCFG, isc->savecfg);
+ break;
+ default:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_NBXCFG, isc->savecfg);
+ }
+
+ /* Clear Error status */
+ switch (isc->chiptype) {
+ case CHIP_I840:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_I8XX_ERRSTS, 0xc000);
+ break;
+ case CHIP_I845:
+ case CHIP_I850:
+ case CHIP_I865:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_I8XX_ERRSTS, 0x00ff);
+ break;
+ default:
+ pci_conf_write(isc->isc_pc, isc->isc_tag,
+ AGP_INTEL_ERRSTS, 0x70);
+ }
+}
+
#if 0
int
agp_intel_detach(struct agp_softc *sc)