summaryrefslogtreecommitdiff
path: root/shared-core/nouveau_mem.c
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-12-09 10:23:43 -0800
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-12-09 10:23:43 -0800
commit6656db10551bbb8770dd945b6d81d5138521f208 (patch)
tree68e457660c174ee2e16353691126ddd754c79398 /shared-core/nouveau_mem.c
parentc99566fb810c9d8cae5e9cd39d1772b55e2f514c (diff)
parent12e68f8059485fb4f02a15f74ab2fa3bdff38c81 (diff)
Merge branch 'modesetting-gem'
Diffstat (limited to 'shared-core/nouveau_mem.c')
-rw-r--r--shared-core/nouveau_mem.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c
index d79c1a52..1078a9c5 100644
--- a/shared-core/nouveau_mem.c
+++ b/shared-core/nouveau_mem.c
@@ -34,6 +34,7 @@
#include "drm.h"
#include "drm_sarea.h"
#include "nouveau_drv.h"
+#include "nv50_kms_wrapper.h"
static struct mem_block *
split_block(struct mem_block *p, uint64_t start, uint64_t size,
@@ -120,6 +121,17 @@ static struct mem_block *find_block(struct mem_block *heap, uint64_t start)
return NULL;
}
+struct mem_block *find_block_by_handle(struct mem_block *heap, drm_handle_t handle)
+{
+ struct mem_block *p;
+
+ list_for_each(p, heap)
+ if (p->map_handle == handle)
+ return p;
+
+ return NULL;
+}
+
void nouveau_mem_free_block(struct mem_block *p)
{
p->file_priv = NULL;
@@ -734,6 +746,30 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block)
DRM_DEBUG("freeing 0x%llx type=0x%08x\n", block->start, block->flags);
+ /* Check if the deallocations cause problems for our modesetting system. */
+ if (drm_core_check_feature(dev, DRIVER_MODESET)) {
+ if (dev_priv->card_type >= NV_50) {
+ struct nv50_crtc *crtc = NULL;
+ struct nv50_display *display = nv50_get_display(dev);
+
+ list_for_each_entry(crtc, &display->crtcs, item) {
+ if (crtc->fb->block == block) {
+ crtc->fb->block = NULL;
+
+ if (!crtc->blanked)
+ crtc->blank(crtc, true);
+ }
+
+ if (crtc->cursor->block == block) {
+ crtc->cursor->block = NULL;
+
+ if (crtc->cursor->visible)
+ crtc->cursor->hide(crtc);
+ }
+ }
+ }
+ }
+
if (block->flags&NOUVEAU_MEM_MAPPED)
drm_rmmap(dev, block->map);