summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorOwain Ainsworth <oga@cvs.openbsd.org>2010-08-07 19:32:45 +0000
committerOwain Ainsworth <oga@cvs.openbsd.org>2010-08-07 19:32:45 +0000
commitd899855f52cc00469f75e04e2268554df804f6e6 (patch)
treea41816dcacd74b557582169c5a74089eb885dc1e /sys
parenta2d10e6a555ee2e8783833969467bbba5c6beaba (diff)
Suspend/resume for agp_amd.c
Note: the unconditional restore of the status register is ok because all of the bits are either ones we want to preserve or read-only. ok deraadt@
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/pci/agp_amd.c57
1 files changed, 55 insertions, 2 deletions
diff --git a/sys/dev/pci/agp_amd.c b/sys/dev/pci/agp_amd.c
index 7e40096dfd7..2256fd2798e 100644
--- a/sys/dev/pci/agp_amd.c
+++ b/sys/dev/pci/agp_amd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: agp_amd.c,v 1.15 2010/04/08 00:23:53 tedu Exp $ */
+/* $OpenBSD: agp_amd.c,v 1.16 2010/08/07 19:32:44 oga Exp $ */
/* $NetBSD: agp_amd.c,v 1.6 2001/10/06 02:48:50 thorpej Exp $ */
/*-
@@ -73,9 +73,15 @@ struct agp_amd_softc {
bus_space_tag_t iot;
bus_addr_t asc_apaddr;
bus_size_t asc_apsize;
+ pcireg_t asc_apctrl;
+ pcireg_t asc_modectrl;
+ u_int16_t asc_status;
};
void agp_amd_attach(struct device *, struct device *, void *);
+int agp_amd_activate(struct device *, int);
+void agp_amd_save(struct agp_amd_softc *);
+void agp_amd_restore(struct agp_amd_softc *);
int agp_amd_probe(struct device *, void *, void *);
bus_size_t agp_amd_get_aperture(void *);
struct agp_amd_gatt *agp_amd_alloc_gatt(bus_dma_tag_t, bus_size_t);
@@ -85,7 +91,8 @@ void agp_amd_unbind_page(void *, bus_size_t);
void agp_amd_flush_tlb(void *);
struct cfattach amdagp_ca = {
- sizeof(struct agp_amd_softc), agp_amd_probe, agp_amd_attach
+ sizeof(struct agp_amd_softc), agp_amd_probe, agp_amd_attach, NULL,
+ agp_amd_activate
};
struct cfdriver amdagp_cd = {
@@ -269,6 +276,52 @@ agp_amd_detach(void *sc)
}
#endif
+int
+agp_amd_activate(struct device *arg, int act)
+{
+ struct agp_amd_softc *asc = (struct agp_amd_softc *)arg;
+
+ switch (act) {
+ case DVACT_SUSPEND:
+ agp_amd_save(asc);
+ break;
+ case DVACT_RESUME:
+ agp_amd_restore(asc);
+ break;
+ }
+
+ return (0);
+}
+
+void
+agp_amd_save(struct agp_amd_softc *asc)
+{
+ asc->asc_apctrl = pci_conf_read(asc->asc_pc, asc->asc_tag,
+ AGP_AMD751_APCTRL);
+ asc->asc_modectrl = pci_conf_read(asc->asc_pc, asc->asc_tag,
+ AGP_AMD751_MODECTRL);
+ asc->asc_status = READ2(AGP_AMD751_STATUS);
+}
+
+void
+agp_amd_restore(struct agp_amd_softc *asc)
+{
+
+ /* restore aperture size */
+ pci_conf_write(asc->asc_pc, asc->asc_tag, AGP_AMD751_APCTRL,
+ asc->asc_apctrl);
+
+ /* Install the gatt. */
+ WRITE4(AGP_AMD751_ATTBASE, asc->gatt->ag_physical);
+
+ /* Reenable synchronisation between host and agp. */
+ pci_conf_write(asc->asc_pc, asc->asc_tag, AGP_AMD751_MODECTRL,
+ asc->asc_modectrl);
+ /* Enable the TLB and flush */
+ WRITE2(AGP_AMD751_STATUS, asc->asc_status);
+ agp_amd_flush_tlb(asc);
+}
+
bus_size_t
agp_amd_get_aperture(void *sc)
{