diff options
author | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-08-07 19:32:45 +0000 |
---|---|---|
committer | Owain Ainsworth <oga@cvs.openbsd.org> | 2010-08-07 19:32:45 +0000 |
commit | d899855f52cc00469f75e04e2268554df804f6e6 (patch) | |
tree | a41816dcacd74b557582169c5a74089eb885dc1e /sys | |
parent | a2d10e6a555ee2e8783833969467bbba5c6beaba (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.c | 57 |
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) { |