diff options
Diffstat (limited to 'sys/dev/pci/drm/radeon/radeon_cs.c')
-rw-r--r-- | sys/dev/pci/drm/radeon/radeon_cs.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/sys/dev/pci/drm/radeon/radeon_cs.c b/sys/dev/pci/drm/radeon/radeon_cs.c index 6f35c794d11..80fcd5a4939 100644 --- a/sys/dev/pci/drm/radeon/radeon_cs.c +++ b/sys/dev/pci/drm/radeon/radeon_cs.c @@ -24,8 +24,9 @@ * Authors: * Jerome Glisse <glisse@freedesktop.org> */ -#include <dev/pci/drm/drmP.h> -#include <dev/pci/drm/radeon_drm.h> +#include <linux/list_sort.h> +#include <drm/drmP.h> +#include <drm/radeon_drm.h> #include "radeon_reg.h" #include "radeon.h" #include "radeon_trace.h" @@ -73,7 +74,6 @@ static void radeon_cs_buckets_get_list(struct radeon_cs_buckets *b, static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) { - struct drm_device *ddev = p->rdev->ddev; struct radeon_cs_chunk *chunk; struct radeon_cs_buckets buckets; unsigned i; @@ -87,7 +87,8 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) p->dma_reloc_idx = 0; /* FIXME: we assume that each relocs use 4 dwords */ p->nrelocs = chunk->length_dw / 4; - p->relocs = drm_calloc_large(p->nrelocs, sizeof(struct radeon_bo_list)); + p->relocs = kvmalloc_array(p->nrelocs, sizeof(struct radeon_bo_list), + GFP_KERNEL | __GFP_ZERO); if (p->relocs == NULL) { return -ENOMEM; } @@ -100,7 +101,7 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) unsigned priority; r = (struct drm_radeon_cs_reloc *)&chunk->kdata[i*4]; - gobj = drm_gem_object_lookup(ddev, p->filp, r->handle); + gobj = drm_gem_object_lookup(p->filp, r->handle); if (gobj == NULL) { DRM_ERROR("gem object lookup failed 0x%x\n", r->handle); @@ -117,16 +118,18 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) priority = (r->flags & RADEON_RELOC_PRIO_MASK) * 2 + !!r->write_domain; - /* the first reloc of an UVD job is the msg and that must be in - VRAM, also but everything into VRAM on AGP cards and older - IGP chips to avoid image corruptions */ + /* The first reloc of an UVD job is the msg and that must be in + * VRAM, the second reloc is the DPB and for WMV that must be in + * VRAM as well. Also put everything into VRAM on AGP cards and older + * IGP chips to avoid image corruptions + */ if (p->ring == R600_RING_TYPE_UVD_INDEX && - (i == 0 || (p->rdev->flags & RADEON_IS_AGP) || + (i <= 0 || (p->rdev->flags & RADEON_IS_AGP) || p->rdev->family == CHIP_RS780 || p->rdev->family == CHIP_RS880)) { /* TODO: is this still needed for NI+ ? */ - p->relocs[i].prefered_domains = + p->relocs[i].preferred_domains = RADEON_GEM_DOMAIN_VRAM; p->relocs[i].allowed_domains = @@ -144,14 +147,14 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) return -EINVAL; } - p->relocs[i].prefered_domains = domain; + p->relocs[i].preferred_domains = domain; if (domain == RADEON_GEM_DOMAIN_VRAM) domain |= RADEON_GEM_DOMAIN_GTT; p->relocs[i].allowed_domains = domain; } if (radeon_ttm_tt_has_userptr(p->relocs[i].robj->tbo.ttm)) { - uint32_t domain = p->relocs[i].prefered_domains; + uint32_t domain = p->relocs[i].preferred_domains; if (!(domain & RADEON_GEM_DOMAIN_GTT)) { DRM_ERROR("Only RADEON_GEM_DOMAIN_GTT is " "allowed for userptr BOs\n"); @@ -159,10 +162,20 @@ static int radeon_cs_parser_relocs(struct radeon_cs_parser *p) } need_mmap_lock = true; domain = RADEON_GEM_DOMAIN_GTT; - p->relocs[i].prefered_domains = domain; + p->relocs[i].preferred_domains = domain; p->relocs[i].allowed_domains = domain; } + /* Objects shared as dma-bufs cannot be moved to VRAM */ + if (p->relocs[i].robj->prime_shared_count) { + p->relocs[i].allowed_domains &= ~RADEON_GEM_DOMAIN_VRAM; + if (!p->relocs[i].allowed_domains) { + DRM_ERROR("BO associated with dma-buf cannot " + "be moved to VRAM\n"); + return -EINVAL; + } + } + p->relocs[i].tv.bo = &p->relocs[i].robj->tbo; p->relocs[i].tv.shared = !r->write_domain; @@ -332,7 +345,7 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) continue; } - p->chunks[i].kdata = drm_malloc_ab(size, sizeof(uint32_t)); + p->chunks[i].kdata = kvmalloc_array(size, sizeof(uint32_t), GFP_KERNEL); size *= sizeof(uint32_t); if (p->chunks[i].kdata == NULL) { return -ENOMEM; @@ -427,14 +440,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error, bo if (bo == NULL) continue; - drm_gem_object_unreference_unlocked(&bo->gem_base); + drm_gem_object_put_unlocked(&bo->gem_base); } } kfree(parser->track); - drm_free_large(parser->relocs); - drm_free_large(parser->vm_bos); + kvfree(parser->relocs); + kvfree(parser->vm_bos); for (i = 0; i < parser->nchunks; i++) - drm_free_large(parser->chunks[i].kdata); + kvfree(parser->chunks[i].kdata); kfree(parser->chunks); kfree(parser->chunks_array); radeon_ib_free(parser->rdev, &parser->ib); |