Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'drm-etnaviv-next-2025-01-08' of https://git.pengutronix.de/git/lst/linux into drm-next

- cleanups
- add fdinfo memory support
- add explicit reset handling

Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Lucas Stach <l.stach@pengutronix.de>
Link: https://patchwork.freedesktop.org/patch/msgid/41c1e476c6014010247d164ac8d21bd6f922cce1.camel@pengutronix.de

+92 -22
+1 -2
drivers/gpu/drm/etnaviv/etnaviv_cmdbuf.c
··· 9 9 #include "etnaviv_gem.h" 10 10 #include "etnaviv_gpu.h" 11 11 #include "etnaviv_mmu.h" 12 - #include "etnaviv_perfmon.h" 13 12 14 13 #define SUBALLOC_SIZE SZ_512K 15 14 #define SUBALLOC_GRANULE SZ_4K ··· 99 100 mutex_unlock(&suballoc->lock); 100 101 ret = wait_event_interruptible_timeout(suballoc->free_event, 101 102 suballoc->free_space, 102 - msecs_to_jiffies(10 * 1000)); 103 + secs_to_jiffies(10)); 103 104 if (!ret) { 104 105 dev_err(suballoc->dev, 105 106 "Timeout waiting for cmdbuf space\n");
+11 -1
drivers/gpu/drm/etnaviv/etnaviv_drv.c
··· 488 488 ETNA_IOCTL(PM_QUERY_SIG, pm_query_sig, DRM_RENDER_ALLOW), 489 489 }; 490 490 491 - DEFINE_DRM_GEM_FOPS(fops); 491 + static void etnaviv_show_fdinfo(struct drm_printer *p, struct drm_file *file) 492 + { 493 + drm_show_memory_stats(p, file); 494 + } 495 + 496 + static const struct file_operations fops = { 497 + .owner = THIS_MODULE, 498 + DRM_GEM_FOPS, 499 + .show_fdinfo = drm_show_fdinfo, 500 + }; 492 501 493 502 static const struct drm_driver etnaviv_drm_driver = { 494 503 .driver_features = DRIVER_GEM | DRIVER_RENDER, ··· 507 498 #ifdef CONFIG_DEBUG_FS 508 499 .debugfs_init = etnaviv_debugfs_init, 509 500 #endif 501 + .show_fdinfo = etnaviv_show_fdinfo, 510 502 .ioctls = etnaviv_ioctls, 511 503 .num_ioctls = DRM_ETNAVIV_NUM_IOCTLS, 512 504 .fops = &fops,
+26 -2
drivers/gpu/drm/etnaviv/etnaviv_gem.c
··· 342 342 static void *etnaviv_gem_vmap_impl(struct etnaviv_gem_object *obj) 343 343 { 344 344 struct page **pages; 345 + pgprot_t prot; 345 346 346 347 lockdep_assert_held(&obj->lock); 347 348 ··· 350 349 if (IS_ERR(pages)) 351 350 return NULL; 352 351 353 - return vmap(pages, obj->base.size >> PAGE_SHIFT, 354 - VM_MAP, pgprot_writecombine(PAGE_KERNEL)); 352 + switch (obj->flags & ETNA_BO_CACHE_MASK) { 353 + case ETNA_BO_CACHED: 354 + prot = PAGE_KERNEL; 355 + break; 356 + case ETNA_BO_UNCACHED: 357 + prot = pgprot_noncached(PAGE_KERNEL); 358 + break; 359 + case ETNA_BO_WC: 360 + default: 361 + prot = pgprot_writecombine(PAGE_KERNEL); 362 + } 363 + 364 + return vmap(pages, obj->base.size >> PAGE_SHIFT, VM_MAP, prot); 355 365 } 356 366 357 367 static inline enum dma_data_direction etnaviv_op_to_dma_dir(u32 op) ··· 540 528 mutex_unlock(&priv->gem_lock); 541 529 } 542 530 531 + static enum drm_gem_object_status etnaviv_gem_status(struct drm_gem_object *obj) 532 + { 533 + struct etnaviv_gem_object *etnaviv_obj = to_etnaviv_bo(obj); 534 + enum drm_gem_object_status status = 0; 535 + 536 + if (etnaviv_obj->pages) 537 + status |= DRM_GEM_OBJECT_RESIDENT; 538 + 539 + return status; 540 + } 541 + 543 542 static const struct vm_operations_struct vm_ops = { 544 543 .fault = etnaviv_gem_fault, 545 544 .open = drm_gem_vm_open, ··· 564 541 .get_sg_table = etnaviv_gem_prime_get_sg_table, 565 542 .vmap = etnaviv_gem_prime_vmap, 566 543 .mmap = etnaviv_gem_mmap, 544 + .status = etnaviv_gem_status, 567 545 .vm_ops = &vm_ops, 568 546 }; 569 547
-2
drivers/gpu/drm/etnaviv/etnaviv_gem.h
··· 44 44 u32 flags; 45 45 46 46 struct list_head gem_node; 47 - struct etnaviv_gpu *gpu; /* non-null if active */ 48 47 atomic_t gpu_active; 49 - u32 access; 50 48 51 49 struct page **pages; 52 50 struct sg_table *sgt;
+41
drivers/gpu/drm/etnaviv/etnaviv_gpu.c
··· 13 13 #include <linux/platform_device.h> 14 14 #include <linux/pm_runtime.h> 15 15 #include <linux/regulator/consumer.h> 16 + #include <linux/reset.h> 16 17 #include <linux/thermal.h> 17 18 18 19 #include "etnaviv_cmdbuf.h" ··· 169 168 DBG("%s: invalid param: %u", dev_name(gpu->dev), param); 170 169 return -EINVAL; 171 170 } 171 + 172 + return 0; 173 + } 174 + 175 + static int etnaviv_gpu_reset_deassert(struct etnaviv_gpu *gpu) 176 + { 177 + int ret; 178 + 179 + /* 180 + * 32 core clock cycles (slowest clock) required before deassertion 181 + * 1 microsecond might match all implementations without computation 182 + */ 183 + usleep_range(1, 2); 184 + 185 + ret = reset_control_deassert(gpu->rst); 186 + if (ret) 187 + return ret; 188 + 189 + /* 190 + * 128 core clock cycles (slowest clock) required before any activity on AHB 191 + * 1 microsecond might match all implementations without computation 192 + */ 193 + usleep_range(1, 2); 172 194 173 195 return 0; 174 196 } ··· 821 797 if (ret < 0) { 822 798 dev_err(gpu->dev, "Failed to enable GPU power domain\n"); 823 799 goto pm_put; 800 + } 801 + 802 + ret = etnaviv_gpu_reset_deassert(gpu); 803 + if (ret) { 804 + dev_err(gpu->dev, "GPU reset deassert failed\n"); 805 + goto fail; 824 806 } 825 807 826 808 etnaviv_hw_identify(gpu); ··· 1889 1859 gpu->mmio = devm_platform_ioremap_resource(pdev, 0); 1890 1860 if (IS_ERR(gpu->mmio)) 1891 1861 return PTR_ERR(gpu->mmio); 1862 + 1863 + 1864 + /* Get Reset: */ 1865 + gpu->rst = devm_reset_control_get_optional_exclusive(&pdev->dev, NULL); 1866 + if (IS_ERR(gpu->rst)) 1867 + return dev_err_probe(dev, PTR_ERR(gpu->rst), 1868 + "failed to get reset\n"); 1869 + 1870 + err = reset_control_assert(gpu->rst); 1871 + if (err) 1872 + return dev_err_probe(dev, err, "failed to assert reset\n"); 1892 1873 1893 1874 /* Get Interrupt: */ 1894 1875 gpu->irq = platform_get_irq(pdev, 0);
+2
drivers/gpu/drm/etnaviv/etnaviv_gpu.h
··· 93 93 struct etnaviv_cmdbuf_suballoc; 94 94 struct regulator; 95 95 struct clk; 96 + struct reset_control; 96 97 97 98 #define ETNA_NR_EVENTS 30 98 99 ··· 159 158 struct clk *clk_reg; 160 159 struct clk *clk_core; 161 160 struct clk *clk_shader; 161 + struct reset_control *rst; 162 162 163 163 unsigned int freq_scale; 164 164 unsigned int fe_waitcycles;
+11 -15
drivers/gpu/drm/etnaviv/etnaviv_mmu.c
··· 19 19 size_t unmapped_page, unmapped = 0; 20 20 size_t pgsize = SZ_4K; 21 21 22 - if (!IS_ALIGNED(iova | size, pgsize)) { 23 - pr_err("unaligned: iova 0x%lx size 0x%zx min_pagesz 0x%zx\n", 24 - iova, size, pgsize); 25 - return; 26 - } 27 - 28 22 while (unmapped < size) { 29 23 unmapped_page = context->global->ops->unmap(context, iova, 30 24 pgsize); ··· 38 44 size_t pgsize = SZ_4K; 39 45 size_t orig_size = size; 40 46 int ret = 0; 41 - 42 - if (!IS_ALIGNED(iova | paddr | size, pgsize)) { 43 - pr_err("unaligned: iova 0x%lx pa %pa size 0x%zx min_pagesz 0x%zx\n", 44 - iova, &paddr, size, pgsize); 45 - return -EINVAL; 46 - } 47 47 48 48 while (size) { 49 49 ret = context->global->ops->map(context, iova, paddr, pgsize, ··· 70 82 return -EINVAL; 71 83 72 84 for_each_sgtable_dma_sg(sgt, sg, i) { 73 - phys_addr_t pa = sg_dma_address(sg) - sg->offset; 74 - unsigned int da_len = sg_dma_len(sg) + sg->offset; 85 + phys_addr_t pa = sg_dma_address(sg); 86 + unsigned int da_len = sg_dma_len(sg); 75 87 unsigned int bytes = min_t(unsigned int, da_len, va_len); 76 88 77 - VERB("map[%d]: %08x %pap(%x)", i, iova, &pa, bytes); 89 + VERB("map[%d]: %08x %pap(%x)", i, da, &pa, bytes); 90 + 91 + if (!IS_ALIGNED(iova | pa | bytes, SZ_4K)) { 92 + dev_err(context->global->dev, 93 + "unaligned: iova 0x%x pa %pa size 0x%x\n", 94 + iova, &pa, bytes); 95 + ret = -EINVAL; 96 + goto fail; 97 + } 78 98 79 99 ret = etnaviv_context_map(context, da, pa, bytes, prot); 80 100 if (ret)