summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Levy <alevy@redhat.com>2011-06-23 13:47:07 +0200
committerAlon Levy <alevy@redhat.com>2011-07-07 13:05:55 +0200
commitf24b725cf00b448b1f5cbf79e1f83095b90e4f46 (patch)
tree5f0f4b83ef4d4da51838c1198c1f5f453c770430
parentedbe6e26519a1fdb008373fe52cdb8534474f121 (diff)
display: add FlushRelease and FlushSurfaces for alternative V06 (2) revision implementations3.v3.async.v3
-rw-r--r--display/driver.c46
1 files changed, 43 insertions, 3 deletions
diff --git a/display/driver.c b/display/driver.c
index 227b126..fdfa3af 100644
--- a/display/driver.c
+++ b/display/driver.c
@@ -957,14 +957,54 @@ VOID DrvDisableSurface(DHPDEV in_pdev)
DEBUG_PRINT((pdev, 1, "%s: 0x%lx exit\n", __FUNCTION__, pdev));
}
+static void FlushSurfaces(PDev *pdev)
+{
+ UINT32 surface_id;
+ SurfaceInfo *surface_info;
+ SURFOBJ *surf_obj;
+ RECTL area = {0, 0, 0, 0};
+
+ if (pdev->pci_revision < QXL_REVISION_STABLE_V10) {
+ DEBUG_PRINT((pdev, 1, "%s: revision too old for QXL_IO_FLUSH_SURFACES", __FUNCTION__));
+ for (surface_id = pdev->n_surfaces - 1 ; surface_id > 0 ; --surface_id) {
+ surface_info = GetSurfaceInfo(pdev, surface_id);
+ if (!surface_info->draw_area.base_mem) {
+ continue;
+ }
+ surf_obj = surface_info->draw_area.surf_obj;
+ if (!surf_obj) {
+ continue;
+ }
+ area.right = surf_obj->sizlBitmap.cx;
+ area.bottom = surf_obj->sizlBitmap.cy;
+ UpdateArea(pdev, &area, surface_id);
+ }
+ } else {
+ async_io(pdev, ASYNCABLE_FLUSH_SURFACES, 0);
+ }
+}
+static void FlushRelease(PDev *pdev)
+{
+ if (pdev->pci_revision < QXL_REVISION_STABLE_V10) {
+ DEBUG_PRINT((pdev, 1, "%s: revision too old for QXL_IO_FLUSH_RELEASE", __FUNCTION__));
+ // ooming a few times causes the server to flush
+ // all releasable resources
+ WRITE_PORT_UCHAR(pdev->notify_oom_port, 0);
+ WRITE_PORT_UCHAR(pdev->notify_oom_port, 0);
+ WRITE_PORT_UCHAR(pdev->notify_oom_port, 0);
+ } else {
+ WRITE_PORT_UCHAR(pdev->flush_release_port, 0);
+ }
+}
+
static BOOL AssertModeDisable(PDev *pdev)
{
DEBUG_PRINT((pdev, 3, "%s entry\n", __FUNCTION__));
/* flush command ring and update all surfaces */
WRITE_PORT_UCHAR(pdev->notify_cmd_port, 0);
WRITE_PORT_UCHAR(pdev->notify_cursor_port, 0);
- WRITE_PORT_UCHAR(pdev->flush_surfaces_port, 0);
- WRITE_PORT_UCHAR(pdev->destroy_all_surfaces_port, 0);
+ FlushSurfaces(pdev);
+ async_io(pdev, ASYNCABLE_DESTROY_ALL_SURFACES, 0);
/* move all surfaces from device to system memory */
if (!MoveAllSurfacesToRam(pdev)) {
return FALSE;
@@ -973,7 +1013,7 @@ static BOOL AssertModeDisable(PDev *pdev)
ReleaseCacheDeviceMemoryResources(pdev);
EmptyReleaseRing(pdev);
/* Get the last free list onto the release ring */
- WRITE_PORT_UCHAR(pdev->flush_release_port, 0);
+ FlushRelease(pdev);
DEBUG_PRINT((pdev, 4, "%s after FLUSH_RELEASE\n", __FUNCTION__));
/* And release that. mspace allocators should be clean after. */
EmptyReleaseRing(pdev);