From 3024f23c6551e219b0236041a8205bf1bc60ed94 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 31 Jan 2007 14:50:57 +0100 Subject: memory manager: Make device driver aware of different memory types. Memory types are either fixed (on-card or pre-bound AGP) or not fixed (dynamically bound) to an aperture. They also carry information about: 1) Whether they can be mapped cached. 2) Whether they are at all mappable. 3) Whether they need an ioremap to be accessible from kernel space. In this way VRAM memory and, for example, pre-bound AGP appear identical to the memory manager. This also makes support for unmappable VRAM simple to implement. --- linux-core/i915_buffer.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index c3e54468..53002301 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -64,3 +64,36 @@ int i915_invalidate_caches(drm_device_t * dev, uint32_t flags) return i915_emit_mi_flush(dev, flush_cmd); } + +int i915_init_mem_type(drm_device_t *dev, uint32_t type, + drm_mem_type_manager_t *man) +{ + switch(type) { + case DRM_BO_MEM_LOCAL: + break; + case DRM_BO_MEM_TT: + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | + _DRM_FLAG_MEMTYPE_CACHED; + break; + case DRM_BO_MEM_PRIV0: + if (!(drm_core_has_AGP(dev) && dev->agp)) { + DRM_ERROR("AGP is not enabled for memory type %u\n", + (unsigned) type); + return -EINVAL; + } + man->io_offset = dev->agp->agp_info.aper_base; + man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; + + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | + _DRM_FLAG_MEMTYPE_CACHED | + _DRM_FLAG_MEMTYPE_FIXED | + _DRM_FLAG_NEEDS_IOREMAP; + + man->io_addr = NULL; + break; + default: + DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); + return -EINVAL; + } + return 0; +} -- cgit v1.2.3 From c269d560e4d71448cfc9c2ea51eee3d5feafaad4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 2 Feb 2007 14:47:44 +0100 Subject: Make vm handle buffer objects instead of ttm objects. Remove ttm objects. Make vm aware of PCI memory type buffer objects. (Only works for pre 2.6.16 kernels for now). --- linux-core/i915_buffer.c | 1 - 1 file changed, 1 deletion(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 53002301..dc2cca33 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -70,7 +70,6 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, { switch(type) { case DRM_BO_MEM_LOCAL: - break; case DRM_BO_MEM_TT: man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CACHED; -- cgit v1.2.3 From 2d962332dea5ed328ae45c6ef7298ea15216b635 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 5 Feb 2007 16:13:32 +0100 Subject: i915: Add copy-blit operation. --- linux-core/i915_buffer.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index dc2cca33..cdbe579a 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -96,3 +96,47 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, } return 0; } + +void i915_emit_copy_blit(drm_device_t *dev, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t pages, + int direction) +{ + uint32_t cur_pages; + uint32_t stride = PAGE_SIZE; + drm_i915_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + + if (!dev_priv) + return; + + if (direction) { + stride = -stride; + src_offset += (pages - 1) << PAGE_SHIFT; + dst_offset += (pages - 1) << PAGE_SHIFT; + } + + while(pages > 0) { + cur_pages = pages; + if (cur_pages > 2048) + cur_pages = 2048; + pages -= cur_pages; + + BEGIN_LP_RING(8); + OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + XY_SRC_COPY_BLT_WRITE_RGB); + OUT_RING((stride & 0xffff) | ( 0xcc << 16) | (1 << 24) | + (1 << 25)); + OUT_RING(0); + OUT_RING((cur_pages << 16) | (PAGE_SIZE >> 2)); + OUT_RING(dst_offset); + OUT_RING(0); + OUT_RING(stride & 0xffff); + OUT_RING(src_offset); + ADVANCE_LP_RING(); + dst_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1); + src_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1); + } + return; +} -- cgit v1.2.3 From 609e3b037526021d20c7cc18b7fed1152206dc68 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Feb 2007 14:20:33 +0100 Subject: Implement a policy for selecting memory types. --- linux-core/i915_buffer.c | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index cdbe579a..13a3e9bb 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -97,6 +97,17 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, return 0; } +uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type) +{ + switch(type) { + case DRM_BO_MEM_LOCAL: + case DRM_BO_MEM_TT: + return DRM_BO_FLAG_MEM_LOCAL; + default: + return DRM_BO_FLAG_MEM_TT; + } +} + void i915_emit_copy_blit(drm_device_t *dev, uint32_t src_offset, uint32_t dst_offset, -- cgit v1.2.3 From 71b9e876f99db219fcbf4e3ab977b64b068cc2b4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 6 Feb 2007 16:59:45 +0100 Subject: Simplify pci map vs no pci map choice. --- linux-core/i915_buffer.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 13a3e9bb..c1cdd112 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -71,8 +71,17 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, switch(type) { case DRM_BO_MEM_LOCAL: case DRM_BO_MEM_TT: + if (!(drm_core_has_AGP(dev) && dev->agp)) { + DRM_ERROR("AGP is not enabled for memory type %u\n", + (unsigned) type); + return -EINVAL; + } + man->io_offset = dev->agp->agp_info.aper_base; + man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; + man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_CACHED; + _DRM_FLAG_MEMTYPE_CACHED | + _DRM_FLAG_NEEDS_IOREMAP; break; case DRM_BO_MEM_PRIV0: if (!(drm_core_has_AGP(dev) && dev->agp)) { @@ -82,13 +91,11 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, } man->io_offset = dev->agp->agp_info.aper_base; man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; - + man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_CACHED | _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP; - man->io_addr = NULL; break; default: DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); -- cgit v1.2.3 From c1fbd8a56653b91af57a408bbcf20a760a2bd8c8 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 7 Feb 2007 17:25:13 +0100 Subject: Checkpoint commit. Flag handling and memory type selection cleanup. glxgears won't start. --- linux-core/i915_buffer.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index c1cdd112..5d1c39be 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -70,6 +70,9 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, { switch(type) { case DRM_BO_MEM_LOCAL: + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | + _DRM_FLAG_MEMTYPE_CACHED; + break; case DRM_BO_MEM_TT: if (!(drm_core_has_AGP(dev) && dev->agp)) { DRM_ERROR("AGP is not enabled for memory type %u\n", @@ -80,7 +83,7 @@ int i915_init_mem_type(drm_device_t *dev, uint32_t type, man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_CACHED | + _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP; break; case DRM_BO_MEM_PRIV0: -- cgit v1.2.3 From b2bcbf874b0f26ca0c490fb0453bef64ce6d9dd7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Thu, 8 Feb 2007 21:28:33 +0100 Subject: Add an accelerated buffer copy cleanup helper. Export helper functions and make some important buffer-object functions non-static. Add an i915 accelerated blit buffer move for pci memory buffers. --- linux-core/i915_buffer.c | 34 +++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 5d1c39be..41f05b78 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -118,7 +118,7 @@ uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type) } } -void i915_emit_copy_blit(drm_device_t *dev, +static void i915_emit_copy_blit(drm_device_t *dev, uint32_t src_offset, uint32_t dst_offset, uint32_t pages, @@ -161,3 +161,35 @@ void i915_emit_copy_blit(drm_device_t *dev, } return; } + +static int drm_bo_move_blit(drm_buffer_object_t *bo, + int evict, + int no_wait, + drm_bo_mem_reg_t *new_mem) +{ + drm_bo_mem_reg_t *old_mem = &bo->mem; + int dir = 0; + + if ((old_mem->mem_type == new_mem->mem_type) && + (new_mem->mm_node->start < + old_mem->mm_node->start + old_mem->mm_node->size)) { + dir = 1; + } + + i915_emit_copy_blit(bo->dev, + old_mem->mm_node->start << PAGE_SHIFT, + new_mem->mm_node->start << PAGE_SHIFT, + new_mem->num_pages, + dir); + + i915_emit_mi_flush(bo->dev, MI_READ_FLUSH | MI_EXE_FLUSH); + + return drm_bo_move_accel_cleanup(bo, evict, no_wait, + DRM_FENCE_TYPE_EXE | + DRM_I915_FENCE_TYPE_RW, + DRM_I915_FENCE_FLAG_FLUSHED, + new_mem); +} + + + -- cgit v1.2.3 From 53aee3122a1821b8ca24ed2bc5c1940cb0f2ff8e Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Fri, 9 Feb 2007 16:36:53 +0100 Subject: I915 accelerated blit copy functional. Fixed - to System memory copies are implemented by flipping in a cache-coherent TTM, blitting to it, and then flipping it out. --- linux-core/i915_buffer.c | 82 +++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 67 insertions(+), 15 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 41f05b78..70ba9a67 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -132,37 +132,28 @@ static void i915_emit_copy_blit(drm_device_t *dev, if (!dev_priv) return; - if (direction) { - stride = -stride; - src_offset += (pages - 1) << PAGE_SHIFT; - dst_offset += (pages - 1) << PAGE_SHIFT; - } - + i915_kernel_lost_context(dev); while(pages > 0) { cur_pages = pages; if (cur_pages > 2048) cur_pages = 2048; pages -= cur_pages; - BEGIN_LP_RING(8); - OUT_RING(XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | + BEGIN_LP_RING(6); + OUT_RING(SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); OUT_RING((stride & 0xffff) | ( 0xcc << 16) | (1 << 24) | - (1 << 25)); - OUT_RING(0); - OUT_RING((cur_pages << 16) | (PAGE_SIZE >> 2)); + (1 << 25) | (direction ? (1 << 30) : 0)); + OUT_RING((cur_pages << 16) | PAGE_SIZE); OUT_RING(dst_offset); - OUT_RING(0); OUT_RING(stride & 0xffff); OUT_RING(src_offset); ADVANCE_LP_RING(); - dst_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1); - src_offset += (cur_pages << PAGE_SHIFT)*(direction ? -1 : 1); } return; } -static int drm_bo_move_blit(drm_buffer_object_t *bo, +static int i915_move_blit(drm_buffer_object_t *bo, int evict, int no_wait, drm_bo_mem_reg_t *new_mem) @@ -191,5 +182,66 @@ static int drm_bo_move_blit(drm_buffer_object_t *bo, new_mem); } +/* + * Flip destination ttm into cached-coherent AGP, + * then blit and subsequently move out again. + */ + + +static int i915_move_flip(drm_buffer_object_t *bo, + int evict, + int no_wait, + drm_bo_mem_reg_t *new_mem) +{ + drm_device_t *dev = bo->dev; + drm_bo_mem_reg_t tmp_mem; + int ret; + + tmp_mem = *new_mem; + tmp_mem.mm_node = NULL; + tmp_mem.mask = DRM_BO_FLAG_MEM_TT | + DRM_BO_FLAG_CACHED | + DRM_BO_FLAG_FORCE_CACHING; + + ret = drm_bo_mem_space(dev, &tmp_mem, no_wait); + if (ret) + return ret; + ret = drm_bind_ttm(bo->ttm, 1, tmp_mem.mm_node->start); + if (ret) + goto out_cleanup; + ret = i915_move_blit(bo, 1, no_wait, &tmp_mem); + if (ret) + goto out_cleanup; + + ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); +out_cleanup: + if (tmp_mem.mm_node) { + mutex_lock(&dev->struct_mutex); + drm_mm_put_block(tmp_mem.mm_node); + tmp_mem.mm_node = NULL; + mutex_unlock(&dev->struct_mutex); + } + return ret; +} + + +int i915_move(drm_buffer_object_t *bo, + int evict, + int no_wait, + drm_bo_mem_reg_t *new_mem) +{ + drm_bo_mem_reg_t *old_mem = &bo->mem; + + if (old_mem->mem_type == DRM_BO_MEM_LOCAL) + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { + if (i915_move_flip(bo, evict, no_wait, new_mem)) + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + } else { + if (i915_move_blit(bo, evict, no_wait, new_mem)) + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + } + return 0; +} -- cgit v1.2.3 From 85ee2a8d044cd4d8de4894a794151af9471648e3 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Sat, 10 Feb 2007 12:06:36 +0100 Subject: Various bugfixes. --- linux-core/i915_buffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 70ba9a67..a357a53e 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -234,9 +234,9 @@ int i915_move(drm_buffer_object_t *bo, { drm_bo_mem_reg_t *old_mem = &bo->mem; - if (old_mem->mem_type == DRM_BO_MEM_LOCAL) + if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); - if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { + } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { if (i915_move_flip(bo, evict, no_wait, new_mem)) return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else { -- cgit v1.2.3 From f02f83ee08a2bb87700544a9b67f475532e84af4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 12 Feb 2007 17:47:57 +0100 Subject: Cleanup and fix support for pinned buffers. --- linux-core/i915_buffer.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index a357a53e..7655902f 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -154,9 +154,9 @@ static void i915_emit_copy_blit(drm_device_t *dev, } static int i915_move_blit(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem) + int evict, + int no_wait, + drm_bo_mem_reg_t *new_mem) { drm_bo_mem_reg_t *old_mem = &bo->mem; int dir = 0; @@ -203,7 +203,7 @@ static int i915_move_flip(drm_buffer_object_t *bo, DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING; - ret = drm_bo_mem_space(dev, &tmp_mem, no_wait); + ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); if (ret) return ret; @@ -238,10 +238,12 @@ int i915_move(drm_buffer_object_t *bo, return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { if (i915_move_flip(bo, evict, no_wait, new_mem)) - return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + return drm_bo_move_memcpy(bo, evict, no_wait, + new_mem); } else { - if (i915_move_blit(bo, evict, no_wait, new_mem)) - return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); + if (i915_move_blit(bo, evict, no_wait, new_mem)) + return drm_bo_move_memcpy(bo, evict, no_wait, + new_mem); } return 0; } -- cgit v1.2.3 From 398913dc0e632c71e3095a7d50dae911aed18884 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 12 Feb 2007 20:34:50 +0100 Subject: Lindent. --- linux-core/i915_buffer.c | 103 ++++++++++++++++++++--------------------------- 1 file changed, 43 insertions(+), 60 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 7655902f..4fab0bef 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -33,7 +33,6 @@ #include "i915_drm.h" #include "i915_drv.h" - drm_ttm_backend_t *i915_create_ttm_backend_entry(drm_device_t * dev) { return drm_agp_init_ttm(dev, NULL); @@ -65,51 +64,49 @@ int i915_invalidate_caches(drm_device_t * dev, uint32_t flags) return i915_emit_mi_flush(dev, flush_cmd); } -int i915_init_mem_type(drm_device_t *dev, uint32_t type, - drm_mem_type_manager_t *man) +int i915_init_mem_type(drm_device_t * dev, uint32_t type, + drm_mem_type_manager_t * man) { - switch(type) { + switch (type) { case DRM_BO_MEM_LOCAL: man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_CACHED; + _DRM_FLAG_MEMTYPE_CACHED; break; case DRM_BO_MEM_TT: if (!(drm_core_has_AGP(dev) && dev->agp)) { - DRM_ERROR("AGP is not enabled for memory type %u\n", - (unsigned) type); + DRM_ERROR("AGP is not enabled for memory type %u\n", + (unsigned)type); return -EINVAL; } man->io_offset = dev->agp->agp_info.aper_base; man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_CSELECT | - _DRM_FLAG_NEEDS_IOREMAP; + _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP; break; case DRM_BO_MEM_PRIV0: if (!(drm_core_has_AGP(dev) && dev->agp)) { - DRM_ERROR("AGP is not enabled for memory type %u\n", - (unsigned) type); + DRM_ERROR("AGP is not enabled for memory type %u\n", + (unsigned)type); return -EINVAL; } man->io_offset = dev->agp->agp_info.aper_base; man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | - _DRM_FLAG_MEMTYPE_FIXED | - _DRM_FLAG_NEEDS_IOREMAP; + _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP; break; default: - DRM_ERROR("Unsupported memory type %u\n", (unsigned) type); + DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); return -EINVAL; } return 0; } -uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type) +uint32_t i915_evict_flags(drm_device_t * dev, uint32_t type) { - switch(type) { + switch (type) { case DRM_BO_MEM_LOCAL: case DRM_BO_MEM_TT: return DRM_BO_FLAG_MEM_LOCAL; @@ -118,11 +115,10 @@ uint32_t i915_evict_flags(drm_device_t *dev, uint32_t type) } } -static void i915_emit_copy_blit(drm_device_t *dev, - uint32_t src_offset, - uint32_t dst_offset, - uint32_t pages, - int direction) +static void i915_emit_copy_blit(drm_device_t * dev, + uint32_t src_offset, + uint32_t dst_offset, + uint32_t pages, int direction) { uint32_t cur_pages; uint32_t stride = PAGE_SIZE; @@ -131,9 +127,9 @@ static void i915_emit_copy_blit(drm_device_t *dev, if (!dev_priv) return; - + i915_kernel_lost_context(dev); - while(pages > 0) { + while (pages > 0) { cur_pages = pages; if (cur_pages > 2048) cur_pages = 2048; @@ -142,7 +138,7 @@ static void i915_emit_copy_blit(drm_device_t *dev, BEGIN_LP_RING(6); OUT_RING(SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA | XY_SRC_COPY_BLT_WRITE_RGB); - OUT_RING((stride & 0xffff) | ( 0xcc << 16) | (1 << 24) | + OUT_RING((stride & 0xffff) | (0xcc << 16) | (1 << 24) | (1 << 25) | (direction ? (1 << 30) : 0)); OUT_RING((cur_pages << 16) | PAGE_SIZE); OUT_RING(dst_offset); @@ -153,33 +149,29 @@ static void i915_emit_copy_blit(drm_device_t *dev, return; } -static int i915_move_blit(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem) +static int i915_move_blit(drm_buffer_object_t * bo, + int evict, int no_wait, drm_bo_mem_reg_t * new_mem) { drm_bo_mem_reg_t *old_mem = &bo->mem; int dir = 0; - if ((old_mem->mem_type == new_mem->mem_type) && - (new_mem->mm_node->start < - old_mem->mm_node->start + old_mem->mm_node->size)) { + if ((old_mem->mem_type == new_mem->mem_type) && + (new_mem->mm_node->start < + old_mem->mm_node->start + old_mem->mm_node->size)) { dir = 1; } i915_emit_copy_blit(bo->dev, old_mem->mm_node->start << PAGE_SHIFT, new_mem->mm_node->start << PAGE_SHIFT, - new_mem->num_pages, - dir); + new_mem->num_pages, dir); i915_emit_mi_flush(bo->dev, MI_READ_FLUSH | MI_EXE_FLUSH); return drm_bo_move_accel_cleanup(bo, evict, no_wait, DRM_FENCE_TYPE_EXE | - DRM_I915_FENCE_TYPE_RW, - DRM_I915_FENCE_FLAG_FLUSHED, - new_mem); + DRM_I915_FENCE_TYPE_RW, + DRM_I915_FENCE_FLAG_FLUSHED, new_mem); } /* @@ -187,11 +179,8 @@ static int i915_move_blit(drm_buffer_object_t *bo, * then blit and subsequently move out again. */ - -static int i915_move_flip(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem) +static int i915_move_flip(drm_buffer_object_t * bo, + int evict, int no_wait, drm_bo_mem_reg_t * new_mem) { drm_device_t *dev = bo->dev; drm_bo_mem_reg_t tmp_mem; @@ -200,23 +189,22 @@ static int i915_move_flip(drm_buffer_object_t *bo, tmp_mem = *new_mem; tmp_mem.mm_node = NULL; tmp_mem.mask = DRM_BO_FLAG_MEM_TT | - DRM_BO_FLAG_CACHED | - DRM_BO_FLAG_FORCE_CACHING; - + DRM_BO_FLAG_CACHED | DRM_BO_FLAG_FORCE_CACHING; + ret = drm_bo_mem_space(bo, &tmp_mem, no_wait); - if (ret) + if (ret) return ret; - + ret = drm_bind_ttm(bo->ttm, 1, tmp_mem.mm_node->start); - if (ret) + if (ret) goto out_cleanup; ret = i915_move_blit(bo, 1, no_wait, &tmp_mem); - if (ret) + if (ret) goto out_cleanup; - + ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); -out_cleanup: + out_cleanup: if (tmp_mem.mm_node) { mutex_lock(&dev->struct_mutex); drm_mm_put_block(tmp_mem.mm_node); @@ -226,24 +214,19 @@ out_cleanup: return ret; } - -int i915_move(drm_buffer_object_t *bo, - int evict, - int no_wait, - drm_bo_mem_reg_t *new_mem) +int i915_move(drm_buffer_object_t * bo, + int evict, int no_wait, drm_bo_mem_reg_t * new_mem) { drm_bo_mem_reg_t *old_mem = &bo->mem; if (old_mem->mem_type == DRM_BO_MEM_LOCAL) { return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else if (new_mem->mem_type == DRM_BO_MEM_LOCAL) { - if (i915_move_flip(bo, evict, no_wait, new_mem)) - return drm_bo_move_memcpy(bo, evict, no_wait, - new_mem); + if (i915_move_flip(bo, evict, no_wait, new_mem)) + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } else { if (i915_move_blit(bo, evict, no_wait, new_mem)) - return drm_bo_move_memcpy(bo, evict, no_wait, - new_mem); + return drm_bo_move_memcpy(bo, evict, no_wait, new_mem); } return 0; } -- cgit v1.2.3 From 9efdae317ce01cea95f75855b175243ae858fde4 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Tue, 13 Feb 2007 20:05:32 +0100 Subject: More bugfixes. Fixed memory, pinned buffers and unmappable memory now seems fully functional. --- linux-core/i915_buffer.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 4fab0bef..3ccfab38 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -93,7 +93,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type, man->io_offset = dev->agp->agp_info.aper_base; man->io_size = dev->agp->agp_info.aper_size * 1024 * 1024; man->io_addr = NULL; - man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | + man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP; break; @@ -111,7 +111,7 @@ uint32_t i915_evict_flags(drm_device_t * dev, uint32_t type) case DRM_BO_MEM_TT: return DRM_BO_FLAG_MEM_LOCAL; default: - return DRM_BO_FLAG_MEM_TT; + return DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_CACHED; } } @@ -204,10 +204,11 @@ static int i915_move_flip(drm_buffer_object_t * bo, goto out_cleanup; ret = drm_bo_move_ttm(bo, evict, no_wait, new_mem); - out_cleanup: +out_cleanup: if (tmp_mem.mm_node) { mutex_lock(&dev->struct_mutex); - drm_mm_put_block(tmp_mem.mm_node); + if (tmp_mem.mm_node != bo->pinned_node) + drm_mm_put_block(tmp_mem.mm_node); tmp_mem.mm_node = NULL; mutex_unlock(&dev->struct_mutex); } -- cgit v1.2.3 From 04760563b88c8e94f3ae448710d1ab8b350c2e5f Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Wed, 14 Feb 2007 12:39:02 +0100 Subject: Set the drm bus map type for each buffer object memory type. --- linux-core/i915_buffer.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'linux-core/i915_buffer.c') diff --git a/linux-core/i915_buffer.c b/linux-core/i915_buffer.c index 3ccfab38..374b28df 100644 --- a/linux-core/i915_buffer.c +++ b/linux-core/i915_buffer.c @@ -71,6 +71,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type, case DRM_BO_MEM_LOCAL: man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CACHED; + man->drm_bus_maptype = 0; break; case DRM_BO_MEM_TT: if (!(drm_core_has_AGP(dev) && dev->agp)) { @@ -83,6 +84,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type, man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_CSELECT | _DRM_FLAG_NEEDS_IOREMAP; + man->drm_bus_maptype = _DRM_AGP; break; case DRM_BO_MEM_PRIV0: if (!(drm_core_has_AGP(dev) && dev->agp)) { @@ -95,7 +97,7 @@ int i915_init_mem_type(drm_device_t * dev, uint32_t type, man->io_addr = NULL; man->flags = _DRM_FLAG_MEMTYPE_MAPPABLE | _DRM_FLAG_MEMTYPE_FIXED | _DRM_FLAG_NEEDS_IOREMAP; - + man->drm_bus_maptype = _DRM_AGP; break; default: DRM_ERROR("Unsupported memory type %u\n", (unsigned)type); -- cgit v1.2.3