aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/nv50_vram.c
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-02-14 09:57:35 +1000
committerBen Skeggs <bskeggs@redhat.com>2011-02-25 06:46:07 +1000
commit8f7286f8e4e80f7b868ba3d117ae900f0d207cbe (patch)
tree018804469b7bce4033b4156442c904512282fab2 /drivers/gpu/drm/nouveau/nv50_vram.c
parent26c0c9e33a2eb44b345d22d5928d5c8b7b261226 (diff)
downloadkernel_samsung_smdk4412-8f7286f8e4e80f7b868ba3d117ae900f0d207cbe.zip
kernel_samsung_smdk4412-8f7286f8e4e80f7b868ba3d117ae900f0d207cbe.tar.gz
kernel_samsung_smdk4412-8f7286f8e4e80f7b868ba3d117ae900f0d207cbe.tar.bz2
drm/nv50: support for compression
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nv50_vram.c')
-rw-r--r--drivers/gpu/drm/nouveau/nv50_vram.c27
1 files changed, 24 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/nv50_vram.c b/drivers/gpu/drm/nouveau/nv50_vram.c
index ff6cbae..ffbc3d8 100644
--- a/drivers/gpu/drm/nouveau/nv50_vram.c
+++ b/drivers/gpu/drm/nouveau/nv50_vram.c
@@ -69,6 +69,11 @@ nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
list_del(&this->rl_entry);
nouveau_mm_put(mm, this);
}
+
+ if (mem->tag) {
+ drm_mm_put_block(mem->tag);
+ mem->tag = NULL;
+ }
mutex_unlock(&mm->mutex);
kfree(mem);
@@ -76,7 +81,7 @@ nv50_vram_del(struct drm_device *dev, struct nouveau_mem **pmem)
int
nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
- u32 type, struct nouveau_mem **pmem)
+ u32 memtype, struct nouveau_mem **pmem)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct ttm_bo_device *bdev = &dev_priv->ttm.bdev;
@@ -84,6 +89,8 @@ nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
struct nouveau_mm *mm = man->priv;
struct nouveau_mm_node *r;
struct nouveau_mem *mem;
+ int comp = (memtype & 0x300) >> 8;
+ int type = (memtype & 0x07f);
int ret;
if (!types[type])
@@ -96,12 +103,26 @@ nv50_vram_new(struct drm_device *dev, u64 size, u32 align, u32 size_nc,
if (!mem)
return -ENOMEM;
+ mutex_lock(&mm->mutex);
+ if (comp) {
+ if (align == 16) {
+ struct nouveau_fb_engine *pfb = &dev_priv->engine.fb;
+ int n = (size >> 4) * comp;
+
+ mem->tag = drm_mm_search_free(&pfb->tag_heap, n, 0, 0);
+ if (mem->tag)
+ mem->tag = drm_mm_get_block(mem->tag, n, 0);
+ }
+
+ if (unlikely(!mem->tag))
+ comp = 0;
+ }
+
INIT_LIST_HEAD(&mem->regions);
mem->dev = dev_priv->dev;
- mem->memtype = type;
+ mem->memtype = (comp << 7) | type;
mem->size = size;
- mutex_lock(&mm->mutex);
do {
ret = nouveau_mm_get(mm, types[type], size, size_nc, align, &r);
if (ret) {