mirror of
https://github.com/torvalds/linux.git
synced 2026-05-30 01:53:29 +02:00
- improve handling of DMA address limited systems
- improve GPU hangcheck - fix address space collision on >= 4K CPU pages - flush all known writeback caches before memory release - various code cleanups -----BEGIN PGP SIGNATURE----- iQFLBAABCAA1FiEEz9DmVLy+XdLQMNIiz8wpfG0KEgsFAmctKccXHGwuc3RhY2hA cGVuZ3V0cm9uaXguZGUACgkQz8wpfG0KEgs4nAf/Z0F6feOHGwE4g7j+Y1/0XwJH xJNzzrcZb3prObsPhDM9YUuDTn+x9O53Rj1HPT9DMtIDrmaAe14VwAG8STQ2Ryij bdg627RMv/uHc1bSiFRXsgR+sKHRPnAcyM00UTXHa0fXawTePJQTxFDlzqr6hX2O XSCsI1QFW05wjYVq7LXSxoac76gTH0Y5WVumWeBkWQUTM10RHxRnA32yykIC9MAT zPA1ZQ/eheZe8H9lq9fC6OomDxx7XdPQ8NR+AhNt74u+77vk3ZfVHRTXlJuwJB3d sBYWO7ChyBO/plTPjSKo3iOgaNkM2Si5gF1rX4pWnLsAFpIa2bjoQ7nqhqaIXw== =l4RX -----END PGP SIGNATURE----- Merge tag 'drm-etnaviv-next-2024-11-07' of https://git.pengutronix.de/git/lst/linux into drm-next - improve handling of DMA address limited systems - improve GPU hangcheck - fix address space collision on >= 4K CPU pages - flush all known writeback caches before memory release - various code cleanups Signed-off-by: Dave Airlie <airlied@redhat.com> From: Lucas Stach <l.stach@pengutronix.de> Link: https://patchwork.freedesktop.org/patch/msgid/c84075a0257e7bee222d008fa3118117422d664e.camel@pengutronix.de
This commit is contained in:
commit
35a6e15aab
|
|
@ -482,7 +482,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
|
|||
} else {
|
||||
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
|
||||
VIVS_GL_FLUSH_CACHE_DEPTH |
|
||||
VIVS_GL_FLUSH_CACHE_COLOR);
|
||||
VIVS_GL_FLUSH_CACHE_COLOR |
|
||||
VIVS_GL_FLUSH_CACHE_SHADER_L1);
|
||||
if (has_blt) {
|
||||
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
|
||||
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include <linux/dma-mapping.h>
|
||||
|
||||
#include <drm/drm_mm.h>
|
||||
|
||||
#include "etnaviv_cmdbuf.h"
|
||||
#include "etnaviv_gem.h"
|
||||
#include "etnaviv_gpu.h"
|
||||
|
|
@ -55,6 +53,7 @@ etnaviv_cmdbuf_suballoc_new(struct device *dev)
|
|||
return suballoc;
|
||||
|
||||
free_suballoc:
|
||||
mutex_destroy(&suballoc->lock);
|
||||
kfree(suballoc);
|
||||
|
||||
return ERR_PTR(ret);
|
||||
|
|
@ -79,6 +78,7 @@ void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc)
|
|||
{
|
||||
dma_free_wc(suballoc->dev, SUBALLOC_SIZE, suballoc->vaddr,
|
||||
suballoc->paddr);
|
||||
mutex_destroy(&suballoc->lock);
|
||||
kfree(suballoc);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -538,6 +538,16 @@ static int etnaviv_bind(struct device *dev)
|
|||
priv->num_gpus = 0;
|
||||
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
|
||||
|
||||
/*
|
||||
* If the GPU is part of a system with DMA addressing limitations,
|
||||
* request pages for our SHM backend buffers from the DMA32 zone to
|
||||
* hopefully avoid performance killing SWIOTLB bounce buffering.
|
||||
*/
|
||||
if (dma_addressing_limited(dev)) {
|
||||
priv->shm_gfp_mask |= GFP_DMA32;
|
||||
priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
|
||||
}
|
||||
|
||||
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
|
||||
if (IS_ERR(priv->cmdbuf_suballoc)) {
|
||||
dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
|
||||
|
|
@ -564,6 +574,7 @@ static int etnaviv_bind(struct device *dev)
|
|||
out_destroy_suballoc:
|
||||
etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
|
||||
out_free_priv:
|
||||
mutex_destroy(&priv->gem_lock);
|
||||
kfree(priv);
|
||||
out_put:
|
||||
drm_dev_put(drm);
|
||||
|
|
@ -608,7 +619,7 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
|
|||
if (!of_device_is_available(core_node))
|
||||
continue;
|
||||
|
||||
drm_of_component_match_add(&pdev->dev, &match,
|
||||
drm_of_component_match_add(dev, &match,
|
||||
component_compare_of, core_node);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -631,9 +642,9 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
|
|||
* bit to make sure we are allocating the command buffers and
|
||||
* TLBs in the lower 4 GiB address space.
|
||||
*/
|
||||
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)) ||
|
||||
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
|
||||
dev_dbg(&pdev->dev, "No suitable DMA available\n");
|
||||
if (dma_set_mask(dev, DMA_BIT_MASK(40)) ||
|
||||
dma_set_coherent_mask(dev, DMA_BIT_MASK(32))) {
|
||||
dev_dbg(dev, "No suitable DMA available\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
|
|
@ -644,7 +655,7 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
|
|||
*/
|
||||
first_node = etnaviv_of_first_available_node();
|
||||
if (first_node) {
|
||||
of_dma_configure(&pdev->dev, first_node, true);
|
||||
of_dma_configure(dev, first_node, true);
|
||||
of_node_put(first_node);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -514,6 +514,7 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj)
|
|||
etnaviv_obj->ops->release(etnaviv_obj);
|
||||
drm_gem_object_release(obj);
|
||||
|
||||
mutex_destroy(&etnaviv_obj->lock);
|
||||
kfree(etnaviv_obj);
|
||||
}
|
||||
|
||||
|
|
@ -543,7 +544,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = {
|
|||
.vm_ops = &vm_ops,
|
||||
};
|
||||
|
||||
static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags,
|
||||
static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
|
||||
const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj)
|
||||
{
|
||||
struct etnaviv_gem_object *etnaviv_obj;
|
||||
|
|
@ -570,6 +571,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags,
|
|||
if (!etnaviv_obj)
|
||||
return -ENOMEM;
|
||||
|
||||
etnaviv_obj->size = ALIGN(size, SZ_4K);
|
||||
etnaviv_obj->flags = flags;
|
||||
etnaviv_obj->ops = ops;
|
||||
|
||||
|
|
@ -590,15 +592,13 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
|
|||
struct drm_gem_object *obj = NULL;
|
||||
int ret;
|
||||
|
||||
size = PAGE_ALIGN(size);
|
||||
|
||||
ret = etnaviv_gem_new_impl(dev, flags, &etnaviv_gem_shmem_ops, &obj);
|
||||
ret = etnaviv_gem_new_impl(dev, size, flags, &etnaviv_gem_shmem_ops, &obj);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class);
|
||||
|
||||
ret = drm_gem_object_init(dev, obj, size);
|
||||
ret = drm_gem_object_init(dev, obj, PAGE_ALIGN(size));
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
|
|
@ -627,7 +627,7 @@ int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags,
|
|||
struct drm_gem_object *obj;
|
||||
int ret;
|
||||
|
||||
ret = etnaviv_gem_new_impl(dev, flags, ops, &obj);
|
||||
ret = etnaviv_gem_new_impl(dev, size, flags, ops, &obj);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
|
@ -686,7 +686,7 @@ static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj)
|
|||
kfree(etnaviv_obj->sgt);
|
||||
}
|
||||
if (etnaviv_obj->pages) {
|
||||
int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
|
||||
unsigned int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
|
||||
|
||||
unpin_user_pages(etnaviv_obj->pages, npages);
|
||||
kvfree(etnaviv_obj->pages);
|
||||
|
|
|
|||
|
|
@ -36,6 +36,11 @@ struct etnaviv_gem_object {
|
|||
const struct etnaviv_gem_ops *ops;
|
||||
struct mutex lock;
|
||||
|
||||
/*
|
||||
* The actual size that is visible to the GPU, not necessarily
|
||||
* PAGE_SIZE aligned, but should be aligned to GPU page size.
|
||||
*/
|
||||
u32 size;
|
||||
u32 flags;
|
||||
|
||||
struct list_head gem_node;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ static struct lock_class_key etnaviv_prime_lock_class;
|
|||
struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj)
|
||||
{
|
||||
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
|
||||
int npages = obj->size >> PAGE_SHIFT;
|
||||
unsigned int npages = obj->size >> PAGE_SHIFT;
|
||||
|
||||
if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@
|
|||
#include <drm/drm_file.h>
|
||||
#include <linux/dma-fence-array.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/dma-resv.h>
|
||||
#include <linux/sync_file.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
|
|
|||
|
|
@ -574,8 +574,8 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
|
|||
continue;
|
||||
}
|
||||
|
||||
/* disable debug registers, as they are not normally needed */
|
||||
control |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
|
||||
/* enable debug register access */
|
||||
control &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
|
||||
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
|
||||
|
||||
failed = false;
|
||||
|
|
@ -839,17 +839,8 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
|
|||
if (ret)
|
||||
goto fail;
|
||||
|
||||
/*
|
||||
* If the GPU is part of a system with DMA addressing limitations,
|
||||
* request pages for our SHM backend buffers from the DMA32 zone to
|
||||
* hopefully avoid performance killing SWIOTLB bounce buffering.
|
||||
*/
|
||||
if (dma_addressing_limited(gpu->dev))
|
||||
priv->shm_gfp_mask |= GFP_DMA32;
|
||||
|
||||
/* Create buffer: */
|
||||
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
|
||||
PAGE_SIZE);
|
||||
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer, SZ_4K);
|
||||
if (ret) {
|
||||
dev_err(gpu->dev, "could not create command buffer\n");
|
||||
goto fail;
|
||||
|
|
@ -1330,17 +1321,16 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
|
|||
{
|
||||
u32 val;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
/* disable clock gating */
|
||||
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
|
||||
/* enable debug register */
|
||||
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
|
||||
val &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
|
||||
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
|
||||
|
||||
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
|
||||
|
||||
mutex_unlock(&gpu->lock);
|
||||
}
|
||||
|
||||
static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
|
||||
|
|
@ -1350,23 +1340,22 @@ static void sync_point_perfmon_sample_post(struct etnaviv_gpu *gpu,
|
|||
unsigned int i;
|
||||
u32 val;
|
||||
|
||||
mutex_lock(&gpu->lock);
|
||||
|
||||
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
|
||||
|
||||
/* enable clock gating */
|
||||
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
|
||||
mutex_unlock(&gpu->lock);
|
||||
|
||||
for (i = 0; i < submit->nr_pmrs; i++) {
|
||||
const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
|
||||
|
||||
*pmr->bo_vma = pmr->sequence;
|
||||
}
|
||||
|
||||
/* disable debug register */
|
||||
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
|
||||
val |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
|
||||
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
|
||||
|
||||
/* enable clock gating */
|
||||
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
|
||||
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
|
||||
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1862,7 +1851,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
|
|||
if (!gpu)
|
||||
return -ENOMEM;
|
||||
|
||||
gpu->dev = &pdev->dev;
|
||||
gpu->dev = dev;
|
||||
mutex_init(&gpu->lock);
|
||||
mutex_init(&gpu->sched_lock);
|
||||
|
||||
|
|
@ -1876,8 +1865,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
|
|||
if (gpu->irq < 0)
|
||||
return gpu->irq;
|
||||
|
||||
err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
|
||||
dev_name(gpu->dev), gpu);
|
||||
err = devm_request_irq(dev, gpu->irq, irq_handler, 0,
|
||||
dev_name(dev), gpu);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err);
|
||||
return err;
|
||||
|
|
@ -1914,13 +1903,13 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
|
|||
* autosuspend delay is rather arbitary: no measurements have
|
||||
* yet been performed to determine an appropriate value.
|
||||
*/
|
||||
pm_runtime_use_autosuspend(gpu->dev);
|
||||
pm_runtime_set_autosuspend_delay(gpu->dev, 200);
|
||||
pm_runtime_enable(gpu->dev);
|
||||
pm_runtime_use_autosuspend(dev);
|
||||
pm_runtime_set_autosuspend_delay(dev, 200);
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
err = component_add(&pdev->dev, &gpu_ops);
|
||||
err = component_add(dev, &gpu_ops);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "failed to register component: %d\n", err);
|
||||
dev_err(dev, "failed to register component: %d\n", err);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
@ -1929,8 +1918,13 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
|
|||
|
||||
static void etnaviv_gpu_platform_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct etnaviv_gpu *gpu = dev_get_drvdata(&pdev->dev);
|
||||
|
||||
component_del(&pdev->dev, &gpu_ops);
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
mutex_destroy(&gpu->lock);
|
||||
mutex_destroy(&gpu->sched_lock);
|
||||
}
|
||||
|
||||
static int etnaviv_gpu_rpm_suspend(struct device *dev)
|
||||
|
|
|
|||
|
|
@ -144,6 +144,7 @@ struct etnaviv_gpu {
|
|||
|
||||
/* hang detection */
|
||||
u32 hangcheck_dma_addr;
|
||||
u32 hangcheck_primid;
|
||||
u32 hangcheck_fence;
|
||||
|
||||
void __iomem *mmio;
|
||||
|
|
|
|||
|
|
@ -69,9 +69,11 @@ static int etnaviv_context_map(struct etnaviv_iommu_context *context,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova,
|
||||
static int etnaviv_iommu_map(struct etnaviv_iommu_context *context,
|
||||
u32 iova, unsigned int va_len,
|
||||
struct sg_table *sgt, int prot)
|
||||
{ struct scatterlist *sg;
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
unsigned int da = iova;
|
||||
unsigned int i;
|
||||
int ret;
|
||||
|
|
@ -81,14 +83,16 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova,
|
|||
|
||||
for_each_sgtable_dma_sg(sgt, sg, i) {
|
||||
phys_addr_t pa = sg_dma_address(sg) - sg->offset;
|
||||
size_t bytes = sg_dma_len(sg) + sg->offset;
|
||||
unsigned int da_len = sg_dma_len(sg) + sg->offset;
|
||||
unsigned int bytes = min_t(unsigned int, da_len, va_len);
|
||||
|
||||
VERB("map[%d]: %08x %pap(%zx)", i, iova, &pa, bytes);
|
||||
VERB("map[%d]: %08x %pap(%x)", i, iova, &pa, bytes);
|
||||
|
||||
ret = etnaviv_context_map(context, da, pa, bytes, prot);
|
||||
if (ret)
|
||||
goto fail;
|
||||
|
||||
va_len -= bytes;
|
||||
da += bytes;
|
||||
}
|
||||
|
||||
|
|
@ -104,21 +108,7 @@ static int etnaviv_iommu_map(struct etnaviv_iommu_context *context, u32 iova,
|
|||
static void etnaviv_iommu_unmap(struct etnaviv_iommu_context *context, u32 iova,
|
||||
struct sg_table *sgt, unsigned len)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
unsigned int da = iova;
|
||||
int i;
|
||||
|
||||
for_each_sgtable_dma_sg(sgt, sg, i) {
|
||||
size_t bytes = sg_dma_len(sg) + sg->offset;
|
||||
|
||||
etnaviv_context_unmap(context, da, bytes);
|
||||
|
||||
VERB("unmap[%d]: %08x(%zx)", i, iova, bytes);
|
||||
|
||||
BUG_ON(!PAGE_ALIGNED(bytes));
|
||||
|
||||
da += bytes;
|
||||
}
|
||||
etnaviv_context_unmap(context, iova, len);
|
||||
|
||||
context->flush_seq++;
|
||||
}
|
||||
|
|
@ -131,7 +121,7 @@ static void etnaviv_iommu_remove_mapping(struct etnaviv_iommu_context *context,
|
|||
lockdep_assert_held(&context->lock);
|
||||
|
||||
etnaviv_iommu_unmap(context, mapping->vram_node.start,
|
||||
etnaviv_obj->sgt, etnaviv_obj->base.size);
|
||||
etnaviv_obj->sgt, etnaviv_obj->size);
|
||||
drm_mm_remove_node(&mapping->vram_node);
|
||||
}
|
||||
|
||||
|
|
@ -305,16 +295,14 @@ int etnaviv_iommu_map_gem(struct etnaviv_iommu_context *context,
|
|||
node = &mapping->vram_node;
|
||||
|
||||
if (va)
|
||||
ret = etnaviv_iommu_insert_exact(context, node,
|
||||
etnaviv_obj->base.size, va);
|
||||
ret = etnaviv_iommu_insert_exact(context, node, etnaviv_obj->size, va);
|
||||
else
|
||||
ret = etnaviv_iommu_find_iova(context, node,
|
||||
etnaviv_obj->base.size);
|
||||
ret = etnaviv_iommu_find_iova(context, node, etnaviv_obj->size);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
|
||||
mapping->iova = node->start;
|
||||
ret = etnaviv_iommu_map(context, node->start, sgt,
|
||||
ret = etnaviv_iommu_map(context, node->start, etnaviv_obj->size, sgt,
|
||||
ETNAVIV_PROT_READ | ETNAVIV_PROT_WRITE);
|
||||
|
||||
if (ret < 0) {
|
||||
|
|
@ -358,7 +346,7 @@ static void etnaviv_iommu_context_free(struct kref *kref)
|
|||
container_of(kref, struct etnaviv_iommu_context, refcount);
|
||||
|
||||
etnaviv_cmdbuf_suballoc_unmap(context, &context->cmdbuf_mapping);
|
||||
|
||||
mutex_destroy(&context->lock);
|
||||
context->global->ops->free(context);
|
||||
}
|
||||
void etnaviv_iommu_context_put(struct etnaviv_iommu_context *context)
|
||||
|
|
|
|||
|
|
@ -61,7 +61,6 @@ struct etnaviv_iommu_global {
|
|||
/* P(age) T(able) A(rray) */
|
||||
u64 *pta_cpu;
|
||||
dma_addr_t pta_dma;
|
||||
struct spinlock pta_lock;
|
||||
DECLARE_BITMAP(pta_alloc, ETNAVIV_PTA_ENTRIES);
|
||||
} v2;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -62,6 +62,8 @@ static u32 pipe_perf_reg_read(struct etnaviv_gpu *gpu,
|
|||
u32 value = 0;
|
||||
unsigned i;
|
||||
|
||||
lockdep_assert_held(&gpu->lock);
|
||||
|
||||
for (i = 0; i < gpu->identity.pixel_pipes; i++) {
|
||||
pipe_select(gpu, clock, i);
|
||||
value += perf_reg_read(gpu, domain, signal);
|
||||
|
|
@ -81,6 +83,8 @@ static u32 pipe_reg_read(struct etnaviv_gpu *gpu,
|
|||
u32 value = 0;
|
||||
unsigned i;
|
||||
|
||||
lockdep_assert_held(&gpu->lock);
|
||||
|
||||
for (i = 0; i < gpu->identity.pixel_pipes; i++) {
|
||||
pipe_select(gpu, clock, i);
|
||||
value += gpu_read(gpu, signal->data);
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
#include "etnaviv_gpu.h"
|
||||
#include "etnaviv_sched.h"
|
||||
#include "state.xml.h"
|
||||
#include "state_hi.xml.h"
|
||||
|
||||
static int etnaviv_job_hang_limit = 0;
|
||||
module_param_named(job_hang_limit, etnaviv_job_hang_limit, int , 0444);
|
||||
|
|
@ -35,7 +36,7 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
|
|||
{
|
||||
struct etnaviv_gem_submit *submit = to_etnaviv_submit(sched_job);
|
||||
struct etnaviv_gpu *gpu = submit->gpu;
|
||||
u32 dma_addr;
|
||||
u32 dma_addr, primid = 0;
|
||||
int change;
|
||||
|
||||
/*
|
||||
|
|
@ -52,10 +53,22 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job
|
|||
*/
|
||||
dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS);
|
||||
change = dma_addr - gpu->hangcheck_dma_addr;
|
||||
if (submit->exec_state == ETNA_PIPE_3D) {
|
||||
/* guard against concurrent usage from perfmon_sample */
|
||||
mutex_lock(&gpu->lock);
|
||||
gpu_write(gpu, VIVS_MC_PROFILE_CONFIG0,
|
||||
VIVS_MC_PROFILE_CONFIG0_FE_CURRENT_PRIM <<
|
||||
VIVS_MC_PROFILE_CONFIG0_FE__SHIFT);
|
||||
primid = gpu_read(gpu, VIVS_MC_PROFILE_FE_READ);
|
||||
mutex_unlock(&gpu->lock);
|
||||
}
|
||||
if (gpu->state == ETNA_GPU_STATE_RUNNING &&
|
||||
(gpu->completed_fence != gpu->hangcheck_fence ||
|
||||
change < 0 || change > 16)) {
|
||||
change < 0 || change > 16 ||
|
||||
(submit->exec_state == ETNA_PIPE_3D &&
|
||||
gpu->hangcheck_primid != primid))) {
|
||||
gpu->hangcheck_dma_addr = dma_addr;
|
||||
gpu->hangcheck_primid = primid;
|
||||
gpu->hangcheck_fence = gpu->completed_fence;
|
||||
goto out_no_timeout;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,17 +8,17 @@ This file was generated by the rules-ng-ng headergen tool in this git repository
|
|||
git clone git://0x04.net/rules-ng-ng
|
||||
|
||||
The rules-ng-ng source files this header was generated from are:
|
||||
- state.xml ( 29355 bytes, from 2024-01-19 10:18:54)
|
||||
- common.xml ( 35664 bytes, from 2023-12-06 10:55:32)
|
||||
- common_3d.xml ( 15069 bytes, from 2023-11-22 10:05:24)
|
||||
- state_hi.xml ( 35854 bytes, from 2023-12-11 15:50:17)
|
||||
- copyright.xml ( 1597 bytes, from 2016-11-10 13:58:32)
|
||||
- state_2d.xml ( 52271 bytes, from 2023-06-02 12:35:03)
|
||||
- state_3d.xml ( 89522 bytes, from 2024-01-19 10:18:54)
|
||||
- state_blt.xml ( 14592 bytes, from 2023-11-22 10:05:09)
|
||||
- state_vg.xml ( 5975 bytes, from 2016-11-10 13:58:32)
|
||||
- state.xml ( 30729 bytes, from 2024-06-21 11:31:54)
|
||||
- common.xml ( 35664 bytes, from 2023-12-13 09:33:18)
|
||||
- common_3d.xml ( 15069 bytes, from 2023-12-13 09:33:18)
|
||||
- state_hi.xml ( 35909 bytes, from 2024-06-21 11:31:54)
|
||||
- copyright.xml ( 1597 bytes, from 2020-10-28 12:56:03)
|
||||
- state_2d.xml ( 52271 bytes, from 2023-05-30 20:50:02)
|
||||
- state_3d.xml ( 89626 bytes, from 2024-06-21 11:32:57)
|
||||
- state_blt.xml ( 14592 bytes, from 2023-12-13 09:33:18)
|
||||
- state_vg.xml ( 5975 bytes, from 2020-10-28 12:56:03)
|
||||
|
||||
Copyright (C) 2012-2023 by the following authors:
|
||||
Copyright (C) 2012-2024 by the following authors:
|
||||
- Wladimir J. van der Laan <laanwj@gmail.com>
|
||||
- Christian Gmeiner <christian.gmeiner@gmail.com>
|
||||
- Lucas Stach <l.stach@pengutronix.de>
|
||||
|
|
@ -467,6 +467,7 @@ DEALINGS IN THE SOFTWARE.
|
|||
#define VIVS_MC_PROFILE_CONFIG0 0x00000470
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE__MASK 0x000000ff
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE__SHIFT 0
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE_CURRENT_PRIM 0x00000009
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE_DRAW_COUNT 0x0000000a
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE_OUT_VERTEX_COUNT 0x0000000b
|
||||
#define VIVS_MC_PROFILE_CONFIG0_FE_CACHE_MISS_COUNT 0x0000000c
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user