From 473a1997ace1a9fb545d0457549e50d17eb36175 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Sun, 22 Jun 2008 16:29:00 +0200 Subject: NV50: Initial import of kernel modesetting. --- shared-core/nouveau_mem.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 2cf8807d..810eaf9e 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -108,6 +108,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; -- cgit v1.2.3 From 5a0164d1e1799b68b3131efd7b9fcaf20c578257 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Mon, 23 Jun 2008 01:00:42 +1000 Subject: nouveau: allocate drm-use vram buffers from end of vram. This avoids seeing garbage from engine setup etc before X gets around to pointing the CRTCs at a new scanout buffer. Not actually a noticable problem before G80 as PRAMIN is forced to the end of VRAM by the hardware already. --- shared-core/nouveau_mem.c | 58 +++++++++++++++++++++++++++++------------------ 1 file changed, 36 insertions(+), 22 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 810eaf9e..51ac48dd 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -35,8 +35,9 @@ #include "drm_sarea.h" #include "nouveau_drv.h" -static struct mem_block *split_block(struct mem_block *p, uint64_t start, uint64_t size, - struct drm_file *file_priv) +static struct mem_block * +split_block(struct mem_block *p, uint64_t start, uint64_t size, + struct drm_file *file_priv) { /* Maybe cut off the start of an existing block */ if (start > p->start) { @@ -77,10 +78,9 @@ out: return p; } -struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, - uint64_t size, - int align2, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc_block(struct mem_block *heap, uint64_t size, + int align2, struct drm_file *file_priv, int tail) { struct mem_block *p; uint64_t mask = (1 << align2) - 1; @@ -88,10 +88,22 @@ struct mem_block *nouveau_mem_alloc_block(struct mem_block *heap, if (!heap) return NULL; - list_for_each(p, heap) { - uint64_t start = (p->start + mask) & ~mask; - if (p->file_priv == 0 && start + size <= p->start + p->size) - return split_block(p, start, size, file_priv); + if (tail) { + list_for_each_prev(p, heap) { + uint64_t start = ((p->start + p->size) - size) & ~mask; + + if (p->file_priv == 0 && start >= p->start && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } + } else { + list_for_each(p, heap) { + uint64_t start = (p->start + mask) & ~mask; + + if (p->file_priv == 0 && + start + size <= p->start + p->size) + return split_block(p, start, size, file_priv); + } } return NULL; @@ -574,13 +586,13 @@ int nouveau_mem_init(struct drm_device *dev) return 0; } -struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, - uint64_t size, int flags, - struct drm_file *file_priv) +struct mem_block * +nouveau_mem_alloc(struct drm_device *dev, int alignment, uint64_t size, + int flags, struct drm_file *file_priv) { - struct mem_block *block; - int type; struct drm_nouveau_private *dev_priv = dev->dev_private; + struct mem_block *block; + int type, tail = !(flags & NOUVEAU_MEM_USER); /* * Make things easier on ourselves: all allocations are page-aligned. @@ -611,14 +623,14 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, #define NOUVEAU_MEM_ALLOC_AGP {\ type=NOUVEAU_MEM_AGP;\ block = nouveau_mem_alloc_block(dev_priv->agp_heap, size,\ - alignment, file_priv); \ + alignment, file_priv, tail); \ if (block) goto alloc_ok;\ } #define NOUVEAU_MEM_ALLOC_PCI {\ type = NOUVEAU_MEM_PCI;\ block = nouveau_mem_alloc_block(dev_priv->pci_heap, size, \ - alignment, file_priv); \ + alignment, file_priv, tail); \ if ( block ) goto alloc_ok;\ } @@ -627,11 +639,11 @@ struct mem_block* nouveau_mem_alloc(struct drm_device *dev, int alignment, if (!(flags&NOUVEAU_MEM_MAPPED)) {\ block = nouveau_mem_alloc_block(dev_priv->fb_nomap_heap,\ size, alignment, \ - file_priv); \ + file_priv, tail); \ if (block) goto alloc_ok;\ }\ block = nouveau_mem_alloc_block(dev_priv->fb_heap, size,\ - alignment, file_priv);\ + alignment, file_priv, tail);\ if (block) goto alloc_ok;\ } @@ -749,7 +761,9 @@ out_free: * Ioctls */ -int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv) +int +nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, + struct drm_file *file_priv) { struct drm_nouveau_mem_alloc *alloc = data; struct mem_block *block; @@ -759,8 +773,8 @@ int nouveau_ioctl_mem_alloc(struct drm_device *dev, void *data, struct drm_file if (alloc->flags & NOUVEAU_MEM_INTERNAL) return -EINVAL; - block=nouveau_mem_alloc(dev, alloc->alignment, alloc->size, - alloc->flags, file_priv); + block = nouveau_mem_alloc(dev, alloc->alignment, alloc->size, + alloc->flags | NOUVEAU_MEM_USER, file_priv); if (!block) return -ENOMEM; alloc->map_handle=block->map_handle; -- cgit v1.2.3 From 09b67dda0bc040860aedce4a2d28bce1c80e56d6 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 25 Jun 2008 15:16:38 +0200 Subject: NV50: Some cleanup and fixes. --- shared-core/nouveau_mem.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 51ac48dd..4acd6bd6 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -34,6 +34,8 @@ #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, @@ -730,6 +732,33 @@ 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, head) { + if (crtc->fb->block == block) { + crtc->fb->block = NULL; + + /* this will force a lut change next time a fb is loaded */ + crtc->lut->depth = 0; + + 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); -- cgit v1.2.3 From 4d85d5d25116304e476849ee64c206ffb3a7f372 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Wed, 25 Jun 2008 15:27:07 +0200 Subject: NV50: i misunderstood NOUVEAU_MEM_INTERNAL, so remove it --- shared-core/nouveau_mem.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 4acd6bd6..46b6e4d6 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -742,9 +742,6 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) if (crtc->fb->block == block) { crtc->fb->block = NULL; - /* this will force a lut change next time a fb is loaded */ - crtc->lut->depth = 0; - if (!crtc->blanked) crtc->blank(crtc, TRUE); } -- cgit v1.2.3 From 91c742663a618e81da69ad4f098321d9af56d636 Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Fri, 27 Jun 2008 18:58:13 +0200 Subject: NV50: use list_head item instead of list_head head to avoid confusion --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 46b6e4d6..425cebe2 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -738,7 +738,7 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) struct nv50_crtc *crtc = NULL; struct nv50_display *display = nv50_get_display(dev); - list_for_each_entry(crtc, &display->crtcs, head) { + list_for_each_entry(crtc, &display->crtcs, item) { if (crtc->fb->block == block) { crtc->fb->block = NULL; -- cgit v1.2.3 From 062d85062061199f2326982e27d54955a4ad76dc Mon Sep 17 00:00:00 2001 From: Maarten Maathuis Date: Thu, 3 Jul 2008 09:08:01 +0200 Subject: nv50: s/FALSE/false && s/TRUE/true --- shared-core/nouveau_mem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'shared-core/nouveau_mem.c') diff --git a/shared-core/nouveau_mem.c b/shared-core/nouveau_mem.c index 425cebe2..861d699f 100644 --- a/shared-core/nouveau_mem.c +++ b/shared-core/nouveau_mem.c @@ -743,7 +743,7 @@ void nouveau_mem_free(struct drm_device* dev, struct mem_block* block) crtc->fb->block = NULL; if (!crtc->blanked) - crtc->blank(crtc, TRUE); + crtc->blank(crtc, true); } if (crtc->cursor->block == block) { -- cgit v1.2.3