Skip to content

Commit 35a6e15

Browse files
committed
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
2 parents 1f8bdc3 + 2c7ac7d commit 35a6e15

14 files changed

+108
-92
lines changed

drivers/gpu/drm/etnaviv/etnaviv_buffer.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -482,7 +482,8 @@ void etnaviv_buffer_queue(struct etnaviv_gpu *gpu, u32 exec_state,
482482
} else {
483483
CMD_LOAD_STATE(buffer, VIVS_GL_FLUSH_CACHE,
484484
VIVS_GL_FLUSH_CACHE_DEPTH |
485-
VIVS_GL_FLUSH_CACHE_COLOR);
485+
VIVS_GL_FLUSH_CACHE_COLOR |
486+
VIVS_GL_FLUSH_CACHE_SHADER_L1);
486487
if (has_blt) {
487488
CMD_LOAD_STATE(buffer, VIVS_BLT_ENABLE, 0x1);
488489
CMD_LOAD_STATE(buffer, VIVS_BLT_SET_COMMAND, 0x1);

drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55

66
#include <linux/dma-mapping.h>
77

8-
#include <drm/drm_mm.h>
9-
108
#include "etnaviv_cmdbuf.h"
119
#include "etnaviv_gem.h"
1210
#include "etnaviv_gpu.h"
@@ -55,6 +53,7 @@ etnaviv_cmdbuf_suballoc_new(struct device *dev)
5553
return suballoc;
5654

5755
free_suballoc:
56+
mutex_destroy(&suballoc->lock);
5857
kfree(suballoc);
5958

6059
return ERR_PTR(ret);
@@ -79,6 +78,7 @@ void etnaviv_cmdbuf_suballoc_destroy(struct etnaviv_cmdbuf_suballoc *suballoc)
7978
{
8079
dma_free_wc(suballoc->dev, SUBALLOC_SIZE, suballoc->vaddr,
8180
suballoc->paddr);
81+
mutex_destroy(&suballoc->lock);
8282
kfree(suballoc);
8383
}
8484

drivers/gpu/drm/etnaviv/etnaviv_drv.c

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -538,6 +538,16 @@ static int etnaviv_bind(struct device *dev)
538538
priv->num_gpus = 0;
539539
priv->shm_gfp_mask = GFP_HIGHUSER | __GFP_RETRY_MAYFAIL | __GFP_NOWARN;
540540

541+
/*
542+
* If the GPU is part of a system with DMA addressing limitations,
543+
* request pages for our SHM backend buffers from the DMA32 zone to
544+
* hopefully avoid performance killing SWIOTLB bounce buffering.
545+
*/
546+
if (dma_addressing_limited(dev)) {
547+
priv->shm_gfp_mask |= GFP_DMA32;
548+
priv->shm_gfp_mask &= ~__GFP_HIGHMEM;
549+
}
550+
541551
priv->cmdbuf_suballoc = etnaviv_cmdbuf_suballoc_new(drm->dev);
542552
if (IS_ERR(priv->cmdbuf_suballoc)) {
543553
dev_err(drm->dev, "Failed to create cmdbuf suballocator\n");
@@ -564,6 +574,7 @@ static int etnaviv_bind(struct device *dev)
564574
out_destroy_suballoc:
565575
etnaviv_cmdbuf_suballoc_destroy(priv->cmdbuf_suballoc);
566576
out_free_priv:
577+
mutex_destroy(&priv->gem_lock);
567578
kfree(priv);
568579
out_put:
569580
drm_dev_put(drm);
@@ -608,7 +619,7 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
608619
if (!of_device_is_available(core_node))
609620
continue;
610621

611-
drm_of_component_match_add(&pdev->dev, &match,
622+
drm_of_component_match_add(dev, &match,
612623
component_compare_of, core_node);
613624
}
614625
} else {
@@ -631,9 +642,9 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
631642
* bit to make sure we are allocating the command buffers and
632643
* TLBs in the lower 4 GiB address space.
633644
*/
634-
if (dma_set_mask(&pdev->dev, DMA_BIT_MASK(40)) ||
635-
dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32))) {
636-
dev_dbg(&pdev->dev, "No suitable DMA available\n");
645+
if (dma_set_mask(dev, DMA_BIT_MASK(40)) ||
646+
dma_set_coherent_mask(dev, DMA_BIT_MASK(32))) {
647+
dev_dbg(dev, "No suitable DMA available\n");
637648
return -ENODEV;
638649
}
639650

@@ -644,7 +655,7 @@ static int etnaviv_pdev_probe(struct platform_device *pdev)
644655
*/
645656
first_node = etnaviv_of_first_available_node();
646657
if (first_node) {
647-
of_dma_configure(&pdev->dev, first_node, true);
658+
of_dma_configure(dev, first_node, true);
648659
of_node_put(first_node);
649660
}
650661

drivers/gpu/drm/etnaviv/etnaviv_gem.c

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -514,6 +514,7 @@ void etnaviv_gem_free_object(struct drm_gem_object *obj)
514514
etnaviv_obj->ops->release(etnaviv_obj);
515515
drm_gem_object_release(obj);
516516

517+
mutex_destroy(&etnaviv_obj->lock);
517518
kfree(etnaviv_obj);
518519
}
519520

