diff options
Diffstat (limited to 'drivers/gpu/drm/etnaviv')
-rw-r--r-- | drivers/gpu/drm/etnaviv/Kconfig | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_drv.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_dump.c | 5 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem.c | 40 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c | 7 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 35 | ||||
-rw-r--r-- | drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 13 |
9 files changed, 45 insertions, 68 deletions
diff --git a/drivers/gpu/drm/etnaviv/Kconfig b/drivers/gpu/drm/etnaviv/Kconfig index 21df44b78df3..faa7fc68b009 100644 --- a/drivers/gpu/drm/etnaviv/Kconfig +++ b/drivers/gpu/drm/etnaviv/Kconfig @@ -1,3 +1,4 @@ +# SPDX-License-Identifier: GPL-2.0-only config DRM_ETNAVIV tristate "ETNAVIV (DRM support for Vivante GPU IP cores)" diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.c b/drivers/gpu/drm/etnaviv/etnaviv_drv.c index 18c27f795cf6..7eb7cf9c3fa8 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.c @@ -473,7 +473,6 @@ static struct drm_driver etnaviv_drm_driver = { .prime_fd_to_handle = drm_gem_prime_fd_to_handle, .gem_prime_export = drm_gem_prime_export, .gem_prime_import = drm_gem_prime_import, - .gem_prime_res_obj = etnaviv_gem_prime_res_obj, .gem_prime_pin = etnaviv_gem_prime_pin, .gem_prime_unpin = etnaviv_gem_prime_unpin, .gem_prime_get_sg_table = etnaviv_gem_prime_get_sg_table, @@ -515,6 +514,9 @@ static int etnaviv_bind(struct device *dev) } drm->dev_private = priv; + dev->dma_parms = &priv->dma_parms; + dma_set_max_seg_size(dev, SZ_2G); + mutex_init(&priv->gem_lock); INIT_LIST_HEAD(&priv->gem_list); priv->num_gpus = 0; @@ -552,6 +554,8 @@ static void etnaviv_unbind(struct device *dev) component_unbind_all(dev, drm); + dev->dma_parms = NULL; + drm->dev_private = NULL; kfree(priv); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_drv.h b/drivers/gpu/drm/etnaviv/etnaviv_drv.h index a6a7ded37ef1..8798423705e1 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_drv.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_drv.h @@ -42,6 +42,7 @@ struct etnaviv_file_private { struct etnaviv_drm_private { int num_gpus; + struct device_dma_parameters dma_parms; struct etnaviv_gpu *gpu[ETNA_MAX_PIPES]; /* list of GEM objects: */ @@ -60,7 +61,6 @@ void *etnaviv_gem_prime_vmap(struct drm_gem_object *obj); void etnaviv_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr); int etnaviv_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); -struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj); struct drm_gem_object *etnaviv_gem_prime_import_sg_table(struct drm_device *dev, struct dma_buf_attachment *attach, struct sg_table *sg); int etnaviv_gem_prime_pin(struct drm_gem_object *obj); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_dump.c b/drivers/gpu/drm/etnaviv/etnaviv_dump.c index 33854c94cb85..515515ef24f9 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_dump.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_dump.c @@ -125,6 +125,8 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) return; etnaviv_dump_core = false; + mutex_lock(&gpu->mmu->lock); + mmu_size = etnaviv_iommu_dump_size(gpu->mmu); /* We always dump registers, mmu, ring and end marker */ @@ -167,6 +169,7 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) iter.start = __vmalloc(file_size, GFP_KERNEL | __GFP_NOWARN | __GFP_NORETRY, PAGE_KERNEL); if (!iter.start) { + mutex_unlock(&gpu->mmu->lock); dev_warn(gpu->dev, "failed to allocate devcoredump file\n"); return; } @@ -234,6 +237,8 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) obj->base.size); } + mutex_unlock(&gpu->mmu->lock); + etnaviv_core_dump_header(&iter, ETDUMP_BUF_END, iter.data); dev_coredumpv(gpu->dev, iter.start, iter.data - iter.start, GFP_KERNEL); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.c b/drivers/gpu/drm/etnaviv/etnaviv_gem.c index 5c48915f492d..e8778ebb72e6 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.c @@ -397,13 +397,13 @@ int etnaviv_gem_cpu_prep(struct drm_gem_object *obj, u32 op, } if (op & ETNA_PREP_NOSYNC) { - if (!reservation_object_test_signaled_rcu(etnaviv_obj->resv, + if (!reservation_object_test_signaled_rcu(obj->resv, write)) return -EBUSY; } else { unsigned long remain = etnaviv_timeout_to_jiffies(timeout); - ret = reservation_object_wait_timeout_rcu(etnaviv_obj->resv, + ret = reservation_object_wait_timeout_rcu(obj->resv, write, true, remain); if (ret <= 0) return ret == 0 ? -ETIMEDOUT : ret; @@ -459,7 +459,7 @@ static void etnaviv_gem_describe_fence(struct dma_fence *fence, static void etnaviv_gem_describe(struct drm_gem_object *obj, struct seq_file *m) { struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); - struct reservation_object *robj = etnaviv_obj->resv; + struct reservation_object *robj = obj->resv; struct reservation_object_list *fobj; struct dma_fence *fence; unsigned long off = drm_vma_node_start(&obj->vma_node); @@ -549,8 +549,6 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj) drm_gem_free_mmap_offset(obj); etnaviv_obj->ops->release(etnaviv_obj); - if (etnaviv_obj->resv == &etnaviv_obj->_resv) - reservation_object_fini(&etnaviv_obj->_resv); drm_gem_object_release(obj); kfree(etnaviv_obj); @@ -596,12 +594,8 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags, etnaviv_obj->flags = flags; etnaviv_obj->ops = ops; - if (robj) { - etnaviv_obj->resv = robj; - } else { - etnaviv_obj->resv = &etnaviv_obj->_resv; - reservation_object_init(&etnaviv_obj->_resv); - } + if (robj) + etnaviv_obj->base.resv = robj; mutex_init(&etnaviv_obj->lock); INIT_LIST_HEAD(&etnaviv_obj->vram_list); @@ -628,24 +622,18 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file, lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class); ret = drm_gem_object_init(dev, obj, size); - if (ret == 0) { - struct address_space *mapping; - - /* - * Our buffers are kept pinned, so allocating them - * from the MOVABLE zone is a really bad idea, and - * conflicts with CMA. See comments above new_inode() - * why this is required _and_ expected if you're - * going to pin these pages. - */ - mapping = obj->filp->f_mapping; - mapping_set_gfp_mask(mapping, GFP_HIGHUSER | - __GFP_RETRY_MAYFAIL | __GFP_NOWARN); - } - if (ret) goto fail; + /* + * Our buffers are kept pinned, so allocating them from the MOVABLE + * zone is a really bad idea, and conflicts with CMA. See comments + * above new_inode() why this is required _and_ expected if you're + * going to pin these pages. + */ + mapping_set_gfp_mask(obj->filp->f_mapping, GFP_HIGHUSER | + __GFP_RETRY_MAYFAIL | __GFP_NOWARN); + etnaviv_gem_obj_add(dev, obj); ret = drm_gem_handle_create(file, obj, handle); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem.h b/drivers/gpu/drm/etnaviv/etnaviv_gem.h index f0abb744ef95..753c458497d0 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem.h +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem.h @@ -47,10 +47,6 @@ struct etnaviv_gem_object { struct sg_table *sgt; void *vaddr; - /* normally (resv == &_resv) except for imported bo's */ - struct reservation_object *resv; - struct reservation_object _resv; - struct list_head vram_list; /* cache maintenance */ diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c index f21529e635e3..00e8b6a817e3 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c @@ -139,10 +139,3 @@ fail: return ERR_PTR(ret); } - -struct reservation_object *etnaviv_gem_prime_res_obj(struct drm_gem_object *obj) -{ - struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); - - return etnaviv_obj->resv; -} diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c index b2fe3446bfbc..1a636469eeda 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c @@ -1,17 +1,6 @@ +// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2015 Etnaviv Project - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 as published by - * the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along with - * this program. If not, see <http://www.gnu.org/licenses/>. */ #include <linux/dma-fence-array.h> @@ -108,9 +97,9 @@ out_unlock: static void submit_unlock_object(struct etnaviv_gem_submit *submit, int i) { if (submit->bos[i].flags & BO_LOCKED) { - struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; + struct drm_gem_object *obj = &submit->bos[i].obj->base; - ww_mutex_unlock(&etnaviv_obj->resv->lock); + ww_mutex_unlock(&obj->resv->lock); submit->bos[i].flags &= ~BO_LOCKED; } } @@ -122,7 +111,7 @@ static int submit_lock_objects(struct etnaviv_gem_submit *submit, retry: for (i = 0; i < submit->nr_bos; i++) { - struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; + struct drm_gem_object *obj = &submit->bos[i].obj->base; if (slow_locked == i) slow_locked = -1; @@ -130,7 +119,7 @@ retry: contended = i; if (!(submit->bos[i].flags & BO_LOCKED)) { - ret = ww_mutex_lock_interruptible(&etnaviv_obj->resv->lock, + ret = ww_mutex_lock_interruptible(&obj->resv->lock, ticket); if (ret == -EALREADY) DRM_ERROR("BO at index %u already on submit list\n", @@ -153,12 +142,12 @@ fail: submit_unlock_object(submit, slow_locked); if (ret == -EDEADLK) { - struct etnaviv_gem_object *etnaviv_obj; + struct drm_gem_object *obj; - etnaviv_obj = submit->bos[contended].obj; + obj = &submit->bos[contended].obj->base; /* we lost out in a seqno race, lock and retry.. */ - ret = ww_mutex_lock_slow_interruptible(&etnaviv_obj->resv->lock, + ret = ww_mutex_lock_slow_interruptible(&obj->resv->lock, ticket); if (!ret) { submit->bos[contended].flags |= BO_LOCKED; @@ -176,7 +165,7 @@ static int submit_fence_sync(struct etnaviv_gem_submit *submit) for (i = 0; i < submit->nr_bos; i++) { struct etnaviv_gem_submit_bo *bo = &submit->bos[i]; - struct reservation_object *robj = bo->obj->resv; + struct reservation_object *robj = bo->obj->base.resv; if (!(bo->flags & ETNA_SUBMIT_BO_WRITE)) { ret = reservation_object_reserve_shared(robj, 1); @@ -207,13 +196,13 @@ static void submit_attach_object_fences(struct etnaviv_gem_submit *submit) int i; for (i = 0; i < submit->nr_bos; i++) { - struct etnaviv_gem_object *etnaviv_obj = submit->bos[i].obj; + struct drm_gem_object *obj = &submit->bos[i].obj->base; if (submit->bos[i].flags & ETNA_SUBMIT_BO_WRITE) - reservation_object_add_excl_fence(etnaviv_obj->resv, + reservation_object_add_excl_fence(obj->resv, submit->out_fence); else - reservation_object_add_shared_fence(etnaviv_obj->resv, + reservation_object_add_shared_fence(obj->resv, submit->out_fence); submit_unlock_object(submit, i); diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c index 6904535475de..5418a1a87b2c 100644 --- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.c +++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.c @@ -365,6 +365,7 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) dev_info(gpu->dev, "model: GC%x, revision: %x\n", gpu->identity.model, gpu->identity.revision); + gpu->idle_mask = ~VIVS_HI_IDLE_STATE_AXI_LP; /* * If there is a match in the HWDB, we aren't interested in the * remaining register values, as they might be wrong. @@ -412,7 +413,7 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) } /* GC600 idle register reports zero bits where modules aren't present */ - if (gpu->identity.model == chipModel_GC600) { + if (gpu->identity.model == chipModel_GC600) gpu->idle_mask = VIVS_HI_IDLE_STATE_TX | VIVS_HI_IDLE_STATE_RA | VIVS_HI_IDLE_STATE_SE | @@ -421,9 +422,6 @@ static void etnaviv_hw_identify(struct etnaviv_gpu *gpu) VIVS_HI_IDLE_STATE_PE | VIVS_HI_IDLE_STATE_DE | VIVS_HI_IDLE_STATE_FE; - } else { - gpu->idle_mask = ~VIVS_HI_IDLE_STATE_AXI_LP; - } etnaviv_hw_specs(gpu); } @@ -762,7 +760,7 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) if (IS_ERR(gpu->cmdbuf_suballoc)) { dev_err(gpu->dev, "Failed to create cmdbuf suballocator\n"); ret = PTR_ERR(gpu->cmdbuf_suballoc); - goto fail; + goto destroy_iommu; } /* Create buffer: */ @@ -770,7 +768,7 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) PAGE_SIZE); if (ret) { dev_err(gpu->dev, "could not create command buffer\n"); - goto destroy_iommu; + goto destroy_suballoc; } if (gpu->mmu->version == ETNAVIV_IOMMU_V1 && @@ -802,6 +800,9 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu) free_buffer: etnaviv_cmdbuf_free(&gpu->buffer); gpu->buffer.suballoc = NULL; +destroy_suballoc: + etnaviv_cmdbuf_suballoc_destroy(gpu->cmdbuf_suballoc); + gpu->cmdbuf_suballoc = NULL; destroy_iommu: etnaviv_iommu_destroy(gpu->mmu); gpu->mmu = NULL; |