@@ -543,7 +544,7 @@ static const struct drm_gem_object_funcs etnaviv_gem_object_funcs = {
543544
.vm_ops = &vm_ops,
544545
};
545546

546-
static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags,
547+
static int etnaviv_gem_new_impl(struct drm_device *dev, u32 size, u32 flags,
547548
const struct etnaviv_gem_ops *ops, struct drm_gem_object **obj)
548549
{
549550
struct etnaviv_gem_object *etnaviv_obj;
@@ -570,6 +571,7 @@ static int etnaviv_gem_new_impl(struct drm_device *dev, u32 flags,
570571
if (!etnaviv_obj)
571572
return -ENOMEM;
572573

574+
etnaviv_obj->size = ALIGN(size, SZ_4K);
573575
etnaviv_obj->flags = flags;
574576
etnaviv_obj->ops = ops;
575577

@@ -590,15 +592,13 @@ int etnaviv_gem_new_handle(struct drm_device *dev, struct drm_file *file,
590592
struct drm_gem_object *obj = NULL;
591593
int ret;
592594

593-
size = PAGE_ALIGN(size);
594-
595-
ret = etnaviv_gem_new_impl(dev, flags, &etnaviv_gem_shmem_ops, &obj);
595+
ret = etnaviv_gem_new_impl(dev, size, flags, &etnaviv_gem_shmem_ops, &obj);
596596
if (ret)
597597
goto fail;
598598

599599
lockdep_set_class(&to_etnaviv_bo(obj)->lock, &etnaviv_shm_lock_class);
600600

601-
ret = drm_gem_object_init(dev, obj, size);
601+
ret = drm_gem_object_init(dev, obj, PAGE_ALIGN(size));
602602
if (ret)
603603
goto fail;
604604

@@ -627,7 +627,7 @@ int etnaviv_gem_new_private(struct drm_device *dev, size_t size, u32 flags,
627627
struct drm_gem_object *obj;
628628
int ret;
629629

630-
ret = etnaviv_gem_new_impl(dev, flags, ops, &obj);
630+
ret = etnaviv_gem_new_impl(dev, size, flags, ops, &obj);
631631
if (ret)
632632
return ret;
633633

@@ -686,7 +686,7 @@ static void etnaviv_gem_userptr_release(struct etnaviv_gem_object *etnaviv_obj)
686686
kfree(etnaviv_obj->sgt);
687687
}
688688
if (etnaviv_obj->pages) {
689-
int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
689+
unsigned int npages = etnaviv_obj->base.size >> PAGE_SHIFT;
690690

691691
unpin_user_pages(etnaviv_obj->pages, npages);
692692
kvfree(etnaviv_obj->pages);

drivers/gpu/drm/etnaviv/etnaviv_gem.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ struct etnaviv_gem_object {
3636
const struct etnaviv_gem_ops *ops;
3737
struct mutex lock;
3838

39+
/*
40+
* The actual size that is visible to the GPU, not necessarily
41+
* PAGE_SIZE aligned, but should be aligned to GPU page size.
42+
*/
43+
u32 size;
3944
u32 flags;
4045

4146
struct list_head gem_node;

drivers/gpu/drm/etnaviv/etnaviv_gem_prime.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ static struct lock_class_key etnaviv_prime_lock_class;
1717
struct sg_table *etnaviv_gem_prime_get_sg_table(struct drm_gem_object *obj)
1818
{
1919
struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj);
20-
int npages = obj->size >> PAGE_SHIFT;
20+
unsigned int npages = obj->size >> PAGE_SHIFT;
2121

2222
if (WARN_ON(!etnaviv_obj->pages)) /* should have already pinned! */
2323
return ERR_PTR(-EINVAL);

drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
#include <drm/drm_file.h>
77
#include <linux/dma-fence-array.h>
88
#include <linux/file.h>
9-
#include <linux/pm_runtime.h>
109
#include <linux/dma-resv.h>
1110
#include <linux/sync_file.h>
1211
#include <linux/uaccess.h>

drivers/gpu/drm/etnaviv/etnaviv_gpu.c

Lines changed: 29 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,8 @@ static int etnaviv_hw_reset(struct etnaviv_gpu *gpu)
574574
continue;
575575
}
576576

577-
/* disable debug registers, as they are not normally needed */
578-
control |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
577+
/* enable debug register access */
578+
control &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
579579
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, control);
580580

581581
failed = false;
@@ -839,17 +839,8 @@ int etnaviv_gpu_init(struct etnaviv_gpu *gpu)
839839
if (ret)
840840
goto fail;
841841

842-
/*
843-
* If the GPU is part of a system with DMA addressing limitations,
844-
* request pages for our SHM backend buffers from the DMA32 zone to
845-
* hopefully avoid performance killing SWIOTLB bounce buffering.
846-
*/
847-
if (dma_addressing_limited(gpu->dev))
848-
priv->shm_gfp_mask |= GFP_DMA32;
849-
850842
/* Create buffer: */
851-
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer,
852-
PAGE_SIZE);
843+
ret = etnaviv_cmdbuf_init(priv->cmdbuf_suballoc, &gpu->buffer, SZ_4K);
853844
if (ret) {
854845
dev_err(gpu->dev, "could not create command buffer\n");
855846
goto fail;
@@ -1330,17 +1321,16 @@ static void sync_point_perfmon_sample_pre(struct etnaviv_gpu *gpu,
13301321
{
13311322
u32 val;
13321323

1324+
mutex_lock(&gpu->lock);
1325+
13331326
/* disable clock gating */
13341327
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
13351328
val &= ~VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
13361329
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
13371330

1338-
/* enable debug register */
1339-
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
1340-
val &= ~VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
1341-
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
1342-
13431331
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_PRE);
1332+
1333+
mutex_unlock(&gpu->lock);
13441334
}
13451335

13461336
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,
13501340
unsigned int i;
13511341
u32 val;
13521342

1343+
mutex_lock(&gpu->lock);
1344+
13531345
sync_point_perfmon_sample(gpu, event, ETNA_PM_PROCESS_POST);
13541346

1347+
/* enable clock gating */
1348+
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
1349+
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
1350+
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
1351+
1352+
mutex_unlock(&gpu->lock);
1353+
13551354
for (i = 0; i < submit->nr_pmrs; i++) {
13561355
const struct etnaviv_perfmon_request *pmr = submit->pmrs + i;
13571356

13581357
*pmr->bo_vma = pmr->sequence;
13591358
}
1360-
1361-
/* disable debug register */
1362-
val = gpu_read(gpu, VIVS_HI_CLOCK_CONTROL);
1363-
val |= VIVS_HI_CLOCK_CONTROL_DISABLE_DEBUG_REGISTERS;
1364-
gpu_write(gpu, VIVS_HI_CLOCK_CONTROL, val);
1365-
1366-
/* enable clock gating */
1367-
val = gpu_read_power(gpu, VIVS_PM_POWER_CONTROLS);
1368-
val |= VIVS_PM_POWER_CONTROLS_ENABLE_MODULE_CLOCK_GATING;
1369-
gpu_write_power(gpu, VIVS_PM_POWER_CONTROLS, val);
13701359
}
13711360

13721361

@@ -1862,7 +1851,7 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
18621851
if (!gpu)
18631852
return -ENOMEM;
18641853

1865-
gpu->dev = &pdev->dev;
1854+
gpu->dev = dev;
18661855
mutex_init(&gpu->lock);
18671856
mutex_init(&gpu->sched_lock);
18681857

@@ -1876,8 +1865,8 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
18761865
if (gpu->irq < 0)
18771866
return gpu->irq;
18781867

1879-
err = devm_request_irq(&pdev->dev, gpu->irq, irq_handler, 0,
1880-
dev_name(gpu->dev), gpu);
1868+
err = devm_request_irq(dev, gpu->irq, irq_handler, 0,
1869+
dev_name(dev), gpu);
18811870
if (err) {
18821871
dev_err(dev, "failed to request IRQ%u: %d\n", gpu->irq, err);
18831872
return err;
@@ -1914,13 +1903,13 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
19141903
* autosuspend delay is rather arbitary: no measurements have
19151904
* yet been performed to determine an appropriate value.
19161905
*/
1917-
pm_runtime_use_autosuspend(gpu->dev);
1918-
pm_runtime_set_autosuspend_delay(gpu->dev, 200);
1919-
pm_runtime_enable(gpu->dev);
1906+
pm_runtime_use_autosuspend(dev);
1907+
pm_runtime_set_autosuspend_delay(dev, 200);
1908+
pm_runtime_enable(dev);
19201909

1921-
err = component_add(&pdev->dev, &gpu_ops);
1910+
err = component_add(dev, &gpu_ops);
19221911
if (err < 0) {
1923-
dev_err(&pdev->dev, "failed to register component: %d\n", err);
1912+
dev_err(dev, "failed to register component: %d\n", err);
19241913
return err;
19251914
}
19261915

@@ -1929,8 +1918,13 @@ static int etnaviv_gpu_platform_probe(struct platform_device *pdev)
19291918

19301919
static void etnaviv_gpu_platform_remove(struct platform_device *pdev)
19311920
{
1921+
struct etnaviv_gpu *gpu = dev_get_drvdata(&pdev->dev);
1922+
19321923
component_del(&pdev->dev, &gpu_ops);
19331924
pm_runtime_disable(&pdev->dev);
1925+
1926+
mutex_destroy(&gpu->lock);
1927+
mutex_destroy(&gpu->sched_lock);
19341928
}
19351929

19361930
static int etnaviv_gpu_rpm_suspend(struct device *dev)

drivers/gpu/drm/etnaviv/etnaviv_gpu.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ struct etnaviv_gpu {
144144

145145
/* hang detection */
146146
u32 hangcheck_dma_addr;
147+
u32 hangcheck_primid;
147148
u32 hangcheck_fence;
148149

149150
void __iomem *mmio;

0 commit comments

Comments
 (0)