History

Merge tag 'drm-misc-next-2025-12-12' of https://gitlab.freedesktop.org/drm/misc/kernel into drm-next

drm-misc-next for 6.19: UAPI Changes: - panfrost: Add PANFROST_BO_SYNC ioctl - panthor: Add PANTHOR_BO_SYNC ioctl Core Changes: - atomic: Add drm_device pointer to drm_private_obj - bridge: Introduce drm_bridge_unplug, drm_bridge_enter, and drm_bridge_exit - dma-buf: Improve sg_table debugging - dma-fence: Add new helpers, and use them when needed - dp_mst: Avoid out-of-bounds access with VCPI==0 - gem: Reduce page table overhead with transparent huge pages - panic: Report invalid panic modes - sched: Add TODO entries - ttm: Various cleanups - vblank: Various refactoring and cleanups - Kconfig cleanups - Removed support for kdb Driver Changes: - amdxdna: Fix race conditions at suspend, Improve handling of zero tail pointers, Fix cu_idx being overwritten during command setup - ast: Support imported cursor buffers - - panthor: Enable timestamp propagation, Multiple improvements and fixes to improve the overall robustness, notably of the scheduler. - panels: - panel-edp: Support for CSW MNE007QB3-1, AUO B140HAN06.4, AUO B140QAX01.H Signed-off-by: Dave Airlie <airlied@redhat.com> [airlied: fix mm conflict] From: Maxime Ripard <mripard@redhat.com> Link: https://patch.msgid.link/20251212-spectacular-agama-of-abracadabra-aaef32@penduick

Dave Airlie committed 10 months ago

Commit 6c8e4042 parents 9448598 470cb09103 files · +2537 −1482Browse files

Unified · Split

103 files
  1. Documentation/gpu/drm-mm.rst +23 −6
  2. Documentation/gpu/todo.rst +45 −0
  3. Documentation/process/debugging/kgdb.rst +0 −28
  4. drivers/accel/amdxdna/aie2_message.c +12 −6
  5. drivers/accel/amdxdna/aie2_pci.c +1 −1
  6. drivers/accel/amdxdna/aie2_pci.h +3 −0
  7. drivers/accel/amdxdna/aie2_pm.c +16 −1
  8. drivers/accel/amdxdna/aie2_psp.c +15 −0
  9. drivers/accel/amdxdna/aie2_smu.c +4 −23
  10. drivers/accel/amdxdna/amdxdna_mailbox.c +1 −18
  11. drivers/accel/amdxdna/amdxdna_pci_drv.h +0 −1
  12. drivers/accel/amdxdna/amdxdna_pm.c +2 −20
  13. drivers/accel/amdxdna/npu1_regs.c +2 −0
  14. drivers/accel/amdxdna/npu2_regs.c +2 −0
  15. drivers/accel/amdxdna/npu4_regs.c +2 −0
  16. drivers/accel/amdxdna/npu5_regs.c +2 −0
  17. drivers/accel/amdxdna/npu6_regs.c +2 −0
  18. drivers/dma-buf/Kconfig +1 −1
  19. drivers/dma-buf/dma-buf.c +62 −17
  20. drivers/dma-buf/dma-fence.c +62 −38
  21. drivers/dma-buf/st-dma-fence.c +2 −2
  22. drivers/gpu/drm/Kconfig +59 −140
  23. drivers/gpu/drm/amd/amdgpu/dce_v10_0.c +11 −24
  24. drivers/gpu/drm/amd/amdgpu/dce_v6_0.c +11 −24
  25. drivers/gpu/drm/amd/amdgpu/dce_v8_0.c +11 −24
  26. drivers/gpu/drm/amd/amdkfd/kfd_process.c +3 −3
  27. drivers/gpu/drm/ast/ast_cursor.c +62 −21
  28. drivers/gpu/drm/bridge/ti-sn65dsi83.c +66 −20
  29. drivers/gpu/drm/display/drm_dp_mst_topology.c +2 −1
  30. drivers/gpu/drm/drm_atomic.c +1 −0
  31. drivers/gpu/drm/drm_bridge.c +62 −0
  32. drivers/gpu/drm/drm_fb_helper.c +0 −108
  33. drivers/gpu/drm/drm_gem.c +155 −49
  34. drivers/gpu/drm/drm_gem_shmem_helper.c +41 −36
  35. drivers/gpu/drm/drm_panic.c +62 −13
  36. drivers/gpu/drm/drm_plane.c +2 −2
  37. drivers/gpu/drm/drm_vblank.c +21 −31
  38. drivers/gpu/drm/hyperv/Kconfig +14 −0
  39. drivers/gpu/drm/i915/Makefile +1 −2
  40. drivers/gpu/drm/i915/gem/i915_gem_object_types.h +6 −4
  41. drivers/gpu/drm/i915/gem/i915_gem_shmem.c +41 −17
  42. drivers/gpu/drm/i915/gem/i915_gemfs.c +0 −71
  43. drivers/gpu/drm/i915/gem/i915_gemfs.h +0 −14
  44. drivers/gpu/drm/i915/gem/selftests/huge_pages.c +3 −12
  45. drivers/gpu/drm/i915/i915_drv.h +0 −5
  46. drivers/gpu/drm/nouveau/dispnv04/crtc.c +4 −20
  47. drivers/gpu/drm/panel/panel-edp.c +3 −0
  48. drivers/gpu/drm/panfrost/panfrost_device.c +3 −0
  49. drivers/gpu/drm/panfrost/panfrost_device.h +1 −0
  50. drivers/gpu/drm/panfrost/panfrost_drv.c +104 −3
  51. drivers/gpu/drm/panfrost/panfrost_drv.h +9 −0
  52. drivers/gpu/drm/panfrost/panfrost_gem.c +257 −0
  53. drivers/gpu/drm/panfrost/panfrost_gem.h +12 −0
  54. drivers/gpu/drm/panfrost/panfrost_gpu.c +23 −3
  55. drivers/gpu/drm/panfrost/panfrost_regs.h +8 −2
  56. drivers/gpu/drm/panthor/panthor_device.c +12 −1
  57. drivers/gpu/drm/panthor/panthor_drv.c +84 −3
  58. drivers/gpu/drm/panthor/panthor_drv.h +9 −0
  59. drivers/gpu/drm/panthor/panthor_fw.c +2 −2
  60. drivers/gpu/drm/panthor/panthor_gem.c +255 −3
  61. drivers/gpu/drm/panthor/panthor_gem.h +8 −0
  62. drivers/gpu/drm/panthor/panthor_gpu.c +13 −8
  63. drivers/gpu/drm/panthor/panthor_mmu.c +183 −131
  64. drivers/gpu/drm/panthor/panthor_sched.c +129 −121
  65. drivers/gpu/drm/pl111/pl111_display.c +2 −2
  66. drivers/gpu/drm/pl111/pl111_drv.c +15 −14
  67. drivers/gpu/drm/pl111/pl111_nomadik.c +2 −2
  68. drivers/gpu/drm/pl111/pl111_nomadik.h +2 −2
  69. drivers/gpu/drm/pl111/pl111_versatile.c +27 −26
  70. drivers/gpu/drm/pl111/pl111_versatile.h +1 −1
  71. drivers/gpu/drm/radeon/atombios_crtc.c +19 −55
  72. drivers/gpu/drm/radeon/radeon_legacy_crtc.c +6 −17
  73. drivers/gpu/drm/radeon/radeon_mode.h +1 −9
  74. drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c +1 −1
  75. drivers/gpu/drm/ttm/ttm_bo.c +33 −31
  76. drivers/gpu/drm/ttm/ttm_bo_util.c +25 −32
  77. drivers/gpu/drm/ttm/ttm_bo_vm.c +5 −7
  78. drivers/gpu/drm/ttm/ttm_device.c +1 −4
  79. drivers/gpu/drm/ttm/ttm_pool.c +14 −12
  80. drivers/gpu/drm/ttm/ttm_resource.c +4 −10
  81. drivers/gpu/drm/ttm/ttm_tt.c +1 −1
  82. drivers/gpu/drm/v3d/Makefile +1 −2
  83. drivers/gpu/drm/v3d/v3d_bo.c +2 −4
  84. drivers/gpu/drm/v3d/v3d_drv.c +1 −1
  85. drivers/gpu/drm/v3d/v3d_drv.h +1 −10
  86. drivers/gpu/drm/v3d/v3d_gem.c +19 −2
  87. drivers/gpu/drm/v3d/v3d_gemfs.c +0 −62
  88. drivers/gpu/drm/vgem/Kconfig +9 −0
  89. drivers/gpu/drm/xe/xe_hw_fence.c +1 −3
  90. drivers/video/fbdev/core/fbcon.c +0 −24
  91. drivers/video/fbdev/core/fbcon.h +0 −1
  92. include/drm/drm_atomic.h +5 −0
  93. include/drm/drm_bridge.h +12 −0
  94. include/drm/drm_device.h +15 −0
  95. include/drm/drm_fb_helper.h +0 −21
  96. include/drm/drm_gem.h +42 −3
  97. include/drm/drm_gem_shmem_helper.h +0 −3
  98. include/drm/drm_modeset_helper_vtables.h +0 −23
  99. include/drm/drm_vblank.h +1 −2
  100. include/linux/dma-fence.h +28 −7
  101. include/linux/fb.h +0 −4
  102. include/uapi/drm/panfrost_drm.h +75 −1
  103. include/uapi/drm/panthor_drm.h +154 −3
Documentation/gpu/drm-mm.rst+23−6
@@ -155,7 +155,12 @@ drm_gem_object_init() will create an shmfs file of the · 154 unmodified lines
155155 requested size and store it into the struct :c:type:`struct
156156 drm_gem_object <drm_gem_object>` filp field. The memory is
157157 used as either main storage for the object when the graphics hardware
158−uses system memory directly or as a backing store otherwise.
158+uses system memory directly or as a backing store otherwise. Drivers
159+can call drm_gem_huge_mnt_create() to create, mount and use a huge
160+shmem mountpoint instead of the default one ('shm_mnt'). For builds
161+with CONFIG_TRANSPARENT_HUGEPAGE enabled, further calls to
162+drm_gem_object_init() will let shmem allocate huge pages when
163+possible.
159164
160165 Drivers are responsible for the actual physical pages allocation by
161166 calling shmem_read_mapping_page_gfp() for each page.
@@ -290,15 +295,27 @@ The open and close operations must update the GEM object reference · 128 unmodified lines
290295 count. Drivers can use the drm_gem_vm_open() and drm_gem_vm_close() helper
291296 functions directly as open and close handlers.
292297
293−The fault operation handler is responsible for mapping individual pages
294−to userspace when a page fault occurs. Depending on the memory
295−allocation scheme, drivers can allocate pages at fault time, or can
296−decide to allocate memory for the GEM object at the time the object is
297−created.
298+The fault operation handler is responsible for mapping pages to
299+userspace when a page fault occurs. Depending on the memory allocation
300+scheme, drivers can allocate pages at fault time, or can decide to
301+allocate memory for the GEM object at the time the object is created.
298302
299303 Drivers that want to map the GEM object upfront instead of handling page
300304 faults can implement their own mmap file operation handler.
301305
306+In order to reduce page table overhead, if the internal shmem mountpoint
307+"shm_mnt" is configured to use transparent huge pages (for builds with
308+CONFIG_TRANSPARENT_HUGEPAGE enabled) and if the shmem backing store
309+managed to allocate a huge page for a faulty address, the fault handler
310+will first attempt to insert that huge page into the VMA before falling
311+back to individual page insertion. mmap() user address alignment for GEM
312+objects is handled by providing a custom get_unmapped_area file
313+operation which forwards to the shmem backing store. For most drivers,
314+which don't create a huge mountpoint by default or through a module
315+parameter, transparent huge pages can be enabled by either setting the
316+"transparent_hugepage_shmem" kernel parameter or the
317+"/sys/kernel/mm/transparent_hugepage/shmem_enabled" sysfs knob.
318+
302319 For platforms without MMU the GEM core provides a helper method
303320 drm_gem_dma_get_unmapped_area(). The mmap() routines will call this to get a
304321 proposed address for the mapping.
Documentation/gpu/todo.rst+45−0
@@ -878,6 +878,51 @@ Contact: Christian König · 877 unmodified lines
878878
879879 Level: Starter
880880
881+DRM GPU Scheduler
882+=================
883+
884+Provide a universal successor for drm_sched_resubmit_jobs()
885+-----------------------------------------------------------
886+
887+drm_sched_resubmit_jobs() is deprecated. Main reason being that it leads to
888+reinitializing dma_fences. See that function's docu for details. The better
889+approach for valid resubmissions by amdgpu and Xe is (apparently) to figure out
890+which job (and, through association: which entity) caused the hang. Then, the
891+job's buffer data, together with all other jobs' buffer data currently in the
892+same hardware ring, must be invalidated. This can for example be done by
893+overwriting it. amdgpu currently determines which jobs are in the ring and need
894+to be overwritten by keeping copies of the job. Xe obtains that information by
895+directly accessing drm_sched's pending_list.
896+
897+Tasks:
898+
899+1. implement scheduler functionality through which the driver can obtain the
900+ information which *broken* jobs are currently in the hardware ring.
901+2. Such infrastructure would then typically be used in
902+ drm_sched_backend_ops.timedout_job(). Document that.
903+3. Port a driver as first user.
904+4. Document the new alternative in the docu of deprecated
905+ drm_sched_resubmit_jobs().
906+
907+Contact: Christian König <christian.koenig@amd.com>
908+ Philipp Stanner <phasta@kernel.org>
909+
910+Level: Advanced
911+
912+Add locking for runqueues
913+-------------------------
914+
915+There is an old FIXME by Sima in include/drm/gpu_scheduler.h. It details that
916+struct drm_sched_rq is read at many places without any locks, not even with a
917+READ_ONCE. At XDC 2025 no one could really tell why that is the case, whether
918+locks are needed and whether they could be added. (But for real, that should
919+probably be locked!). Check whether it's possible to add locks everywhere, and
920+do so if yes.
921+
922+Contact: Philipp Stanner <phasta@kernel.org>
923+
924+Level: Intermediate
925+
881926 Outside DRM
882927 ===========
883928
Documentation/process/debugging/kgdb.rst+0−28
@@ -889,34 +889,6 @@ in the virtual console layer. On resuming kernel execution, the kernel · 888 unmodified lines
889889 debugger calls kgdboc_post_exp_handler() which in turn calls
890890 con_debug_leave().
891891
892−Any video driver that wants to be compatible with the kernel debugger
893−and the atomic kms callbacks must implement the ``mode_set_base_atomic``,
894−``fb_debug_enter`` and ``fb_debug_leave operations``. For the
895−``fb_debug_enter`` and ``fb_debug_leave`` the option exists to use the
896−generic drm fb helper functions or implement something custom for the
897−hardware. The following example shows the initialization of the
898−.mode_set_base_atomic operation in
899−drivers/gpu/drm/i915/intel_display.c::
900−
901−
902− static const struct drm_crtc_helper_funcs intel_helper_funcs = {
903− [...]
904− .mode_set_base_atomic = intel_pipe_set_base_atomic,
905− [...]
906− };
907−
908−
909−Here is an example of how the i915 driver initializes the
910−fb_debug_enter and fb_debug_leave functions to use the generic drm
911−helpers in ``drivers/gpu/drm/i915/intel_fb.c``::
912−
913−
914− static struct fb_ops intelfb_ops = {
915− [...]
916− .fb_debug_enter = drm_fb_helper_debug_enter,
917− .fb_debug_leave = drm_fb_helper_debug_leave,
918− [...]
919− };
920892
921893
922894 Credits
drivers/accel/amdxdna/aie2_message.c+12−6
@@ -39,7 +39,6 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, · 38 unmodified lines
3939 if (!ndev->mgmt_chann)
4040 return -ENODEV;
4141
42− drm_WARN_ON(&xdna->ddev, xdna->rpm_on && !mutex_is_locked(&xdna->dev_lock));
4342 ret = xdna_send_msg_wait(xdna, ndev->mgmt_chann, msg);
4443 if (ret == -ETIME) {
4544 xdna_mailbox_stop_channel(ndev->mgmt_chann);
@@ -59,8 +58,15 @@ static int aie2_send_mgmt_msg_wait(struct amdxdna_dev_hdl *ndev, · 13 unmodified lines
5958 int aie2_suspend_fw(struct amdxdna_dev_hdl *ndev)
6059 {
6160 DECLARE_AIE2_MSG(suspend, MSG_OP_SUSPEND);
61+ int ret;
6262
63− return aie2_send_mgmt_msg_wait(ndev, &msg);
63+ ret = aie2_send_mgmt_msg_wait(ndev, &msg);
64+ if (ret) {
65+ XDNA_ERR(ndev->xdna, "Failed to suspend fw, ret %d", ret);
66+ return ret;
67+ }
68+
69+ return aie2_psp_waitmode_poll(ndev->psp_hdl);
6470 }
6571
6672 int aie2_resume_fw(struct amdxdna_dev_hdl *ndev)
@@ -646,6 +652,7 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz · 579 unmodified lines
646652 u32 cmd_len;
647653 void *cmd;
648654
655+ memset(npu_slot, 0, sizeof(*npu_slot));
649656 cmd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
650657 if (*size < sizeof(*npu_slot) + cmd_len)
651658 return -EINVAL;
@@ -654,7 +661,6 @@ aie2_cmdlist_fill_npu_cf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *siz · 2 unmodified lines
654661 if (npu_slot->cu_idx == INVALID_CU_IDX)
655662 return -EINVAL;
656663
657− memset(npu_slot, 0, sizeof(*npu_slot));
658664 npu_slot->type = EXEC_NPU_TYPE_NON_ELF;
659665 npu_slot->arg_cnt = cmd_len / sizeof(u32);
660666 memcpy(npu_slot->args, cmd, cmd_len);
@@ -671,6 +677,7 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si · 10 unmodified lines
671677 u32 cmd_len;
672678 u32 arg_sz;
673679
680+ memset(npu_slot, 0, sizeof(*npu_slot));
674681 sn = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
675682 arg_sz = cmd_len - sizeof(*sn);
676683 if (cmd_len < sizeof(*sn) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -683,7 +690,6 @@ aie2_cmdlist_fill_npu_dpu(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si · 6 unmodified lines
683690 if (npu_slot->cu_idx == INVALID_CU_IDX)
684691 return -EINVAL;
685692
686− memset(npu_slot, 0, sizeof(*npu_slot));
687693 npu_slot->type = EXEC_NPU_TYPE_PARTIAL_ELF;
688694 npu_slot->inst_buf_addr = sn->buffer;
689695 npu_slot->inst_size = sn->buffer_size;
@@ -703,6 +709,7 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t · 13 unmodified lines
703709 u32 cmd_len;
704710 u32 arg_sz;
705711
712+ memset(npu_slot, 0, sizeof(*npu_slot));
706713 pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
707714 arg_sz = cmd_len - sizeof(*pd);
708715 if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -715,7 +722,6 @@ aie2_cmdlist_fill_npu_preempt(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t · 6 unmodified lines
715722 if (npu_slot->cu_idx == INVALID_CU_IDX)
716723 return -EINVAL;
717724
718− memset(npu_slot, 0, sizeof(*npu_slot));
719725 npu_slot->type = EXEC_NPU_TYPE_PREEMPT;
720726 npu_slot->inst_buf_addr = pd->inst_buf;
721727 npu_slot->save_buf_addr = pd->save_buf;
@@ -739,6 +745,7 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si · 17 unmodified lines
739745 u32 cmd_len;
740746 u32 arg_sz;
741747
748+ memset(npu_slot, 0, sizeof(*npu_slot));
742749 pd = amdxdna_cmd_get_payload(cmd_bo, &cmd_len);
743750 arg_sz = cmd_len - sizeof(*pd);
744751 if (cmd_len < sizeof(*pd) || arg_sz > MAX_NPU_ARGS_SIZE)
@@ -747,7 +754,6 @@ aie2_cmdlist_fill_npu_elf(struct amdxdna_gem_obj *cmd_bo, void *slot, size_t *si · 2 unmodified lines
747754 if (*size < sizeof(*npu_slot) + arg_sz)
748755 return -EINVAL;
749756
750− memset(npu_slot, 0, sizeof(*npu_slot));
751757 npu_slot->type = EXEC_NPU_TYPE_ELF;
752758 npu_slot->inst_buf_addr = pd->inst_buf;
753759 npu_slot->save_buf_addr = pd->save_buf;
drivers/accel/amdxdna/aie2_pci.c+1−1
@@ -322,7 +322,7 @@ static int aie2_xrs_set_dft_dpm_level(struct drm_device *ddev, u32 dpm_level) · 321 unmodified lines
322322 if (ndev->pw_mode != POWER_MODE_DEFAULT || ndev->dpm_level == dpm_level)
323323 return 0;
324324
325− return ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
325+ return aie2_pm_set_dpm(ndev, dpm_level);
326326 }
327327
328328 static struct xrs_action_ops aie2_xrs_actions = {
drivers/accel/amdxdna/aie2_pci.h+3−0
@@ -70,6 +70,7 @@ enum psp_reg_idx { · 69 unmodified lines
7070 PSP_INTR_REG = PSP_NUM_IN_REGS,
7171 PSP_STATUS_REG,
7272 PSP_RESP_REG,
73+ PSP_PWAITMODE_REG,
7374 PSP_MAX_REGS /* Keep this at the end */
7475 };
7576
@@ -285,11 +286,13 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level); · 209 unmodified lines
285286 /* aie2_pm.c */
286287 int aie2_pm_init(struct amdxdna_dev_hdl *ndev);
287288 int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type target);
289+int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level);
288290
289291 /* aie2_psp.c */
290292 struct psp_device *aie2m_psp_create(struct drm_device *ddev, struct psp_config *conf);
291293 int aie2_psp_start(struct psp_device *psp);
292294 void aie2_psp_stop(struct psp_device *psp);
295+int aie2_psp_waitmode_poll(struct psp_device *psp);
293296
294297 /* aie2_error.c */
295298 int aie2_error_async_events_alloc(struct amdxdna_dev_hdl *ndev);
drivers/accel/amdxdna/aie2_pm.c+16−1
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010
1111 #include "aie2_pci.h"
1212 #include "amdxdna_pci_drv.h"
13+#include "amdxdna_pm.h"
1314
1415 #define AIE2_CLK_GATING_ENABLE 1
1516 #define AIE2_CLK_GATING_DISABLE 0
@@ -26,6 +27,20 @@ static int aie2_pm_set_clk_gating(struct amdxdna_dev_hdl *ndev, u32 val) · 10 unmodified lines
2627 return 0;
2728 }
2829
30+int aie2_pm_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
31+{
32+ int ret;
33+
34+ ret = amdxdna_pm_resume_get(ndev->xdna);
35+ if (ret)
36+ return ret;
37+
38+ ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
39+ amdxdna_pm_suspend_put(ndev->xdna);
40+
41+ return ret;
42+}
43+
2944 int aie2_pm_init(struct amdxdna_dev_hdl *ndev)
3045 {
3146 int ret;
@@ -94,7 +109,7 @@ int aie2_pm_set_mode(struct amdxdna_dev_hdl *ndev, enum amdxdna_power_mode_type · 62 unmodified lines
94109 return -EOPNOTSUPP;
95110 }
96111
97− ret = ndev->priv->hw_ops.set_dpm(ndev, dpm_level);
112+ ret = aie2_pm_set_dpm(ndev, dpm_level);
98113 if (ret)
99114 return ret;
100115
drivers/accel/amdxdna/aie2_psp.c+15−0
@@ -76,6 +76,21 @@ static int psp_exec(struct psp_device *psp, u32 *reg_vals) · 75 unmodified lines
7676 return 0;
7777 }
7878
79+int aie2_psp_waitmode_poll(struct psp_device *psp)
80+{
81+ struct amdxdna_dev *xdna = to_xdna_dev(psp->ddev);
82+ u32 mode_reg;
83+ int ret;
84+
85+ ret = readx_poll_timeout(readl, PSP_REG(psp, PSP_PWAITMODE_REG), mode_reg,
86+ (mode_reg & 0x1) == 1,
87+ PSP_POLL_INTERVAL, PSP_POLL_TIMEOUT);
88+ if (ret)
89+ XDNA_ERR(xdna, "fw waitmode reg error, ret %d", ret);
90+
91+ return ret;
92+}
93+
7994 void aie2_psp_stop(struct psp_device *psp)
8095 {
8196 u32 reg_vals[PSP_NUM_IN_REGS] = { PSP_RELEASE_TMR, };
drivers/accel/amdxdna/aie2_smu.c+4−23
@@ -11,7 +11,6 @@ · 10 unmodified lines
1111
1212 #include "aie2_pci.h"
1313 #include "amdxdna_pci_drv.h"
14−#include "amdxdna_pm.h"
1514
1615 #define SMU_RESULT_OK 1
1716
@@ -67,16 +66,12 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) · 49 unmodified lines
6766 u32 freq;
6867 int ret;
6968
70− ret = amdxdna_pm_resume_get(ndev->xdna);
71− if (ret)
72− return ret;
73−
7469 ret = aie2_smu_exec(ndev, AIE2_SMU_SET_MPNPUCLK_FREQ,
7570 ndev->priv->dpm_clk_tbl[dpm_level].npuclk, &freq);
7671 if (ret) {
7772 XDNA_ERR(ndev->xdna, "Set npu clock to %d failed, ret %d\n",
7873 ndev->priv->dpm_clk_tbl[dpm_level].npuclk, ret);
79− goto suspend_put;
74+ return ret;
8075 }
8176 ndev->npuclk_freq = freq;
8277
@@ -85,10 +80,9 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) · 2 unmodified lines
8580 if (ret) {
8681 XDNA_ERR(ndev->xdna, "Set h clock to %d failed, ret %d\n",
8782 ndev->priv->dpm_clk_tbl[dpm_level].hclk, ret);
88− goto suspend_put;
83+ return ret;
8984 }
9085
91− amdxdna_pm_suspend_put(ndev->xdna);
9286 ndev->hclk_freq = freq;
9387 ndev->dpm_level = dpm_level;
9488 ndev->max_tops = 2 * ndev->total_col;
@@ -98,35 +92,26 @@ int npu1_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) · 3 unmodified lines
9892 ndev->npuclk_freq, ndev->hclk_freq);
9993
10094 return 0;
101−
102−suspend_put:
103− amdxdna_pm_suspend_put(ndev->xdna);
104− return ret;
10595 }
10696
10797 int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level)
10898 {
10999 int ret;
110100
111− ret = amdxdna_pm_resume_get(ndev->xdna);
112− if (ret)
113− return ret;
114−
115101 ret = aie2_smu_exec(ndev, AIE2_SMU_SET_HARD_DPMLEVEL, dpm_level, NULL);
116102 if (ret) {
117103 XDNA_ERR(ndev->xdna, "Set hard dpm level %d failed, ret %d ",
118104 dpm_level, ret);
119− goto suspend_put;
105+ return ret;
120106 }
121107
122108 ret = aie2_smu_exec(ndev, AIE2_SMU_SET_SOFT_DPMLEVEL, dpm_level, NULL);
123109 if (ret) {
124110 XDNA_ERR(ndev->xdna, "Set soft dpm level %d failed, ret %d",
125111 dpm_level, ret);
126− goto suspend_put;
112+ return ret;
127113 }
128114
129− amdxdna_pm_suspend_put(ndev->xdna);
130115 ndev->npuclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].npuclk;
131116 ndev->hclk_freq = ndev->priv->dpm_clk_tbl[dpm_level].hclk;
132117 ndev->dpm_level = dpm_level;
@@ -137,10 +122,6 @@ int npu4_set_dpm(struct amdxdna_dev_hdl *ndev, u32 dpm_level) · 4 unmodified lines
137122 ndev->npuclk_freq, ndev->hclk_freq);
138123
139124 return 0;
140−
141−suspend_put:
142− amdxdna_pm_suspend_put(ndev->xdna);
143− return ret;
144125 }
145126
146127 int aie2_smu_init(struct amdxdna_dev_hdl *ndev)
drivers/accel/amdxdna/amdxdna_mailbox.c+1−18
@@ -112,22 +112,6 @@ static u32 mailbox_reg_read(struct mailbox_channel *mb_chann, u32 mbox_reg) · 111 unmodified lines
112112 return readl(ringbuf_addr);
113113 }
114114
115−static int mailbox_reg_read_non_zero(struct mailbox_channel *mb_chann, u32 mbox_reg, u32 *val)
116−{
117− struct xdna_mailbox_res *mb_res = &mb_chann->mb->res;
118− void __iomem *ringbuf_addr = mb_res->mbox_base + mbox_reg;
119− int ret, value;
120−
121− /* Poll till value is not zero */
122− ret = readx_poll_timeout(readl, ringbuf_addr, value,
123− value, 1 /* us */, 100);
124− if (ret < 0)
125− return ret;
126−
127− *val = value;
128− return 0;
129−}
130−
131115 static inline void
132116 mailbox_set_headptr(struct mailbox_channel *mb_chann, u32 headptr_val)
133117 {
@@ -286,8 +270,7 @@ static int mailbox_get_msg(struct mailbox_channel *mb_chann) · 152 unmodified lines
286270 u32 start_addr;
287271 int ret;
288272
289− if (mailbox_reg_read_non_zero(mb_chann, mb_chann->res[CHAN_RES_I2X].mb_tail_ptr_reg, &tail))
290− return -EINVAL;
273+ tail = mailbox_get_tailptr(mb_chann, CHAN_RES_I2X);
291274 head = mb_chann->i2x_head;
292275 ringbuf_size = mailbox_get_ringbuf_size(mb_chann, CHAN_RES_I2X);
293276 start_addr = mb_chann->res[CHAN_RES_I2X].rb_start_addr;
drivers/accel/amdxdna/amdxdna_pci_drv.h+0−1
@@ -101,7 +101,6 @@ struct amdxdna_dev { · 100 unmodified lines
101101 struct amdxdna_fw_ver fw_ver;
102102 struct rw_semaphore notifier_lock; /* for mmu notifier*/
103103 struct workqueue_struct *notifier_wq;
104− bool rpm_on;
105104 };
106105
107106 /*
drivers/accel/amdxdna/amdxdna_pm.c+2−20
@@ -15,14 +15,9 @@ int amdxdna_pm_suspend(struct device *dev) · 14 unmodified lines
1515 {
1616 struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
1717 int ret = -EOPNOTSUPP;
18− bool rpm;
1918
20− if (xdna->dev_info->ops->suspend) {
21− rpm = xdna->rpm_on;
22− xdna->rpm_on = false;
19+ if (xdna->dev_info->ops->suspend)
2320 ret = xdna->dev_info->ops->suspend(xdna);
24− xdna->rpm_on = rpm;
25− }
2621
2722 XDNA_DBG(xdna, "Suspend done ret %d", ret);
2823 return ret;
@@ -32,14 +27,9 @@ int amdxdna_pm_resume(struct device *dev) · 3 unmodified lines
3227 {
3328 struct amdxdna_dev *xdna = to_xdna_dev(dev_get_drvdata(dev));
3429 int ret = -EOPNOTSUPP;
35− bool rpm;
3630
37− if (xdna->dev_info->ops->resume) {
38− rpm = xdna->rpm_on;
39− xdna->rpm_on = false;
31+ if (xdna->dev_info->ops->resume)
4032 ret = xdna->dev_info->ops->resume(xdna);
41− xdna->rpm_on = rpm;
42− }
4333
4434 XDNA_DBG(xdna, "Resume done ret %d", ret);
4535 return ret;
@@ -50,9 +40,6 @@ int amdxdna_pm_resume_get(struct amdxdna_dev *xdna) · 4 unmodified lines
5040 struct device *dev = xdna->ddev.dev;
5141 int ret;
5242
53− if (!xdna->rpm_on)
54− return 0;
55−
5643 ret = pm_runtime_resume_and_get(dev);
5744 if (ret) {
5845 XDNA_ERR(xdna, "Resume failed: %d", ret);
@@ -66,9 +53,6 @@ void amdxdna_pm_suspend_put(struct amdxdna_dev *xdna) · 7 unmodified lines
6653 {
6754 struct device *dev = xdna->ddev.dev;
6855
69− if (!xdna->rpm_on)
70− return;
71−
7256 pm_runtime_put_autosuspend(dev);
7357 }
7458
@@ -81,14 +65,12 @@ void amdxdna_pm_init(struct amdxdna_dev *xdna) · 6 unmodified lines
8165 pm_runtime_use_autosuspend(dev);
8266 pm_runtime_allow(dev);
8367 pm_runtime_put_autosuspend(dev);
84− xdna->rpm_on = true;
8568 }
8669
8770 void amdxdna_pm_fini(struct amdxdna_dev *xdna)
8871 {
8972 struct device *dev = xdna->ddev.dev;
9073
91− xdna->rpm_on = false;
9274 pm_runtime_get_noresume(dev);
9375 pm_runtime_forbid(dev);
9476 }
drivers/accel/amdxdna/npu1_regs.c+2−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include "amdxdna_pci_drv.h"
1414
1515 /* Address definition from NPU1 docs */
16+#define MPNPU_PWAITMODE 0x3010034
1617 #define MPNPU_PUB_SEC_INTR 0x3010090
1718 #define MPNPU_PUB_PWRMGMT_INTR 0x3010094
1819 #define MPNPU_PUB_SCRATCH2 0x30100A0
@@ -92,6 +93,7 @@ static const struct amdxdna_dev_priv npu1_dev_priv = { · 73 unmodified lines
9293 DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU1_PSP, MPNPU_PUB_SEC_INTR),
9394 DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU1_PSP, MPNPU_PUB_SCRATCH2),
9495 DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU1_PSP, MPNPU_PUB_SCRATCH3),
96+ DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU1_PSP, MPNPU_PWAITMODE),
9597 },
9698 .smu_regs_off = {
9799 DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU1_SMU, MPNPU_PUB_SCRATCH5),
drivers/accel/amdxdna/npu2_regs.c+2−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include "amdxdna_pci_drv.h"
1414
1515 /* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
16+#define MPNPU_PWAITMODE 0x301003C
1617 #define MPNPU_PUB_SEC_INTR 0x3010060
1718 #define MPNPU_PUB_PWRMGMT_INTR 0x3010064
1819 #define MPNPU_PUB_SCRATCH0 0x301006C
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu2_dev_priv = { · 66 unmodified lines
8586 DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU2_PSP, MP0_C2PMSG_73),
8687 DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU2_PSP, MP0_C2PMSG_123),
8788 DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU2_REG, MPNPU_PUB_SCRATCH3),
89+ DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU2_REG, MPNPU_PWAITMODE),
8890 },
8991 .smu_regs_off = {
9092 DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU2_SMU, MP1_C2PMSG_0),
drivers/accel/amdxdna/npu4_regs.c+2−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include "amdxdna_pci_drv.h"
1414
1515 /* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
16+#define MPNPU_PWAITMODE 0x301003C
1617 #define MPNPU_PUB_SEC_INTR 0x3010060
1718 #define MPNPU_PUB_PWRMGMT_INTR 0x3010064
1819 #define MPNPU_PUB_SCRATCH0 0x301006C
@@ -116,6 +117,7 @@ static const struct amdxdna_dev_priv npu4_dev_priv = { · 97 unmodified lines
116117 DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU4_PSP, MP0_C2PMSG_73),
117118 DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU4_PSP, MP0_C2PMSG_123),
118119 DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU4_REG, MPNPU_PUB_SCRATCH3),
120+ DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU4_REG, MPNPU_PWAITMODE),
119121 },
120122 .smu_regs_off = {
121123 DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU4_SMU, MP1_C2PMSG_0),
drivers/accel/amdxdna/npu5_regs.c+2−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include "amdxdna_pci_drv.h"
1414
1515 /* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
16+#define MPNPU_PWAITMODE 0x301003C
1617 #define MPNPU_PUB_SEC_INTR 0x3010060
1718 #define MPNPU_PUB_PWRMGMT_INTR 0x3010064
1819 #define MPNPU_PUB_SCRATCH0 0x301006C
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu5_dev_priv = { · 66 unmodified lines
8586 DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU5_PSP, MP0_C2PMSG_73),
8687 DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU5_PSP, MP0_C2PMSG_123),
8788 DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU5_REG, MPNPU_PUB_SCRATCH3),
89+ DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU5_REG, MPNPU_PWAITMODE),
8890 },
8991 .smu_regs_off = {
9092 DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU5_SMU, MP1_C2PMSG_0),
drivers/accel/amdxdna/npu6_regs.c+2−0
@@ -13,6 +13,7 @@ · 12 unmodified lines
1313 #include "amdxdna_pci_drv.h"
1414
1515 /* NPU Public Registers on MpNPUAxiXbar (refer to Diag npu_registers.h) */
16+#define MPNPU_PWAITMODE 0x301003C
1617 #define MPNPU_PUB_SEC_INTR 0x3010060
1718 #define MPNPU_PUB_PWRMGMT_INTR 0x3010064
1819 #define MPNPU_PUB_SCRATCH0 0x301006C
@@ -85,6 +86,7 @@ static const struct amdxdna_dev_priv npu6_dev_priv = { · 66 unmodified lines
8586 DEFINE_BAR_OFFSET(PSP_INTR_REG, NPU6_PSP, MP0_C2PMSG_73),
8687 DEFINE_BAR_OFFSET(PSP_STATUS_REG, NPU6_PSP, MP0_C2PMSG_123),
8788 DEFINE_BAR_OFFSET(PSP_RESP_REG, NPU6_REG, MPNPU_PUB_SCRATCH3),
89+ DEFINE_BAR_OFFSET(PSP_PWAITMODE_REG, NPU6_REG, MPNPU_PWAITMODE),
8890 },
8991 .smu_regs_off = {
9092 DEFINE_BAR_OFFSET(SMU_CMD_REG, NPU6_SMU, MP1_C2PMSG_0),
drivers/dma-buf/Kconfig+1−1
@@ -55,7 +55,7 @@ config DMABUF_MOVE_NOTIFY · 54 unmodified lines
5555 config DMABUF_DEBUG
5656 bool "DMA-BUF debug checks"
5757 depends on DMA_SHARED_BUFFER
58− default y if DMA_API_DEBUG
58+ default y if DEBUG
5959 help
6060 This option enables additional checks for DMA-BUF importers and
6161 exporters. Specifically it validates that importers do not peek at the
drivers/dma-buf/dma-buf.c+62−17
@@ -35,6 +35,12 @@ · 34 unmodified lines
3535
3636 #include "dma-buf-sysfs-stats.h"
3737
38+/* Wrapper to hide the sg_table page link from the importer */
39+struct dma_buf_sg_table_wrapper {
40+ struct sg_table *original;
41+ struct sg_table wrapper;
42+};
43+
3844 static inline int is_dma_buf_file(struct file *);
3945
4046 static DEFINE_MUTEX(dmabuf_list_mutex);
@@ -820,21 +826,59 @@ void dma_buf_put(struct dma_buf *dmabuf) · 779 unmodified lines
820826 }
821827 EXPORT_SYMBOL_NS_GPL(dma_buf_put, "DMA_BUF");
822828
823−static void mangle_sg_table(struct sg_table *sg_table)
829+static int dma_buf_wrap_sg_table(struct sg_table **sg_table)
824830 {
825−#ifdef CONFIG_DMABUF_DEBUG
826− int i;
827− struct scatterlist *sg;
828−
829− /* To catch abuse of the underlying struct page by importers mix
830− * up the bits, but take care to preserve the low SG_ bits to
831− * not corrupt the sgt. The mixing is undone on unmap
832− * before passing the sgt back to the exporter.
831+ struct scatterlist *to_sg, *from_sg;
832+ struct sg_table *from = *sg_table;
833+ struct dma_buf_sg_table_wrapper *to;
834+ int i, ret;
835+
836+ if (!IS_ENABLED(CONFIG_DMABUF_DEBUG))
837+ return 0;
838+
839+ /*
840+ * To catch abuse of the underlying struct page by importers copy the
841+ * sg_table without copying the page_link and give only the copy back to
842+ * the importer.
833843 */
834− for_each_sgtable_sg(sg_table, sg, i)
835− sg->page_link ^= ~0xffUL;
836−#endif
844+ to = kzalloc(sizeof(*to), GFP_KERNEL);
845+ if (!to)
846+ return -ENOMEM;
847+
848+ ret = sg_alloc_table(&to->wrapper, from->nents, GFP_KERNEL);
849+ if (ret)
850+ goto free_to;
851+
852+ to_sg = to->wrapper.sgl;
853+ for_each_sgtable_dma_sg(from, from_sg, i) {
854+ to_sg->offset = 0;
855+ to_sg->length = 0;
856+ sg_assign_page(to_sg, NULL);
857+ sg_dma_address(to_sg) = sg_dma_address(from_sg);
858+ sg_dma_len(to_sg) = sg_dma_len(from_sg);
859+ to_sg = sg_next(to_sg);
860+ }
837861
862+ to->original = from;
863+ *sg_table = &to->wrapper;
864+ return 0;
865+
866+free_to:
867+ kfree(to);
868+ return ret;
869+}
870+
871+static void dma_buf_unwrap_sg_table(struct sg_table **sg_table)
872+{
873+ struct dma_buf_sg_table_wrapper *copy;
874+
875+ if (!IS_ENABLED(CONFIG_DMABUF_DEBUG))
876+ return;
877+
878+ copy = container_of(*sg_table, typeof(*copy), wrapper);
879+ *sg_table = copy->original;
880+ sg_free_table(&copy->wrapper);
881+ kfree(copy);
838882 }
839883
840884 static inline bool
@@ -1131,10 +1175,11 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 290 unmodified lines
11311175 if (ret < 0)
11321176 goto error_unmap;
11331177 }
1134− mangle_sg_table(sg_table);
1178+ ret = dma_buf_wrap_sg_table(&sg_table);
1179+ if (ret)
1180+ goto error_unmap;
11351181
1136−#ifdef CONFIG_DMA_API_DEBUG
1137− {
1182+ if (IS_ENABLED(CONFIG_DMA_API_DEBUG)) {
11381183 struct scatterlist *sg;
11391184 u64 addr;
11401185 int len;
@@ -1146,10 +1191,10 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 5 unmodified lines
11461191 if (!PAGE_ALIGNED(addr) || !PAGE_ALIGNED(len)) {
11471192 pr_debug("%s: addr %llx or len %x is not page aligned!\n",
11481193 __func__, addr, len);
1194+ break;
11491195 }
11501196 }
11511197 }
1152−#endif /* CONFIG_DMA_API_DEBUG */
11531198 return sg_table;
11541199
11551200 error_unmap:
@@ -1213,7 +1258,7 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, · 57 unmodified lines
12131258
12141259 dma_resv_assert_held(attach->dmabuf->resv);
12151260
1216− mangle_sg_table(sg_table);
1261+ dma_buf_unwrap_sg_table(&sg_table);
12171262 attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
12181263
12191264 if (dma_buf_pin_on_map(attach))
drivers/dma-buf/dma-fence.c+62−38
@@ -358,11 +358,8 @@ void __dma_fence_might_wait(void) · 357 unmodified lines
358358 *
359359 * Unlike dma_fence_signal_timestamp(), this function must be called with
360360 * &dma_fence.lock held.
361− *
362− * Returns 0 on success and a negative error value when @fence has been
363− * signalled already.
364361 */
365−int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
362+void dma_fence_signal_timestamp_locked(struct dma_fence *fence,
366363 ktime_t timestamp)
367364 {
368365 struct dma_fence_cb *cur, *tmp;
@@ -372,7 +369,7 @@ int dma_fence_signal_timestamp_locked(struct dma_fence *fence, · 3 unmodified lines
372369
373370 if (unlikely(test_and_set_bit(DMA_FENCE_FLAG_SIGNALED_BIT,
374371 &fence->flags)))
375− return -EINVAL;
372+ return;
376373
377374 /* Stash the cb_list before replacing it with the timestamp */
378375 list_replace(&fence->cb_list, &cb_list);
@@ -385,8 +382,6 @@ int dma_fence_signal_timestamp_locked(struct dma_fence *fence, · 6 unmodified lines
385382 INIT_LIST_HEAD(&cur->node);
386383 cur->func(fence, cur);
387384 }
388−
389− return 0;
390385 }
391386 EXPORT_SYMBOL(dma_fence_signal_timestamp_locked);
392387
@@ -401,23 +396,17 @@ EXPORT_SYMBOL(dma_fence_signal_timestamp_locked); · 8 unmodified lines
401396 * can only go from the unsignaled to the signaled state and not back, it will
402397 * only be effective the first time. Set the timestamp provided as the fence
403398 * signal timestamp.
404− *
405− * Returns 0 on success and a negative error value when @fence has been
406− * signalled already.
407399 */
408−int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
400+void dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp)
409401 {
410402 unsigned long flags;
411− int ret;
412403
413404 if (WARN_ON(!fence))
414− return -EINVAL;
405+ return;
415406
416407 spin_lock_irqsave(fence->lock, flags);
417− ret = dma_fence_signal_timestamp_locked(fence, timestamp);
408+ dma_fence_signal_timestamp_locked(fence, timestamp);
418409 spin_unlock_irqrestore(fence->lock, flags);
419−
420− return ret;
421410 }
422411 EXPORT_SYMBOL(dma_fence_signal_timestamp);
423412
@@ -433,16 +422,57 @@ EXPORT_SYMBOL(dma_fence_signal_timestamp); · 9 unmodified lines
433422 *
434423 * Unlike dma_fence_signal(), this function must be called with &dma_fence.lock
435424 * held.
436− *
437− * Returns 0 on success and a negative error value when @fence has been
438− * signalled already.
439425 */
440−int dma_fence_signal_locked(struct dma_fence *fence)
426+void dma_fence_signal_locked(struct dma_fence *fence)
441427 {
442− return dma_fence_signal_timestamp_locked(fence, ktime_get());
428+ dma_fence_signal_timestamp_locked(fence, ktime_get());
443429 }
444430 EXPORT_SYMBOL(dma_fence_signal_locked);
445431
432+/**
433+ * dma_fence_check_and_signal_locked - signal the fence if it's not yet signaled
434+ * @fence: the fence to check and signal
435+ *
436+ * Checks whether a fence was signaled and signals it if it was not yet signaled.
437+ *
438+ * Unlike dma_fence_check_and_signal(), this function must be called with
439+ * &struct dma_fence.lock being held.
440+ *
441+ * Return: true if fence has been signaled already, false otherwise.
442+ */
443+bool dma_fence_check_and_signal_locked(struct dma_fence *fence)
444+{
445+ bool ret;
446+
447+ ret = dma_fence_test_signaled_flag(fence);
448+ dma_fence_signal_locked(fence);
449+
450+ return ret;
451+}
452+EXPORT_SYMBOL(dma_fence_check_and_signal_locked);
453+
454+/**
455+ * dma_fence_check_and_signal - signal the fence if it's not yet signaled
456+ * @fence: the fence to check and signal
457+ *
458+ * Checks whether a fence was signaled and signals it if it was not yet signaled.
459+ * All this is done in a race-free manner.
460+ *
461+ * Return: true if fence has been signaled already, false otherwise.
462+ */
463+bool dma_fence_check_and_signal(struct dma_fence *fence)
464+{
465+ unsigned long flags;
466+ bool ret;
467+
468+ spin_lock_irqsave(fence->lock, flags);
469+ ret = dma_fence_check_and_signal_locked(fence);
470+ spin_unlock_irqrestore(fence->lock, flags);
471+
472+ return ret;
473+}
474+EXPORT_SYMBOL(dma_fence_check_and_signal);
475+
446476 /**
447477 * dma_fence_signal - signal completion of a fence
448478 * @fence: the fence to signal
@@ -452,28 +482,22 @@ EXPORT_SYMBOL(dma_fence_signal_locked); · 3 unmodified lines
452482 * dma_fence_add_callback(). Can be called multiple times, but since a fence
453483 * can only go from the unsignaled to the signaled state and not back, it will
454484 * only be effective the first time.
455− *
456− * Returns 0 on success and a negative error value when @fence has been
457− * signalled already.
458485 */
459−int dma_fence_signal(struct dma_fence *fence)
486+void dma_fence_signal(struct dma_fence *fence)
460487 {
461488 unsigned long flags;
462− int ret;
463489 bool tmp;
464490
465491 if (WARN_ON(!fence))
466− return -EINVAL;
492+ return;
467493
468494 tmp = dma_fence_begin_signalling();
469495
470496 spin_lock_irqsave(fence->lock, flags);
471− ret = dma_fence_signal_timestamp_locked(fence, ktime_get());
497+ dma_fence_signal_timestamp_locked(fence, ktime_get());
472498 spin_unlock_irqrestore(fence->lock, flags);
473499
474500 dma_fence_end_signalling(tmp);
475−
476− return ret;
477501 }
478502 EXPORT_SYMBOL(dma_fence_signal);
479503
@@ -543,7 +567,7 @@ void dma_fence_release(struct kref *kref) · 63 unmodified lines
543567 trace_dma_fence_destroy(fence);
544568
545569 if (!list_empty(&fence->cb_list) &&
546− !test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
570+ !dma_fence_test_signaled_flag(fence)) {
547571 const char __rcu *timeline;
548572 const char __rcu *driver;
549573 unsigned long flags;
@@ -600,7 +624,7 @@ static bool __dma_fence_enable_signaling(struct dma_fence *fence) · 50 unmodified lines
600624 was_set = test_and_set_bit(DMA_FENCE_FLAG_ENABLE_SIGNAL_BIT,
601625 &fence->flags);
602626
603− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
627+ if (dma_fence_test_signaled_flag(fence))
604628 return false;
605629
606630 if (!was_set && fence->ops->enable_signaling) {
@@ -664,7 +688,7 @@ int dma_fence_add_callback(struct dma_fence *fence, struct dma_fence_cb *cb, · 57 unmodified lines
664688 if (WARN_ON(!fence || !func))
665689 return -EINVAL;
666690
667− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
691+ if (dma_fence_test_signaled_flag(fence)) {
668692 INIT_LIST_HEAD(&cb->node);
669693 return -ENOENT;
670694 }
@@ -781,7 +805,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) · 110 unmodified lines
781805
782806 spin_lock_irqsave(fence->lock, flags);
783807
784− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
808+ if (dma_fence_test_signaled_flag(fence))
785809 goto out;
786810
787811 if (intr && signal_pending(current)) {
@@ -798,7 +822,7 @@ dma_fence_default_wait(struct dma_fence *fence, bool intr, signed long timeout) · 10 unmodified lines
798822 cb.task = current;
799823 list_add(&cb.base.node, &fence->cb_list);
800824
801− while (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags) && ret > 0) {
825+ while (!dma_fence_test_signaled_flag(fence) && ret > 0) {
802826 if (intr)
803827 __set_current_state(TASK_INTERRUPTIBLE);
804828 else
@@ -830,7 +854,7 @@ dma_fence_test_signaled_any(struct dma_fence **fences, uint32_t count, · 25 unmodified lines
830854
831855 for (i = 0; i < count; ++i) {
832856 struct dma_fence *fence = fences[i];
833− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags)) {
857+ if (dma_fence_test_signaled_flag(fence)) {
834858 if (idx)
835859 *idx = i;
836860 return true;
@@ -1108,7 +1132,7 @@ const char __rcu *dma_fence_driver_name(struct dma_fence *fence) · 271 unmodified lines
11081132 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
11091133 "RCU protection is required for safe access to returned string");
11101134
1111− if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
1135+ if (!dma_fence_test_signaled_flag(fence))
11121136 return fence->ops->get_driver_name(fence);
11131137 else
11141138 return "detached-driver";
@@ -1140,7 +1164,7 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence) · 25 unmodified lines
11401164 RCU_LOCKDEP_WARN(!rcu_read_lock_held(),
11411165 "RCU protection is required for safe access to returned string");
11421166
1143− if (!test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
1167+ if (!dma_fence_test_signaled_flag(fence))
11441168 return fence->ops->get_timeline_name(fence);
11451169 else
11461170 return "signaled-timeline";
drivers/dma-buf/st-dma-fence.c+2−2
@@ -126,7 +126,7 @@ static int test_signaling(void *arg) · 125 unmodified lines
126126 goto err_free;
127127 }
128128
129− if (dma_fence_signal(f)) {
129+ if (dma_fence_check_and_signal(f)) {
130130 pr_err("Fence reported being already signaled\n");
131131 goto err_free;
132132 }
@@ -136,7 +136,7 @@ static int test_signaling(void *arg) · 3 unmodified lines
136136 goto err_free;
137137 }
138138
139− if (!dma_fence_signal(f)) {
139+ if (!dma_fence_test_signaled_flag(f)) {
140140 pr_err("Fence reported not being already signaled\n");
141141 goto err_free;
142142 }
drivers/gpu/drm/Kconfig+59−140
@@ -265,164 +265,83 @@ config DRM_SCHED · 264 unmodified lines
265265 tristate
266266 depends on DRM
267267
268−source "drivers/gpu/drm/sysfb/Kconfig"
268+# Separate option as not all DRM drivers use it
269+config DRM_PANEL_BACKLIGHT_QUIRKS
270+ tristate
269271
270−source "drivers/gpu/drm/arm/Kconfig"
272+config DRM_LIB_RANDOM
273+ bool
274+ default n
271275
272−source "drivers/gpu/drm/radeon/Kconfig"
276+config DRM_PRIVACY_SCREEN
277+ bool
278+ default n
273279
280+# DRM driver Kconfig files, sorted
281+source "drivers/gpu/drm/adp/Kconfig"
274282 source "drivers/gpu/drm/amd/amdgpu/Kconfig"
275−
276−source "drivers/gpu/drm/nouveau/Kconfig"
277−
278−source "drivers/gpu/drm/nova/Kconfig"
279−
280−source "drivers/gpu/drm/i915/Kconfig"
281−
282−source "drivers/gpu/drm/xe/Kconfig"
283−
284−source "drivers/gpu/drm/kmb/Kconfig"
285−
286−config DRM_VGEM
287− tristate "Virtual GEM provider"
288− depends on DRM && MMU
289− select DRM_GEM_SHMEM_HELPER
290− help
291− Choose this option to get a virtual graphics memory manager,
292− as used by Mesa's software renderer for enhanced performance.
293− If M is selected the module will be called vgem.
294−
295−source "drivers/gpu/drm/vkms/Kconfig"
296−
297−source "drivers/gpu/drm/exynos/Kconfig"
298−
299−source "drivers/gpu/drm/rockchip/Kconfig"
300−
301−source "drivers/gpu/drm/vmwgfx/Kconfig"
302−
303−source "drivers/gpu/drm/gma500/Kconfig"
304−
305−source "drivers/gpu/drm/udl/Kconfig"
306−
307−source "drivers/gpu/drm/ast/Kconfig"
308−
309−source "drivers/gpu/drm/mgag200/Kconfig"
310−
283+source "drivers/gpu/drm/arm/Kconfig"
311284 source "drivers/gpu/drm/armada/Kconfig"
312−
285+source "drivers/gpu/drm/aspeed/Kconfig"
286+source "drivers/gpu/drm/ast/Kconfig"
313287 source "drivers/gpu/drm/atmel-hlcdc/Kconfig"
314−
315−source "drivers/gpu/drm/renesas/Kconfig"
316−
317−source "drivers/gpu/drm/sun4i/Kconfig"
318−
319−source "drivers/gpu/drm/omapdrm/Kconfig"
320−
321−source "drivers/gpu/drm/tilcdc/Kconfig"
322−
323−source "drivers/gpu/drm/qxl/Kconfig"
324−
325−source "drivers/gpu/drm/virtio/Kconfig"
326−
327−source "drivers/gpu/drm/msm/Kconfig"
328−
329−source "drivers/gpu/drm/fsl-dcu/Kconfig"
330−
331−source "drivers/gpu/drm/tegra/Kconfig"
332−
333−source "drivers/gpu/drm/stm/Kconfig"
334−
335−source "drivers/gpu/drm/panel/Kconfig"
336−
337288 source "drivers/gpu/drm/bridge/Kconfig"
338−
339−source "drivers/gpu/drm/sti/Kconfig"
340−
341−source "drivers/gpu/drm/imx/Kconfig"
342−
343−source "drivers/gpu/drm/ingenic/Kconfig"
344−
345−source "drivers/gpu/drm/v3d/Kconfig"
346−
347−source "drivers/gpu/drm/vc4/Kconfig"
348−
349−source "drivers/gpu/drm/loongson/Kconfig"
350−
351289 source "drivers/gpu/drm/etnaviv/Kconfig"
352−
290+source "drivers/gpu/drm/exynos/Kconfig"
291+source "drivers/gpu/drm/fsl-dcu/Kconfig"
292+source "drivers/gpu/drm/gma500/Kconfig"
293+source "drivers/gpu/drm/gud/Kconfig"
353294 source "drivers/gpu/drm/hisilicon/Kconfig"
354−
295+source "drivers/gpu/drm/hyperv/Kconfig"
296+source "drivers/gpu/drm/i915/Kconfig"
297+source "drivers/gpu/drm/imagination/Kconfig"
298+source "drivers/gpu/drm/imx/Kconfig"
299+source "drivers/gpu/drm/ingenic/Kconfig"
300+source "drivers/gpu/drm/kmb/Kconfig"
301+source "drivers/gpu/drm/lima/Kconfig"
355302 source "drivers/gpu/drm/logicvc/Kconfig"
356−
303+source "drivers/gpu/drm/loongson/Kconfig"
304+source "drivers/gpu/drm/mcde/Kconfig"
357305 source "drivers/gpu/drm/mediatek/Kconfig"
358−
359−source "drivers/gpu/drm/mxsfb/Kconfig"
360−
361306 source "drivers/gpu/drm/meson/Kconfig"
362−
363−source "drivers/gpu/drm/tiny/Kconfig"
364−
365−source "drivers/gpu/drm/pl111/Kconfig"
366−
367−source "drivers/gpu/drm/tve200/Kconfig"
368−
369−source "drivers/gpu/drm/xen/Kconfig"
370−
371−source "drivers/gpu/drm/vboxvideo/Kconfig"
372−
373−source "drivers/gpu/drm/lima/Kconfig"
374−
307+source "drivers/gpu/drm/mgag200/Kconfig"
308+source "drivers/gpu/drm/msm/Kconfig"
309+source "drivers/gpu/drm/mxsfb/Kconfig"
310+source "drivers/gpu/drm/nouveau/Kconfig"
311+source "drivers/gpu/drm/nova/Kconfig"
312+source "drivers/gpu/drm/omapdrm/Kconfig"
313+source "drivers/gpu/drm/panel/Kconfig"
375314 source "drivers/gpu/drm/panfrost/Kconfig"
376−
377315 source "drivers/gpu/drm/panthor/Kconfig"
378−
379−source "drivers/gpu/drm/aspeed/Kconfig"
380−
381−source "drivers/gpu/drm/mcde/Kconfig"
382−
383−source "drivers/gpu/drm/tidss/Kconfig"
384−
385−source "drivers/gpu/drm/adp/Kconfig"
386−
387−source "drivers/gpu/drm/xlnx/Kconfig"
388−
389−source "drivers/gpu/drm/gud/Kconfig"
390−
316+source "drivers/gpu/drm/pl111/Kconfig"
317+source "drivers/gpu/drm/qxl/Kconfig"
318+source "drivers/gpu/drm/radeon/Kconfig"
319+source "drivers/gpu/drm/renesas/Kconfig"
320+source "drivers/gpu/drm/rockchip/Kconfig"
391321 source "drivers/gpu/drm/sitronix/Kconfig"
392−
393322 source "drivers/gpu/drm/solomon/Kconfig"
394−
395323 source "drivers/gpu/drm/sprd/Kconfig"
396−
397−source "drivers/gpu/drm/imagination/Kconfig"
398−
324+source "drivers/gpu/drm/sti/Kconfig"
325+source "drivers/gpu/drm/stm/Kconfig"
326+source "drivers/gpu/drm/sun4i/Kconfig"
327+source "drivers/gpu/drm/sysfb/Kconfig"
328+source "drivers/gpu/drm/tegra/Kconfig"
329+source "drivers/gpu/drm/tidss/Kconfig"
330+source "drivers/gpu/drm/tilcdc/Kconfig"
331+source "drivers/gpu/drm/tiny/Kconfig"
332+source "drivers/gpu/drm/tve200/Kconfig"
399333 source "drivers/gpu/drm/tyr/Kconfig"
400−
401−config DRM_HYPERV
402− tristate "DRM Support for Hyper-V synthetic video device"
403− depends on DRM && PCI && HYPERV_VMBUS
404− select DRM_CLIENT_SELECTION
405− select DRM_KMS_HELPER
406− select DRM_GEM_SHMEM_HELPER
407− help
408− This is a KMS driver for Hyper-V synthetic video device. Choose this
409− option if you would like to enable drm driver for Hyper-V virtual
410− machine. Unselect Hyper-V framebuffer driver (CONFIG_FB_HYPERV) so
411− that DRM driver is used by default.
412−
413− If M is selected the module will be called hyperv_drm.
414−
415−# Separate option as not all DRM drivers use it
416−config DRM_PANEL_BACKLIGHT_QUIRKS
417− tristate
418−
419−config DRM_LIB_RANDOM
420− bool
421− default n
422−
423−config DRM_PRIVACY_SCREEN
424− bool
425− default n
334+source "drivers/gpu/drm/udl/Kconfig"
335+source "drivers/gpu/drm/v3d/Kconfig"
336+source "drivers/gpu/drm/vboxvideo/Kconfig"
337+source "drivers/gpu/drm/vc4/Kconfig"
338+source "drivers/gpu/drm/vgem/Kconfig"
339+source "drivers/gpu/drm/virtio/Kconfig"
340+source "drivers/gpu/drm/vkms/Kconfig"
341+source "drivers/gpu/drm/vmwgfx/Kconfig"
342+source "drivers/gpu/drm/xe/Kconfig"
343+source "drivers/gpu/drm/xen/Kconfig"
344+source "drivers/gpu/drm/xlnx/Kconfig"
426345
427346 endif
428347
drivers/gpu/drm/amd/amdgpu/dce_v10_0.c+11−24
@@ -1838,7 +1838,7 @@ static void dce_v10_0_grph_enable(struct drm_crtc *crtc, bool enable) · 1837 unmodified lines
18381838
18391839 static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc,
18401840 struct drm_framebuffer *fb,
1841− int x, int y, int atomic)
1841+ int x, int y)
18421842 {
18431843 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
18441844 struct drm_device *dev = crtc->dev;
@@ -1855,15 +1855,12 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, · 10 unmodified lines
18551855 bool bypass_lut = false;
18561856
18571857 /* no fb bound */
1858− if (!atomic && !crtc->primary->fb) {
1858+ if (!crtc->primary->fb) {
18591859 DRM_DEBUG_KMS("No FB bound\n");
18601860 return 0;
18611861 }
18621862
1863− if (atomic)
1864− target_fb = fb;
1865− else
1866− target_fb = crtc->primary->fb;
1863+ target_fb = crtc->primary->fb;
18671864
18681865 /* If atomic, assume fb object is pinned & idle & fenced and
18691866 * just update base pointers
@@ -1874,13 +1871,11 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, · 4 unmodified lines
18741871 if (unlikely(r != 0))
18751872 return r;
18761873
1877− if (!atomic) {
1878− abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1879− r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1880− if (unlikely(r != 0)) {
1881− amdgpu_bo_unreserve(abo);
1882− return -EINVAL;
1883− }
1874+ abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1875+ r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1876+ if (unlikely(r != 0)) {
1877+ amdgpu_bo_unreserve(abo);
1878+ return -EINVAL;
18841879 }
18851880 fb_location = amdgpu_bo_gpu_offset(abo);
18861881
@@ -2068,7 +2063,7 @@ static int dce_v10_0_crtc_do_set_base(struct drm_crtc *crtc, · 181 unmodified lines
20682063 /* set pageflip to happen anywhere in vblank interval */
20692064 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
20702065
2071− if (!atomic && fb && fb != crtc->primary->fb) {
2066+ if (fb && fb != crtc->primary->fb) {
20722067 abo = gem_to_amdgpu_bo(fb->obj[0]);
20732068 r = amdgpu_bo_reserve(abo, true);
20742069 if (unlikely(r != 0))
@@ -2611,7 +2606,7 @@ static int dce_v10_0_crtc_mode_set(struct drm_crtc *crtc, · 536 unmodified lines
26112606
26122607 amdgpu_atombios_crtc_set_pll(crtc, adjusted_mode);
26132608 amdgpu_atombios_crtc_set_dtd_timing(crtc, adjusted_mode);
2614− dce_v10_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2609+ dce_v10_0_crtc_do_set_base(crtc, old_fb, x, y);
26152610 amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode);
26162611 amdgpu_atombios_crtc_scaler_setup(crtc);
26172612 dce_v10_0_cursor_reset(crtc);
@@ -2659,14 +2654,7 @@ static bool dce_v10_0_crtc_mode_fixup(struct drm_crtc *crtc, · 41 unmodified lines
26592654 static int dce_v10_0_crtc_set_base(struct drm_crtc *crtc, int x, int y,
26602655 struct drm_framebuffer *old_fb)
26612656 {
2662− return dce_v10_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2663−}
2664−
2665−static int dce_v10_0_crtc_set_base_atomic(struct drm_crtc *crtc,
2666− struct drm_framebuffer *fb,
2667− int x, int y, enum mode_set_atomic state)
2668−{
2669− return dce_v10_0_crtc_do_set_base(crtc, fb, x, y, 1);
2657+ return dce_v10_0_crtc_do_set_base(crtc, old_fb, x, y);
26702658 }
26712659
26722660 static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = {
@@ -2674,7 +2662,6 @@ static const struct drm_crtc_helper_funcs dce_v10_0_crtc_helper_funcs = { · 1 unmodified line
26742662 .mode_fixup = dce_v10_0_crtc_mode_fixup,
26752663 .mode_set = dce_v10_0_crtc_mode_set,
26762664 .mode_set_base = dce_v10_0_crtc_set_base,
2677− .mode_set_base_atomic = dce_v10_0_crtc_set_base_atomic,
26782665 .prepare = dce_v10_0_crtc_prepare,
26792666 .commit = dce_v10_0_crtc_commit,
26802667 .disable = dce_v10_0_crtc_disable,
drivers/gpu/drm/amd/amdgpu/dce_v6_0.c+11−24
@@ -1876,7 +1876,7 @@ static void dce_v6_0_grph_enable(struct drm_crtc *crtc, bool enable) · 1875 unmodified lines
18761876
18771877 static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc,
18781878 struct drm_framebuffer *fb,
1879− int x, int y, int atomic)
1879+ int x, int y)
18801880 {
18811881 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
18821882 struct drm_device *dev = crtc->dev;
@@ -1892,15 +1892,12 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc, · 9 unmodified lines
18921892 bool bypass_lut = false;
18931893
18941894 /* no fb bound */
1895− if (!atomic && !crtc->primary->fb) {
1895+ if (!crtc->primary->fb) {
18961896 DRM_DEBUG_KMS("No FB bound\n");
18971897 return 0;
18981898 }
18991899
1900− if (atomic)
1901− target_fb = fb;
1902− else
1903− target_fb = crtc->primary->fb;
1900+ target_fb = crtc->primary->fb;
19041901
19051902 /* If atomic, assume fb object is pinned & idle & fenced and
19061903 * just update base pointers
@@ -1911,13 +1908,11 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc, · 4 unmodified lines
19111908 if (unlikely(r != 0))
19121909 return r;
19131910
1914− if (!atomic) {
1915− abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1916− r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1917− if (unlikely(r != 0)) {
1918− amdgpu_bo_unreserve(abo);
1919− return -EINVAL;
1920− }
1911+ abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1912+ r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1913+ if (unlikely(r != 0)) {
1914+ amdgpu_bo_unreserve(abo);
1915+ return -EINVAL;
19211916 }
19221917 fb_location = amdgpu_bo_gpu_offset(abo);
19231918
@@ -2083,7 +2078,7 @@ static int dce_v6_0_crtc_do_set_base(struct drm_crtc *crtc, · 159 unmodified lines
20832078 /* set pageflip to happen anywhere in vblank interval */
20842079 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
20852080
2086− if (!atomic && fb && fb != crtc->primary->fb) {
2081+ if (fb && fb != crtc->primary->fb) {
20872082 abo = gem_to_amdgpu_bo(fb->obj[0]);
20882083 r = amdgpu_bo_reserve(abo, true);
20892084 if (unlikely(r != 0))
@@ -2578,7 +2573,7 @@ static int dce_v6_0_crtc_mode_set(struct drm_crtc *crtc, · 488 unmodified lines
25782573
25792574 amdgpu_atombios_crtc_set_pll(crtc, adjusted_mode);
25802575 amdgpu_atombios_crtc_set_dtd_timing(crtc, adjusted_mode);
2581− dce_v6_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2576+ dce_v6_0_crtc_do_set_base(crtc, old_fb, x, y);
25822577 amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode);
25832578 amdgpu_atombios_crtc_scaler_setup(crtc);
25842579 dce_v6_0_cursor_reset(crtc);
@@ -2626,14 +2621,7 @@ static bool dce_v6_0_crtc_mode_fixup(struct drm_crtc *crtc, · 41 unmodified lines
26262621 static int dce_v6_0_crtc_set_base(struct drm_crtc *crtc, int x, int y,
26272622 struct drm_framebuffer *old_fb)
26282623 {
2629− return dce_v6_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2630−}
2631−
2632−static int dce_v6_0_crtc_set_base_atomic(struct drm_crtc *crtc,
2633− struct drm_framebuffer *fb,
2634− int x, int y, enum mode_set_atomic state)
2635−{
2636− return dce_v6_0_crtc_do_set_base(crtc, fb, x, y, 1);
2624+ return dce_v6_0_crtc_do_set_base(crtc, old_fb, x, y);
26372625 }
26382626
26392627 static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = {
@@ -2641,7 +2629,6 @@ static const struct drm_crtc_helper_funcs dce_v6_0_crtc_helper_funcs = { · 1 unmodified line
26412629 .mode_fixup = dce_v6_0_crtc_mode_fixup,
26422630 .mode_set = dce_v6_0_crtc_mode_set,
26432631 .mode_set_base = dce_v6_0_crtc_set_base,
2644− .mode_set_base_atomic = dce_v6_0_crtc_set_base_atomic,
26452632 .prepare = dce_v6_0_crtc_prepare,
26462633 .commit = dce_v6_0_crtc_commit,
26472634 .disable = dce_v6_0_crtc_disable,
drivers/gpu/drm/amd/amdgpu/dce_v8_0.c+11−24
@@ -1785,7 +1785,7 @@ static void dce_v8_0_grph_enable(struct drm_crtc *crtc, bool enable) · 1784 unmodified lines
17851785
17861786 static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc,
17871787 struct drm_framebuffer *fb,
1788− int x, int y, int atomic)
1788+ int x, int y)
17891789 {
17901790 struct amdgpu_crtc *amdgpu_crtc = to_amdgpu_crtc(crtc);
17911791 struct drm_device *dev = crtc->dev;
@@ -1802,15 +1802,12 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, · 10 unmodified lines
18021802 bool bypass_lut = false;
18031803
18041804 /* no fb bound */
1805− if (!atomic && !crtc->primary->fb) {
1805+ if (!crtc->primary->fb) {
18061806 DRM_DEBUG_KMS("No FB bound\n");
18071807 return 0;
18081808 }
18091809
1810− if (atomic)
1811− target_fb = fb;
1812− else
1813− target_fb = crtc->primary->fb;
1810+ target_fb = crtc->primary->fb;
18141811
18151812 /* If atomic, assume fb object is pinned & idle & fenced and
18161813 * just update base pointers
@@ -1821,13 +1818,11 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, · 4 unmodified lines
18211818 if (unlikely(r != 0))
18221819 return r;
18231820
1824− if (!atomic) {
1825− abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1826− r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1827− if (unlikely(r != 0)) {
1828− amdgpu_bo_unreserve(abo);
1829− return -EINVAL;
1830− }
1821+ abo->flags |= AMDGPU_GEM_CREATE_VRAM_CONTIGUOUS;
1822+ r = amdgpu_bo_pin(abo, AMDGPU_GEM_DOMAIN_VRAM);
1823+ if (unlikely(r != 0)) {
1824+ amdgpu_bo_unreserve(abo);
1825+ return -EINVAL;
18311826 }
18321827 fb_location = amdgpu_bo_gpu_offset(abo);
18331828
@@ -1995,7 +1990,7 @@ static int dce_v8_0_crtc_do_set_base(struct drm_crtc *crtc, · 161 unmodified lines
19951990 /* set pageflip to happen anywhere in vblank interval */
19961991 WREG32(mmMASTER_UPDATE_MODE + amdgpu_crtc->crtc_offset, 0);
19971992
1998− if (!atomic && fb && fb != crtc->primary->fb) {
1993+ if (fb && fb != crtc->primary->fb) {
19991994 abo = gem_to_amdgpu_bo(fb->obj[0]);
20001995 r = amdgpu_bo_reserve(abo, true);
20011996 if (unlikely(r != 0))
@@ -2537,7 +2532,7 @@ static int dce_v8_0_crtc_mode_set(struct drm_crtc *crtc, · 535 unmodified lines
25372532
25382533 amdgpu_atombios_crtc_set_pll(crtc, adjusted_mode);
25392534 amdgpu_atombios_crtc_set_dtd_timing(crtc, adjusted_mode);
2540− dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2535+ dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y);
25412536 amdgpu_atombios_crtc_overscan_setup(crtc, mode, adjusted_mode);
25422537 amdgpu_atombios_crtc_scaler_setup(crtc);
25432538 dce_v8_0_cursor_reset(crtc);
@@ -2585,14 +2580,7 @@ static bool dce_v8_0_crtc_mode_fixup(struct drm_crtc *crtc, · 41 unmodified lines
25852580 static int dce_v8_0_crtc_set_base(struct drm_crtc *crtc, int x, int y,
25862581 struct drm_framebuffer *old_fb)
25872582 {
2588− return dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y, 0);
2589−}
2590−
2591−static int dce_v8_0_crtc_set_base_atomic(struct drm_crtc *crtc,
2592− struct drm_framebuffer *fb,
2593− int x, int y, enum mode_set_atomic state)
2594−{
2595− return dce_v8_0_crtc_do_set_base(crtc, fb, x, y, 1);
2583+ return dce_v8_0_crtc_do_set_base(crtc, old_fb, x, y);
25962584 }
25972585
25982586 static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = {
@@ -2600,7 +2588,6 @@ static const struct drm_crtc_helper_funcs dce_v8_0_crtc_helper_funcs = { · 1 unmodified line
26002588 .mode_fixup = dce_v8_0_crtc_mode_fixup,
26012589 .mode_set = dce_v8_0_crtc_mode_set,
26022590 .mode_set_base = dce_v8_0_crtc_set_base,
2603− .mode_set_base_atomic = dce_v8_0_crtc_set_base_atomic,
26042591 .prepare = dce_v8_0_crtc_prepare,
26052592 .commit = dce_v8_0_crtc_commit,
26062593 .disable = dce_v8_0_crtc_disable,
drivers/gpu/drm/amd/amdkfd/kfd_process.c+3−3
@@ -1987,10 +1987,10 @@ kfd_process_gpuid_from_node(struct kfd_process *p, struct kfd_node *node, · 1986 unmodified lines
19871987 return -EINVAL;
19881988 }
19891989
1990−static int signal_eviction_fence(struct kfd_process *p)
1990+static bool signal_eviction_fence(struct kfd_process *p)
19911991 {
19921992 struct dma_fence *ef;
1993− int ret;
1993+ bool ret;
19941994
19951995 rcu_read_lock();
19961996 ef = dma_fence_get_rcu_safe(&p->ef);
@@ -1998,7 +1998,7 @@ static int signal_eviction_fence(struct kfd_process *p) · 1 unmodified line
19981998 if (!ef)
19991999 return -EINVAL;
20002000
2001− ret = dma_fence_signal(ef);
2001+ ret = dma_fence_check_and_signal(ef);
20022002 dma_fence_put(ef);
20032003
20042004 return ret;
drivers/gpu/drm/ast/ast_cursor.c+62−21
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828 #include <drm/drm_damage_helper.h>
2929 #include <drm/drm_format_helper.h>
3030 #include <drm/drm_gem_atomic_helper.h>
31+#include <drm/drm_gem_framebuffer_helper.h>
3132 #include <drm/drm_print.h>
3233
3334 #include "ast_drv.h"
@@ -181,6 +182,62 @@ static int ast_cursor_plane_helper_atomic_check(struct drm_plane *plane, · 147 unmodified lines
181182 return 0;
182183 }
183184
185+static const u8 *ast_cursor_plane_get_argb4444(struct ast_cursor_plane *ast_cursor_plane,
186+ struct drm_shadow_plane_state *shadow_plane_state,
187+ const struct drm_rect *clip)
188+{
189+ struct drm_plane_state *plane_state = &shadow_plane_state->base;
190+ struct drm_framebuffer *fb = plane_state->fb;
191+ u8 *argb4444 = NULL;
192+
193+ if (drm_gem_fb_begin_cpu_access(fb, DMA_FROM_DEVICE) == 0) {
194+ switch (fb->format->format) {
195+ case DRM_FORMAT_ARGB4444:
196+ if (shadow_plane_state->data[0].is_iomem) {
197+ struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
198+ IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
199+ };
200+ unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
201+ AST_HWC_PITCH,
202+ };
203+
204+ drm_fb_memcpy(argb4444_dst, argb4444_dst_pitch,
205+ shadow_plane_state->data, fb, clip);
206+ argb4444 = argb4444_dst[0].vaddr;
207+ } else {
208+ argb4444 = shadow_plane_state->data[0].vaddr;
209+ }
210+ break;
211+ case DRM_FORMAT_ARGB8888:
212+ {
213+ struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
214+ IOSYS_MAP_INIT_VADDR(ast_cursor_plane->argb4444),
215+ };
216+ unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
217+ AST_HWC_PITCH,
218+ };
219+
220+ drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch,
221+ shadow_plane_state->data, fb, clip,
222+ &shadow_plane_state->fmtcnv_state);
223+ argb4444 = argb4444_dst[0].vaddr;
224+ }
225+ break;
226+ }
227+
228+ drm_gem_fb_end_cpu_access(fb, DMA_FROM_DEVICE);
229+ } else {
230+ /*
231+ * Fall back to white square if GEM object is not ready. Gives
232+ * the user an indication where the cursor is located.
233+ */
234+ memset(ast_cursor_plane->argb4444, 0xff, sizeof(ast_cursor_plane->argb4444));
235+ argb4444 = ast_cursor_plane->argb4444;
236+ }
237+
238+ return argb4444;
239+}
240+
184241 static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane,
185242 struct drm_atomic_state *state)
186243 {
@@ -205,29 +262,13 @@ static void ast_cursor_plane_helper_atomic_update(struct drm_plane *plane, · 18 unmodified lines
205262 */
206263
207264 if (drm_atomic_helper_damage_merged(old_plane_state, plane_state, &damage)) {
208− u8 *argb4444;
265+ const u8 *argb4444 = ast_cursor_plane_get_argb4444(ast_cursor_plane,
266+ shadow_plane_state,
267+ &damage);
209268
210− switch (fb->format->format) {
211− case DRM_FORMAT_ARGB4444:
212− argb4444 = shadow_plane_state->data[0].vaddr;
213− break;
214− default:
215− argb4444 = ast_cursor_plane->argb4444;
216− {
217− struct iosys_map argb4444_dst[DRM_FORMAT_MAX_PLANES] = {
218− IOSYS_MAP_INIT_VADDR(argb4444),
219− };
220− unsigned int argb4444_dst_pitch[DRM_FORMAT_MAX_PLANES] = {
221− AST_HWC_PITCH,
222− };
269+ if (argb4444)
270+ ast_set_cursor_image(ast, argb4444, fb->width, fb->height);
223271
224− drm_fb_argb8888_to_argb4444(argb4444_dst, argb4444_dst_pitch,
225− shadow_plane_state->data, fb, &damage,
226− &shadow_plane_state->fmtcnv_state);
227− }
228− break;
229− }
230− ast_set_cursor_image(ast, argb4444, fb->width, fb->height);
231272 ast_set_cursor_base(ast, dst_off);
232273 }
233274
drivers/gpu/drm/bridge/ti-sn65dsi83.c+66−20
@@ -406,6 +406,10 @@ static void sn65dsi83_reset_work(struct work_struct *ws) · 405 unmodified lines
406406 {
407407 struct sn65dsi83 *ctx = container_of(ws, struct sn65dsi83, reset_work);
408408 int ret;
409+ int idx;
410+
411+ if (!drm_bridge_enter(&ctx->bridge, &idx))
412+ return;
409413
410414 /* Reset the pipe */
411415 ret = sn65dsi83_reset_pipe(ctx);
@@ -415,12 +419,18 @@ static void sn65dsi83_reset_work(struct work_struct *ws) · 3 unmodified lines
415419 }
416420 if (ctx->irq)
417421 enable_irq(ctx->irq);
422+
423+ drm_bridge_exit(idx);
418424 }
419425
420426 static void sn65dsi83_handle_errors(struct sn65dsi83 *ctx)
421427 {
422428 unsigned int irq_stat;
423429 int ret;
430+ int idx;
431+
432+ if (!drm_bridge_enter(&ctx->bridge, &idx))
433+ return;
424434
425435 /*
426436 * Schedule a reset in case of:
@@ -448,6 +458,8 @@ static void sn65dsi83_handle_errors(struct sn65dsi83 *ctx) · 21 unmodified lines
448458
449459 schedule_work(&ctx->reset_work);
450460 }
461+
462+ drm_bridge_exit(idx);
451463 }
452464
453465 static void sn65dsi83_monitor_work(struct work_struct *work)
@@ -470,6 +482,37 @@ static void sn65dsi83_monitor_stop(struct sn65dsi83 *ctx) · 16 unmodified lines
470482 cancel_delayed_work_sync(&ctx->monitor_work);
471483 }
472484
485+/*
486+ * Release resources taken by sn65dsi83_atomic_pre_enable().
487+ *
488+ * Invoked by sn65dsi83_atomic_disable() normally, or by devres after
489+ * sn65dsi83_remove() in case this happens befora atomic_disable.
490+ */
491+static void sn65dsi83_release_resources(void *data)
492+{
493+ struct sn65dsi83 *ctx = (struct sn65dsi83 *)data;
494+ int ret;
495+
496+ if (ctx->irq) {
497+ /* Disable irq */
498+ regmap_write(ctx->regmap, REG_IRQ_EN, 0x0);
499+ regmap_write(ctx->regmap, REG_IRQ_GLOBAL, 0x0);
500+ } else {
501+ /* Stop the polling task */
502+ sn65dsi83_monitor_stop(ctx);
503+ }
504+
505+ /* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
506+ gpiod_set_value_cansleep(ctx->enable_gpio, 0);
507+ usleep_range(10000, 11000);
508+
509+ ret = regulator_disable(ctx->vcc);
510+ if (ret)
511+ dev_err(ctx->dev, "Failed to disable vcc: %d\n", ret);
512+
513+ regcache_mark_dirty(ctx->regmap);
514+}
515+
473516 static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge,
474517 struct drm_atomic_state *state)
475518 {
@@ -485,11 +528,15 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, · 9 unmodified lines
485528 __le16 le16val;
486529 u16 val;
487530 int ret;
531+ int idx;
532+
533+ if (!drm_bridge_enter(bridge, &idx))
534+ return;
488535
489536 ret = regulator_enable(ctx->vcc);
490537 if (ret) {
491538 dev_err(ctx->dev, "Failed to enable vcc: %d\n", ret);
492− return;
539+ goto err_exit;
493540 }
494541
495542 /* Deassert reset */
@@ -632,7 +679,7 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, · 136 unmodified lines
632679 dev_err(ctx->dev, "failed to lock PLL, ret=%i\n", ret);
633680 /* On failure, disable PLL again and exit. */
634681 regmap_write(ctx->regmap, REG_RC_PLL_EN, 0x00);
635− return;
682+ goto err_add_action;
636683 }
637684
638685 /* Trigger reset after CSR register update. */
@@ -640,6 +687,11 @@ static void sn65dsi83_atomic_pre_enable(struct drm_bridge *bridge, · 1 unmodified line
640687
641688 /* Wait for 10ms after soft reset as specified in datasheet */
642689 usleep_range(10000, 12000);
690+
691+err_add_action:
692+ devm_add_action(ctx->dev, sn65dsi83_release_resources, ctx);
693+err_exit:
694+ drm_bridge_exit(idx);
643695 }
644696
645697 static void sn65dsi83_atomic_enable(struct drm_bridge *bridge,
@@ -647,6 +699,10 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, · 1 unmodified line
647699 {
648700 struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
649701 unsigned int pval;
702+ int idx;
703+
704+ if (!drm_bridge_enter(bridge, &idx))
705+ return;
650706
651707 /* Clear all errors that got asserted during initialization. */
652708 regmap_read(ctx->regmap, REG_IRQ_STAT, &pval);
@@ -666,32 +722,22 @@ static void sn65dsi83_atomic_enable(struct drm_bridge *bridge, · 13 unmodified lines
666722 /* Use the polling task */
667723 sn65dsi83_monitor_start(ctx);
668724 }
725+
726+ drm_bridge_exit(idx);
669727 }
670728
671729 static void sn65dsi83_atomic_disable(struct drm_bridge *bridge,
672730 struct drm_atomic_state *state)
673731 {
674732 struct sn65dsi83 *ctx = bridge_to_sn65dsi83(bridge);
675− int ret;
733+ int idx;
676734
677− if (ctx->irq) {
678− /* Disable irq */
679− regmap_write(ctx->regmap, REG_IRQ_EN, 0x0);
680− regmap_write(ctx->regmap, REG_IRQ_GLOBAL, 0x0);
681− } else {
682− /* Stop the polling task */
683− sn65dsi83_monitor_stop(ctx);
684− }
685−
686− /* Put the chip in reset, pull EN line low, and assure 10ms reset low timing. */
687− gpiod_set_value_cansleep(ctx->enable_gpio, 0);
688− usleep_range(10000, 11000);
735+ if (!drm_bridge_enter(bridge, &idx))
736+ return;
689737
690− ret = regulator_disable(ctx->vcc);
691− if (ret)
692− dev_err(ctx->dev, "Failed to disable vcc: %d\n", ret);
738+ devm_release_action(ctx->dev, sn65dsi83_release_resources, ctx);
693739
694− regcache_mark_dirty(ctx->regmap);
740+ drm_bridge_exit(idx);
695741 }
696742
697743 static enum drm_mode_status
@@ -1012,7 +1058,7 @@ static void sn65dsi83_remove(struct i2c_client *client) · 314 unmodified lines
10121058 {
10131059 struct sn65dsi83 *ctx = i2c_get_clientdata(client);
10141060
1015− drm_bridge_remove(&ctx->bridge);
1061+ drm_bridge_unplug(&ctx->bridge);
10161062 }
10171063
10181064 static const struct i2c_device_id sn65dsi83_id[] = {
drivers/gpu/drm/display/drm_dp_mst_topology.c+2−1
@@ -4572,7 +4572,8 @@ int drm_dp_atomic_release_time_slots(struct drm_atomic_state *state, · 4571 unmodified lines
45724572 if (!payload->delete) {
45734573 payload->pbn = 0;
45744574 payload->delete = true;
4575− topology_state->payload_mask &= ~BIT(payload->vcpi - 1);
4575+ if (payload->vcpi > 0)
4576+ topology_state->payload_mask &= ~BIT(payload->vcpi - 1);
45764577 }
45774578
45784579 return 0;
drivers/gpu/drm/drm_atomic.c+1−0
@@ -906,6 +906,7 @@ drm_atomic_private_obj_init(struct drm_device *dev, · 905 unmodified lines
906906
907907 drm_modeset_lock_init(&obj->lock);
908908
909+ obj->dev = dev;
909910 obj->state = state;
910911 obj->funcs = funcs;
911912 list_add_tail(&obj->head, &dev->mode_config.privobj_list);
drivers/gpu/drm/drm_bridge.c+62−0
@@ -27,6 +27,7 @@ · 26 unmodified lines
2727 #include <linux/media-bus-format.h>
2828 #include <linux/module.h>
2929 #include <linux/mutex.h>
30+#include <linux/srcu.h>
3031
3132 #include <drm/drm_atomic_state_helper.h>
3233 #include <drm/drm_bridge.h>
@@ -202,6 +203,67 @@ static DEFINE_MUTEX(bridge_lock); · 169 unmodified lines
202203 static LIST_HEAD(bridge_list);
203204 static LIST_HEAD(bridge_lingering_list);
204205
206+DEFINE_STATIC_SRCU(drm_bridge_unplug_srcu);
207+
208+/**
209+ * drm_bridge_enter - Enter DRM bridge critical section
210+ * @bridge: DRM bridge
211+ * @idx: Pointer to index that will be passed to the matching drm_bridge_exit()
212+ *
213+ * This function marks and protects the beginning of a section that should not
214+ * be entered after the bridge has been unplugged. The section end is marked
215+ * with drm_bridge_exit(). Calls to this function can be nested.
216+ *
217+ * Returns:
218+ * True if it is OK to enter the section, false otherwise.
219+ */
220+bool drm_bridge_enter(struct drm_bridge *bridge, int *idx)
221+{
222+ *idx = srcu_read_lock(&drm_bridge_unplug_srcu);
223+
224+ if (bridge->unplugged) {
225+ srcu_read_unlock(&drm_bridge_unplug_srcu, *idx);
226+ return false;
227+ }
228+
229+ return true;
230+}
231+EXPORT_SYMBOL(drm_bridge_enter);
232+
233+/**
234+ * drm_bridge_exit - Exit DRM bridge critical section
235+ * @idx: index returned by drm_bridge_enter()
236+ *
237+ * This function marks the end of a section that should not be entered after
238+ * the bridge has been unplugged.
239+ */
240+void drm_bridge_exit(int idx)
241+{
242+ srcu_read_unlock(&drm_bridge_unplug_srcu, idx);
243+}
244+EXPORT_SYMBOL(drm_bridge_exit);
245+
246+/**
247+ * drm_bridge_unplug - declare a DRM bridge was unplugged and remove it
248+ * @bridge: DRM bridge
249+ *
250+ * This tells the bridge has been physically unplugged and no operations on
251+ * device resources must be done anymore. Entry-points can use
252+ * drm_bridge_enter() and drm_bridge_exit() to protect device resources in
253+ * a race free manner.
254+ *
255+ * Also unregisters the bridge.
256+ */
257+void drm_bridge_unplug(struct drm_bridge *bridge)
258+{
259+ bridge->unplugged = true;
260+
261+ synchronize_srcu(&drm_bridge_unplug_srcu);
262+
263+ drm_bridge_remove(bridge);
264+}
265+EXPORT_SYMBOL(drm_bridge_unplug);
266+
205267 static void __drm_bridge_free(struct kref *kref)
206268 {
207269 struct drm_bridge *bridge = container_of(kref, struct drm_bridge, refcount);
drivers/gpu/drm/drm_fb_helper.c+0−108
@@ -75,9 +75,6 @@ MODULE_PARM_DESC(drm_leak_fbdev_smem, · 74 unmodified lines
7575 "Allow unsafe leaking fbdev physical smem address [default=false]");
7676 #endif
7777
78−static LIST_HEAD(kernel_fb_helper_list);
79−static DEFINE_MUTEX(kernel_fb_helper_lock);
80−
8178 /**
8279 * DOC: fbdev helpers
8380 *
@@ -115,101 +112,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock); · 31 unmodified lines
115112 * mmap page writes.
116113 */
117114
118−static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
119−{
120− uint16_t *r_base, *g_base, *b_base;
121−
122− if (crtc->funcs->gamma_set == NULL)
123− return;
124−
125− r_base = crtc->gamma_store;
126− g_base = r_base + crtc->gamma_size;
127− b_base = g_base + crtc->gamma_size;
128−
129− crtc->funcs->gamma_set(crtc, r_base, g_base, b_base,
130− crtc->gamma_size, NULL);
131−}
132−
133−/**
134− * drm_fb_helper_debug_enter - implementation for &fb_ops.fb_debug_enter
135− * @info: fbdev registered by the helper
136− */
137−int drm_fb_helper_debug_enter(struct fb_info *info)
138−{
139− struct drm_fb_helper *helper = info->par;
140− const struct drm_crtc_helper_funcs *funcs;
141− struct drm_mode_set *mode_set;
142−
143− list_for_each_entry(helper, &kernel_fb_helper_list, kernel_fb_list) {
144− mutex_lock(&helper->client.modeset_mutex);
145− drm_client_for_each_modeset(mode_set, &helper->client) {
146− if (!mode_set->crtc->enabled)
147− continue;
148−
149− funcs = mode_set->crtc->helper_private;
150− if (funcs->mode_set_base_atomic == NULL)
151− continue;
152−
153− if (drm_drv_uses_atomic_modeset(mode_set->crtc->dev))
154− continue;
155−
156− funcs->mode_set_base_atomic(mode_set->crtc,
157− mode_set->fb,
158− mode_set->x,
159− mode_set->y,
160− ENTER_ATOMIC_MODE_SET);
161− }
162− mutex_unlock(&helper->client.modeset_mutex);
163− }
164−
165− return 0;
166−}
167−EXPORT_SYMBOL(drm_fb_helper_debug_enter);
168−
169−/**
170− * drm_fb_helper_debug_leave - implementation for &fb_ops.fb_debug_leave
171− * @info: fbdev registered by the helper
172− */
173−int drm_fb_helper_debug_leave(struct fb_info *info)
174−{
175− struct drm_fb_helper *helper = info->par;
176− struct drm_client_dev *client = &helper->client;
177− struct drm_device *dev = helper->dev;
178− struct drm_crtc *crtc;
179− const struct drm_crtc_helper_funcs *funcs;
180− struct drm_mode_set *mode_set;
181− struct drm_framebuffer *fb;
182−
183− mutex_lock(&client->modeset_mutex);
184− drm_client_for_each_modeset(mode_set, client) {
185− crtc = mode_set->crtc;
186− if (drm_drv_uses_atomic_modeset(crtc->dev))
187− continue;
188−
189− funcs = crtc->helper_private;
190− fb = crtc->primary->fb;
191−
192− if (!crtc->enabled)
193− continue;
194−
195− if (!fb) {
196− drm_err(dev, "no fb to restore?\n");
197− continue;
198− }
199−
200− if (funcs->mode_set_base_atomic == NULL)
201− continue;
202−
203− drm_fb_helper_restore_lut_atomic(mode_set->crtc);
204− funcs->mode_set_base_atomic(mode_set->crtc, fb, crtc->x,
205− crtc->y, LEAVE_ATOMIC_MODE_SET);
206− }
207− mutex_unlock(&client->modeset_mutex);
208−
209− return 0;
210−}
211−EXPORT_SYMBOL(drm_fb_helper_debug_leave);
212−
213115 static int
214116 __drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper,
215117 bool force)
@@ -397,7 +299,6 @@ void drm_fb_helper_prepare(struct drm_device *dev, struct drm_fb_helper *helper, · 181 unmodified lines
397299 if (!preferred_bpp)
398300 preferred_bpp = 32;
399301
400− INIT_LIST_HEAD(&helper->kernel_fb_list);
401302 spin_lock_init(&helper->damage_lock);
402303 INIT_WORK(&helper->resume_work, drm_fb_helper_resume_worker);
403304 INIT_WORK(&helper->damage_work, drm_fb_helper_damage_work);
@@ -534,11 +435,6 @@ void drm_fb_helper_fini(struct drm_fb_helper *fb_helper) · 130 unmodified lines
534435
535436 drm_fb_helper_release_info(fb_helper);
536437
537− mutex_lock(&kernel_fb_helper_lock);
538− if (!list_empty(&fb_helper->kernel_fb_list))
539− list_del(&fb_helper->kernel_fb_list);
540− mutex_unlock(&kernel_fb_helper_lock);
541−
542438 if (!fb_helper->client.funcs)
543439 drm_client_release(&fb_helper->client);
544440 }
@@ -1766,10 +1662,6 @@ __drm_fb_helper_initial_config_and_unlock(struct drm_fb_helper *fb_helper) · 1221 unmodified lines
17661662 drm_info(dev, "fb%d: %s frame buffer device\n",
17671663 info->node, info->fix.id);
17681664
1769− mutex_lock(&kernel_fb_helper_lock);
1770− list_add(&fb_helper->kernel_fb_list, &kernel_fb_helper_list);
1771− mutex_unlock(&kernel_fb_helper_lock);
1772−
17731665 return 0;
17741666
17751667 err_drm_fb_helper_release_info:
drivers/gpu/drm/drm_gem.c+155−49
@@ -29,6 +29,9 @@ · 28 unmodified lines
2929 #include <linux/export.h>
3030 #include <linux/file.h>
3131 #include <linux/fs.h>
32+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
33+#include <linux/fs_context.h>
34+#endif
3235 #include <linux/iosys-map.h>
3336 #include <linux/mem_encrypt.h>
3437 #include <linux/mm.h>
@@ -36,6 +39,7 @@ · 1 unmodified line
3639 #include <linux/module.h>
3740 #include <linux/pagemap.h>
3841 #include <linux/pagevec.h>
42+#include <linux/sched/mm.h>
3943 #include <linux/shmem_fs.h>
4044 #include <linux/slab.h>
4145 #include <linux/string_helpers.h>
@@ -81,6 +85,60 @@ · 39 unmodified lines
8185 * up at a later date, and as our interface with shmfs for memory allocation.
8286 */
8387
88+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
89+static void drm_gem_huge_mnt_free(struct drm_device *dev, void *data)
90+{
91+ kern_unmount(dev->huge_mnt);
92+}
93+
94+/**
95+ * drm_gem_huge_mnt_create - Create, mount and use a huge tmpfs mountpoint
96+ * @dev: DRM device that will use the huge tmpfs mountpoint
97+ * @value: huge tmpfs mount option value
98+ *
99+ * This function creates and mounts a dedicated huge tmpfs mountpoint for the
100+ * lifetime of the DRM device @dev which is used at GEM object initialization
101+ * with drm_gem_object_init().
102+ *
103+ * The most common option for @value is "within_size" which only allocates huge
104+ * pages if the page will be fully within the GEM object size. "always",
105+ * "advise" and "never" are supported too but the latter would just create a
106+ * mountpoint similar to the default one (`shm_mnt`). See shmemfs and
107+ * Transparent Hugepage for more information.
108+ *
109+ * Returns:
110+ * 0 on success or a negative error code on failure.
111+ */
112+int drm_gem_huge_mnt_create(struct drm_device *dev, const char *value)
113+{
114+ struct file_system_type *type;
115+ struct fs_context *fc;
116+ int ret;
117+
118+ if (unlikely(drm_gem_get_huge_mnt(dev)))
119+ return 0;
120+
121+ type = get_fs_type("tmpfs");
122+ if (unlikely(!type))
123+ return -EOPNOTSUPP;
124+ fc = fs_context_for_mount(type, SB_KERNMOUNT);
125+ if (IS_ERR(fc))
126+ return PTR_ERR(fc);
127+ ret = vfs_parse_fs_string(fc, "source", "tmpfs");
128+ if (unlikely(ret))
129+ return -ENOPARAM;
130+ ret = vfs_parse_fs_string(fc, "huge", value);
131+ if (unlikely(ret))
132+ return -ENOPARAM;
133+
134+ dev->huge_mnt = fc_mount_longterm(fc);
135+ put_fs_context(fc);
136+
137+ return drmm_add_action_or_reset(dev, drm_gem_huge_mnt_free, NULL);
138+}
139+EXPORT_SYMBOL_GPL(drm_gem_huge_mnt_create);
140+#endif
141+
84142 static void
85143 drm_gem_init_release(struct drm_device *dev, void *ptr)
86144 {
@@ -113,29 +171,28 @@ drm_gem_init(struct drm_device *dev) · 26 unmodified lines
113171 }
114172
115173 /**
116− * drm_gem_object_init_with_mnt - initialize an allocated shmem-backed GEM
117− * object in a given shmfs mountpoint
174+ * drm_gem_object_init - initialize an allocated shmem-backed GEM object
118175 *
119176 * @dev: drm_device the object should be initialized for
120177 * @obj: drm_gem_object to initialize
121178 * @size: object size
122− * @gemfs: tmpfs mount where the GEM object will be created. If NULL, use
123− * the usual tmpfs mountpoint (`shm_mnt`).
124179 *
125180 * Initialize an already allocated GEM object of the specified size with
126− * shmfs backing store.
181+ * shmfs backing store. A huge mountpoint can be used by calling
182+ * drm_gem_huge_mnt_create() beforehand.
127183 */
128−int drm_gem_object_init_with_mnt(struct drm_device *dev,
129− struct drm_gem_object *obj, size_t size,
130− struct vfsmount *gemfs)
184+int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj,
185+ size_t size)
131186 {
187+ struct vfsmount *huge_mnt;
132188 struct file *filp;
133189
134190 drm_gem_private_object_init(dev, obj, size);
135191
136− if (gemfs)
137− filp = shmem_file_setup_with_mnt(gemfs, "drm mm object", size,
138− VM_NORESERVE);
192+ huge_mnt = drm_gem_get_huge_mnt(dev);
193+ if (huge_mnt)
194+ filp = shmem_file_setup_with_mnt(huge_mnt, "drm mm object",
195+ size, VM_NORESERVE);
139196 else
140197 filp = shmem_file_setup("drm mm object", size, VM_NORESERVE);
141198
@@ -146,22 +203,6 @@ int drm_gem_object_init_with_mnt(struct drm_device *dev, · 4 unmodified lines
146203
147204 return 0;
148205 }
149−EXPORT_SYMBOL(drm_gem_object_init_with_mnt);
150−
151−/**
152− * drm_gem_object_init - initialize an allocated shmem-backed GEM object
153− * @dev: drm_device the object should be initialized for
154− * @obj: drm_gem_object to initialize
155− * @size: object size
156− *
157− * Initialize an already allocated GEM object of the specified size with
158− * shmfs backing store.
159− */
160−int drm_gem_object_init(struct drm_device *dev, struct drm_gem_object *obj,
161− size_t size)
162−{
163− return drm_gem_object_init_with_mnt(dev, obj, size, NULL);
164−}
165206 EXPORT_SYMBOL(drm_gem_object_init);
166207
167208 /**
@@ -1181,36 +1222,27 @@ err_drm_gem_object_put: · 1013 unmodified lines
11811222 }
11821223 EXPORT_SYMBOL(drm_gem_mmap_obj);
11831224
1184−/**
1185− * drm_gem_mmap - memory map routine for GEM objects
1186− * @filp: DRM file pointer
1187− * @vma: VMA for the area to be mapped
1188− *
1189− * If a driver supports GEM object mapping, mmap calls on the DRM file
1190− * descriptor will end up here.
1191− *
1192− * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
1193− * contain the fake offset we created when the GTT map ioctl was called on
1194− * the object) and map it with a call to drm_gem_mmap_obj().
1195− *
1196− * If the caller is not granted access to the buffer object, the mmap will fail
1197− * with EACCES. Please see the vma manager for more information.
1225+/*
1226+ * Look up a GEM object in offset space based on the exact start address. The
1227+ * caller must be granted access to the object. Returns a GEM object on success
1228+ * or a negative error code on failure. The returned GEM object needs to be
1229+ * released with drm_gem_object_put().
11981230 */
1199−int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
1231+static struct drm_gem_object *
1232+drm_gem_object_lookup_at_offset(struct file *filp, unsigned long start,
1233+ unsigned long pages)
12001234 {
12011235 struct drm_file *priv = filp->private_data;
12021236 struct drm_device *dev = priv->minor->dev;
12031237 struct drm_gem_object *obj = NULL;
12041238 struct drm_vma_offset_node *node;
1205− int ret;
12061239
12071240 if (drm_dev_is_unplugged(dev))
1208− return -ENODEV;
1241+ return ERR_PTR(-ENODEV);
12091242
12101243 drm_vma_offset_lock_lookup(dev->vma_offset_manager);
12111244 node = drm_vma_offset_exact_lookup_locked(dev->vma_offset_manager,
1212− vma->vm_pgoff,
1213− vma_pages(vma));
1245+ start, pages);
12141246 if (likely(node)) {
12151247 obj = container_of(node, struct drm_gem_object, vma_node);
12161248 /*
@@ -1229,14 +1261,88 @@ int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma) · 12 unmodified lines
12291261 drm_vma_offset_unlock_lookup(dev->vma_offset_manager);
12301262
12311263 if (!obj)
1232− return -EINVAL;
1264+ return ERR_PTR(-EINVAL);
12331265
12341266 if (!drm_vma_node_is_allowed(node, priv)) {
12351267 drm_gem_object_put(obj);
1236− return -EACCES;
1268+ return ERR_PTR(-EACCES);
12371269 }
12381270
1239− ret = drm_gem_mmap_obj(obj, drm_vma_node_size(node) << PAGE_SHIFT,
1271+ return obj;
1272+}
1273+
1274+#ifdef CONFIG_MMU
1275+/**
1276+ * drm_gem_get_unmapped_area - get memory mapping region routine for GEM objects
1277+ * @filp: DRM file pointer
1278+ * @uaddr: User address hint
1279+ * @len: Mapping length
1280+ * @pgoff: Offset (in pages)
1281+ * @flags: Mapping flags
1282+ *
1283+ * If a driver supports GEM object mapping, before ending up in drm_gem_mmap(),
1284+ * mmap calls on the DRM file descriptor will first try to find a free linear
1285+ * address space large enough for a mapping. Since GEM objects are backed by
1286+ * shmem buffers, this should preferably be handled by the shmem virtual memory
1287+ * filesystem which can appropriately align addresses to huge page sizes when
1288+ * needed.
1289+ *
1290+ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
1291+ * contain the fake offset we created) and call shmem_get_unmapped_area() with
1292+ * the right file pointer.
1293+ *
1294+ * If a GEM object is not available at the given offset or if the caller is not
1295+ * granted access to it, fall back to mm_get_unmapped_area().
1296+ */
1297+unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
1298+ unsigned long len, unsigned long pgoff,
1299+ unsigned long flags)
1300+{
1301+ struct drm_gem_object *obj;
1302+ unsigned long ret;
1303+
1304+ obj = drm_gem_object_lookup_at_offset(filp, pgoff, len >> PAGE_SHIFT);
1305+ if (IS_ERR(obj) || !obj->filp || !obj->filp->f_op->get_unmapped_area)
1306+ return mm_get_unmapped_area(filp, uaddr, len, 0,
1307+ flags);
1308+
1309+ ret = obj->filp->f_op->get_unmapped_area(obj->filp, uaddr, len, 0,
1310+ flags);
1311+
1312+ drm_gem_object_put(obj);
1313+
1314+ return ret;
1315+}
1316+EXPORT_SYMBOL_GPL(drm_gem_get_unmapped_area);
1317+#endif
1318+
1319+/**
1320+ * drm_gem_mmap - memory map routine for GEM objects
1321+ * @filp: DRM file pointer
1322+ * @vma: VMA for the area to be mapped
1323+ *
1324+ * If a driver supports GEM object mapping, mmap calls on the DRM file
1325+ * descriptor will end up here.
1326+ *
1327+ * Look up the GEM object based on the offset passed in (vma->vm_pgoff will
1328+ * contain the fake offset we created) and map it with a call to
1329+ * drm_gem_mmap_obj().
1330+ *
1331+ * If the caller is not granted access to the buffer object, the mmap will fail
1332+ * with EACCES. Please see the vma manager for more information.
1333+ */
1334+int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma)
1335+{
1336+ struct drm_gem_object *obj;
1337+ int ret;
1338+
1339+ obj = drm_gem_object_lookup_at_offset(filp, vma->vm_pgoff,
1340+ vma_pages(vma));
1341+ if (IS_ERR(obj))
1342+ return PTR_ERR(obj);
1343+
1344+ ret = drm_gem_mmap_obj(obj,
1345+ drm_vma_node_size(&obj->vma_node) << PAGE_SHIFT,
12401346 vma);
12411347
12421348 drm_gem_object_put(obj);
drivers/gpu/drm/drm_gem_shmem_helper.c+41−36
@@ -50,7 +50,7 @@ static const struct drm_gem_object_funcs drm_gem_shmem_funcs = { · 49 unmodified lines
5050 };
5151
5252 static int __drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem,
53− size_t size, bool private, struct vfsmount *gemfs)
53+ size_t size, bool private)
5454 {
5555 struct drm_gem_object *obj = &shmem->base;
5656 int ret = 0;
@@ -62,7 +62,7 @@ static int __drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_obj · 5 unmodified lines
6262 drm_gem_private_object_init(dev, obj, size);
6363 shmem->map_wc = false; /* dma-buf mappings use always writecombine */
6464 } else {
65− ret = drm_gem_object_init_with_mnt(dev, obj, size, gemfs);
65+ ret = drm_gem_object_init(dev, obj, size);
6666 }
6767 if (ret) {
6868 drm_gem_private_object_fini(obj);
@@ -103,13 +103,12 @@ err_release: · 34 unmodified lines
103103 */
104104 int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size)
105105 {
106− return __drm_gem_shmem_init(dev, shmem, size, false, NULL);
106+ return __drm_gem_shmem_init(dev, shmem, size, false);
107107 }
108108 EXPORT_SYMBOL_GPL(drm_gem_shmem_init);
109109
110110 static struct drm_gem_shmem_object *
111−__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private,
112− struct vfsmount *gemfs)
111+__drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private)
113112 {
114113 struct drm_gem_shmem_object *shmem;
115114 struct drm_gem_object *obj;
@@ -129,7 +128,7 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private, · 13 unmodified lines
129128 obj = &shmem->base;
130129 }
131130
132− ret = __drm_gem_shmem_init(dev, shmem, size, private, gemfs);
131+ ret = __drm_gem_shmem_init(dev, shmem, size, private);
133132 if (ret) {
134133 kfree(obj);
135134 return ERR_PTR(ret);
@@ -150,31 +149,10 @@ __drm_gem_shmem_create(struct drm_device *dev, size_t size, bool private, · 14 unmodified lines
150149 */
151150 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size)
152151 {
153− return __drm_gem_shmem_create(dev, size, false, NULL);
152+ return __drm_gem_shmem_create(dev, size, false);
154153 }
155154 EXPORT_SYMBOL_GPL(drm_gem_shmem_create);
156155
157−/**
158− * drm_gem_shmem_create_with_mnt - Allocate an object with the given size in a
159− * given mountpoint
160− * @dev: DRM device
161− * @size: Size of the object to allocate
162− * @gemfs: tmpfs mount where the GEM object will be created
163− *
164− * This function creates a shmem GEM object in a given tmpfs mountpoint.
165− *
166− * Returns:
167− * A struct drm_gem_shmem_object * on success or an ERR_PTR()-encoded negative
168− * error code on failure.
169− */
170−struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,
171− size_t size,
172− struct vfsmount *gemfs)
173−{
174− return __drm_gem_shmem_create(dev, size, false, gemfs);
175−}
176−EXPORT_SYMBOL_GPL(drm_gem_shmem_create_with_mnt);
177−
178156 /**
179157 * drm_gem_shmem_release - Release resources associated with a shmem GEM object.
180158 * @shmem: shmem GEM object
@@ -567,6 +545,26 @@ int drm_gem_shmem_dumb_create(struct drm_file *file, struct drm_device *dev, · 386 unmodified lines
567545 }
568546 EXPORT_SYMBOL_GPL(drm_gem_shmem_dumb_create);
569547
548+static bool drm_gem_shmem_try_map_pmd(struct vm_fault *vmf, unsigned long addr,
549+ struct page *page)
550+{
551+#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
552+ unsigned long pfn = page_to_pfn(page);
553+ unsigned long paddr = pfn << PAGE_SHIFT;
554+ bool aligned = (addr & ~PMD_MASK) == (paddr & ~PMD_MASK);
555+
556+ if (aligned &&
557+ pmd_none(*vmf->pmd) &&
558+ folio_test_pmd_mappable(page_folio(page))) {
559+ pfn &= PMD_MASK >> PAGE_SHIFT;
560+ if (vmf_insert_pfn_pmd(vmf, pfn, false) == VM_FAULT_NOPAGE)
561+ return true;
562+ }
563+#endif
564+
565+ return false;
566+}
567+
570568 static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf)
571569 {
572570 struct vm_area_struct *vma = vmf->vma;
@@ -574,11 +572,12 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) · 1 unmodified line
574572 struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
575573 loff_t num_pages = obj->size >> PAGE_SHIFT;
576574 vm_fault_t ret;
577− struct page *page;
575+ struct page **pages = shmem->pages;
578576 pgoff_t page_offset;
577+ unsigned long pfn;
579578
580− /* We don't use vmf->pgoff since that has the fake offset */
581− page_offset = (vmf->address - vma->vm_start) >> PAGE_SHIFT;
579+ /* Offset to faulty address in the VMA. */
580+ page_offset = vmf->pgoff - vma->vm_pgoff;
582581
583582 dma_resv_lock(shmem->base.resv, NULL);
584583
@@ -586,12 +585,18 @@ static vm_fault_t drm_gem_shmem_fault(struct vm_fault *vmf) · 1 unmodified line
586585 drm_WARN_ON_ONCE(obj->dev, !shmem->pages) ||
587586 shmem->madv < 0) {
588587 ret = VM_FAULT_SIGBUS;
589− } else {
590− page = shmem->pages[page_offset];
588+ goto out;
589+ }
591590
592− ret = vmf_insert_pfn(vma, vmf->address, page_to_pfn(page));
591+ if (drm_gem_shmem_try_map_pmd(vmf, vmf->address, pages[page_offset])) {
592+ ret = VM_FAULT_NOPAGE;
593+ goto out;
593594 }
594595
596+ pfn = page_to_pfn(pages[page_offset]);
597+ ret = vmf_insert_pfn(vma, vmf->address, pfn);
598+
599+ out:
595600 dma_resv_unlock(shmem->base.resv);
596601
597602 return ret;
@@ -824,7 +829,7 @@ drm_gem_shmem_prime_import_sg_table(struct drm_device *dev, · 226 unmodified lines
824829 size_t size = PAGE_ALIGN(attach->dmabuf->size);
825830 struct drm_gem_shmem_object *shmem;
826831
827− shmem = __drm_gem_shmem_create(dev, size, true, NULL);
832+ shmem = __drm_gem_shmem_create(dev, size, true);
828833 if (IS_ERR(shmem))
829834 return ERR_CAST(shmem);
830835
@@ -872,7 +877,7 @@ struct drm_gem_object *drm_gem_shmem_prime_import_no_map(struct drm_device *dev, · 41 unmodified lines
872877
873878 size = PAGE_ALIGN(attach->dmabuf->size);
874879
875− shmem = __drm_gem_shmem_create(dev, size, true, NULL);
880+ shmem = __drm_gem_shmem_create(dev, size, true);
876881 if (IS_ERR(shmem)) {
877882 ret = PTR_ERR(shmem);
878883 goto fail_detach;
drivers/gpu/drm/drm_panic.c+62−13
@@ -39,12 +39,6 @@ MODULE_AUTHOR("Jocelyn Falempe"); · 38 unmodified lines
3939 MODULE_DESCRIPTION("DRM panic handler");
4040 MODULE_LICENSE("GPL");
4141
42−static char drm_panic_screen[16] = CONFIG_DRM_PANIC_SCREEN;
43−module_param_string(panic_screen, drm_panic_screen, sizeof(drm_panic_screen), 0644);
44−MODULE_PARM_DESC(panic_screen,
45− "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default="
46− CONFIG_DRM_PANIC_SCREEN "]");
47−
4842 /**
4943 * DOC: overview
5044 *
@@ -813,14 +807,59 @@ static void draw_panic_static_qr_code(struct drm_scanout_buffer *sb) · 762 unmodified lines
813807 draw_panic_static_user(sb);
814808 }
815809 #else
816−static void draw_panic_static_qr_code(struct drm_scanout_buffer *sb)
810+static void drm_panic_qr_init(void) {};
811+static void drm_panic_qr_exit(void) {};
812+#endif
813+
814+enum drm_panic_type {
815+ DRM_PANIC_TYPE_KMSG,
816+ DRM_PANIC_TYPE_USER,
817+ DRM_PANIC_TYPE_QR,
818+};
819+
820+static enum drm_panic_type drm_panic_type = -1;
821+
822+static const char *drm_panic_type_map[] = {
823+ [DRM_PANIC_TYPE_KMSG] = "kmsg",
824+ [DRM_PANIC_TYPE_USER] = "user",
825+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
826+ [DRM_PANIC_TYPE_QR] = "qr",
827+#endif
828+};
829+
830+static int drm_panic_type_set(const char *val, const struct kernel_param *kp)
817831 {
818− draw_panic_static_user(sb);
832+ unsigned int i;
833+
834+ for (i = 0; i < ARRAY_SIZE(drm_panic_type_map); i++) {
835+ if (!strcmp(val, drm_panic_type_map[i])) {
836+ drm_panic_type = i;
837+ return 0;
838+ }
839+ }
840+
841+ return -EINVAL;
819842 }
820843
821−static void drm_panic_qr_init(void) {};
822−static void drm_panic_qr_exit(void) {};
844+static int drm_panic_type_get(char *buffer, const struct kernel_param *kp)
845+{
846+ return scnprintf(buffer, PAGE_SIZE, "%s\n",
847+ drm_panic_type_map[drm_panic_type]);
848+}
849+
850+static const struct kernel_param_ops drm_panic_ops = {
851+ .set = drm_panic_type_set,
852+ .get = drm_panic_type_get,
853+};
854+
855+module_param_cb(panic_screen, &drm_panic_ops, NULL, 0644);
856+MODULE_PARM_DESC(panic_screen,
857+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
858+ "Choose what will be displayed by drm_panic, 'user', 'kmsg' or 'qr' [default="
859+#else
860+ "Choose what will be displayed by drm_panic, 'user' or 'kmsg' [default="
823861 #endif
862+ CONFIG_DRM_PANIC_SCREEN "]");
824863
825864 /*
826865 * drm_panic_is_format_supported()
@@ -838,11 +877,19 @@ static bool drm_panic_is_format_supported(const struct drm_format_info *format) · 11 unmodified lines
838877
839878 static void draw_panic_dispatch(struct drm_scanout_buffer *sb)
840879 {
841− if (!strcmp(drm_panic_screen, "kmsg")) {
880+ switch (drm_panic_type) {
881+ case DRM_PANIC_TYPE_KMSG:
842882 draw_panic_static_kmsg(sb);
843− } else if (!strcmp(drm_panic_screen, "qr_code")) {
883+ break;
884+
885+#if IS_ENABLED(CONFIG_DRM_PANIC_SCREEN_QR_CODE)
886+ case DRM_PANIC_TYPE_QR:
844887 draw_panic_static_qr_code(sb);
845− } else {
888+ break;
889+#endif
890+
891+ case DRM_PANIC_TYPE_USER:
892+ default:
846893 draw_panic_static_user(sb);
847894 }
848895 }
@@ -1025,6 +1072,8 @@ void drm_panic_unregister(struct drm_device *dev) · 176 unmodified lines
10251072 */
10261073 void __init drm_panic_init(void)
10271074 {
1075+ if (drm_panic_type == -1)
1076+ drm_panic_type_set(CONFIG_DRM_PANIC_SCREEN, NULL);
10281077 drm_panic_qr_init();
10291078 }
10301079
drivers/gpu/drm/drm_plane.c+2−2
@@ -1867,9 +1867,9 @@ int drm_plane_create_color_pipeline_property(struct drm_plane *plane, · 1866 unmodified lines
18671867 prop = drm_property_create_enum(plane->dev, DRM_MODE_PROP_ATOMIC,
18681868 "COLOR_PIPELINE",
18691869 all_pipelines, len);
1870− if (IS_ERR(prop)) {
1870+ if (!prop) {
18711871 kfree(all_pipelines);
1872− return PTR_ERR(prop);
1872+ return -ENOMEM;
18731873 }
18741874
18751875 drm_object_attach_property(&plane->base, prop, 0);
drivers/gpu/drm/drm_vblank.c+21−31
@@ -551,7 +551,7 @@ int drm_vblank_init(struct drm_device *dev, unsigned int num_crtcs) · 550 unmodified lines
551551 dev->num_crtcs = num_crtcs;
552552
553553 for (i = 0; i < num_crtcs; i++) {
554− struct drm_vblank_crtc *vblank = &dev->vblank[i];
554+ struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, i);
555555
556556 vblank->dev = dev;
557557 vblank->pipe = i;
@@ -605,7 +605,9 @@ EXPORT_SYMBOL(drm_dev_has_vblank); · 47 unmodified lines
605605 */
606606 wait_queue_head_t *drm_crtc_vblank_waitqueue(struct drm_crtc *crtc)
607607 {
608− return &crtc->dev->vblank[drm_crtc_index(crtc)].queue;
608+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
609+
610+ return &vblank->queue;
609611 }
610612 EXPORT_SYMBOL(drm_crtc_vblank_waitqueue);
611613
@@ -710,7 +712,6 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal( · 98 unmodified lines
710712 {
711713 struct drm_device *dev = crtc->dev;
712714 unsigned int pipe = crtc->index;
713− struct drm_vblank_crtc *vblank = &dev->vblank[pipe];
714715 struct timespec64 ts_etime, ts_vblank_time;
715716 ktime_t stime, etime;
716717 bool vbl_status;
@@ -729,10 +730,13 @@ drm_crtc_vblank_helper_get_vblank_timestamp_internal( · 12 unmodified lines
729730 return false;
730731 }
731732
732− if (drm_drv_uses_atomic_modeset(dev))
733+ if (drm_drv_uses_atomic_modeset(dev)) {
734+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
735+
733736 mode = &vblank->hwmode;
734− else
737+ } else {
735738 mode = &crtc->hwmode;
739+ }
736740
737741 /* If mode timing undefined, just return as no-op:
738742 * Happens during initial modesetting of a crtc.
@@ -1285,29 +1289,27 @@ void drm_crtc_vblank_put(struct drm_crtc *crtc) · 546 unmodified lines
12851289 EXPORT_SYMBOL(drm_crtc_vblank_put);
12861290
12871291 /**
1288− * drm_wait_one_vblank - wait for one vblank
1289− * @dev: DRM device
1290− * @pipe: CRTC index
1292+ * drm_crtc_wait_one_vblank - wait for one vblank
1293+ * @crtc: DRM crtc
12911294 *
1292− * This waits for one vblank to pass on @pipe, using the irq driver interfaces.
1293− * It is a failure to call this when the vblank irq for @pipe is disabled, e.g.
1295+ * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
1296+ * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
12941297 * due to lack of driver support or because the crtc is off.
12951298 *
1296− * This is the legacy version of drm_crtc_wait_one_vblank().
1299+ * Returns: 0 on success, negative error on failures.
12971300 */
1298−void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe)
1301+int drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
12991302 {
1300− struct drm_vblank_crtc *vblank = drm_vblank_crtc(dev, pipe);
1303+ struct drm_device *dev = crtc->dev;
1304+ int pipe = drm_crtc_index(crtc);
1305+ struct drm_vblank_crtc *vblank = drm_crtc_vblank_crtc(crtc);
13011306 int ret;
13021307 u64 last;
13031308
1304− if (drm_WARN_ON(dev, pipe >= dev->num_crtcs))
1305− return;
1306−
13071309 ret = drm_vblank_get(dev, pipe);
13081310 if (drm_WARN(dev, ret, "vblank not available on crtc %i, ret=%i\n",
13091311 pipe, ret))
1310− return;
1312+ return ret;
13111313
13121314 last = drm_vblank_count(dev, pipe);
13131315
@@ -1318,20 +1320,8 @@ void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe) · 4 unmodified lines
13181320 drm_WARN(dev, ret == 0, "vblank wait timed out on crtc %i\n", pipe);
13191321
13201322 drm_vblank_put(dev, pipe);
1321−}
1322−EXPORT_SYMBOL(drm_wait_one_vblank);
13231323
1324−/**
1325− * drm_crtc_wait_one_vblank - wait for one vblank
1326− * @crtc: DRM crtc
1327− *
1328− * This waits for one vblank to pass on @crtc, using the irq driver interfaces.
1329− * It is a failure to call this when the vblank irq for @crtc is disabled, e.g.
1330− * due to lack of driver support or because the crtc is off.
1331− */
1332−void drm_crtc_wait_one_vblank(struct drm_crtc *crtc)
1333−{
1334− drm_wait_one_vblank(crtc->dev, drm_crtc_index(crtc));
1324+ return ret ? 0 : -ETIMEDOUT;
13351325 }
13361326 EXPORT_SYMBOL(drm_crtc_wait_one_vblank);
13371327
@@ -1794,7 +1784,7 @@ int drm_wait_vblank_ioctl(struct drm_device *dev, void *data, · 456 unmodified lines
17941784 if (pipe >= dev->num_crtcs)
17951785 return -EINVAL;
17961786
1797− vblank = &dev->vblank[pipe];
1787+ vblank = drm_vblank_crtc(dev, pipe);
17981788
17991789 /* If the counter is currently enabled and accurate, short-circuit
18001790 * queries to return the cached timestamp of the last vblank.
drivers/gpu/drm/hyperv/Kconfig+14−0
@@ -0,0 +1,14 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+config DRM_HYPERV
3+ tristate "DRM Support for Hyper-V synthetic video device"
4+ depends on DRM && PCI && HYPERV_VMBUS
5+ select DRM_CLIENT_SELECTION
6+ select DRM_KMS_HELPER
7+ select DRM_GEM_SHMEM_HELPER
8+ help
9+ This is a KMS driver for Hyper-V synthetic video device. Choose this
10+ option if you would like to enable drm driver for Hyper-V virtual
11+ machine. Unselect Hyper-V framebuffer driver (CONFIG_FB_HYPERV) so
12+ that DRM driver is used by default.
13+
14+ If M is selected the module will be called hyperv_drm.
drivers/gpu/drm/i915/Makefile+1−2
@@ -170,8 +170,7 @@ gem-y += \ · 169 unmodified lines
170170 gem/i915_gem_ttm_move.o \
171171 gem/i915_gem_ttm_pm.o \
172172 gem/i915_gem_userptr.o \
173− gem/i915_gem_wait.o \
174− gem/i915_gemfs.o
173+ gem/i915_gem_wait.o
175174 i915-y += \
176175 $(gem-y) \
177176 i915_active.o \
drivers/gpu/drm/i915/gem/i915_gem_object_types.h+6−4
@@ -348,12 +348,13 @@ struct drm_i915_gem_object { · 347 unmodified lines
348348 */
349349 #define I915_BO_ALLOC_GPU_ONLY BIT(6)
350350 #define I915_BO_ALLOC_CCS_AUX BIT(7)
351+#define I915_BO_ALLOC_NOTHP BIT(8)
351352 /*
352353 * Object is allowed to retain its initial data and will not be cleared on first
353354 * access if used along with I915_BO_ALLOC_USER. This is mainly to keep
354355 * preallocated framebuffer data intact while transitioning it to i915drmfb.
355356 */
356−#define I915_BO_PREALLOC BIT(8)
357+#define I915_BO_PREALLOC BIT(9)
357358 #define I915_BO_ALLOC_FLAGS (I915_BO_ALLOC_CONTIGUOUS | \
358359 I915_BO_ALLOC_VOLATILE | \
359360 I915_BO_ALLOC_CPU_CLEAR | \
@@ -362,10 +363,11 @@ struct drm_i915_gem_object { · 2 unmodified lines
362363 I915_BO_ALLOC_PM_EARLY | \
363364 I915_BO_ALLOC_GPU_ONLY | \
364365 I915_BO_ALLOC_CCS_AUX | \
366+ I915_BO_ALLOC_NOTHP | \
365367 I915_BO_PREALLOC)
366−#define I915_BO_READONLY BIT(9)
367−#define I915_TILING_QUIRK_BIT 10 /* unknown swizzling; do not release! */
368−#define I915_BO_PROTECTED BIT(11)
368+#define I915_BO_READONLY BIT(10)
369+#define I915_TILING_QUIRK_BIT 11 /* unknown swizzling; do not release! */
370+#define I915_BO_PROTECTED BIT(12)
369371 /**
370372 * @mem_flags - Mutable placement-related flags
371373 *
drivers/gpu/drm/i915/gem/i915_gem_shmem.c+41−17
@@ -9,14 +9,16 @@ · 8 unmodified lines
99 #include <linux/uio.h>
1010
1111 #include <drm/drm_cache.h>
12+#include <drm/drm_gem.h>
13+#include <drm/drm_print.h>
1214
1315 #include "gem/i915_gem_region.h"
1416 #include "i915_drv.h"
1517 #include "i915_gem_object.h"
1618 #include "i915_gem_tiling.h"
17−#include "i915_gemfs.h"
1819 #include "i915_scatterlist.h"
1920 #include "i915_trace.h"
21+#include "i915_utils.h"
2022
2123 /*
2224 * Move folios to appropriate lru and release the batch, decrementing the
@@ -494,9 +496,11 @@ const struct drm_i915_gem_object_ops i915_gem_shmem_ops = { · 471 unmodified lines
494496
495497 static int __create_shmem(struct drm_i915_private *i915,
496498 struct drm_gem_object *obj,
497− resource_size_t size)
499+ resource_size_t size,
500+ unsigned int flags)
498501 {
499− unsigned long flags = VM_NORESERVE;
502+ unsigned long shmem_flags = VM_NORESERVE;
503+ struct vfsmount *huge_mnt;
500504 struct file *filp;
501505
502506 drm_gem_private_object_init(&i915->drm, obj, size);
@@ -515,11 +519,12 @@ static int __create_shmem(struct drm_i915_private *i915, · 12 unmodified lines
515519 if (BITS_PER_LONG == 64 && size > MAX_LFS_FILESIZE)
516520 return -E2BIG;
517521
518− if (i915->mm.gemfs)
519− filp = shmem_file_setup_with_mnt(i915->mm.gemfs, "i915", size,
520− flags);
522+ huge_mnt = drm_gem_get_huge_mnt(&i915->drm);
523+ if (!(flags & I915_BO_ALLOC_NOTHP) && huge_mnt)
524+ filp = shmem_file_setup_with_mnt(huge_mnt, "i915", size,
525+ shmem_flags);
521526 else
522− filp = shmem_file_setup("i915", size, flags);
527+ filp = shmem_file_setup("i915", size, shmem_flags);
523528 if (IS_ERR(filp))
524529 return PTR_ERR(filp);
525530
@@ -548,7 +553,7 @@ static int shmem_object_init(struct intel_memory_region *mem, · 22 unmodified lines
548553 gfp_t mask;
549554 int ret;
550555
551− ret = __create_shmem(i915, &obj->base, size);
556+ ret = __create_shmem(i915, &obj->base, size, flags);
552557 if (ret)
553558 return ret;
554559
@@ -644,21 +649,40 @@ fail: · 89 unmodified lines
644649
645650 static int init_shmem(struct intel_memory_region *mem)
646651 {
647− i915_gemfs_init(mem->i915);
648− intel_memory_region_set_name(mem, "system");
652+ struct drm_i915_private *i915 = mem->i915;
649653
650− return 0; /* We have fallback to the kernel mnt if gemfs init failed. */
651−}
654+ /*
655+ * By creating our own shmemfs mountpoint, we can pass in
656+ * mount flags that better match our usecase.
657+ *
658+ * One example, although it is probably better with a per-file
659+ * control, is selecting huge page allocations ("huge=within_size").
660+ * However, we only do so on platforms which benefit from it, or to
661+ * offset the overhead of iommu lookups, where with latter it is a net
662+ * win even on platforms which would otherwise see some performance
663+ * regressions such a slow reads issue on Broadwell and Skylake.
664+ */
652665
653−static int release_shmem(struct intel_memory_region *mem)
654−{
655− i915_gemfs_fini(mem->i915);
656− return 0;
666+ if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915))
667+ goto no_thp;
668+
669+ drm_gem_huge_mnt_create(&i915->drm, "within_size");
670+ if (drm_gem_get_huge_mnt(&i915->drm))
671+ drm_info(&i915->drm, "Using Transparent Hugepages\n");
672+ else
673+ drm_notice(&i915->drm,
674+ "Transparent Hugepage support is recommended for optimal performance%s\n",
675+ GRAPHICS_VER(i915) >= 11 ? " on this platform!" :
676+ " when IOMMU is enabled!");
677+
678+ no_thp:
679+ intel_memory_region_set_name(mem, "system");
680+
681+ return 0; /* We have fallback to the kernel mnt if huge mnt failed. */
657682 }
658683
659684 static const struct intel_memory_region_ops shmem_region_ops = {
660685 .init = init_shmem,
661− .release = release_shmem,
662686 .init_object = shmem_object_init,
663687 };
664688
drivers/gpu/drm/i915/gem/i915_gemfs.c+0−71
@@ -1,71 +0,0 @@
1−// SPDX-License-Identifier: MIT
2−/*
3− * Copyright © 2017 Intel Corporation
4− */
5−
6−#include <linux/fs.h>
7−#include <linux/mount.h>
8−#include <linux/fs_context.h>
9−
10−#include <drm/drm_print.h>
11−
12−#include "i915_drv.h"
13−#include "i915_gemfs.h"
14−#include "i915_utils.h"
15−
16−void i915_gemfs_init(struct drm_i915_private *i915)
17−{
18− struct file_system_type *type;
19− struct fs_context *fc;
20− struct vfsmount *gemfs;
21− int ret;
22−
23− /*
24− * By creating our own shmemfs mountpoint, we can pass in
25− * mount flags that better match our usecase.
26− *
27− * One example, although it is probably better with a per-file
28− * control, is selecting huge page allocations ("huge=within_size").
29− * However, we only do so on platforms which benefit from it, or to
30− * offset the overhead of iommu lookups, where with latter it is a net
31− * win even on platforms which would otherwise see some performance
32− * regressions such a slow reads issue on Broadwell and Skylake.
33− */
34−
35− if (GRAPHICS_VER(i915) < 11 && !i915_vtd_active(i915))
36− return;
37−
38− if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
39− goto err;
40−
41− type = get_fs_type("tmpfs");
42− if (!type)
43− goto err;
44−
45− fc = fs_context_for_mount(type, SB_KERNMOUNT);
46− if (IS_ERR(fc))
47− goto err;
48− ret = vfs_parse_fs_string(fc, "source", "tmpfs");
49− if (!ret)
50− ret = vfs_parse_fs_string(fc, "huge", "within_size");
51− if (!ret)
52− gemfs = fc_mount_longterm(fc);
53− put_fs_context(fc);
54− if (ret)
55− goto err;
56−
57− i915->mm.gemfs = gemfs;
58− drm_info(&i915->drm, "Using Transparent Hugepages\n");
59− return;
60−
61−err:
62− drm_notice(&i915->drm,
63− "Transparent Hugepage support is recommended for optimal performance%s\n",
64− GRAPHICS_VER(i915) >= 11 ? " on this platform!" :
65− " when IOMMU is enabled!");
66−}
67−
68−void i915_gemfs_fini(struct drm_i915_private *i915)
69−{
70− kern_unmount(i915->mm.gemfs);
71−}
drivers/gpu/drm/i915/gem/i915_gemfs.h+0−14
@@ -1,14 +0,0 @@
1−/* SPDX-License-Identifier: MIT */
2−/*
3− * Copyright © 2017 Intel Corporation
4− */
5−
6−#ifndef __I915_GEMFS_H__
7−#define __I915_GEMFS_H__
8−
9−struct drm_i915_private;
10−
11−void i915_gemfs_init(struct drm_i915_private *i915);
12−void i915_gemfs_fini(struct drm_i915_private *i915);
13−
14−#endif
drivers/gpu/drm/i915/gem/selftests/huge_pages.c+3−12
@@ -1316,7 +1316,7 @@ typedef struct drm_i915_gem_object * · 1315 unmodified lines
13161316
13171317 static inline bool igt_can_allocate_thp(struct drm_i915_private *i915)
13181318 {
1319− return i915->mm.gemfs && has_transparent_hugepage();
1319+ return !!drm_gem_get_huge_mnt(&i915->drm);
13201320 }
13211321
13221322 static struct drm_i915_gem_object *
@@ -1761,7 +1761,6 @@ static int igt_tmpfs_fallback(void *arg) · 438 unmodified lines
17611761 struct drm_i915_private *i915 = arg;
17621762 struct i915_address_space *vm;
17631763 struct i915_gem_context *ctx;
1764− struct vfsmount *gemfs = i915->mm.gemfs;
17651764 struct drm_i915_gem_object *obj;
17661765 struct i915_vma *vma;
17671766 struct file *file;
@@ -1779,15 +1778,8 @@ static int igt_tmpfs_fallback(void *arg) · 11 unmodified lines
17791778 }
17801779 vm = i915_gem_context_get_eb_vm(ctx);
17811780
1782− /*
1783− * Make sure that we don't burst into a ball of flames upon falling back
1784− * to tmpfs, which we rely on if on the off-chance we encounter a failure
1785− * when setting up gemfs.
1786− */
1787−
1788− i915->mm.gemfs = NULL;
1789−
1790− obj = i915_gem_object_create_shmem(i915, PAGE_SIZE);
1781+ obj = i915_gem_object_create_region(i915->mm.regions[INTEL_REGION_SMEM],
1782+ PAGE_SIZE, 0, I915_BO_ALLOC_NOTHP);
17911783 if (IS_ERR(obj)) {
17921784 err = PTR_ERR(obj);
17931785 goto out_restore;
@@ -1819,7 +1811,6 @@ static int igt_tmpfs_fallback(void *arg) · 25 unmodified lines
18191811 out_put:
18201812 i915_gem_object_put(obj);
18211813 out_restore:
1822− i915->mm.gemfs = gemfs;
18231814
18241815 i915_vm_put(vm);
18251816 out:
drivers/gpu/drm/i915/i915_drv.h+0−5
@@ -141,11 +141,6 @@ struct i915_gem_mm { · 140 unmodified lines
141141 */
142142 atomic_t free_count;
143143
144− /**
145− * tmpfs instance used for shmem backed objects
146− */
147− struct vfsmount *gemfs;
148−
149144 struct intel_memory_region *regions[INTEL_REGION_UNKNOWN];
150145
151146 struct notifier_block oom_notifier;
drivers/gpu/drm/nouveau/dispnv04/crtc.c+4−20
@@ -837,7 +837,7 @@ nv_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, · 836 unmodified lines
837837 static int
838838 nv04_crtc_do_mode_set_base(struct drm_crtc *crtc,
839839 struct drm_framebuffer *passed_fb,
840− int x, int y, bool atomic)
840+ int x, int y)
841841 {
842842 struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
843843 struct drm_device *dev = crtc->dev;
@@ -850,19 +850,12 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, · 6 unmodified lines
850850 NV_DEBUG(drm, "index %d\n", nv_crtc->index);
851851
852852 /* no fb bound */
853− if (!atomic && !crtc->primary->fb) {
853+ if (!crtc->primary->fb) {
854854 NV_DEBUG(drm, "No FB bound\n");
855855 return 0;
856856 }
857857
858− /* If atomic, we want to switch to the fb we were passed, so
859− * now we update pointers to do that.
860− */
861− if (atomic) {
862− drm_fb = passed_fb;
863− } else {
864− drm_fb = crtc->primary->fb;
865− }
858+ drm_fb = crtc->primary->fb;
866859
867860 nvbo = nouveau_gem_object(drm_fb->obj[0]);
868861 nv_crtc->fb.offset = nvbo->offset;
@@ -920,15 +913,7 @@ nv04_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y, · 51 unmodified lines
920913 int ret = nv_crtc_swap_fbs(crtc, old_fb);
921914 if (ret)
922915 return ret;
923− return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y, false);
924−}
925−
926−static int
927−nv04_crtc_mode_set_base_atomic(struct drm_crtc *crtc,
928− struct drm_framebuffer *fb,
929− int x, int y, enum mode_set_atomic state)
930−{
931− return nv04_crtc_do_mode_set_base(crtc, fb, x, y, true);
916+ return nv04_crtc_do_mode_set_base(crtc, old_fb, x, y);
932917 }
933918
934919 static void nv04_cursor_upload(struct drm_device *dev, struct nouveau_bo *src,
@@ -1274,7 +1259,6 @@ static const struct drm_crtc_helper_funcs nv04_crtc_helper_funcs = { · 339 unmodified lines
12741259 .commit = nv_crtc_commit,
12751260 .mode_set = nv_crtc_mode_set,
12761261 .mode_set_base = nv04_crtc_mode_set_base,
1277− .mode_set_base_atomic = nv04_crtc_mode_set_base_atomic,
12781262 .disable = nv_crtc_disable,
12791263 .get_scanout_position = nouveau_display_scanoutpos,
12801264 };
drivers/gpu/drm/panel/panel-edp.c+3−0
@@ -1880,6 +1880,7 @@ static const struct panel_delay delay_80_500_e50_d50 = { · 1879 unmodified lines
18801880 */
18811881 static const struct edp_panel_entry edp_panels[] = {
18821882 EDP_PANEL_ENTRY('A', 'U', 'O', 0x04a4, &delay_200_500_e50, "B122UAN01.0"),
1883+ EDP_PANEL_ENTRY('A', 'U', 'O', 0x0ba4, &delay_200_500_e50, "B140QAX01.H"),
18831884 EDP_PANEL_ENTRY('A', 'U', 'O', 0x105c, &delay_200_500_e50, "B116XTN01.0"),
18841885 EDP_PANEL_ENTRY('A', 'U', 'O', 0x1062, &delay_200_500_e50, "B120XAN01.0"),
18851886 EDP_PANEL_ENTRY('A', 'U', 'O', 0x125c, &delay_200_500_e50, "Unknown"),
@@ -1904,6 +1905,7 @@ static const struct edp_panel_entry edp_panels[] = { · 18 unmodified lines
19041905 EDP_PANEL_ENTRY('A', 'U', 'O', 0x615c, &delay_200_500_e50, "B116XAN06.1"),
19051906 EDP_PANEL_ENTRY('A', 'U', 'O', 0x635c, &delay_200_500_e50, "B116XAN06.3"),
19061907 EDP_PANEL_ENTRY('A', 'U', 'O', 0x639c, &delay_200_500_e50, "B140HAK02.7"),
1908+ EDP_PANEL_ENTRY('A', 'U', 'O', 0x643d, &delay_200_500_e50, "B140HAN06.4"),
19071909 EDP_PANEL_ENTRY('A', 'U', 'O', 0x723c, &delay_200_500_e50, "B140XTN07.2"),
19081910 EDP_PANEL_ENTRY('A', 'U', 'O', 0x73aa, &delay_200_500_e50, "B116XTN02.3"),
19091911 EDP_PANEL_ENTRY('A', 'U', 'O', 0x8594, &delay_200_500_e50, "B133UAN01.0"),
@@ -2033,6 +2035,7 @@ static const struct edp_panel_entry edp_panels[] = { · 123 unmodified lines
20332035 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1462, &delay_200_500_e50, "MNE007QS5-2"),
20342036 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1468, &delay_200_500_e50, "MNE007QB2-2"),
20352037 EDP_PANEL_ENTRY('C', 'S', 'W', 0x146e, &delay_80_500_e50_d50, "MNE007QB3-1"),
2038+ EDP_PANEL_ENTRY('C', 'S', 'W', 0x147c, &delay_200_500_e50_d100, "MNE007QB3-1"),
20362039 EDP_PANEL_ENTRY('C', 'S', 'W', 0x1519, &delay_200_500_e80_d50, "MNF601BS1-3"),
20372040
20382041 EDP_PANEL_ENTRY('E', 'T', 'C', 0x0000, &delay_50_500_e200_d200_po2e335, "LP079QX1-SP0V"),
drivers/gpu/drm/panfrost/panfrost_device.c+3−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include "panfrost_device.h"
1313 #include "panfrost_devfreq.h"
1414 #include "panfrost_features.h"
15+#include "panfrost_gem.h"
1516 #include "panfrost_issues.h"
1617 #include "panfrost_gpu.h"
1718 #include "panfrost_job.h"
@@ -267,6 +268,8 @@ int panfrost_device_init(struct panfrost_device *pfdev) · 249 unmodified lines
267268 if (err)
268269 goto out_job;
269270
271+ panfrost_gem_init(pfdev);
272+
270273 return 0;
271274 out_job:
272275 panfrost_jm_fini(pfdev);
drivers/gpu/drm/panfrost/panfrost_device.h+1−0
@@ -79,6 +79,7 @@ struct panfrost_features { · 78 unmodified lines
7979 u32 thread_max_workgroup_sz;
8080 u32 thread_max_barrier_sz;
8181 u32 coherency_features;
82+ u32 selected_coherency;
8283 u32 afbc_features;
8384 u32 texture_features[4];
8485 u32 js_features[16];
drivers/gpu/drm/panfrost/panfrost_drv.c+104−3
@@ -95,6 +95,7 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct · 94 unmodified lines
9595 PANFROST_FEATURE_ARRAY(JS_FEATURES, js_features, 15);
9696 PANFROST_FEATURE(NR_CORE_GROUPS, nr_core_groups);
9797 PANFROST_FEATURE(THREAD_TLS_ALLOC, thread_tls_alloc);
98+ PANFROST_FEATURE(SELECTED_COHERENCY, selected_coherency);
9899
99100 case DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP:
100101 ret = panfrost_ioctl_query_timestamp(pfdev, &param->value);
@@ -125,6 +126,10 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct · 24 unmodified lines
125126 return 0;
126127 }
127128
129+#define PANFROST_BO_FLAGS (PANFROST_BO_NOEXEC | \
130+ PANFROST_BO_HEAP | \
131+ PANFROST_BO_WB_MMAP)
132+
128133 static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data,
129134 struct drm_file *file)
130135 {
@@ -134,8 +139,7 @@ static int panfrost_ioctl_create_bo(struct drm_device *dev, void *data, · 3 unmodified lines
134139 struct panfrost_gem_mapping *mapping;
135140 int ret;
136141
137− if (!args->size || args->pad ||
138− (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP)))
142+ if (!args->size || args->pad || (args->flags & ~PANFROST_BO_FLAGS))
139143 return -EINVAL;
140144
141145 /* Heaps should never be executable */
@@ -579,6 +583,91 @@ static int panfrost_ioctl_jm_ctx_destroy(struct drm_device *dev, void *data, · 437 unmodified lines
579583 return panfrost_jm_ctx_destroy(file, args->handle);
580584 }
581585
586+static int panfrost_ioctl_sync_bo(struct drm_device *ddev, void *data,
587+ struct drm_file *file)
588+{
589+ struct drm_panfrost_sync_bo *args = data;
590+ struct drm_panfrost_bo_sync_op *ops;
591+ struct drm_gem_object *obj;
592+ int ret;
593+ u32 i;
594+
595+ if (args->pad)
596+ return -EINVAL;
597+
598+ if (!args->op_count)
599+ return 0;
600+
601+ ops = kvmalloc_array(args->op_count, sizeof(*ops), GFP_KERNEL);
602+ if (!ops) {
603+ DRM_DEBUG("Failed to allocate incoming BO sync ops array\n");
604+ return -ENOMEM;
605+ }
606+
607+ if (copy_from_user(ops, (void __user *)(uintptr_t)args->ops,
608+ args->op_count * sizeof(*ops))) {
609+ DRM_DEBUG("Failed to copy in BO sync ops\n");
610+ ret = -EFAULT;
611+ goto err_ops;
612+ }
613+
614+ for (i = 0; i < args->op_count; i++) {
615+ obj = drm_gem_object_lookup(file, ops[i].handle);
616+ if (!obj) {
617+ ret = -ENOENT;
618+ goto err_ops;
619+ }
620+
621+ ret = panfrost_gem_sync(obj, ops[i].type,
622+ ops[i].offset, ops[i].size);
623+
624+ drm_gem_object_put(obj);
625+
626+ if (ret)
627+ goto err_ops;
628+ }
629+
630+err_ops:
631+ kvfree(ops);
632+
633+ return ret;
634+}
635+
636+static int panfrost_ioctl_query_bo_info(struct drm_device *dev, void *data,
637+ struct drm_file *file_priv)
638+{
639+ struct drm_panfrost_query_bo_info *args = data;
640+ struct drm_gem_object *gem_obj;
641+ struct panfrost_gem_object *bo;
642+
643+ gem_obj = drm_gem_object_lookup(file_priv, args->handle);
644+ if (!gem_obj) {
645+ DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle);
646+ return -ENOENT;
647+ }
648+
649+ bo = to_panfrost_bo(gem_obj);
650+ args->pad = 0;
651+ args->create_flags = 0;
652+ args->extra_flags = 0;
653+
654+ if (drm_gem_is_imported(gem_obj)) {
655+ args->extra_flags |= DRM_PANFROST_BO_IS_IMPORTED;
656+ } else {
657+ if (bo->noexec)
658+ args->create_flags |= PANFROST_BO_NOEXEC;
659+
660+ if (bo->is_heap)
661+ args->create_flags |= PANFROST_BO_HEAP;
662+
663+ if (!bo->base.map_wc)
664+ args->create_flags |= PANFROST_BO_WB_MMAP;
665+ }
666+
667+ drm_gem_object_put(gem_obj);
668+ return 0;
669+}
670+
582671 int panfrost_unstable_ioctl_check(void)
583672 {
584673 if (!unstable_ioctls)
@@ -648,6 +737,8 @@ static const struct drm_ioctl_desc panfrost_drm_driver_ioctls[] = { · 63 unmodified lines
648737 PANFROST_IOCTL(SET_LABEL_BO, set_label_bo, DRM_RENDER_ALLOW),
649738 PANFROST_IOCTL(JM_CTX_CREATE, jm_ctx_create, DRM_RENDER_ALLOW),
650739 PANFROST_IOCTL(JM_CTX_DESTROY, jm_ctx_destroy, DRM_RENDER_ALLOW),
740+ PANFROST_IOCTL(SYNC_BO, sync_bo, DRM_RENDER_ALLOW),
741+ PANFROST_IOCTL(QUERY_BO_INFO, query_bo_info, DRM_RENDER_ALLOW),
651742 };
652743
653744 static void panfrost_gpu_show_fdinfo(struct panfrost_device *pfdev,
@@ -837,6 +928,9 @@ static void panfrost_debugfs_init(struct drm_minor *minor) · 183 unmodified lines
837928 * - 1.4 - adds SET_LABEL_BO
838929 * - 1.5 - adds JM_CTX_{CREATE,DESTROY} ioctls and extend SUBMIT to allow
839930 * context creation with configurable priorities/affinity
931+ * - 1.6 - adds PANFROST_BO_MAP_WB, PANFROST_IOCTL_SYNC_BO,
932+ * PANFROST_IOCTL_QUERY_BO_INFO and
933+ * DRM_PANFROST_PARAM_SELECTED_COHERENCY
840934 */
841935 static const struct drm_driver panfrost_drm_driver = {
842936 .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
@@ -849,15 +943,22 @@ static const struct drm_driver panfrost_drm_driver = { · 6 unmodified lines
849943 .name = "panfrost",
850944 .desc = "panfrost DRM",
851945 .major = 1,
852− .minor = 5,
946+ .minor = 6,
853947
854948 .gem_create_object = panfrost_gem_create_object,
949+ .gem_prime_import = panfrost_gem_prime_import,
855950 .gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
856951 #ifdef CONFIG_DEBUG_FS
857952 .debugfs_init = panfrost_debugfs_init,
858953 #endif
859954 };
860955
956+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
957+bool panfrost_transparent_hugepage = true;
958+module_param_named(transparent_hugepage, panfrost_transparent_hugepage, bool, 0400);
959+MODULE_PARM_DESC(transparent_hugepage, "Use a dedicated tmpfs mount point with Transparent Hugepage enabled (true = default)");
960+#endif
961+
861962 static int panfrost_probe(struct platform_device *pdev)
862963 {
863964 struct panfrost_device *pfdev;
drivers/gpu/drm/panfrost/panfrost_drv.h+9−0
@@ -0,0 +1,9 @@
1+/* SPDX-License-Identifier: GPL-2.0 or MIT */
2+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
3+
4+#ifndef __PANFROST_DRV_H__
5+#define __PANFROST_DRV_H__
6+
7+extern bool panfrost_transparent_hugepage;
8+
9+#endif
drivers/gpu/drm/panfrost/panfrost_gem.c+257−0
@@ -1,5 +1,6 @@
11 // SPDX-License-Identifier: GPL-2.0
22 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
3+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
34
45 #include <linux/cleanup.h>
56 #include <linux/err.h>
@@ -10,9 +11,26 @@ · 4 unmodified lines
1011 #include <drm/panfrost_drm.h>
1112 #include <drm/drm_print.h>
1213 #include "panfrost_device.h"
14+#include "panfrost_drv.h"
1315 #include "panfrost_gem.h"
1416 #include "panfrost_mmu.h"
1517
18+void panfrost_gem_init(struct panfrost_device *pfdev)
19+{
20+ int err;
21+
22+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
23+ !panfrost_transparent_hugepage)
24+ return;
25+
26+ err = drm_gem_huge_mnt_create(&pfdev->base, "within_size");
27+ if (drm_gem_get_huge_mnt(&pfdev->base))
28+ drm_info(&pfdev->base, "Using Transparent Hugepage\n");
29+ else if (err)
30+ drm_warn(&pfdev->base, "Can't use Transparent Hugepage (%d)\n",
31+ err);
32+}
33+
1634 #ifdef CONFIG_DEBUG_FS
1735 static void panfrost_gem_debugfs_bo_add(struct panfrost_device *pfdev,
1836 struct panfrost_gem_object *bo)
@@ -259,6 +277,128 @@ static size_t panfrost_gem_rss(struct drm_gem_object *obj) · 240 unmodified lines
259277 return 0;
260278 }
261279
280+static struct sg_table *
281+panfrost_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
282+ enum dma_data_direction dir)
283+{
284+ struct sg_table *sgt = drm_gem_map_dma_buf(attach, dir);
285+
286+ if (!IS_ERR(sgt))
287+ attach->priv = sgt;
288+
289+ return sgt;
290+}
291+
292+static void
293+panfrost_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
294+ struct sg_table *sgt,
295+ enum dma_data_direction dir)
296+{
297+ attach->priv = NULL;
298+ drm_gem_unmap_dma_buf(attach, sgt, dir);
299+}
300+
301+static int
302+panfrost_gem_prime_begin_cpu_access(struct dma_buf *dma_buf,
303+ enum dma_data_direction dir)
304+{
305+ struct drm_gem_object *obj = dma_buf->priv;
306+ struct drm_device *dev = obj->dev;
307+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
308+ struct dma_buf_attachment *attach;
309+
310+ dma_resv_lock(obj->resv, NULL);
311+ if (shmem->sgt)
312+ dma_sync_sgtable_for_cpu(dev->dev, shmem->sgt, dir);
313+
314+ if (shmem->vaddr)
315+ invalidate_kernel_vmap_range(shmem->vaddr, shmem->base.size);
316+
317+ list_for_each_entry(attach, &dma_buf->attachments, node) {
318+ struct sg_table *sgt = attach->priv;
319+
320+ if (sgt)
321+ dma_sync_sgtable_for_cpu(attach->dev, sgt, dir);
322+ }
323+ dma_resv_unlock(obj->resv);
324+
325+ return 0;
326+}
327+
328+static int
329+panfrost_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
330+ enum dma_data_direction dir)
331+{
332+ struct drm_gem_object *obj = dma_buf->priv;
333+ struct drm_device *dev = obj->dev;
334+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
335+ struct dma_buf_attachment *attach;
336+
337+ dma_resv_lock(obj->resv, NULL);
338+ list_for_each_entry(attach, &dma_buf->attachments, node) {
339+ struct sg_table *sgt = attach->priv;
340+
341+ if (sgt)
342+ dma_sync_sgtable_for_device(attach->dev, sgt, dir);
343+ }
344+
345+ if (shmem->vaddr)
346+ flush_kernel_vmap_range(shmem->vaddr, shmem->base.size);
347+
348+ if (shmem->sgt)
349+ dma_sync_sgtable_for_device(dev->dev, shmem->sgt, dir);
350+
351+ dma_resv_unlock(obj->resv);
352+ return 0;
353+}
354+
355+static const struct dma_buf_ops panfrost_dma_buf_ops = {
356+ .attach = drm_gem_map_attach,
357+ .detach = drm_gem_map_detach,
358+ .map_dma_buf = panfrost_gem_prime_map_dma_buf,
359+ .unmap_dma_buf = panfrost_gem_prime_unmap_dma_buf,
360+ .release = drm_gem_dmabuf_release,
361+ .mmap = drm_gem_dmabuf_mmap,
362+ .vmap = drm_gem_dmabuf_vmap,
363+ .vunmap = drm_gem_dmabuf_vunmap,
364+ .begin_cpu_access = panfrost_gem_prime_begin_cpu_access,
365+ .end_cpu_access = panfrost_gem_prime_end_cpu_access,
366+};
367+
368+static struct dma_buf *
369+panfrost_gem_prime_export(struct drm_gem_object *obj, int flags)
370+{
371+ struct drm_device *dev = obj->dev;
372+ struct dma_buf_export_info exp_info = {
373+ .exp_name = KBUILD_MODNAME,
374+ .owner = THIS_MODULE,
375+ .ops = &panfrost_dma_buf_ops,
376+ .size = obj->size,
377+ .flags = flags,
378+ .priv = obj,
379+ .resv = obj->resv,
380+ };
381+
382+ return drm_gem_dmabuf_export(dev, &exp_info);
383+}
384+
385+struct drm_gem_object *
386+panfrost_gem_prime_import(struct drm_device *dev,
387+ struct dma_buf *dma_buf)
388+{
389+ struct drm_gem_object *obj = dma_buf->priv;
390+
391+ if (dma_buf->ops == &panfrost_dma_buf_ops && obj->dev == dev) {
392+ /* Importing dmabuf exported from our own gem increases
393+ * refcount on gem itself instead of f_count of dmabuf.
394+ */
395+ drm_gem_object_get(obj);
396+ return obj;
397+ }
398+
399+ return drm_gem_prime_import(dev, dma_buf);
400+}
401+
262402 static const struct drm_gem_object_funcs panfrost_gem_funcs = {
263403 .free = panfrost_gem_free_object,
264404 .open = panfrost_gem_open,
@@ -267,6 +407,7 @@ static const struct drm_gem_object_funcs panfrost_gem_funcs = { · 2 unmodified lines
267407 .pin = panfrost_gem_pin,
268408 .unpin = drm_gem_shmem_object_unpin,
269409 .get_sg_table = drm_gem_shmem_object_get_sg_table,
410+ .export = panfrost_gem_prime_export,
270411 .vmap = drm_gem_shmem_object_vmap,
271412 .vunmap = drm_gem_shmem_object_vunmap,
272413 .mmap = drm_gem_shmem_object_mmap,
@@ -303,12 +444,42 @@ struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t · 30 unmodified lines
303444 return &obj->base.base;
304445 }
305446
447+static bool
448+should_map_wc(struct panfrost_gem_object *bo)
449+{
450+ struct panfrost_device *pfdev = to_panfrost_device(bo->base.base.dev);
451+
452+ /* We can't do uncached mappings if the device is coherent,
453+ * because the zeroing done by the shmem layer at page allocation
454+ * time happens on a cached mapping which isn't CPU-flushed (at least
455+ * not on Arm64 where the flush is deferred to PTE setup time, and
456+ * only done conditionally based on the mapping permissions). We can't
457+ * rely on dma_map_sgtable()/dma_sync_sgtable_for_xxx() either to flush
458+ * those, because they are NOPed if dma_dev_coherent() returns true.
459+ */
460+ if (pfdev->coherent)
461+ return false;
462+
463+ /* Cached mappings are explicitly requested, so no write-combine. */
464+ if (bo->wb_mmap)
465+ return false;
466+
467+ /* The default is write-combine. */
468+ return true;
469+}
470+
306471 struct panfrost_gem_object *
307472 panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags)
308473 {
309474 struct drm_gem_shmem_object *shmem;
310475 struct panfrost_gem_object *bo;
311476
477+ /* The heap buffer is not supposed to be CPU-visible, so don't allow
478+ * WB_MMAP on those.
479+ */
480+ if ((flags & PANFROST_BO_HEAP) && (flags & PANFROST_BO_WB_MMAP))
481+ return ERR_PTR(-EINVAL);
482+
312483 /* Round up heap allocations to 2MB to keep fault handling simple */
313484 if (flags & PANFROST_BO_HEAP)
314485 size = roundup(size, SZ_2M);
@@ -320,6 +491,8 @@ panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags) · 5 unmodified lines
320491 bo = to_panfrost_bo(&shmem->base);
321492 bo->noexec = !!(flags & PANFROST_BO_NOEXEC);
322493 bo->is_heap = !!(flags & PANFROST_BO_HEAP);
494+ bo->wb_mmap = !!(flags & PANFROST_BO_WB_MMAP);
495+ bo->base.map_wc = should_map_wc(bo);
323496
324497 return bo;
325498 }
@@ -366,6 +539,90 @@ panfrost_gem_set_label(struct drm_gem_object *obj, const char *label) · 40 unmodified lines
366539 kfree_const(old_label);
367540 }
368541
542+int
543+panfrost_gem_sync(struct drm_gem_object *obj, u32 type, u32 offset, u32 size)
544+{
545+ struct panfrost_gem_object *bo = to_panfrost_bo(obj);
546+ struct drm_gem_shmem_object *shmem = &bo->base;
547+ const struct drm_device *dev = shmem->base.dev;
548+ struct sg_table *sgt;
549+ struct scatterlist *sgl;
550+ unsigned int count;
551+
552+ /* Make sure the range is in bounds. */
553+ if (offset + size < offset || offset + size > shmem->base.size)
554+ return -EINVAL;
555+
556+ /* Disallow CPU-cache maintenance on imported buffers. */
557+ if (drm_gem_is_imported(&shmem->base))
558+ return -EINVAL;
559+
560+ switch (type) {
561+ case PANFROST_BO_SYNC_CPU_CACHE_FLUSH:
562+ case PANFROST_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE:
563+ break;
564+
565+ default:
566+ return -EINVAL;
567+ }
568+
569+ /* Don't bother if it's WC-mapped */
570+ if (shmem->map_wc)
571+ return 0;
572+
573+ /* Nothing to do if the size is zero. */
574+ if (size == 0)
575+ return 0;
576+
577+ sgt = drm_gem_shmem_get_pages_sgt(shmem);
578+ if (IS_ERR(sgt))
579+ return PTR_ERR(sgt);
580+
581+ for_each_sgtable_dma_sg(sgt, sgl, count) {
582+ if (size == 0)
583+ break;
584+
585+ dma_addr_t paddr = sg_dma_address(sgl);
586+ size_t len = sg_dma_len(sgl);
587+
588+ if (len <= offset) {
589+ offset -= len;
590+ continue;
591+ }
592+
593+ paddr += offset;
594+ len -= offset;
595+ len = min_t(size_t, len, size);
596+ size -= len;
597+ offset = 0;
598+
599+ /* It's unclear whether dma_sync_xxx() is the right API to do CPU
600+ * cache maintenance given an IOMMU can register their own
601+ * implementation doing more than just CPU cache flushes/invalidation,
602+ * and what we really care about here is CPU caches only, but that's
603+ * the best we have that is both arch-agnostic and does at least the
604+ * CPU cache maintenance on a <page,offset,size> tuple.
605+ *
606+ * Also, I wish we could do a single
607+ *
608+ * dma_sync_single_for_device(BIDIR)
609+ *
610+ * and get a flush+invalidate, but that's not how it's implemented
611+ * in practice (at least on arm64), so we have to make it
612+ *
613+ * dma_sync_single_for_device(TO_DEVICE)
614+ * dma_sync_single_for_cpu(FROM_DEVICE)
615+ *
616+ * for the flush+invalidate case.
617+ */
618+ dma_sync_single_for_device(dev->dev, paddr, len, DMA_TO_DEVICE);
619+ if (type == PANFROST_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE)
620+ dma_sync_single_for_cpu(dev->dev, paddr, len, DMA_FROM_DEVICE);
621+ }
622+
623+ return 0;
624+}
625+
369626 void
370627 panfrost_gem_internal_set_label(struct drm_gem_object *obj, const char *label)
371628 {
drivers/gpu/drm/panfrost/panfrost_gem.h+12−0
@@ -98,6 +98,11 @@ struct panfrost_gem_object { · 97 unmodified lines
9898 bool noexec :1;
9999 bool is_heap :1;
100100
101+ /* On coherent devices, this reflects the creation flags, not the true
102+ * cacheability attribute of the mapping.
103+ */
104+ bool wb_mmap :1;
105+
101106 #ifdef CONFIG_DEBUG_FS
102107 struct panfrost_gem_debugfs debugfs;
103108 #endif
@@ -124,12 +129,17 @@ drm_mm_node_to_panfrost_mapping(struct drm_mm_node *node) · 20 unmodified lines
124129 return container_of(node, struct panfrost_gem_mapping, mmnode);
125130 }
126131
132+void panfrost_gem_init(struct panfrost_device *pfdev);
133+
127134 struct drm_gem_object *panfrost_gem_create_object(struct drm_device *dev, size_t size);
128135
129136 struct drm_gem_object *
130137 panfrost_gem_prime_import_sg_table(struct drm_device *dev,
131138 struct dma_buf_attachment *attach,
132139 struct sg_table *sgt);
140+struct drm_gem_object *
141+panfrost_gem_prime_import(struct drm_device *dev,
142+ struct dma_buf *dma_buf);
133143
134144 struct panfrost_gem_object *
135145 panfrost_gem_create(struct drm_device *dev, size_t size, u32 flags);
@@ -148,6 +158,8 @@ int panfrost_gem_shrinker_init(struct drm_device *dev); · 12 unmodified lines
148158 void panfrost_gem_shrinker_cleanup(struct drm_device *dev);
149159
150160 void panfrost_gem_set_label(struct drm_gem_object *obj, const char *label);
161+int panfrost_gem_sync(struct drm_gem_object *obj, u32 type,
162+ u32 offset, u32 size);
151163 void panfrost_gem_internal_set_label(struct drm_gem_object *obj, const char *label);
152164
153165 #ifdef CONFIG_DEBUG_FS
drivers/gpu/drm/panfrost/panfrost_gpu.c+23−3
@@ -159,8 +159,8 @@ static void panfrost_gpu_init_quirks(struct panfrost_device *pfdev) · 158 unmodified lines
159159 pfdev->features.revision >= 0x2000)
160160 quirks |= JM_MAX_JOB_THROTTLE_LIMIT << JM_JOB_THROTTLE_LIMIT_SHIFT;
161161 else if (panfrost_model_eq(pfdev, 0x6000) &&
162− pfdev->features.coherency_features == COHERENCY_ACE)
163− quirks |= (COHERENCY_ACE_LITE | COHERENCY_ACE) <<
162+ pfdev->features.coherency_features == BIT(COHERENCY_ACE))
163+ quirks |= (BIT(COHERENCY_ACE_LITE) | BIT(COHERENCY_ACE)) <<
164164 JM_FORCE_COHERENCY_FEATURES_SHIFT;
165165
166166 if (panfrost_has_hw_feature(pfdev, HW_FEATURE_IDVS_GROUP_SIZE))
@@ -263,7 +263,27 @@ static int panfrost_gpu_init_features(struct panfrost_device *pfdev) · 96 unmodified lines
263263 pfdev->features.max_threads = gpu_read(pfdev, GPU_THREAD_MAX_THREADS);
264264 pfdev->features.thread_max_workgroup_sz = gpu_read(pfdev, GPU_THREAD_MAX_WORKGROUP_SIZE);
265265 pfdev->features.thread_max_barrier_sz = gpu_read(pfdev, GPU_THREAD_MAX_BARRIER_SIZE);
266− pfdev->features.coherency_features = gpu_read(pfdev, GPU_COHERENCY_FEATURES);
266+
267+ if (panfrost_has_hw_feature(pfdev, HW_FEATURE_COHERENCY_REG))
268+ pfdev->features.coherency_features = gpu_read(pfdev, GPU_COHERENCY_FEATURES);
269+ else
270+ pfdev->features.coherency_features = BIT(COHERENCY_ACE_LITE);
271+
272+ BUILD_BUG_ON(COHERENCY_ACE_LITE != DRM_PANFROST_GPU_COHERENCY_ACE_LITE);
273+ BUILD_BUG_ON(COHERENCY_ACE != DRM_PANFROST_GPU_COHERENCY_ACE);
274+ BUILD_BUG_ON(COHERENCY_NONE != DRM_PANFROST_GPU_COHERENCY_NONE);
275+
276+ if (!pfdev->coherent) {
277+ pfdev->features.selected_coherency = COHERENCY_NONE;
278+ } else if (pfdev->features.coherency_features & BIT(COHERENCY_ACE)) {
279+ pfdev->features.selected_coherency = COHERENCY_ACE;
280+ } else if (pfdev->features.coherency_features & BIT(COHERENCY_ACE_LITE)) {
281+ pfdev->features.selected_coherency = COHERENCY_ACE_LITE;
282+ } else {
283+ drm_WARN(&pfdev->base, true, "No known coherency protocol supported");
284+ pfdev->features.selected_coherency = COHERENCY_NONE;
285+ }
286+
267287 pfdev->features.afbc_features = gpu_read(pfdev, GPU_AFBC_FEATURES);
268288 for (i = 0; i < 4; i++)
269289 pfdev->features.texture_features[i] = gpu_read(pfdev, GPU_TEXTURE_FEATURES(i));
drivers/gpu/drm/panfrost/panfrost_regs.h+8−2
@@ -102,9 +102,15 @@ · 101 unmodified lines
102102 #define GPU_L2_PRESENT_LO 0x120 /* (RO) Level 2 cache present bitmap, low word */
103103 #define GPU_L2_PRESENT_HI 0x124 /* (RO) Level 2 cache present bitmap, high word */
104104
105+/* GPU_COHERENCY_FEATURES is a bitmask of BIT(COHERENCY_xxx) values encoding the
106+ * set of supported coherency protocols. GPU_COHERENCY_ENABLE is passed a
107+ * COHERENCY_xxx value.
108+ */
105109 #define GPU_COHERENCY_FEATURES 0x300 /* (RO) Coherency features present */
106−#define COHERENCY_ACE_LITE BIT(0)
107−#define COHERENCY_ACE BIT(1)
110+#define GPU_COHERENCY_ENABLE 0x304 /* (RW) Coherency protocol selection */
111+#define COHERENCY_ACE_LITE 0
112+#define COHERENCY_ACE 1
113+#define COHERENCY_NONE 31
108114
109115 #define GPU_STACK_PRESENT_LO 0xE00 /* (RO) Core stack present bitmap, low word */
110116 #define GPU_STACK_PRESENT_HI 0xE04 /* (RO) Core stack present bitmap, high word */
drivers/gpu/drm/panthor/panthor_device.c+12−1
@@ -18,6 +18,7 @@ · 17 unmodified lines
1818 #include "panthor_devfreq.h"
1919 #include "panthor_device.h"
2020 #include "panthor_fw.h"
21+#include "panthor_gem.h"
2122 #include "panthor_gpu.h"
2223 #include "panthor_hw.h"
2324 #include "panthor_mmu.h"
@@ -27,6 +28,12 @@ · 3 unmodified lines
2728
2829 static int panthor_gpu_coherency_init(struct panthor_device *ptdev)
2930 {
31+ BUILD_BUG_ON(GPU_COHERENCY_NONE != DRM_PANTHOR_GPU_COHERENCY_NONE);
32+ BUILD_BUG_ON(GPU_COHERENCY_ACE_LITE != DRM_PANTHOR_GPU_COHERENCY_ACE_LITE);
33+ BUILD_BUG_ON(GPU_COHERENCY_ACE != DRM_PANTHOR_GPU_COHERENCY_ACE);
34+
35+ /* Start with no coherency, and update it if the device is flagged coherent. */
36+ ptdev->gpu_info.selected_coherency = GPU_COHERENCY_NONE;
3037 ptdev->coherent = device_get_dma_attr(ptdev->base.dev) == DEV_DMA_COHERENT;
3138
3239 if (!ptdev->coherent)
@@ -36,8 +43,10 @@ static int panthor_gpu_coherency_init(struct panthor_device *ptdev) · 3 unmodified lines
3643 * ACE protocol has never been supported for command stream frontend GPUs.
3744 */
3845 if ((gpu_read(ptdev, GPU_COHERENCY_FEATURES) &
39− GPU_COHERENCY_PROT_BIT(ACE_LITE)))
46+ GPU_COHERENCY_PROT_BIT(ACE_LITE))) {
47+ ptdev->gpu_info.selected_coherency = GPU_COHERENCY_ACE_LITE;
4048 return 0;
49+ }
4150
4251 drm_err(&ptdev->base, "Coherency not supported by the device");
4352 return -ENOTSUPP;
@@ -294,6 +303,8 @@ int panthor_device_init(struct panthor_device *ptdev) · 250 unmodified lines
294303 if (ret)
295304 goto err_unplug_fw;
296305
306+ panthor_gem_init(ptdev);
307+
297308 /* ~3 frames */
298309 pm_runtime_set_autosuspend_delay(ptdev->base.dev, 50);
299310 pm_runtime_use_autosuspend(ptdev->base.dev);
drivers/gpu/drm/panthor/panthor_drv.c+84−3
@@ -177,7 +177,8 @@ panthor_get_uobj_array(const struct drm_panthor_obj_array *in, u32 min_stride, · 176 unmodified lines
177177 PANTHOR_UOBJ_DECL(struct drm_panthor_sync_op, timeline_value), \
178178 PANTHOR_UOBJ_DECL(struct drm_panthor_queue_submit, syncs), \
179179 PANTHOR_UOBJ_DECL(struct drm_panthor_queue_create, ringbuf_size), \
180− PANTHOR_UOBJ_DECL(struct drm_panthor_vm_bind_op, syncs))
180+ PANTHOR_UOBJ_DECL(struct drm_panthor_vm_bind_op, syncs), \
181+ PANTHOR_UOBJ_DECL(struct drm_panthor_bo_sync_op, size))
181182
182183 /**
183184 * PANTHOR_UOBJ_SET() - Copy a kernel object to a user object.
@@ -901,7 +902,8 @@ static int panthor_ioctl_vm_destroy(struct drm_device *ddev, void *data, · 717 unmodified lines
901902 return panthor_vm_pool_destroy_vm(pfile->vms, args->id);
902903 }
903904
904−#define PANTHOR_BO_FLAGS DRM_PANTHOR_BO_NO_MMAP
905+#define PANTHOR_BO_FLAGS (DRM_PANTHOR_BO_NO_MMAP | \
906+ DRM_PANTHOR_BO_WB_MMAP)
905907
906908 static int panthor_ioctl_bo_create(struct drm_device *ddev, void *data,
907909 struct drm_file *file)
@@ -920,6 +922,10 @@ static int panthor_ioctl_bo_create(struct drm_device *ddev, void *data, · 12 unmodified lines
920922 goto out_dev_exit;
921923 }
922924
925+ if ((args->flags & DRM_PANTHOR_BO_NO_MMAP) &&
926+ (args->flags & DRM_PANTHOR_BO_WB_MMAP))
927+ return -EINVAL;
928+
923929 if (args->exclusive_vm_id) {
924930 vm = panthor_vm_pool_get_vm(pfile->vms, args->exclusive_vm_id);
925931 if (!vm) {
@@ -1396,6 +1402,66 @@ static int panthor_ioctl_set_user_mmio_offset(struct drm_device *ddev, · 470 unmodified lines
13961402 return 0;
13971403 }
13981404
1405+static int panthor_ioctl_bo_sync(struct drm_device *ddev, void *data,
1406+ struct drm_file *file)
1407+{
1408+ struct drm_panthor_bo_sync *args = data;
1409+ struct drm_panthor_bo_sync_op *ops;
1410+ struct drm_gem_object *obj;
1411+ int ret;
1412+
1413+ if (!args->ops.count)
1414+ return 0;
1415+
1416+ ret = PANTHOR_UOBJ_GET_ARRAY(ops, &args->ops);
1417+ if (ret)
1418+ return ret;
1419+
1420+ for (u32 i = 0; i < args->ops.count; i++) {
1421+ obj = drm_gem_object_lookup(file, ops[i].handle);
1422+ if (!obj) {
1423+ ret = -ENOENT;
1424+ goto err_ops;
1425+ }
1426+
1427+ ret = panthor_gem_sync(obj, ops[i].type, ops[i].offset,
1428+ ops[i].size);
1429+
1430+ drm_gem_object_put(obj);
1431+
1432+ if (ret)
1433+ goto err_ops;
1434+ }
1435+
1436+err_ops:
1437+ kvfree(ops);
1438+
1439+ return ret;
1440+}
1441+
1442+static int panthor_ioctl_bo_query_info(struct drm_device *ddev, void *data,
1443+ struct drm_file *file)
1444+{
1445+ struct drm_panthor_bo_query_info *args = data;
1446+ struct panthor_gem_object *bo;
1447+ struct drm_gem_object *obj;
1448+
1449+ obj = drm_gem_object_lookup(file, args->handle);
1450+ if (!obj)
1451+ return -ENOENT;
1452+
1453+ bo = to_panthor_bo(obj);
1454+ args->pad = 0;
1455+ args->create_flags = bo->flags;
1456+
1457+ args->extra_flags = 0;
1458+ if (drm_gem_is_imported(&bo->base.base))
1459+ args->extra_flags |= DRM_PANTHOR_BO_IS_IMPORTED;
1460+
1461+ drm_gem_object_put(obj);
1462+ return 0;
1463+}
1464+
13991465 static int
14001466 panthor_open(struct drm_device *ddev, struct drm_file *file)
14011467 {
@@ -1470,6 +1536,8 @@ static const struct drm_ioctl_desc panthor_drm_driver_ioctls[] = { · 68 unmodified lines
14701536 PANTHOR_IOCTL(GROUP_SUBMIT, group_submit, DRM_RENDER_ALLOW),
14711537 PANTHOR_IOCTL(BO_SET_LABEL, bo_set_label, DRM_RENDER_ALLOW),
14721538 PANTHOR_IOCTL(SET_USER_MMIO_OFFSET, set_user_mmio_offset, DRM_RENDER_ALLOW),
1539+ PANTHOR_IOCTL(BO_SYNC, bo_sync, DRM_RENDER_ALLOW),
1540+ PANTHOR_IOCTL(BO_QUERY_INFO, bo_query_info, DRM_RENDER_ALLOW),
14731541 };
14741542
14751543 static int panthor_mmap(struct file *filp, struct vm_area_struct *vma)
@@ -1559,6 +1627,7 @@ static const struct file_operations panthor_drm_driver_fops = { · 83 unmodified lines
15591627 .read = drm_read,
15601628 .llseek = noop_llseek,
15611629 .mmap = panthor_mmap,
1630+ .get_unmapped_area = drm_gem_get_unmapped_area,
15621631 .show_fdinfo = drm_show_fdinfo,
15631632 .fop_flags = FOP_UNSIGNED_OFFSET,
15641633 };
@@ -1604,6 +1673,11 @@ static void panthor_debugfs_init(struct drm_minor *minor) · 39 unmodified lines
16041673 * - 1.3 - adds DRM_PANTHOR_GROUP_STATE_INNOCENT flag
16051674 * - 1.4 - adds DRM_IOCTL_PANTHOR_BO_SET_LABEL ioctl
16061675 * - 1.5 - adds DRM_PANTHOR_SET_USER_MMIO_OFFSET ioctl
1676+ * - 1.6 - enables GLB_COUNTER_EN
1677+ * - 1.7 - adds DRM_PANTHOR_BO_WB_MMAP flag
1678+ * - adds DRM_IOCTL_PANTHOR_BO_SYNC ioctl
1679+ * - adds DRM_IOCTL_PANTHOR_BO_QUERY_INFO ioctl
1680+ * - adds drm_panthor_gpu_info::selected_coherency
16071681 */
16081682 static const struct drm_driver panthor_drm_driver = {
16091683 .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ |
@@ -1617,15 +1691,22 @@ static const struct drm_driver panthor_drm_driver = { · 7 unmodified lines
16171691 .name = "panthor",
16181692 .desc = "Panthor DRM driver",
16191693 .major = 1,
1620− .minor = 5,
1694+ .minor = 7,
16211695
16221696 .gem_create_object = panthor_gem_create_object,
16231697 .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
1698+ .gem_prime_import = panthor_gem_prime_import,
16241699 #ifdef CONFIG_DEBUG_FS
16251700 .debugfs_init = panthor_debugfs_init,
16261701 #endif
16271702 };
16281703
1704+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
1705+bool panthor_transparent_hugepage = true;
1706+module_param_named(transparent_hugepage, panthor_transparent_hugepage, bool, 0400);
1707+MODULE_PARM_DESC(transparent_hugepage, "Use a dedicated tmpfs mount point with Transparent Hugepage enabled (true = default)");
1708+#endif
1709+
16291710 static int panthor_probe(struct platform_device *pdev)
16301711 {
16311712 struct panthor_device *ptdev;
drivers/gpu/drm/panthor/panthor_drv.h+9−0
@@ -0,0 +1,9 @@
1+/* SPDX-License-Identifier: GPL-2.0 or MIT */
2+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
3+
4+#ifndef __PANTHOR_DRV_H__
5+#define __PANTHOR_DRV_H__
6+
7+extern bool panthor_transparent_hugepage;
8+
9+#endif
drivers/gpu/drm/panthor/panthor_fw.c+2−2
@@ -1044,7 +1044,8 @@ static void panthor_fw_init_global_iface(struct panthor_device *ptdev) · 1043 unmodified lines
10441044 if (panthor_fw_has_glb_state(ptdev))
10451045 glb_iface->input->ack_irq_mask |= GLB_STATE_MASK;
10461046
1047− panthor_fw_update_reqs(glb_iface, req, GLB_IDLE_EN, GLB_IDLE_EN);
1047+ panthor_fw_update_reqs(glb_iface, req, GLB_IDLE_EN | GLB_COUNTER_EN,
1048+ GLB_IDLE_EN | GLB_COUNTER_EN);
10481049 panthor_fw_toggle_reqs(glb_iface, req, ack,
10491050 GLB_CFG_ALLOC_EN |
10501051 GLB_CFG_POWEROFF_TIMER |
@@ -1187,7 +1188,6 @@ void panthor_fw_pre_reset(struct panthor_device *ptdev, bool on_hang) · 136 unmodified lines
11871188 else
11881189 ptdev->reset.fast = true;
11891190 }
1190− panthor_fw_stop(ptdev);
11911191
11921192 panthor_job_irq_suspend(&ptdev->fw->irq);
11931193 panthor_fw_stop(ptdev);
drivers/gpu/drm/panthor/panthor_gem.c+255−3
@@ -1,6 +1,7 @@
11 // SPDX-License-Identifier: GPL-2.0 or MIT
22 /* Copyright 2019 Linaro, Ltd, Rob Herring <robh@kernel.org> */
33 /* Copyright 2023 Collabora ltd. */
4+/* Copyright 2025 Amazon.com, Inc. or its affiliates */
45
56 #include <linux/cleanup.h>
67 #include <linux/dma-buf.h>
@@ -12,10 +13,27 @@ · 5 unmodified lines
1213 #include <drm/panthor_drm.h>
1314
1415 #include "panthor_device.h"
16+#include "panthor_drv.h"
1517 #include "panthor_fw.h"
1618 #include "panthor_gem.h"
1719 #include "panthor_mmu.h"
1820
21+void panthor_gem_init(struct panthor_device *ptdev)
22+{
23+ int err;
24+
25+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) &&
26+ !panthor_transparent_hugepage)
27+ return;
28+
29+ err = drm_gem_huge_mnt_create(&ptdev->base, "within_size");
30+ if (drm_gem_get_huge_mnt(&ptdev->base))
31+ drm_info(&ptdev->base, "Using Transparent Hugepage\n");
32+ else if (err)
33+ drm_warn(&ptdev->base, "Can't use Transparent Hugepage (%d)\n",
34+ err);
35+}
36+
1937 #ifdef CONFIG_DEBUG_FS
2038 static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo)
2139 {
@@ -59,6 +77,39 @@ static void panthor_gem_debugfs_set_usage_flags(struct panthor_gem_object *bo, u · 37 unmodified lines
5977 static void panthor_gem_debugfs_bo_init(struct panthor_gem_object *bo) {}
6078 #endif
6179
80+static bool
81+should_map_wc(struct panthor_gem_object *bo, struct panthor_vm *exclusive_vm)
82+{
83+ struct panthor_device *ptdev = container_of(bo->base.base.dev, struct panthor_device, base);
84+
85+ /* We can't do uncached mappings if the device is coherent,
86+ * because the zeroing done by the shmem layer at page allocation
87+ * time happens on a cached mapping which isn't CPU-flushed (at least
88+ * not on Arm64 where the flush is deferred to PTE setup time, and
89+ * only done conditionally based on the mapping permissions). We can't
90+ * rely on dma_map_sgtable()/dma_sync_sgtable_for_xxx() either to flush
91+ * those, because they are NOPed if dma_dev_coherent() returns true.
92+ *
93+ * FIXME: Note that this problem is going to pop up again when we
94+ * decide to support mapping buffers with the NO_MMAP flag as
95+ * non-shareable (AKA buffers accessed only by the GPU), because we
96+ * need the same CPU flush to happen after page allocation, otherwise
97+ * there's a risk of data leak or late corruption caused by a dirty
98+ * cacheline being evicted. At this point we'll need a way to force
99+ * CPU cache maintenance regardless of whether the device is coherent
100+ * or not.
101+ */
102+ if (ptdev->coherent)
103+ return false;
104+
105+ /* Cached mappings are explicitly requested, so no write-combine. */
106+ if (bo->flags & DRM_PANTHOR_BO_WB_MMAP)
107+ return false;
108+
109+ /* The default is write-combine. */
110+ return true;
111+}
112+
62113 static void panthor_gem_free_object(struct drm_gem_object *obj)
63114 {
64115 struct panthor_gem_object *bo = to_panthor_bo(obj);
@@ -145,6 +196,7 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, · 80 unmodified lines
145196 bo = to_panthor_bo(&obj->base);
146197 kbo->obj = &obj->base;
147198 bo->flags = bo_flags;
199+ bo->base.map_wc = should_map_wc(bo, vm);
148200 bo->exclusive_vm_root_gem = panthor_vm_root_gem(vm);
149201 drm_gem_object_get(bo->exclusive_vm_root_gem);
150202 bo->base.base.resv = bo->exclusive_vm_root_gem->resv;
@@ -184,14 +236,130 @@ err_free_bo: · 33 unmodified lines
184236 return ERR_PTR(ret);
185237 }
186238
239+static struct sg_table *
240+panthor_gem_prime_map_dma_buf(struct dma_buf_attachment *attach,
241+ enum dma_data_direction dir)
242+{
243+ struct sg_table *sgt = drm_gem_map_dma_buf(attach, dir);
244+
245+ if (!IS_ERR(sgt))
246+ attach->priv = sgt;
247+
248+ return sgt;
249+}
250+
251+static void
252+panthor_gem_prime_unmap_dma_buf(struct dma_buf_attachment *attach,
253+ struct sg_table *sgt,
254+ enum dma_data_direction dir)
255+{
256+ attach->priv = NULL;
257+ drm_gem_unmap_dma_buf(attach, sgt, dir);
258+}
259+
260+static int
261+panthor_gem_prime_begin_cpu_access(struct dma_buf *dma_buf,
262+ enum dma_data_direction dir)
263+{
264+ struct drm_gem_object *obj = dma_buf->priv;
265+ struct drm_device *dev = obj->dev;
266+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
267+ struct dma_buf_attachment *attach;
268+
269+ dma_resv_lock(obj->resv, NULL);
270+ if (shmem->sgt)
271+ dma_sync_sgtable_for_cpu(dev->dev, shmem->sgt, dir);
272+
273+ if (shmem->vaddr)
274+ invalidate_kernel_vmap_range(shmem->vaddr, shmem->base.size);
275+
276+ list_for_each_entry(attach, &dma_buf->attachments, node) {
277+ struct sg_table *sgt = attach->priv;
278+
279+ if (sgt)
280+ dma_sync_sgtable_for_cpu(attach->dev, sgt, dir);
281+ }
282+ dma_resv_unlock(obj->resv);
283+
284+ return 0;
285+}
286+
287+static int
288+panthor_gem_prime_end_cpu_access(struct dma_buf *dma_buf,
289+ enum dma_data_direction dir)
290+{
291+ struct drm_gem_object *obj = dma_buf->priv;
292+ struct drm_device *dev = obj->dev;
293+ struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
294+ struct dma_buf_attachment *attach;
295+
296+ dma_resv_lock(obj->resv, NULL);
297+ list_for_each_entry(attach, &dma_buf->attachments, node) {
298+ struct sg_table *sgt = attach->priv;
299+
300+ if (sgt)
301+ dma_sync_sgtable_for_device(attach->dev, sgt, dir);
302+ }
303+
304+ if (shmem->vaddr)
305+ flush_kernel_vmap_range(shmem->vaddr, shmem->base.size);
306+
307+ if (shmem->sgt)
308+ dma_sync_sgtable_for_device(dev->dev, shmem->sgt, dir);
309+
310+ dma_resv_unlock(obj->resv);
311+ return 0;
312+}
313+
314+static const struct dma_buf_ops panthor_dma_buf_ops = {
315+ .attach = drm_gem_map_attach,
316+ .detach = drm_gem_map_detach,
317+ .map_dma_buf = panthor_gem_prime_map_dma_buf,
318+ .unmap_dma_buf = panthor_gem_prime_unmap_dma_buf,
319+ .release = drm_gem_dmabuf_release,
320+ .mmap = drm_gem_dmabuf_mmap,
321+ .vmap = drm_gem_dmabuf_vmap,
322+ .vunmap = drm_gem_dmabuf_vunmap,
323+ .begin_cpu_access = panthor_gem_prime_begin_cpu_access,
324+ .end_cpu_access = panthor_gem_prime_end_cpu_access,
325+};
326+
187327 static struct dma_buf *
188328 panthor_gem_prime_export(struct drm_gem_object *obj, int flags)
189329 {
330+ struct drm_device *dev = obj->dev;
331+ struct dma_buf_export_info exp_info = {
332+ .exp_name = KBUILD_MODNAME,
333+ .owner = THIS_MODULE,
334+ .ops = &panthor_dma_buf_ops,
335+ .size = obj->size,
336+ .flags = flags,
337+ .priv = obj,
338+ .resv = obj->resv,
339+ };
340+
190341 /* We can't export GEMs that have an exclusive VM. */
191342 if (to_panthor_bo(obj)->exclusive_vm_root_gem)
192343 return ERR_PTR(-EINVAL);
193344
194− return drm_gem_prime_export(obj, flags);
345+ return drm_gem_dmabuf_export(dev, &exp_info);
346+}
347+
348+struct drm_gem_object *
349+panthor_gem_prime_import(struct drm_device *dev,
350+ struct dma_buf *dma_buf)
351+{
352+ struct drm_gem_object *obj = dma_buf->priv;
353+
354+ if (dma_buf->ops == &panthor_dma_buf_ops && obj->dev == dev) {
355+ /* Importing dmabuf exported from our own gem increases
356+ * refcount on gem itself instead of f_count of dmabuf.
357+ */
358+ drm_gem_object_get(obj);
359+ return obj;
360+ }
361+
362+ return drm_gem_prime_import(dev, dma_buf);
195363 }
196364
197365 static enum drm_gem_object_status panthor_gem_status(struct drm_gem_object *obj)
@@ -229,7 +397,6 @@ static const struct drm_gem_object_funcs panthor_gem_funcs = { · 31 unmodified lines
229397 */
230398 struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t size)
231399 {
232− struct panthor_device *ptdev = container_of(ddev, struct panthor_device, base);
233400 struct panthor_gem_object *obj;
234401
235402 obj = kzalloc(sizeof(*obj), GFP_KERNEL);
@@ -237,7 +404,6 @@ struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t · 1 unmodified line
237404 return ERR_PTR(-ENOMEM);
238405
239406 obj->base.base.funcs = &panthor_gem_funcs;
240− obj->base.map_wc = !ptdev->coherent;
241407 mutex_init(&obj->label.lock);
242408
243409 panthor_gem_debugfs_bo_init(obj);
@@ -272,6 +438,7 @@ panthor_gem_create_with_handle(struct drm_file *file, · 28 unmodified lines
272438
273439 bo = to_panthor_bo(&shmem->base);
274440 bo->flags = flags;
441+ bo->base.map_wc = should_map_wc(bo, exclusive_vm);
275442
276443 if (exclusive_vm) {
277444 bo->exclusive_vm_root_gem = panthor_vm_root_gem(exclusive_vm);
@@ -349,6 +516,91 @@ panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label) · 71 unmodified lines
349516 panthor_gem_bo_set_label(bo->obj, str);
350517 }
351518
519+int
520+panthor_gem_sync(struct drm_gem_object *obj, u32 type,
521+ u64 offset, u64 size)
522+{
523+ struct panthor_gem_object *bo = to_panthor_bo(obj);
524+ struct drm_gem_shmem_object *shmem = &bo->base;
525+ const struct drm_device *dev = shmem->base.dev;
526+ struct sg_table *sgt;
527+ struct scatterlist *sgl;
528+ unsigned int count;
529+
530+ /* Make sure the range is in bounds. */
531+ if (offset + size < offset || offset + size > shmem->base.size)
532+ return -EINVAL;
533+
534+ /* Disallow CPU-cache maintenance on imported buffers. */
535+ if (drm_gem_is_imported(&shmem->base))
536+ return -EINVAL;
537+
538+ switch (type) {
539+ case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH:
540+ case DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE:
541+ break;
542+
543+ default:
544+ return -EINVAL;
545+ }
546+
547+ /* Don't bother if it's WC-mapped */
548+ if (shmem->map_wc)
549+ return 0;
550+
551+ /* Nothing to do if the size is zero. */
552+ if (size == 0)
553+ return 0;
554+
555+ sgt = drm_gem_shmem_get_pages_sgt(shmem);
556+ if (IS_ERR(sgt))
557+ return PTR_ERR(sgt);
558+
559+ for_each_sgtable_dma_sg(sgt, sgl, count) {
560+ if (size == 0)
561+ break;
562+
563+ dma_addr_t paddr = sg_dma_address(sgl);
564+ size_t len = sg_dma_len(sgl);
565+
566+ if (len <= offset) {
567+ offset -= len;
568+ continue;
569+ }
570+
571+ paddr += offset;
572+ len -= offset;
573+ len = min_t(size_t, len, size);
574+ size -= len;
575+ offset = 0;
576+
577+ /* It's unclear whether dma_sync_xxx() is the right API to do CPU
578+ * cache maintenance given an IOMMU can register their own
579+ * implementation doing more than just CPU cache flushes/invalidation,
580+ * and what we really care about here is CPU caches only, but that's
581+ * the best we have that is both arch-agnostic and does at least the
582+ * CPU cache maintenance on a <page,offset,size> tuple.
583+ *
584+ * Also, I wish we could do a single
585+ *
586+ * dma_sync_single_for_device(BIDIR)
587+ *
588+ * and get a flush+invalidate, but that's not how it's implemented
589+ * in practice (at least on arm64), so we have to make it
590+ *
591+ * dma_sync_single_for_device(TO_DEVICE)
592+ * dma_sync_single_for_cpu(FROM_DEVICE)
593+ *
594+ * for the flush+invalidate case.
595+ */
596+ dma_sync_single_for_device(dev->dev, paddr, len, DMA_TO_DEVICE);
597+ if (type == DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE)
598+ dma_sync_single_for_cpu(dev->dev, paddr, len, DMA_FROM_DEVICE);
599+ }
600+
601+ return 0;
602+}
603+
352604 #ifdef CONFIG_DEBUG_FS
353605 struct gem_size_totals {
354606 size_t size;
drivers/gpu/drm/panthor/panthor_gem.h+8−0
@@ -136,6 +136,8 @@ struct panthor_gem_object *to_panthor_bo(struct drm_gem_object *obj) · 135 unmodified lines
136136 return container_of(to_drm_gem_shmem_obj(obj), struct panthor_gem_object, base);
137137 }
138138
139+void panthor_gem_init(struct panthor_device *ptdev);
140+
139141 struct drm_gem_object *panthor_gem_create_object(struct drm_device *ddev, size_t size);
140142
141143 int
@@ -146,6 +148,12 @@ panthor_gem_create_with_handle(struct drm_file *file, · 4 unmodified lines
146148
147149 void panthor_gem_bo_set_label(struct drm_gem_object *obj, const char *label);
148150 void panthor_gem_kernel_bo_set_label(struct panthor_kernel_bo *bo, const char *label);
151+int panthor_gem_sync(struct drm_gem_object *obj,
152+ u32 type, u64 offset, u64 size);
153+
154+struct drm_gem_object *
155+panthor_gem_prime_import(struct drm_device *dev,
156+ struct dma_buf *dma_buf);
149157
150158 static inline u64
151159 panthor_kernel_bo_gpuva(struct panthor_kernel_bo *bo)
drivers/gpu/drm/panthor/panthor_gpu.c+13−8
@@ -51,7 +51,7 @@ struct panthor_gpu { · 50 unmodified lines
5151 static void panthor_gpu_coherency_set(struct panthor_device *ptdev)
5252 {
5353 gpu_write(ptdev, GPU_COHERENCY_PROTOCOL,
54− ptdev->coherent ? GPU_COHERENCY_PROT_BIT(ACE_LITE) : GPU_COHERENCY_NONE);
54+ ptdev->gpu_info.selected_coherency);
5555 }
5656
5757 static void panthor_gpu_l2_config_set(struct panthor_device *ptdev)
@@ -289,38 +289,42 @@ int panthor_gpu_l2_power_on(struct panthor_device *ptdev) · 231 unmodified lines
289289 int panthor_gpu_flush_caches(struct panthor_device *ptdev,
290290 u32 l2, u32 lsc, u32 other)
291291 {
292− bool timedout = false;
293292 unsigned long flags;
293+ int ret = 0;
294294
295295 /* Serialize cache flush operations. */
296296 guard(mutex)(&ptdev->gpu->cache_flush_lock);
297297
298298 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
299− if (!drm_WARN_ON(&ptdev->base,
300− ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
299+ if (!(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED)) {
301300 ptdev->gpu->pending_reqs |= GPU_IRQ_CLEAN_CACHES_COMPLETED;
302301 gpu_write(ptdev, GPU_CMD, GPU_FLUSH_CACHES(l2, lsc, other));
302+ } else {
303+ ret = -EIO;
303304 }
304305 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
305306
307+ if (ret)
308+ return ret;
309+
306310 if (!wait_event_timeout(ptdev->gpu->reqs_acked,
307311 !(ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED),
308312 msecs_to_jiffies(100))) {
309313 spin_lock_irqsave(&ptdev->gpu->reqs_lock, flags);
310314 if ((ptdev->gpu->pending_reqs & GPU_IRQ_CLEAN_CACHES_COMPLETED) != 0 &&
311315 !(gpu_read(ptdev, GPU_INT_RAWSTAT) & GPU_IRQ_CLEAN_CACHES_COMPLETED))
312− timedout = true;
316+ ret = -ETIMEDOUT;
313317 else
314318 ptdev->gpu->pending_reqs &= ~GPU_IRQ_CLEAN_CACHES_COMPLETED;
315319 spin_unlock_irqrestore(&ptdev->gpu->reqs_lock, flags);
316320 }
317321
318− if (timedout) {
322+ if (ret) {
323+ panthor_device_schedule_reset(ptdev);
319324 drm_err(&ptdev->base, "Flush caches timeout");
320− return -ETIMEDOUT;
321325 }
322326
323− return 0;
327+ return ret;
324328 }
325329
326330 /**
@@ -360,6 +364,7 @@ int panthor_gpu_soft_reset(struct panthor_device *ptdev) · 33 unmodified lines
360364 return -ETIMEDOUT;
361365 }
362366
367+ ptdev->gpu->pending_reqs = 0;
363368 return 0;
364369 }
365370
drivers/gpu/drm/panthor/panthor_mmu.c+183−131
@@ -375,6 +375,15 @@ struct panthor_vm { · 374 unmodified lines
375375 * flagged as faulty as a result.
376376 */
377377 bool unhandled_fault;
378+
379+ /** @locked_region: Information about the currently locked region currently. */
380+ struct {
381+ /** @locked_region.start: Start of the locked region. */
382+ u64 start;
383+
384+ /** @locked_region.size: Size of the locked region. */
385+ u64 size;
386+ } locked_region;
378387 };
379388
380389 /**
@@ -510,27 +519,27 @@ static int wait_ready(struct panthor_device *ptdev, u32 as_nr) · 129 unmodified lines
510519 return ret;
511520 }
512521
513−static int write_cmd(struct panthor_device *ptdev, u32 as_nr, u32 cmd)
522+static int as_send_cmd_and_wait(struct panthor_device *ptdev, u32 as_nr, u32 cmd)
514523 {
515524 int status;
516525
517526 /* write AS_COMMAND when MMU is ready to accept another command */
518527 status = wait_ready(ptdev, as_nr);
519− if (!status)
528+ if (!status) {
520529 gpu_write(ptdev, AS_COMMAND(as_nr), cmd);
530+ status = wait_ready(ptdev, as_nr);
531+ }
521532
522533 return status;
523534 }
524535
525−static void lock_region(struct panthor_device *ptdev, u32 as_nr,
526− u64 region_start, u64 size)
536+static u64 pack_region_range(struct panthor_device *ptdev, u64 region_start, u64 size)
527537 {
528538 u8 region_width;
529− u64 region;
530539 u64 region_end = region_start + size;
531540
532− if (!size)
533− return;
541+ if (drm_WARN_ON_ONCE(&ptdev->base, !size))
542+ return 0;
534543
535544 /*
536545 * The locked region is a naturally aligned power of 2 block encoded as
@@ -549,106 +558,51 @@ static void lock_region(struct panthor_device *ptdev, u32 as_nr, · 12 unmodified lines
549558 */
550559 region_start &= GENMASK_ULL(63, region_width);
551560
552− region = region_width | region_start;
553−
554− /* Lock the region that needs to be updated */
555− gpu_write64(ptdev, AS_LOCKADDR(as_nr), region);
556− write_cmd(ptdev, as_nr, AS_COMMAND_LOCK);
557−}
558−
559−static int mmu_hw_do_operation_locked(struct panthor_device *ptdev, int as_nr,
560− u64 iova, u64 size, u32 op)
561−{
562− const u32 l2_flush_op = CACHE_CLEAN | CACHE_INV;
563− u32 lsc_flush_op;
564− int ret;
565−
566− lockdep_assert_held(&ptdev->mmu->as.slots_lock);
567−
568− switch (op) {
569− case AS_COMMAND_FLUSH_MEM:
570− lsc_flush_op = CACHE_CLEAN | CACHE_INV;
571− break;
572− case AS_COMMAND_FLUSH_PT:
573− lsc_flush_op = 0;
574− break;
575− default:
576− drm_WARN(&ptdev->base, 1, "Unexpected AS_COMMAND: %d", op);
577− return -EINVAL;
578− }
579−
580− if (as_nr < 0)
581− return 0;
582−
583− /*
584− * If the AS number is greater than zero, then we can be sure
585− * the device is up and running, so we don't need to explicitly
586− * power it up
587− */
588−
589− lock_region(ptdev, as_nr, iova, size);
590−
591− ret = wait_ready(ptdev, as_nr);
592− if (ret)
593− return ret;
594−
595− ret = panthor_gpu_flush_caches(ptdev, l2_flush_op, lsc_flush_op, 0);
596− if (ret)
597− return ret;
598−
599− /*
600− * Explicitly unlock the region as the AS is not unlocked automatically
601− * at the end of the GPU_CONTROL cache flush command, unlike
602− * AS_COMMAND_FLUSH_MEM or AS_COMMAND_FLUSH_PT.
603− */
604− write_cmd(ptdev, as_nr, AS_COMMAND_UNLOCK);
605−
606− /* Wait for the unlock command to complete */
607− return wait_ready(ptdev, as_nr);
608−}
609−
610−static int mmu_hw_do_operation(struct panthor_vm *vm,
611− u64 iova, u64 size, u32 op)
612−{
613− struct panthor_device *ptdev = vm->ptdev;
614− int ret;
615−
616− mutex_lock(&ptdev->mmu->as.slots_lock);
617− ret = mmu_hw_do_operation_locked(ptdev, vm->as.id, iova, size, op);
618− mutex_unlock(&ptdev->mmu->as.slots_lock);
619−
620− return ret;
561+ return region_width | region_start;
621562 }
622563
623564 static int panthor_mmu_as_enable(struct panthor_device *ptdev, u32 as_nr,
624565 u64 transtab, u64 transcfg, u64 memattr)
625566 {
626− int ret;
627−
628− ret = mmu_hw_do_operation_locked(ptdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
629− if (ret)
630− return ret;
631−
632567 gpu_write64(ptdev, AS_TRANSTAB(as_nr), transtab);
633568 gpu_write64(ptdev, AS_MEMATTR(as_nr), memattr);
634569 gpu_write64(ptdev, AS_TRANSCFG(as_nr), transcfg);
635570
636− return write_cmd(ptdev, as_nr, AS_COMMAND_UPDATE);
571+ return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
637572 }
638573
639−static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr)
574+static int panthor_mmu_as_disable(struct panthor_device *ptdev, u32 as_nr,
575+ bool recycle_slot)
640576 {
577+ struct panthor_vm *vm = ptdev->mmu->as.slots[as_nr].vm;
641578 int ret;
642579
643− ret = mmu_hw_do_operation_locked(ptdev, as_nr, 0, ~0ULL, AS_COMMAND_FLUSH_MEM);
580+ lockdep_assert_held(&ptdev->mmu->as.slots_lock);
581+
582+ /* Flush+invalidate RW caches, invalidate RO ones. */
583+ ret = panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV,
584+ CACHE_CLEAN | CACHE_INV, CACHE_INV);
644585 if (ret)
645586 return ret;
646587
588+ if (vm && vm->locked_region.size) {
589+ /* Unlock the region if there's a lock pending. */
590+ ret = as_send_cmd_and_wait(ptdev, vm->as.id, AS_COMMAND_UNLOCK);
591+ if (ret)
592+ return ret;
593+ }
594+
595+ /* If the slot is going to be used immediately, don't bother changing
596+ * the config.
597+ */
598+ if (recycle_slot)
599+ return 0;
600+
647601 gpu_write64(ptdev, AS_TRANSTAB(as_nr), 0);
648602 gpu_write64(ptdev, AS_MEMATTR(as_nr), 0);
649603 gpu_write64(ptdev, AS_TRANSCFG(as_nr), AS_TRANSCFG_ADRMODE_UNMAPPED);
650604
651− return write_cmd(ptdev, as_nr, AS_COMMAND_UPDATE);
605+ return as_send_cmd_and_wait(ptdev, as_nr, AS_COMMAND_UPDATE);
652606 }
653607
654608 static u32 panthor_mmu_fault_mask(struct panthor_device *ptdev, u32 value)
@@ -722,6 +676,10 @@ int panthor_vm_active(struct panthor_vm *vm) · 67 unmodified lines
722676 if (refcount_inc_not_zero(&vm->as.active_cnt))
723677 goto out_dev_exit;
724678
679+ /* Make sure we don't race with lock/unlock_region() calls
680+ * happening around VM bind operations.
681+ */
682+ mutex_lock(&vm->op_lock);
725683 mutex_lock(&ptdev->mmu->as.slots_lock);
726684
727685 if (refcount_inc_not_zero(&vm->as.active_cnt))
@@ -759,6 +717,11 @@ int panthor_vm_active(struct panthor_vm *vm) · 31 unmodified lines
759717
760718 drm_WARN_ON(&ptdev->base, refcount_read(&lru_vm->as.active_cnt));
761719 as = lru_vm->as.id;
720+
721+ ret = panthor_mmu_as_disable(ptdev, as, true);
722+ if (ret)
723+ goto out_unlock;
724+
762725 panthor_vm_release_as_locked(lru_vm);
763726 }
764727
@@ -789,6 +752,10 @@ out_enable_as: · 24 unmodified lines
789752 gpu_write(ptdev, MMU_INT_MASK, ~ptdev->mmu->as.faulty_mask);
790753 }
791754
755+ /* The VM update is guarded by ::op_lock, which we take at the beginning
756+ * of this function, so we don't expect any locked region here.
757+ */
758+ drm_WARN_ON(&vm->ptdev->base, vm->locked_region.size > 0);
792759 ret = panthor_mmu_as_enable(vm->ptdev, vm->as.id, transtab, transcfg, vm->memattr);
793760
794761 out_make_active:
@@ -799,6 +766,7 @@ out_make_active: · 4 unmodified lines
799766
800767 out_unlock:
801768 mutex_unlock(&ptdev->mmu->as.slots_lock);
769+ mutex_unlock(&vm->op_lock);
802770
803771 out_dev_exit:
804772 drm_dev_exit(cookie);
@@ -882,44 +850,64 @@ static size_t get_pgsize(u64 addr, size_t size, size_t *count) · 77 unmodified lines
882850 return SZ_2M;
883851 }
884852
885−static int panthor_vm_flush_range(struct panthor_vm *vm, u64 iova, u64 size)
853+static void panthor_vm_declare_unusable(struct panthor_vm *vm)
886854 {
887855 struct panthor_device *ptdev = vm->ptdev;
888− int ret = 0, cookie;
889−
890− if (vm->as.id < 0)
891− return 0;
856+ int cookie;
892857
893− /* If the device is unplugged, we just silently skip the flush. */
894− if (!drm_dev_enter(&ptdev->base, &cookie))
895− return 0;
896−
897− ret = mmu_hw_do_operation(vm, iova, size, AS_COMMAND_FLUSH_PT);
858+ if (vm->unusable)
859+ return;
898860
899− drm_dev_exit(cookie);
900− return ret;
861+ vm->unusable = true;
862+ mutex_lock(&ptdev->mmu->as.slots_lock);
863+ if (vm->as.id >= 0 && drm_dev_enter(&ptdev->base, &cookie)) {
864+ panthor_mmu_as_disable(ptdev, vm->as.id, false);
865+ drm_dev_exit(cookie);
866+ }
867+ mutex_unlock(&ptdev->mmu->as.slots_lock);
901868 }
902869
903−static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
870+static void panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size)
904871 {
905872 struct panthor_device *ptdev = vm->ptdev;
906873 struct io_pgtable_ops *ops = vm->pgtbl_ops;
907874 u64 start_iova = iova;
908875 u64 offset = 0;
909876
877+ if (!size)
878+ return;
879+
880+ drm_WARN_ON(&ptdev->base,
881+ (iova < vm->locked_region.start) ||
882+ (iova + size > vm->locked_region.start + vm->locked_region.size));
883+
910884 while (offset < size) {
911885 size_t unmapped_sz = 0, pgcount;
912886 size_t pgsize = get_pgsize(iova + offset, size - offset, &pgcount);
913887
914888 unmapped_sz = ops->unmap_pages(ops, iova + offset, pgsize, pgcount, NULL);
889+ if (drm_WARN_ON_ONCE(&ptdev->base, unmapped_sz != pgsize * pgcount)) {
890+ /* Gracefully handle sparsely unmapped regions to avoid leaving
891+ * page table pages behind when the drm_gpuvm and VM page table
892+ * are out-of-sync. This is not supposed to happen, hence the
893+ * above WARN_ON().
894+ */
895+ while (!ops->iova_to_phys(ops, iova + unmapped_sz) &&
896+ unmapped_sz < pgsize * pgcount)
897+ unmapped_sz += SZ_4K;
898+
899+ /* We're passed the point where we can try to fix things,
900+ * so flag the VM unusable to make sure it's not going
901+ * to be used anymore.
902+ */
903+ panthor_vm_declare_unusable(vm);
915904
916− if (drm_WARN_ON(&ptdev->base, unmapped_sz != pgsize * pgcount)) {
917− drm_err(&ptdev->base, "failed to unmap range %llx-%llx (requested range %llx-%llx)\n",
918− iova + offset + unmapped_sz,
919− iova + offset + pgsize * pgcount,
920− iova, iova + size);
921− panthor_vm_flush_range(vm, iova, offset + unmapped_sz);
922− return -EINVAL;
905+ /* If we don't make progress, we're screwed. That also means
906+ * something else prevents us from unmapping the region, but
907+ * there's not much we can do here: time for debugging.
908+ */
909+ if (drm_WARN_ON_ONCE(&ptdev->base, !unmapped_sz))
910+ return;
923911 }
924912
925913 drm_dbg(&ptdev->base,
@@ -929,8 +917,6 @@ static int panthor_vm_unmap_pages(struct panthor_vm *vm, u64 iova, u64 size) · 3 unmodified lines
929917
930918 offset += unmapped_sz;
931919 }
932−
933− return panthor_vm_flush_range(vm, iova, size);
934920 }
935921
936922 static int
@@ -948,6 +934,10 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot, · 11 unmodified lines
948934 if (!size)
949935 return 0;
950936
937+ drm_WARN_ON(&ptdev->base,
938+ (iova < vm->locked_region.start) ||
939+ (iova + size > vm->locked_region.start + vm->locked_region.size));
940+
951941 for_each_sgtable_dma_sg(sgt, sgl, count) {
952942 dma_addr_t paddr = sg_dma_address(sgl);
953943 size_t len = sg_dma_len(sgl);
@@ -978,16 +968,17 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot, · 24 unmodified lines
978968 paddr += mapped;
979969 len -= mapped;
980970
981− if (drm_WARN_ON(&ptdev->base, !ret && !mapped))
971+ /* If nothing was mapped, consider it an ENOMEM. */
972+ if (!ret && !mapped)
982973 ret = -ENOMEM;
983974
984− if (ret) {
985− /* If something failed, unmap what we've already mapped before
986− * returning. The unmap call is not supposed to fail.
975+ /* If something fails, we stop there, and flag the VM unusable. */
976+ if (drm_WARN_ON_ONCE(&ptdev->base, ret)) {
977+ /* Unmap what we've already mapped to avoid leaving page
978+ * table pages behind.
987979 */
988− drm_WARN_ON(&ptdev->base,
989− panthor_vm_unmap_pages(vm, start_iova,
990− iova - start_iova));
980+ panthor_vm_unmap_pages(vm, start_iova, iova - start_iova);
981+ panthor_vm_declare_unusable(vm);
991982 return ret;
992983 }
993984 }
@@ -998,7 +989,7 @@ panthor_vm_map_pages(struct panthor_vm *vm, u64 iova, int prot, · 4 unmodified lines
998989 offset = 0;
999990 }
1000991
1001− return panthor_vm_flush_range(vm, start_iova, iova - start_iova);
992+ return 0;
1002993 }
1003994
1004995 static int flags_to_prot(u32 flags)
@@ -1641,6 +1632,62 @@ static const char *access_type_name(struct panthor_device *ptdev, · 636 unmodified lines
16411632 }
16421633 }
16431634
1635+static int panthor_vm_lock_region(struct panthor_vm *vm, u64 start, u64 size)
1636+{
1637+ struct panthor_device *ptdev = vm->ptdev;
1638+ int ret = 0;
1639+
1640+ mutex_lock(&ptdev->mmu->as.slots_lock);
1641+ drm_WARN_ON(&ptdev->base, vm->locked_region.start || vm->locked_region.size);
1642+ if (vm->as.id >= 0 && size) {
1643+ /* Lock the region that needs to be updated */
1644+ gpu_write64(ptdev, AS_LOCKADDR(vm->as.id),
1645+ pack_region_range(ptdev, start, size));
1646+
1647+ /* If the lock succeeded, update the locked_region info. */
1648+ ret = as_send_cmd_and_wait(ptdev, vm->as.id, AS_COMMAND_LOCK);
1649+ }
1650+
1651+ if (!ret) {
1652+ vm->locked_region.start = start;
1653+ vm->locked_region.size = size;
1654+ }
1655+ mutex_unlock(&ptdev->mmu->as.slots_lock);
1656+
1657+ return ret;
1658+}
1659+
1660+static void panthor_vm_unlock_region(struct panthor_vm *vm)
1661+{
1662+ struct panthor_device *ptdev = vm->ptdev;
1663+
1664+ mutex_lock(&ptdev->mmu->as.slots_lock);
1665+ if (vm->as.id >= 0) {
1666+ int ret;
1667+
1668+ /* flush+invalidate RW caches and invalidate RO ones.
1669+ * TODO: See if we can use FLUSH_PA_RANGE when the physical
1670+ * range is narrow enough and the HW supports it.
1671+ */
1672+ ret = panthor_gpu_flush_caches(ptdev, CACHE_CLEAN | CACHE_INV,
1673+ CACHE_CLEAN | CACHE_INV,
1674+ CACHE_INV);
1675+
1676+ /* Unlock the region if the flush is effective. */
1677+ if (!ret)
1678+ ret = as_send_cmd_and_wait(ptdev, vm->as.id, AS_COMMAND_UNLOCK);
1679+
1680+ /* If we fail to flush or unlock the region, schedule a GPU reset
1681+ * to unblock the situation.
1682+ */
1683+ if (ret)
1684+ panthor_device_schedule_reset(ptdev);
1685+ }
1686+ vm->locked_region.start = 0;
1687+ vm->locked_region.size = 0;
1688+ mutex_unlock(&ptdev->mmu->as.slots_lock);
1689+}
1690+
16441691 static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status)
16451692 {
16461693 bool has_unhandled_faults = false;
@@ -1701,7 +1748,7 @@ static void panthor_mmu_irq_handler(struct panthor_device *ptdev, u32 status) · 54 unmodified lines
17011748 ptdev->mmu->as.slots[as].vm->unhandled_fault = true;
17021749
17031750 /* Disable the MMU to kill jobs on this AS. */
1704− panthor_mmu_as_disable(ptdev, as);
1751+ panthor_mmu_as_disable(ptdev, as, false);
17051752 mutex_unlock(&ptdev->mmu->as.slots_lock);
17061753
17071754 status &= ~mask;
@@ -1730,7 +1777,8 @@ void panthor_mmu_suspend(struct panthor_device *ptdev) · 22 unmodified lines
17301777 struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
17311778
17321779 if (vm) {
1733− drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, i));
1780+ drm_WARN_ON(&ptdev->base,
1781+ panthor_mmu_as_disable(ptdev, i, false));
17341782 panthor_vm_release_as_locked(vm);
17351783 }
17361784 }
@@ -1845,12 +1893,13 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) · 108 unmodified lines
18451893 drm_sched_entity_destroy(&vm->entity);
18461894 drm_sched_fini(&vm->sched);
18471895
1896+ mutex_lock(&vm->op_lock);
18481897 mutex_lock(&ptdev->mmu->as.slots_lock);
18491898 if (vm->as.id >= 0) {
18501899 int cookie;
18511900
18521901 if (drm_dev_enter(&ptdev->base, &cookie)) {
1853− panthor_mmu_as_disable(ptdev, vm->as.id);
1902+ panthor_mmu_as_disable(ptdev, vm->as.id, false);
18541903 drm_dev_exit(cookie);
18551904 }
18561905
@@ -1859,6 +1908,7 @@ static void panthor_vm_free(struct drm_gpuvm *gpuvm) · 2 unmodified lines
18591908 list_del(&vm->as.lru_node);
18601909 }
18611910 mutex_unlock(&ptdev->mmu->as.slots_lock);
1911+ mutex_unlock(&vm->op_lock);
18621912
18631913 free_io_pgtable_ops(vm->pgtbl_ops);
18641914
@@ -2060,12 +2110,9 @@ static int panthor_gpuva_sm_step_remap(struct drm_gpuva_op *op, · 195 unmodified lines
20602110 struct panthor_vm_op_ctx *op_ctx = vm->op_ctx;
20612111 struct panthor_vma *prev_vma = NULL, *next_vma = NULL;
20622112 u64 unmap_start, unmap_range;
2063− int ret;
20642113
20652114 drm_gpuva_op_remap_to_unmap_range(&op->remap, &unmap_start, &unmap_range);
2066− ret = panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
2067− if (ret)
2068− return ret;
2115+ panthor_vm_unmap_pages(vm, unmap_start, unmap_range);
20692116
20702117 if (op->remap.prev) {
20712118 prev_vma = panthor_vm_op_ctx_get_vma(op_ctx);
@@ -2103,13 +2150,9 @@ static int panthor_gpuva_sm_step_unmap(struct drm_gpuva_op *op, · 31 unmodified lines
21032150 {
21042151 struct panthor_vma *unmap_vma = container_of(op->unmap.va, struct panthor_vma, base);
21052152 struct panthor_vm *vm = priv;
2106− int ret;
2107−
2108− ret = panthor_vm_unmap_pages(vm, unmap_vma->base.va.addr,
2109− unmap_vma->base.va.range);
2110− if (drm_WARN_ON(&vm->ptdev->base, ret))
2111− return ret;
21122153
2154+ panthor_vm_unmap_pages(vm, unmap_vma->base.va.addr,
2155+ unmap_vma->base.va.range);
21132156 drm_gpuva_unmap(&op->unmap);
21142157 panthor_vma_unlink(unmap_vma);
21152158 return 0;
@@ -2154,6 +2197,11 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct panthor_vm_op_ctx *op, · 38 unmodified lines
21542197
21552198 mutex_lock(&vm->op_lock);
21562199 vm->op_ctx = op;
2200+
2201+ ret = panthor_vm_lock_region(vm, op->va.addr, op->va.range);
2202+ if (ret)
2203+ goto out;
2204+
21572205 switch (op_type) {
21582206 case DRM_PANTHOR_VM_BIND_OP_TYPE_MAP: {
21592207 const struct drm_gpuvm_map_req map_req = {
@@ -2181,8 +2229,11 @@ panthor_vm_exec_op(struct panthor_vm *vm, struct panthor_vm_op_ctx *op, · 21 unmodified lines
21812229 break;
21822230 }
21832231
2232+ panthor_vm_unlock_region(vm);
2233+
2234+out:
21842235 if (ret && flag_vm_unusable_on_failure)
2185− vm->unusable = true;
2236+ panthor_vm_declare_unusable(vm);
21862237
21872238 vm->op_ctx = NULL;
21882239 mutex_unlock(&vm->op_lock);
@@ -2694,7 +2745,8 @@ void panthor_mmu_unplug(struct panthor_device *ptdev) · 505 unmodified lines
26942745 struct panthor_vm *vm = ptdev->mmu->as.slots[i].vm;
26952746
26962747 if (vm) {
2697− drm_WARN_ON(&ptdev->base, panthor_mmu_as_disable(ptdev, i));
2748+ drm_WARN_ON(&ptdev->base,
2749+ panthor_mmu_as_disable(ptdev, i, false));
26982750 panthor_vm_release_as_locked(vm);
26992751 }
27002752 }
drivers/gpu/drm/panthor/panthor_sched.c+129−121
@@ -108,15 +108,6 @@ struct panthor_csg_slot { · 107 unmodified lines
108108
109109 /** @priority: Group priority. */
110110 u8 priority;
111−
112− /**
113− * @idle: True if the group bound to this slot is idle.
114− *
115− * A group is idle when it has nothing waiting for execution on
116− * all its queues, or when queues are blocked waiting for something
117− * to happen (synchronization object).
118− */
119− bool idle;
120111 };
121112
122113 /**
@@ -878,8 +869,11 @@ panthor_queue_get_syncwait_obj(struct panthor_group *group, struct panthor_queue · 755 unmodified lines
878869 struct iosys_map map;
879870 int ret;
880871
881− if (queue->syncwait.kmap)
882− return queue->syncwait.kmap + queue->syncwait.offset;
872+ if (queue->syncwait.kmap) {
873+ bo = container_of(queue->syncwait.obj,
874+ struct panthor_gem_object, base.base);
875+ goto out_sync;
876+ }
883877
884878 bo = panthor_vm_get_bo_for_va(group->vm,
885879 queue->syncwait.gpu_va,
@@ -896,6 +890,17 @@ panthor_queue_get_syncwait_obj(struct panthor_group *group, struct panthor_queue · 10 unmodified lines
896890 if (drm_WARN_ON(&ptdev->base, !queue->syncwait.kmap))
897891 goto err_put_syncwait_obj;
898892
893+out_sync:
894+ /* Make sure the CPU caches are invalidated before the seqno is read.
895+ * drm_gem_shmem_sync() is a NOP if map_wc=true, so no need to check
896+ * it here.
897+ */
898+ panthor_gem_sync(&bo->base.base, queue->syncwait.offset,
899+ queue->syncwait.sync64 ?
900+ sizeof(struct panthor_syncobj_64b) :
901+ sizeof(struct panthor_syncobj_32b),
902+ DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE);
903+
899904 return queue->syncwait.kmap + queue->syncwait.offset;
900905
901906 err_put_syncwait_obj:
@@ -908,9 +913,8 @@ static void group_free_queue(struct panthor_group *group, struct panthor_queue * · 6 unmodified lines
908913 if (IS_ERR_OR_NULL(queue))
909914 return;
910915
911− /* This should have been disabled before that point. */
912− drm_WARN_ON(&group->ptdev->base,
913− disable_delayed_work_sync(&queue->timeout.work));
916+ /* Disable the timeout before tearing down drm_sched components. */
917+ disable_delayed_work_sync(&queue->timeout.work);
914918
915919 if (queue->entity.fence_context)
916920 drm_sched_entity_destroy(&queue->entity);
@@ -1062,28 +1066,11 @@ group_unbind_locked(struct panthor_group *group) · 145 unmodified lines
10621066 static bool
10631067 group_is_idle(struct panthor_group *group)
10641068 {
1065− struct panthor_device *ptdev = group->ptdev;
1066− u32 inactive_queues;
1067−
1068− if (group->csg_id >= 0)
1069− return ptdev->scheduler->csg_slots[group->csg_id].idle;
1069+ u32 inactive_queues = group->idle_queues | group->blocked_queues;
10701070
1071− inactive_queues = group->idle_queues | group->blocked_queues;
10721071 return hweight32(inactive_queues) == group->queue_count;
10731072 }
10741073
1075−static void
1076−queue_reset_timeout_locked(struct panthor_queue *queue)
1077−{
1078− lockdep_assert_held(&queue->fence_ctx.lock);
1079−
1080− if (queue->timeout.remaining != MAX_SCHEDULE_TIMEOUT) {
1081− mod_delayed_work(queue->scheduler.timeout_wq,
1082− &queue->timeout.work,
1083− msecs_to_jiffies(JOB_TIMEOUT_MS));
1084− }
1085−}
1086−
10871074 static bool
10881075 group_can_run(struct panthor_group *group)
10891076 {
@@ -1100,6 +1087,18 @@ queue_timeout_is_suspended(struct panthor_queue *queue) · 10 unmodified lines
11001087 return queue->timeout.remaining != MAX_SCHEDULE_TIMEOUT;
11011088 }
11021089
1090+static void
1091+queue_reset_timeout_locked(struct panthor_queue *queue)
1092+{
1093+ lockdep_assert_held(&queue->fence_ctx.lock);
1094+
1095+ if (!queue_timeout_is_suspended(queue)) {
1096+ mod_delayed_work(queue->scheduler.timeout_wq,
1097+ &queue->timeout.work,
1098+ msecs_to_jiffies(JOB_TIMEOUT_MS));
1099+ }
1100+}
1101+
11031102 static void
11041103 queue_suspend_timeout_locked(struct panthor_queue *queue)
11051104 {
@@ -1200,12 +1199,10 @@ cs_slot_prog_locked(struct panthor_device *ptdev, u32 csg_id, u32 cs_id) · 94 unmodified lines
12001199 panthor_fw_update_reqs(cs_iface, req,
12011200 CS_IDLE_SYNC_WAIT |
12021201 CS_IDLE_EMPTY |
1203− CS_STATE_START |
1204− CS_EXTRACT_EVENT,
1202+ CS_STATE_START,
12051203 CS_IDLE_SYNC_WAIT |
12061204 CS_IDLE_EMPTY |
1207− CS_STATE_MASK |
1208− CS_EXTRACT_EVENT);
1205+ CS_STATE_MASK);
12091206 if (queue->iface.input->insert != queue->iface.input->extract)
12101207 queue_resume_timeout(queue);
12111208 }
@@ -1725,17 +1722,6 @@ static bool cs_slot_process_irq_locked(struct panthor_device *ptdev, · 513 unmodified lines
17251722 return (events & (CS_FAULT | CS_TILER_OOM)) != 0;
17261723 }
17271724
1728−static void csg_slot_sync_idle_state_locked(struct panthor_device *ptdev, u32 csg_id)
1729−{
1730− struct panthor_csg_slot *csg_slot = &ptdev->scheduler->csg_slots[csg_id];
1731− struct panthor_fw_csg_iface *csg_iface;
1732−
1733− lockdep_assert_held(&ptdev->scheduler->lock);
1734−
1735− csg_iface = panthor_fw_get_csg_iface(ptdev, csg_id);
1736− csg_slot->idle = csg_iface->output->status_state & CSG_STATUS_STATE_IS_IDLE;
1737−}
1738−
17391725 static void csg_slot_process_idle_event_locked(struct panthor_device *ptdev, u32 csg_id)
17401726 {
17411727 struct panthor_scheduler *sched = ptdev->scheduler;
@@ -1997,10 +1983,8 @@ static int csgs_upd_ctx_apply_locked(struct panthor_device *ptdev, · 255 unmodified lines
19971983 if (acked & CSG_STATE_MASK)
19981984 csg_slot_sync_state_locked(ptdev, csg_id);
19991985
2000− if (acked & CSG_STATUS_UPDATE) {
1986+ if (acked & CSG_STATUS_UPDATE)
20011987 csg_slot_sync_queues_state_locked(ptdev, csg_id);
2002− csg_slot_sync_idle_state_locked(ptdev, csg_id);
2003− }
20041988
20051989 if (ret && acked != req_mask &&
20061990 ((csg_iface->input->req ^ csg_iface->output->ack) & req_mask) != 0) {
@@ -2020,10 +2004,10 @@ struct panthor_sched_tick_ctx { · 13 unmodified lines
20202004 struct list_head groups[PANTHOR_CSG_PRIORITY_COUNT];
20212005 u32 idle_group_count;
20222006 u32 group_count;
2023− enum panthor_csg_priority min_priority;
20242007 struct panthor_vm *vms[MAX_CS_PER_CSG];
20252008 u32 as_count;
20262009 bool immediate_tick;
2010+ bool stop_tick;
20272011 u32 csg_upd_failed_mask;
20282012 };
20292013
@@ -2066,17 +2050,21 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched, · 36 unmodified lines
20662050 if (!owned_by_tick_ctx)
20672051 group_get(group);
20682052
2069− list_move_tail(&group->run_node, &ctx->groups[group->priority]);
20702053 ctx->group_count++;
2054+
2055+ /* If we have more than one active group with the same priority,
2056+ * we need to keep ticking to rotate the CSG priority.
2057+ */
20712058 if (group_is_idle(group))
20722059 ctx->idle_group_count++;
2060+ else if (!list_empty(&ctx->groups[group->priority]))
2061+ ctx->stop_tick = false;
2062+
2063+ list_move_tail(&group->run_node, &ctx->groups[group->priority]);
20732064
20742065 if (i == ctx->as_count)
20752066 ctx->vms[ctx->as_count++] = group->vm;
20762067
2077− if (ctx->min_priority > group->priority)
2078− ctx->min_priority = group->priority;
2079−
20802068 if (tick_ctx_is_full(sched, ctx))
20812069 return;
20822070 }
@@ -2085,31 +2073,22 @@ tick_ctx_pick_groups_from_list(const struct panthor_scheduler *sched, · 2 unmodified lines
20852073 static void
20862074 tick_ctx_insert_old_group(struct panthor_scheduler *sched,
20872075 struct panthor_sched_tick_ctx *ctx,
2088− struct panthor_group *group,
2089− bool full_tick)
2076+ struct panthor_group *group)
20902077 {
20912078 struct panthor_csg_slot *csg_slot = &sched->csg_slots[group->csg_id];
20922079 struct panthor_group *other_group;
20932080
2094− if (!full_tick) {
2095− list_add_tail(&group->run_node, &ctx->old_groups[group->priority]);
2096− return;
2097− }
2098−
2099− /* Rotate to make sure groups with lower CSG slot
2100− * priorities have a chance to get a higher CSG slot
2101− * priority next time they get picked. This priority
2102− * has an impact on resource request ordering, so it's
2103− * important to make sure we don't let one group starve
2104− * all other groups with the same group priority.
2105− */
2081+ /* Class groups in descending priority order so we can easily rotate. */
21062082 list_for_each_entry(other_group,
21072083 &ctx->old_groups[csg_slot->group->priority],
21082084 run_node) {
21092085 struct panthor_csg_slot *other_csg_slot = &sched->csg_slots[other_group->csg_id];
21102086
2111− if (other_csg_slot->priority > csg_slot->priority) {
2112− list_add_tail(&csg_slot->group->run_node, &other_group->run_node);
2087+ /* Our group has a higher prio than the one we're testing against,
2088+ * place it just before.
2089+ */
2090+ if (csg_slot->priority > other_csg_slot->priority) {
2091+ list_add_tail(&group->run_node, &other_group->run_node);
21132092 return;
21142093 }
21152094 }
@@ -2119,8 +2098,7 @@ tick_ctx_insert_old_group(struct panthor_scheduler *sched, · 3 unmodified lines
21192098
21202099 static void
21212100 tick_ctx_init(struct panthor_scheduler *sched,
2122− struct panthor_sched_tick_ctx *ctx,
2123− bool full_tick)
2101+ struct panthor_sched_tick_ctx *ctx)
21242102 {
21252103 struct panthor_device *ptdev = sched->ptdev;
21262104 struct panthor_csg_slots_upd_ctx upd_ctx;
@@ -2130,7 +2108,7 @@ tick_ctx_init(struct panthor_scheduler *sched, · 3 unmodified lines
21302108 memset(ctx, 0, sizeof(*ctx));
21312109 csgs_upd_ctx_init(&upd_ctx);
21322110
2133− ctx->min_priority = PANTHOR_CSG_PRIORITY_COUNT;
2111+ ctx->stop_tick = true;
21342112 for (i = 0; i < ARRAY_SIZE(ctx->groups); i++) {
21352113 INIT_LIST_HEAD(&ctx->groups[i]);
21362114 INIT_LIST_HEAD(&ctx->old_groups[i]);
@@ -2158,7 +2136,7 @@ tick_ctx_init(struct panthor_scheduler *sched, · 21 unmodified lines
21582136 group->fatal_queues |= GENMASK(group->queue_count - 1, 0);
21592137 }
21602138
2161− tick_ctx_insert_old_group(sched, ctx, group, full_tick);
2139+ tick_ctx_insert_old_group(sched, ctx, group);
21622140 csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, i,
21632141 csg_iface->output->ack ^ CSG_STATUS_UPDATE,
21642142 CSG_STATUS_UPDATE);
@@ -2442,32 +2420,18 @@ static u64 · 277 unmodified lines
24422420 tick_ctx_update_resched_target(struct panthor_scheduler *sched,
24432421 const struct panthor_sched_tick_ctx *ctx)
24442422 {
2445− /* We had space left, no need to reschedule until some external event happens. */
2446− if (!tick_ctx_is_full(sched, ctx))
2447− goto no_tick;
2448−
2449− /* If idle groups were scheduled, no need to wake up until some external
2450− * event happens (group unblocked, new job submitted, ...).
2451− */
2452− if (ctx->idle_group_count)
2453− goto no_tick;
2423+ u64 resched_target;
24542424
2455− if (drm_WARN_ON(&sched->ptdev->base, ctx->min_priority >= PANTHOR_CSG_PRIORITY_COUNT))
2425+ if (ctx->stop_tick)
24562426 goto no_tick;
24572427
2458− /* If there are groups of the same priority waiting, we need to
2459− * keep the scheduler ticking, otherwise, we'll just wait for
2460− * new groups with higher priority to be queued.
2461− */
2462− if (!list_empty(&sched->groups.runnable[ctx->min_priority])) {
2463− u64 resched_target = sched->last_tick + sched->tick_period;
2428+ resched_target = sched->last_tick + sched->tick_period;
24642429
2465− if (time_before64(sched->resched_target, sched->last_tick) ||
2466− time_before64(resched_target, sched->resched_target))
2467− sched->resched_target = resched_target;
2430+ if (time_before64(sched->resched_target, sched->last_tick) ||
2431+ time_before64(resched_target, sched->resched_target))
2432+ sched->resched_target = resched_target;
24682433
2469− return sched->resched_target - sched->last_tick;
2470− }
2434+ return sched->resched_target - sched->last_tick;
24712435
24722436 no_tick:
24732437 sched->resched_target = U64_MAX;
@@ -2480,9 +2444,11 @@ static void tick_work(struct work_struct *work) · 6 unmodified lines
24802444 tick_work.work);
24812445 struct panthor_device *ptdev = sched->ptdev;
24822446 struct panthor_sched_tick_ctx ctx;
2447+ u64 resched_target = sched->resched_target;
24832448 u64 remaining_jiffies = 0, resched_delay;
24842449 u64 now = get_jiffies_64();
24852450 int prio, ret, cookie;
2451+ bool full_tick;
24862452
24872453 if (!drm_dev_enter(&ptdev->base, &cookie))
24882454 return;
@@ -2491,18 +2457,24 @@ static void tick_work(struct work_struct *work) · 2 unmodified lines
24912457 if (drm_WARN_ON(&ptdev->base, ret))
24922458 goto out_dev_exit;
24932459
2494− if (time_before64(now, sched->resched_target))
2495− remaining_jiffies = sched->resched_target - now;
2460+ /* If the tick is stopped, calculate when the next tick would be */
2461+ if (resched_target == U64_MAX)
2462+ resched_target = sched->last_tick + sched->tick_period;
2463+
2464+ if (time_before64(now, resched_target))
2465+ remaining_jiffies = resched_target - now;
2466+
2467+ full_tick = remaining_jiffies == 0;
24962468
24972469 mutex_lock(&sched->lock);
24982470 if (panthor_device_reset_is_pending(sched->ptdev))
24992471 goto out_unlock;
25002472
2501− tick_ctx_init(sched, &ctx, remaining_jiffies != 0);
2473+ tick_ctx_init(sched, &ctx);
25022474 if (ctx.csg_upd_failed_mask)
25032475 goto out_cleanup_ctx;
25042476
2505− if (remaining_jiffies) {
2477+ if (!full_tick) {
25062478 /* Scheduling forced in the middle of a tick. Only RT groups
25072479 * can preempt non-RT ones. Currently running RT groups can't be
25082480 * preempted.
@@ -2524,9 +2496,29 @@ static void tick_work(struct work_struct *work) · 15 unmodified lines
25242496 for (prio = PANTHOR_CSG_PRIORITY_COUNT - 1;
25252497 prio >= 0 && !tick_ctx_is_full(sched, &ctx);
25262498 prio--) {
2499+ struct panthor_group *old_highest_prio_group =
2500+ list_first_entry_or_null(&ctx.old_groups[prio],
2501+ struct panthor_group, run_node);
2502+
2503+ /* Pull out the group with the highest prio for rotation. */
2504+ if (old_highest_prio_group)
2505+ list_del(&old_highest_prio_group->run_node);
2506+
2507+ /* Re-insert old active groups so they get a chance to run with higher prio. */
2508+ tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true);
2509+
2510+ /* Fill the remaining slots with runnable groups. */
25272511 tick_ctx_pick_groups_from_list(sched, &ctx, &sched->groups.runnable[prio],
25282512 true, false);
2529− tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio], true, true);
2513+
2514+ /* Re-insert the old group with the highest prio, and give it a chance to be
2515+ * scheduled again (but with a lower prio) if there's room left.
2516+ */
2517+ if (old_highest_prio_group) {
2518+ list_add_tail(&old_highest_prio_group->run_node, &ctx.old_groups[prio]);
2519+ tick_ctx_pick_groups_from_list(sched, &ctx, &ctx.old_groups[prio],
2520+ true, true);
2521+ }
25302522 }
25312523
25322524 /* If we have free CSG slots left, pick idle groups */
@@ -2651,14 +2643,33 @@ static void sync_upd_work(struct work_struct *work) · 118 unmodified lines
26512643 sched_queue_delayed_work(sched, tick, 0);
26522644 }
26532645
2646+static void sched_resume_tick(struct panthor_device *ptdev)
2647+{
2648+ struct panthor_scheduler *sched = ptdev->scheduler;
2649+ u64 delay_jiffies, now;
2650+
2651+ drm_WARN_ON(&ptdev->base, sched->resched_target != U64_MAX);
2652+
2653+ /* Scheduler tick was off, recalculate the resched_target based on the
2654+ * last tick event, and queue the scheduler work.
2655+ */
2656+ now = get_jiffies_64();
2657+ sched->resched_target = sched->last_tick + sched->tick_period;
2658+ if (sched->used_csg_slot_count == sched->csg_slot_count &&
2659+ time_before64(now, sched->resched_target))
2660+ delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX);
2661+ else
2662+ delay_jiffies = 0;
2663+
2664+ sched_queue_delayed_work(sched, tick, delay_jiffies);
2665+}
2666+
26542667 static void group_schedule_locked(struct panthor_group *group, u32 queue_mask)
26552668 {
26562669 struct panthor_device *ptdev = group->ptdev;
26572670 struct panthor_scheduler *sched = ptdev->scheduler;
26582671 struct list_head *queue = &sched->groups.runnable[group->priority];
2659− u64 delay_jiffies = 0;
26602672 bool was_idle;
2661− u64 now;
26622673
26632674 if (!group_can_run(group))
26642675 return;
@@ -2703,13 +2714,7 @@ static void group_schedule_locked(struct panthor_group *group, u32 queue_mask) · 38 unmodified lines
27032714 /* Scheduler tick was off, recalculate the resched_target based on the
27042715 * last tick event, and queue the scheduler work.
27052716 */
2706− now = get_jiffies_64();
2707− sched->resched_target = sched->last_tick + sched->tick_period;
2708− if (sched->used_csg_slot_count == sched->csg_slot_count &&
2709− time_before64(now, sched->resched_target))
2710− delay_jiffies = min_t(unsigned long, sched->resched_target - now, ULONG_MAX);
2711−
2712− sched_queue_delayed_work(sched, tick, delay_jiffies);
2717+ sched_resume_tick(ptdev);
27132718 }
27142719
27152720 static void queue_stop(struct panthor_queue *queue,
@@ -2767,13 +2772,6 @@ static void panthor_group_start(struct panthor_group *group) · 51 unmodified lines
27672772 group_put(group);
27682773 }
27692774
2770−static void panthor_sched_immediate_tick(struct panthor_device *ptdev)
2771−{
2772− struct panthor_scheduler *sched = ptdev->scheduler;
2773−
2774− sched_queue_delayed_work(sched, tick, 0);
2775−}
2776−
27772775 /**
27782776 * panthor_sched_report_mmu_fault() - Report MMU faults to the scheduler.
27792777 */
@@ -2781,13 +2779,13 @@ void panthor_sched_report_mmu_fault(struct panthor_device *ptdev) · 1 unmodified line
27812779 {
27822780 /* Force a tick to immediately kill faulty groups. */
27832781 if (ptdev->scheduler)
2784− panthor_sched_immediate_tick(ptdev);
2782+ sched_queue_delayed_work(ptdev->scheduler, tick, 0);
27852783 }
27862784
27872785 void panthor_sched_resume(struct panthor_device *ptdev)
27882786 {
27892787 /* Force a tick to re-evaluate after a resume. */
2790− panthor_sched_immediate_tick(ptdev);
2788+ sched_queue_delayed_work(ptdev->scheduler, tick, 0);
27912789 }
27922790
27932791 void panthor_sched_suspend(struct panthor_device *ptdev)
@@ -2943,8 +2941,6 @@ void panthor_sched_pre_reset(struct panthor_device *ptdev) · 149 unmodified lines
29432941 * new jobs while we're resetting.
29442942 */
29452943 for (i = 0; i < ARRAY_SIZE(sched->groups.runnable); i++) {
2946− /* All groups should be in the idle lists. */
2947− drm_WARN_ON(&ptdev->base, !list_empty(&sched->groups.runnable[i]));
29482944 list_for_each_entry_safe(group, group_tmp, &sched->groups.runnable[i], run_node)
29492945 panthor_group_stop(group);
29502946 }
@@ -3343,6 +3339,18 @@ queue_run_job(struct drm_sched_job *sched_job) · 392 unmodified lines
33433339 if (group->csg_id < 0) {
33443340 group_schedule_locked(group, BIT(job->queue_idx));
33453341 } else {
3342+ u32 queue_mask = BIT(job->queue_idx);
3343+ bool resume_tick = group_is_idle(group) &&
3344+ (group->idle_queues & queue_mask) &&
3345+ !(group->blocked_queues & queue_mask) &&
3346+ sched->resched_target == U64_MAX;
3347+
3348+ /* We just added something to the queue, so it's no longer idle. */
3349+ group->idle_queues &= ~queue_mask;
3350+
3351+ if (resume_tick)
3352+ sched_resume_tick(ptdev);
3353+
33463354 gpu_write(ptdev, CSF_DOORBELL(queue->doorbell_id), 1);
33473355 if (!sched->pm.has_ref &&
33483356 !(group->blocked_queues & BIT(job->queue_idx))) {
drivers/gpu/drm/pl111/pl111_display.c+2−2
@@ -138,7 +138,7 @@ static void pl111_display_enable(struct drm_simple_display_pipe *pipe, · 137 unmodified lines
138138
139139 ret = clk_set_rate(priv->clk, mode->clock * 1000);
140140 if (ret) {
141− dev_err(drm->dev,
141+ drm_err(drm,
142142 "Failed to set pixel clock rate to %d: %d\n",
143143 mode->clock * 1000, ret);
144144 }
@@ -553,7 +553,7 @@ pl111_init_clock_divider(struct drm_device *drm) · 408 unmodified lines
553553 int ret;
554554
555555 if (IS_ERR(parent)) {
556− dev_err(drm->dev, "CLCD: unable to get clcdclk.\n");
556+ drm_err(drm, "CLCD: unable to get clcdclk.\n");
557557 return PTR_ERR(parent);
558558 }
559559
drivers/gpu/drm/pl111/pl111_drv.c+15−14
@@ -55,6 +55,7 @@ · 54 unmodified lines
5555 #include <drm/drm_gem_framebuffer_helper.h>
5656 #include <drm/drm_of.h>
5757 #include <drm/drm_panel.h>
58+#include <drm/drm_print.h>
5859 #include <drm/drm_probe_helper.h>
5960 #include <drm/drm_vblank.h>
6061
@@ -98,7 +99,7 @@ static int pl111_modeset_init(struct drm_device *dev) · 37 unmodified lines
9899 struct drm_panel *tmp_panel;
99100 struct drm_bridge *tmp_bridge;
100101
101− dev_dbg(dev->dev, "checking endpoint %d\n", i);
102+ drm_dbg(dev, "checking endpoint %d\n", i);
102103
103104 ret = drm_of_find_panel_or_bridge(dev->dev->of_node,
104105 0, i,
@@ -114,18 +115,18 @@ static int pl111_modeset_init(struct drm_device *dev) · 9 unmodified lines
114115 defer = true;
115116 } else if (ret != -ENODEV) {
116117 /* Continue, maybe something else is working */
117− dev_err(dev->dev,
118+ drm_err(dev,
118119 "endpoint %d returns %d\n", i, ret);
119120 }
120121 }
121122
122123 if (tmp_panel) {
123− dev_info(dev->dev,
124+ drm_info(dev,
124125 "found panel on endpoint %d\n", i);
125126 panel = tmp_panel;
126127 }
127128 if (tmp_bridge) {
128− dev_info(dev->dev,
129+ drm_info(dev,
129130 "found bridge on endpoint %d\n", i);
130131 bridge = tmp_bridge;
131132 }
@@ -149,9 +150,9 @@ static int pl111_modeset_init(struct drm_device *dev) · 17 unmodified lines
149150 goto finish;
150151 }
151152 } else if (bridge) {
152− dev_info(dev->dev, "Using non-panel bridge\n");
153+ drm_info(dev, "Using non-panel bridge\n");
153154 } else {
154− dev_err(dev->dev, "No bridge, exiting\n");
155+ drm_err(dev, "No bridge, exiting\n");
155156 return -ENODEV;
156157 }
157158
@@ -163,7 +164,7 @@ static int pl111_modeset_init(struct drm_device *dev) · 5 unmodified lines
163164
164165 ret = pl111_display_init(dev);
165166 if (ret != 0) {
166− dev_err(dev->dev, "Failed to init display\n");
167+ drm_err(dev, "Failed to init display\n");
167168 goto out_bridge;
168169 }
169170
@@ -175,7 +176,7 @@ static int pl111_modeset_init(struct drm_device *dev) · 5 unmodified lines
175176 if (!priv->variant->broken_vblank) {
176177 ret = drm_vblank_init(dev, 1);
177178 if (ret != 0) {
178− dev_err(dev->dev, "Failed to init vblank\n");
179+ drm_err(dev, "Failed to init vblank\n");
179180 goto out_bridge;
180181 }
181182 }
@@ -255,13 +256,13 @@ static int pl111_amba_probe(struct amba_device *amba_dev, · 73 unmodified lines
255256
256257 ret = of_reserved_mem_device_init(dev);
257258 if (!ret) {
258− dev_info(dev, "using device-specific reserved memory\n");
259+ drm_info(drm, "using device-specific reserved memory\n");
259260 priv->use_device_memory = true;
260261 }
261262
262263 if (of_property_read_u32(dev->of_node, "max-memory-bandwidth",
263264 &priv->memory_bw)) {
264− dev_info(dev, "no max memory bandwidth specified, assume unlimited\n");
265+ drm_info(drm, "no max memory bandwidth specified, assume unlimited\n");
265266 priv->memory_bw = 0;
266267 }
267268
@@ -276,17 +277,17 @@ static int pl111_amba_probe(struct amba_device *amba_dev, · 8 unmodified lines
276277
277278 priv->regs = devm_ioremap_resource(dev, &amba_dev->res);
278279 if (IS_ERR(priv->regs)) {
279− dev_err(dev, "%s failed mmio\n", __func__);
280+ drm_err(drm, "%s failed mmio\n", __func__);
280281 ret = PTR_ERR(priv->regs);
281282 goto dev_put;
282283 }
283284
284285 /* This may override some variant settings */
285− ret = pl111_versatile_init(dev, priv);
286+ ret = pl111_versatile_init(drm, priv);
286287 if (ret)
287288 goto dev_put;
288289
289− pl111_nomadik_init(dev);
290+ pl111_nomadik_init(drm);
290291
291292 /* turn off interrupts before requesting the irq */
292293 writel(0, priv->regs + priv->ienb);
@@ -294,7 +295,7 @@ static int pl111_amba_probe(struct amba_device *amba_dev, · 1 unmodified line
294295 ret = devm_request_irq(dev, amba_dev->irq[0], pl111_irq, 0,
295296 variant->name, priv);
296297 if (ret != 0) {
297− dev_err(dev, "%s failed irq %d\n", __func__, ret);
298+ drm_err(drm, "%s failed irq %d\n", __func__, ret);
298299 return ret;
299300 }
300301
drivers/gpu/drm/pl111/pl111_nomadik.c+2−2
@@ -9,7 +9,7 @@ · 8 unmodified lines
99 #define PMU_CTRL_OFFSET 0x0000
1010 #define PMU_CTRL_LCDNDIF BIT(26)
1111
12−void pl111_nomadik_init(struct device *dev)
12+void pl111_nomadik_init(struct drm_device *dev)
1313 {
1414 struct regmap *pmu_regmap;
1515
@@ -31,6 +31,6 @@ void pl111_nomadik_init(struct device *dev) · 15 unmodified lines
3131 PMU_CTRL_OFFSET,
3232 PMU_CTRL_LCDNDIF,
3333 0);
34− dev_info(dev, "set Nomadik PMU mux to CLCD mode\n");
34+ drm_info(dev, "set Nomadik PMU mux to CLCD mode\n");
3535 }
3636 EXPORT_SYMBOL_GPL(pl111_nomadik_init);
drivers/gpu/drm/pl111/pl111_nomadik.h+2−2
@@ -8,11 +8,11 @@ struct device; · 7 unmodified lines
88
99 #ifdef CONFIG_ARCH_NOMADIK
1010
11−void pl111_nomadik_init(struct device *dev);
11+void pl111_nomadik_init(struct drm_device *dev);
1212
1313 #else
1414
15−static inline void pl111_nomadik_init(struct device *dev)
15+static inline void pl111_nomadik_init(struct drm_device *dev)
1616 {
1717 }
1818
drivers/gpu/drm/pl111/pl111_versatile.c+27−26
@@ -20,6 +20,7 @@ · 19 unmodified lines
2020 #include <linux/vexpress.h>
2121
2222 #include <drm/drm_fourcc.h>
23+#include <drm/drm_print.h>
2324
2425 #include "pl111_versatile.h"
2526 #include "pl111_drm.h"
@@ -116,7 +117,7 @@ static void pl111_integrator_enable(struct drm_device *drm, u32 format) · 90 unmodified lines
116117 {
117118 u32 val;
118119
119− dev_info(drm->dev, "enable Integrator CLCD connectors\n");
120+ drm_info(drm, "enable Integrator CLCD connectors\n");
120121
121122 /* FIXME: really needed? */
122123 val = INTEGRATOR_CLCD_LCD_STATIC1 | INTEGRATOR_CLCD_LCD_STATIC2 |
@@ -134,7 +135,7 @@ static void pl111_integrator_enable(struct drm_device *drm, u32 format) · 11 unmodified lines
134135 val |= INTEGRATOR_CLCD_LCDMUX_VGA555;
135136 break;
136137 default:
137− dev_err(drm->dev, "unhandled format on Integrator 0x%08x\n",
138+ drm_err(drm, "unhandled format on Integrator 0x%08x\n",
138139 format);
139140 break;
140141 }
@@ -156,7 +157,7 @@ static void pl111_impd1_enable(struct drm_device *drm, u32 format) · 15 unmodified lines
156157 {
157158 u32 val;
158159
159− dev_info(drm->dev, "enable IM-PD1 CLCD connectors\n");
160+ drm_info(drm, "enable IM-PD1 CLCD connectors\n");
160161 val = IMPD1_CTRL_DISP_VGA | IMPD1_CTRL_DISP_ENABLE;
161162
162163 regmap_update_bits(versatile_syscon_map,
@@ -167,7 +168,7 @@ static void pl111_impd1_enable(struct drm_device *drm, u32 format) · 4 unmodified lines
167168
168169 static void pl111_impd1_disable(struct drm_device *drm)
169170 {
170− dev_info(drm->dev, "disable IM-PD1 CLCD connectors\n");
171+ drm_info(drm, "disable IM-PD1 CLCD connectors\n");
171172
172173 regmap_update_bits(versatile_syscon_map,
173174 IMPD1_CTRL_OFFSET,
@@ -194,7 +195,7 @@ static void pl111_impd1_disable(struct drm_device *drm) · 20 unmodified lines
194195
195196 static void pl111_versatile_disable(struct drm_device *drm)
196197 {
197− dev_info(drm->dev, "disable Versatile CLCD connectors\n");
198+ drm_info(drm, "disable Versatile CLCD connectors\n");
198199 regmap_update_bits(versatile_syscon_map,
199200 SYS_CLCD,
200201 SYS_CLCD_CONNECTOR_MASK,
@@ -205,7 +206,7 @@ static void pl111_versatile_enable(struct drm_device *drm, u32 format) · 4 unmodified lines
205206 {
206207 u32 val = 0;
207208
208− dev_info(drm->dev, "enable Versatile CLCD connectors\n");
209+ drm_info(drm, "enable Versatile CLCD connectors\n");
209210
210211 switch (format) {
211212 case DRM_FORMAT_ABGR8888:
@@ -227,7 +228,7 @@ static void pl111_versatile_enable(struct drm_device *drm, u32 format) · 15 unmodified lines
227228 val |= SYS_CLCD_MODE_5551;
228229 break;
229230 default:
230− dev_err(drm->dev, "unhandled format on Versatile 0x%08x\n",
231+ drm_err(drm, "unhandled format on Versatile 0x%08x\n",
231232 format);
232233 break;
233234 }
@@ -247,7 +248,7 @@ static void pl111_versatile_enable(struct drm_device *drm, u32 format) · 13 unmodified lines
247248
248249 static void pl111_realview_clcd_disable(struct drm_device *drm)
249250 {
250− dev_info(drm->dev, "disable RealView CLCD connectors\n");
251+ drm_info(drm, "disable RealView CLCD connectors\n");
251252 regmap_update_bits(versatile_syscon_map,
252253 SYS_CLCD,
253254 SYS_CLCD_CONNECTOR_MASK,
@@ -256,7 +257,7 @@ static void pl111_realview_clcd_disable(struct drm_device *drm) · 2 unmodified lines
256257
257258 static void pl111_realview_clcd_enable(struct drm_device *drm, u32 format)
258259 {
259− dev_info(drm->dev, "enable RealView CLCD connectors\n");
260+ drm_info(drm, "enable RealView CLCD connectors\n");
260261 regmap_update_bits(versatile_syscon_map,
261262 SYS_CLCD,
262263 SYS_CLCD_CONNECTOR_MASK,
@@ -376,7 +377,7 @@ static const struct pl111_variant_data pl111_vexpress = { · 113 unmodified lines
376377 #define VEXPRESS_FPGAMUX_DAUGHTERBOARD_1 0x01
377378 #define VEXPRESS_FPGAMUX_DAUGHTERBOARD_2 0x02
378379
379−static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np,
380+static int pl111_vexpress_clcd_init(struct drm_device *dev, struct device_node *np,
380381 struct pl111_drm_dev_private *priv)
381382 {
382383 struct platform_device *pdev;
@@ -433,22 +434,22 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np, · 50 unmodified lines
433434 mux_motherboard = false;
434435
435436 if (mux_motherboard) {
436− dev_info(dev, "DVI muxed to motherboard CLCD\n");
437+ drm_info(dev, "DVI muxed to motherboard CLCD\n");
437438 val = VEXPRESS_FPGAMUX_MOTHERBOARD;
438− } else if (ct_clcd == dev->of_node) {
439− dev_info(dev,
439+ } else if (ct_clcd == dev->dev->of_node) {
440+ drm_info(dev,
440441 "DVI muxed to daughterboard 1 (core tile) CLCD\n");
441442 val = VEXPRESS_FPGAMUX_DAUGHTERBOARD_1;
442443 } else {
443− dev_info(dev, "core tile graphics present\n");
444− dev_info(dev, "this device will be deactivated\n");
444+ drm_info(dev, "core tile graphics present\n");
445+ drm_info(dev, "this device will be deactivated\n");
445446 return -ENODEV;
446447 }
447448
448449 /* Call into deep Vexpress configuration API */
449450 pdev = of_find_device_by_node(np);
450451 if (!pdev) {
451− dev_err(dev, "can't find the sysreg device, deferring\n");
452+ drm_err(dev, "can't find the sysreg device, deferring\n");
452453 return -EPROBE_DEFER;
453454 }
454455
@@ -461,17 +462,17 @@ static int pl111_vexpress_clcd_init(struct device *dev, struct device_node *np, · 6 unmodified lines
461462 ret = regmap_write(map, 0, val);
462463 platform_device_put(pdev);
463464 if (ret) {
464− dev_err(dev, "error setting DVI muxmode\n");
465+ drm_err(dev, "error setting DVI muxmode\n");
465466 return -ENODEV;
466467 }
467468
468469 priv->variant = &pl111_vexpress;
469− dev_info(dev, "initializing Versatile Express PL111\n");
470+ drm_info(dev, "initializing Versatile Express PL111\n");
470471
471472 return 0;
472473 }
473474
474−int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv)
475+int pl111_versatile_init(struct drm_device *dev, struct pl111_drm_dev_private *priv)
475476 {
476477 const struct of_device_id *clcd_id;
477478 enum versatile_clcd versatile_clcd_type;
@@ -492,7 +493,7 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) · 14 unmodified lines
492493 int ret = pl111_vexpress_clcd_init(dev, np, priv);
493494 of_node_put(np);
494495 if (ret)
495− dev_err(dev, "Versatile Express init failed - %d", ret);
496+ drm_err(dev, "Versatile Express init failed - %d", ret);
496497 return ret;
497498 }
498499
@@ -511,7 +512,7 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) · 12 unmodified lines
511512 map = syscon_node_to_regmap(np);
512513 of_node_put(np);
513514 if (IS_ERR(map)) {
514− dev_err(dev, "no Versatile syscon regmap\n");
515+ drm_err(dev, "no Versatile syscon regmap\n");
515516 return PTR_ERR(map);
516517 }
517518
@@ -520,14 +521,14 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) · 2 unmodified lines
520521 versatile_syscon_map = map;
521522 priv->variant = &pl110_integrator;
522523 priv->variant_display_enable = pl111_integrator_enable;
523− dev_info(dev, "set up callbacks for Integrator PL110\n");
524+ drm_info(dev, "set up callbacks for Integrator PL110\n");
524525 break;
525526 case INTEGRATOR_IMPD1:
526527 versatile_syscon_map = map;
527528 priv->variant = &pl110_impd1;
528529 priv->variant_display_enable = pl111_impd1_enable;
529530 priv->variant_display_disable = pl111_impd1_disable;
530− dev_info(dev, "set up callbacks for IM-PD1 PL110\n");
531+ drm_info(dev, "set up callbacks for IM-PD1 PL110\n");
531532 break;
532533 case VERSATILE_CLCD:
533534 versatile_syscon_map = map;
@@ -542,7 +543,7 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) · 8 unmodified lines
542543 */
543544 priv->ienb = CLCD_PL111_IENB;
544545 priv->ctrl = CLCD_PL111_CNTL;
545− dev_info(dev, "set up callbacks for Versatile PL110\n");
546+ drm_info(dev, "set up callbacks for Versatile PL110\n");
546547 break;
547548 case REALVIEW_CLCD_EB:
548549 case REALVIEW_CLCD_PB1176:
@@ -553,10 +554,10 @@ int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv) · 4 unmodified lines
553554 priv->variant = &pl111_realview;
554555 priv->variant_display_enable = pl111_realview_clcd_enable;
555556 priv->variant_display_disable = pl111_realview_clcd_disable;
556− dev_info(dev, "set up callbacks for RealView PL111\n");
557+ drm_info(dev, "set up callbacks for RealView PL111\n");
557558 break;
558559 default:
559− dev_info(dev, "unknown Versatile system controller\n");
560+ drm_info(dev, "unknown Versatile system controller\n");
560561 break;
561562 }
562563
drivers/gpu/drm/pl111/pl111_versatile.h+1−1
@@ -7,6 +7,6 @@ · 6 unmodified lines
77 struct device;
88 struct pl111_drm_dev_private;
99
10−int pl111_versatile_init(struct device *dev, struct pl111_drm_dev_private *priv);
10+int pl111_versatile_init(struct drm_device *dev, struct pl111_drm_dev_private *priv);
1111
1212 #endif
drivers/gpu/drm/radeon/atombios_crtc.c+19−55
@@ -1133,7 +1133,7 @@ static void atombios_crtc_set_pll(struct drm_crtc *crtc, struct drm_display_mode · 1132 unmodified lines
11331133
11341134 static int dce4_crtc_do_set_base(struct drm_crtc *crtc,
11351135 struct drm_framebuffer *fb,
1136− int x, int y, int atomic)
1136+ int x, int y)
11371137 {
11381138 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
11391139 struct drm_device *dev = crtc->dev;
@@ -1150,33 +1150,23 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, · 10 unmodified lines
11501150 bool bypass_lut = false;
11511151
11521152 /* no fb bound */
1153− if (!atomic && !crtc->primary->fb) {
1153+ if (!crtc->primary->fb) {
11541154 DRM_DEBUG_KMS("No FB bound\n");
11551155 return 0;
11561156 }
11571157
1158− if (atomic)
1159− target_fb = fb;
1160− else
1161− target_fb = crtc->primary->fb;
1158+ target_fb = crtc->primary->fb;
11621159
1163− /* If atomic, assume fb object is pinned & idle & fenced and
1164− * just update base pointers
1165− */
11661160 obj = target_fb->obj[0];
11671161 rbo = gem_to_radeon_bo(obj);
11681162 r = radeon_bo_reserve(rbo, false);
11691163 if (unlikely(r != 0))
11701164 return r;
11711165
1172− if (atomic)
1173− fb_location = radeon_bo_gpu_offset(rbo);
1174− else {
1175− r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1176− if (unlikely(r != 0)) {
1177− radeon_bo_unreserve(rbo);
1178− return -EINVAL;
1179− }
1166+ r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1167+ if (unlikely(r != 0)) {
1168+ radeon_bo_unreserve(rbo);
1169+ return -EINVAL;
11801170 }
11811171
11821172 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
@@ -1437,7 +1427,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, · 254 unmodified lines
14371427 /* set pageflip to happen anywhere in vblank interval */
14381428 WREG32(EVERGREEN_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 0);
14391429
1440− if (!atomic && fb && fb != crtc->primary->fb) {
1430+ if (fb && fb != crtc->primary->fb) {
14411431 rbo = gem_to_radeon_bo(fb->obj[0]);
14421432 r = radeon_bo_reserve(rbo, false);
14431433 if (unlikely(r != 0))
@@ -1454,7 +1444,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, · 10 unmodified lines
14541444
14551445 static int avivo_crtc_do_set_base(struct drm_crtc *crtc,
14561446 struct drm_framebuffer *fb,
1457− int x, int y, int atomic)
1447+ int x, int y)
14581448 {
14591449 struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc);
14601450 struct drm_device *dev = crtc->dev;
@@ -1470,15 +1460,12 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, · 9 unmodified lines
14701460 bool bypass_lut = false;
14711461
14721462 /* no fb bound */
1473− if (!atomic && !crtc->primary->fb) {
1463+ if (!crtc->primary->fb) {
14741464 DRM_DEBUG_KMS("No FB bound\n");
14751465 return 0;
14761466 }
14771467
1478− if (atomic)
1479− target_fb = fb;
1480− else
1481− target_fb = crtc->primary->fb;
1468+ target_fb = crtc->primary->fb;
14821469
14831470 obj = target_fb->obj[0];
14841471 rbo = gem_to_radeon_bo(obj);
@@ -1486,17 +1473,10 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, · 1 unmodified line
14861473 if (unlikely(r != 0))
14871474 return r;
14881475
1489− /* If atomic, assume fb object is pinned & idle & fenced and
1490− * just update base pointers
1491− */
1492− if (atomic)
1493− fb_location = radeon_bo_gpu_offset(rbo);
1494− else {
1495− r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1496− if (unlikely(r != 0)) {
1497− radeon_bo_unreserve(rbo);
1498− return -EINVAL;
1499− }
1476+ r = radeon_bo_pin(rbo, RADEON_GEM_DOMAIN_VRAM, &fb_location);
1477+ if (unlikely(r != 0)) {
1478+ radeon_bo_unreserve(rbo);
1479+ return -EINVAL;
15001480 }
15011481 radeon_bo_get_tiling_flags(rbo, &tiling_flags, NULL);
15021482 radeon_bo_unreserve(rbo);
@@ -1645,7 +1625,7 @@ static int avivo_crtc_do_set_base(struct drm_crtc *crtc, · 142 unmodified lines
16451625 /* set pageflip to happen only at start of vblank interval (front porch) */
16461626 WREG32(AVIVO_D1MODE_MASTER_UPDATE_MODE + radeon_crtc->crtc_offset, 3);
16471627
1648− if (!atomic && fb && fb != crtc->primary->fb) {
1628+ if (fb && fb != crtc->primary->fb) {
16491629 rbo = gem_to_radeon_bo(fb->obj[0]);
16501630 r = radeon_bo_reserve(rbo, false);
16511631 if (unlikely(r != 0))
@@ -1667,26 +1647,11 @@ int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y, · 15 unmodified lines
16671647 struct radeon_device *rdev = dev->dev_private;
16681648
16691649 if (ASIC_IS_DCE4(rdev))
1670− return dce4_crtc_do_set_base(crtc, old_fb, x, y, 0);
1671− else if (ASIC_IS_AVIVO(rdev))
1672− return avivo_crtc_do_set_base(crtc, old_fb, x, y, 0);
1673− else
1674− return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
1675−}
1676−
1677−int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
1678− struct drm_framebuffer *fb,
1679− int x, int y, enum mode_set_atomic state)
1680−{
1681− struct drm_device *dev = crtc->dev;
1682− struct radeon_device *rdev = dev->dev_private;
1683−
1684− if (ASIC_IS_DCE4(rdev))
1685− return dce4_crtc_do_set_base(crtc, fb, x, y, 1);
1650+ return dce4_crtc_do_set_base(crtc, old_fb, x, y);
16861651 else if (ASIC_IS_AVIVO(rdev))
1687− return avivo_crtc_do_set_base(crtc, fb, x, y, 1);
1652+ return avivo_crtc_do_set_base(crtc, old_fb, x, y);
16881653 else
1689− return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
1654+ return radeon_crtc_do_set_base(crtc, old_fb, x, y);
16901655 }
16911656
16921657 /* properly set additional regs when using atombios */
@@ -2215,7 +2180,6 @@ static const struct drm_crtc_helper_funcs atombios_helper_funcs = { · 522 unmodified lines
22152180 .mode_fixup = atombios_crtc_mode_fixup,
22162181 .mode_set = atombios_crtc_mode_set,
22172182 .mode_set_base = atombios_crtc_set_base,
2218− .mode_set_base_atomic = atombios_crtc_set_base_atomic,
22192183 .prepare = atombios_crtc_prepare,
22202184 .commit = atombios_crtc_commit,
22212185 .disable = atombios_crtc_disable,
drivers/gpu/drm/radeon/radeon_legacy_crtc.c+6−17
@@ -360,19 +360,12 @@ static void radeon_crtc_dpms(struct drm_crtc *crtc, int mode) · 359 unmodified lines
360360 int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
361361 struct drm_framebuffer *old_fb)
362362 {
363− return radeon_crtc_do_set_base(crtc, old_fb, x, y, 0);
364−}
365−
366−int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
367− struct drm_framebuffer *fb,
368− int x, int y, enum mode_set_atomic state)
369−{
370− return radeon_crtc_do_set_base(crtc, fb, x, y, 1);
363+ return radeon_crtc_do_set_base(crtc, old_fb, x, y);
371364 }
372365
373366 int radeon_crtc_do_set_base(struct drm_crtc *crtc,
374367 struct drm_framebuffer *fb,
375− int x, int y, int atomic)
368+ int x, int y)
376369 {
377370 struct drm_device *dev = crtc->dev;
378371 struct radeon_device *rdev = dev->dev_private;
@@ -390,15 +383,12 @@ int radeon_crtc_do_set_base(struct drm_crtc *crtc, · 11 unmodified lines
390383
391384 DRM_DEBUG_KMS("\n");
392385 /* no fb bound */
393− if (!atomic && !crtc->primary->fb) {
386+ if (!crtc->primary->fb) {
394387 DRM_DEBUG_KMS("No FB bound\n");
395388 return 0;
396389 }
397390
398− if (atomic)
399− target_fb = fb;
400− else
401− target_fb = crtc->primary->fb;
391+ target_fb = crtc->primary->fb;
402392
403393 switch (target_fb->format->cpp[0] * 8) {
404394 case 8:
@@ -445,7 +435,7 @@ retry: · 40 unmodified lines
445435 * We don't shutdown the display controller because new buffer
446436 * will end up in same spot.
447437 */
448− if (!atomic && fb && fb != crtc->primary->fb) {
438+ if (fb && fb != crtc->primary->fb) {
449439 struct radeon_bo *old_rbo;
450440 unsigned long nsize, osize;
451441
@@ -555,7 +545,7 @@ retry: · 103 unmodified lines
555545 WREG32(RADEON_CRTC_OFFSET + radeon_crtc->crtc_offset, crtc_offset);
556546 WREG32(RADEON_CRTC_PITCH + radeon_crtc->crtc_offset, crtc_pitch);
557547
558− if (!atomic && fb && fb != crtc->primary->fb) {
548+ if (fb && fb != crtc->primary->fb) {
559549 rbo = gem_to_radeon_bo(fb->obj[0]);
560550 r = radeon_bo_reserve(rbo, false);
561551 if (unlikely(r != 0))
@@ -1108,7 +1098,6 @@ static const struct drm_crtc_helper_funcs legacy_helper_funcs = { · 546 unmodified lines
11081098 .mode_fixup = radeon_crtc_mode_fixup,
11091099 .mode_set = radeon_crtc_mode_set,
11101100 .mode_set_base = radeon_crtc_set_base,
1111− .mode_set_base_atomic = radeon_crtc_set_base_atomic,
11121101 .prepare = radeon_crtc_prepare,
11131102 .commit = radeon_crtc_commit,
11141103 .disable = radeon_crtc_disable,
drivers/gpu/drm/radeon/radeon_mode.h+1−9
@@ -804,10 +804,6 @@ extern bool radeon_encoder_is_digital(struct drm_encoder *encoder); · 803 unmodified lines
804804 extern void radeon_crtc_load_lut(struct drm_crtc *crtc);
805805 extern int atombios_crtc_set_base(struct drm_crtc *crtc, int x, int y,
806806 struct drm_framebuffer *old_fb);
807−extern int atombios_crtc_set_base_atomic(struct drm_crtc *crtc,
808− struct drm_framebuffer *fb,
809− int x, int y,
810− enum mode_set_atomic state);
811807 extern int atombios_crtc_mode_set(struct drm_crtc *crtc,
812808 struct drm_display_mode *mode,
813809 struct drm_display_mode *adjusted_mode,
@@ -817,13 +813,9 @@ extern void atombios_crtc_dpms(struct drm_crtc *crtc, int mode); · 3 unmodified lines
817813
818814 extern int radeon_crtc_set_base(struct drm_crtc *crtc, int x, int y,
819815 struct drm_framebuffer *old_fb);
820−extern int radeon_crtc_set_base_atomic(struct drm_crtc *crtc,
821− struct drm_framebuffer *fb,
822− int x, int y,
823− enum mode_set_atomic state);
824816 extern int radeon_crtc_do_set_base(struct drm_crtc *crtc,
825817 struct drm_framebuffer *fb,
826− int x, int y, int atomic);
818+ int x, int y);
827819 extern int radeon_crtc_cursor_set2(struct drm_crtc *crtc,
828820 struct drm_file *file_priv,
829821 uint32_t handle,
drivers/gpu/drm/ttm/tests/ttm_bo_validate_test.c+1−1
@@ -692,7 +692,7 @@ static int threaded_fence_signal(void *arg) · 691 unmodified lines
692692
693693 msleep(20);
694694
695− return dma_fence_signal(fence);
695+ return dma_fence_check_and_signal(fence) ? -EINVAL : 0;
696696 }
697697
698698 static void ttm_bo_validate_move_fence_not_signaled(struct kunit *test)
drivers/gpu/drm/ttm/ttm_bo.c+33−31
@@ -268,8 +268,8 @@ static void ttm_bo_release(struct kref *kref) · 267 unmodified lines
268268 30 * HZ);
269269 }
270270
271− if (bo->bdev->funcs->release_notify)
272− bo->bdev->funcs->release_notify(bo);
271+ if (bdev->funcs->release_notify)
272+ bdev->funcs->release_notify(bo);
273273
274274 drm_vma_offset_remove(bdev->vma_manager, &bo->base.vma_node);
275275 ttm_mem_io_free(bdev, bo->resource);
@@ -283,7 +283,7 @@ static void ttm_bo_release(struct kref *kref) · 7 unmodified lines
283283 ttm_bo_flush_all_fences(bo);
284284 bo->deleted = true;
285285
286− spin_lock(&bo->bdev->lru_lock);
286+ spin_lock(&bdev->lru_lock);
287287
288288 /*
289289 * Make pinned bos immediately available to
@@ -299,7 +299,7 @@ static void ttm_bo_release(struct kref *kref) · 9 unmodified lines
299299 }
300300
301301 kref_init(&bo->kref);
302− spin_unlock(&bo->bdev->lru_lock);
302+ spin_unlock(&bdev->lru_lock);
303303
304304 INIT_WORK(&bo->delayed_delete, ttm_bo_delayed_delete);
305305
@@ -359,7 +359,6 @@ static int ttm_bo_bounce_temp_buffer(struct ttm_buffer_object *bo, · 53 unmodified lines
359359 static int ttm_bo_evict(struct ttm_buffer_object *bo,
360360 struct ttm_operation_ctx *ctx)
361361 {
362− struct ttm_device *bdev = bo->bdev;
363362 struct ttm_resource *evict_mem;
364363 struct ttm_placement placement;
365364 struct ttm_place hop;
@@ -370,7 +369,7 @@ static int ttm_bo_evict(struct ttm_buffer_object *bo, · 4 unmodified lines
370369 dma_resv_assert_held(bo->base.resv);
371370
372371 placement.num_placement = 0;
373− bdev->funcs->evict_flags(bo, &placement);
372+ bo->bdev->funcs->evict_flags(bo, &placement);
374373
375374 if (!placement.num_placement) {
376375 ret = ttm_bo_wait_ctx(bo, ctx);
@@ -423,16 +422,16 @@ bool ttm_bo_eviction_valuable(struct ttm_buffer_object *bo, · 46 unmodified lines
423422 const struct ttm_place *place)
424423 {
425424 struct ttm_resource *res = bo->resource;
426− struct ttm_device *bdev = bo->bdev;
427425
428426 dma_resv_assert_held(bo->base.resv);
429− if (bo->resource->mem_type == TTM_PL_SYSTEM)
427+
428+ if (res->mem_type == TTM_PL_SYSTEM)
430429 return true;
431430
432431 /* Don't evict this BO if it's outside of the
433432 * requested placement range
434433 */
435− return ttm_resource_intersects(bdev, res, place, bo->base.size);
434+ return ttm_resource_intersects(bo->bdev, res, place, bo->base.size);
436435 }
437436 EXPORT_SYMBOL(ttm_bo_eviction_valuable);
438437
@@ -1027,7 +1026,7 @@ int ttm_bo_init_validate(struct ttm_device *bdev, struct ttm_buffer_object *bo, · 588 unmodified lines
10271026 struct sg_table *sg, struct dma_resv *resv,
10281027 void (*destroy) (struct ttm_buffer_object *))
10291028 {
1030− struct ttm_operation_ctx ctx = { interruptible, false };
1029+ struct ttm_operation_ctx ctx = { .interruptible = interruptible };
10311030 int ret;
10321031
10331032 ret = ttm_bo_init_reserved(bdev, bo, type, placement, alignment, &ctx,
@@ -1108,10 +1107,13 @@ struct ttm_bo_swapout_walk { · 74 unmodified lines
11081107 static s64
11091108 ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo)
11101109 {
1111− struct ttm_place place = {.mem_type = bo->resource->mem_type};
1110+ struct ttm_resource *res = bo->resource;
1111+ struct ttm_place place = { .mem_type = res->mem_type };
11121112 struct ttm_bo_swapout_walk *swapout_walk =
11131113 container_of(walk, typeof(*swapout_walk), walk);
11141114 struct ttm_operation_ctx *ctx = walk->arg.ctx;
1115+ struct ttm_device *bdev = bo->bdev;
1116+ struct ttm_tt *tt = bo->ttm;
11151117 s64 ret;
11161118
11171119 /*
@@ -1120,20 +1122,19 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) · 2 unmodified lines
11201122 * The driver may use the fact that we're moving from SYSTEM
11211123 * as an indication that we're about to swap out.
11221124 */
1123− if (bo->pin_count || !bo->bdev->funcs->eviction_valuable(bo, &place)) {
1125+ if (bo->pin_count || !bdev->funcs->eviction_valuable(bo, &place)) {
11241126 ret = -EBUSY;
11251127 goto out;
11261128 }
11271129
1128− if (!bo->ttm || !ttm_tt_is_populated(bo->ttm) ||
1129− bo->ttm->page_flags & TTM_TT_FLAG_EXTERNAL ||
1130− bo->ttm->page_flags & TTM_TT_FLAG_SWAPPED) {
1130+ if (!tt || !ttm_tt_is_populated(tt) ||
1131+ tt->page_flags & (TTM_TT_FLAG_EXTERNAL | TTM_TT_FLAG_SWAPPED)) {
11311132 ret = -EBUSY;
11321133 goto out;
11331134 }
11341135
11351136 if (bo->deleted) {
1136− pgoff_t num_pages = bo->ttm->num_pages;
1137+ pgoff_t num_pages = tt->num_pages;
11371138
11381139 ret = ttm_bo_wait_ctx(bo, ctx);
11391140 if (ret)
@@ -1147,7 +1148,7 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) · 7 unmodified lines
11471148 /*
11481149 * Move to system cached
11491150 */
1150− if (bo->resource->mem_type != TTM_PL_SYSTEM) {
1151+ if (res->mem_type != TTM_PL_SYSTEM) {
11511152 struct ttm_resource *evict_mem;
11521153 struct ttm_place hop;
11531154
@@ -1174,21 +1175,21 @@ ttm_bo_swapout_cb(struct ttm_lru_walk *walk, struct ttm_buffer_object *bo) · 20 unmodified lines
11741175 goto out;
11751176
11761177 ttm_bo_unmap_virtual(bo);
1177− if (bo->bdev->funcs->swap_notify)
1178− bo->bdev->funcs->swap_notify(bo);
1178+ if (bdev->funcs->swap_notify)
1179+ bdev->funcs->swap_notify(bo);
11791180
1180− if (ttm_tt_is_populated(bo->ttm)) {
1181− spin_lock(&bo->bdev->lru_lock);
1182− ttm_resource_del_bulk_move(bo->resource, bo);
1183− spin_unlock(&bo->bdev->lru_lock);
1181+ if (ttm_tt_is_populated(tt)) {
1182+ spin_lock(&bdev->lru_lock);
1183+ ttm_resource_del_bulk_move(res, bo);
1184+ spin_unlock(&bdev->lru_lock);
11841185
1185− ret = ttm_tt_swapout(bo->bdev, bo->ttm, swapout_walk->gfp_flags);
1186+ ret = ttm_tt_swapout(bdev, tt, swapout_walk->gfp_flags);
11861187
1187− spin_lock(&bo->bdev->lru_lock);
1188+ spin_lock(&bdev->lru_lock);
11881189 if (ret)
1189− ttm_resource_add_bulk_move(bo->resource, bo);
1190− ttm_resource_move_to_lru_tail(bo->resource);
1191− spin_unlock(&bo->bdev->lru_lock);
1190+ ttm_resource_add_bulk_move(res, bo);
1191+ ttm_resource_move_to_lru_tail(res);
1192+ spin_unlock(&bdev->lru_lock);
11921193 }
11931194
11941195 out:
@@ -1261,6 +1262,7 @@ void ttm_bo_tt_destroy(struct ttm_buffer_object *bo) · 66 unmodified lines
12611262 int ttm_bo_populate(struct ttm_buffer_object *bo,
12621263 struct ttm_operation_ctx *ctx)
12631264 {
1265+ struct ttm_device *bdev = bo->bdev;
12641266 struct ttm_tt *tt = bo->ttm;
12651267 bool swapped;
12661268 int ret;
@@ -1271,16 +1273,16 @@ int ttm_bo_populate(struct ttm_buffer_object *bo, · 4 unmodified lines
12711273 return 0;
12721274
12731275 swapped = ttm_tt_is_swapped(tt);
1274− ret = ttm_tt_populate(bo->bdev, tt, ctx);
1276+ ret = ttm_tt_populate(bdev, tt, ctx);
12751277 if (ret)
12761278 return ret;
12771279
12781280 if (swapped && !ttm_tt_is_swapped(tt) && !bo->pin_count &&
12791281 bo->resource) {
1280− spin_lock(&bo->bdev->lru_lock);
1282+ spin_lock(&bdev->lru_lock);
12811283 ttm_resource_add_bulk_move(bo->resource, bo);
12821284 ttm_resource_move_to_lru_tail(bo->resource);
1283− spin_unlock(&bo->bdev->lru_lock);
1285+ spin_unlock(&bdev->lru_lock);
12841286 }
12851287
12861288 return 0;
drivers/gpu/drm/ttm/ttm_bo_util.c+25−32
@@ -174,13 +174,13 @@ int ttm_bo_move_memcpy(struct ttm_buffer_object *bo, · 173 unmodified lines
174174
175175 dst_iter = ttm_kmap_iter_linear_io_init(&_dst_iter.io, bdev, dst_mem);
176176 if (PTR_ERR(dst_iter) == -EINVAL && dst_man->use_tt)
177− dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, bo->ttm);
177+ dst_iter = ttm_kmap_iter_tt_init(&_dst_iter.tt, ttm);
178178 if (IS_ERR(dst_iter))
179179 return PTR_ERR(dst_iter);
180180
181181 src_iter = ttm_kmap_iter_linear_io_init(&_src_iter.io, bdev, src_mem);
182182 if (PTR_ERR(src_iter) == -EINVAL && src_man->use_tt)
183− src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, bo->ttm);
183+ src_iter = ttm_kmap_iter_tt_init(&_src_iter.tt, ttm);
184184 if (IS_ERR(src_iter)) {
185185 ret = PTR_ERR(src_iter);
186186 goto out_src_iter;
@@ -318,11 +318,11 @@ static int ttm_bo_ioremap(struct ttm_buffer_object *bo, · 131 unmodified lines
318318 {
319319 struct ttm_resource *mem = bo->resource;
320320
321− if (bo->resource->bus.addr) {
321+ if (mem->bus.addr) {
322322 map->bo_kmap_type = ttm_bo_map_premapped;
323− map->virtual = ((u8 *)bo->resource->bus.addr) + offset;
323+ map->virtual = ((u8 *)mem->bus.addr) + offset;
324324 } else {
325− resource_size_t res = bo->resource->bus.offset + offset;
325+ resource_size_t res = mem->bus.offset + offset;
326326
327327 map->bo_kmap_type = ttm_bo_map_iomap;
328328 if (mem->bus.caching == ttm_write_combined)
@@ -343,13 +343,10 @@ static int ttm_bo_kmap_ttm(struct ttm_buffer_object *bo, · 14 unmodified lines
343343 struct ttm_bo_kmap_obj *map)
344344 {
345345 struct ttm_resource *mem = bo->resource;
346− struct ttm_operation_ctx ctx = {
347− .interruptible = false,
348− .no_wait_gpu = false
349− };
346+ struct ttm_operation_ctx ctx = { };
350347 struct ttm_tt *ttm = bo->ttm;
351348 struct ttm_resource_manager *man =
352− ttm_manager_type(bo->bdev, bo->resource->mem_type);
349+ ttm_manager_type(bo->bdev, mem->mem_type);
353350 pgprot_t prot;
354351 int ret;
355352
@@ -428,20 +425,21 @@ int ttm_bo_kmap(struct ttm_buffer_object *bo, · 72 unmodified lines
428425 unsigned long start_page, unsigned long num_pages,
429426 struct ttm_bo_kmap_obj *map)
430427 {
428+ struct ttm_resource *res = bo->resource;
431429 unsigned long offset, size;
432430 int ret;
433431
434432 map->virtual = NULL;
435433 map->bo = bo;
436− if (num_pages > PFN_UP(bo->resource->size))
434+ if (num_pages > PFN_UP(res->size))
437435 return -EINVAL;
438− if ((start_page + num_pages) > PFN_UP(bo->resource->size))
436+ if ((start_page + num_pages) > PFN_UP(res->size))
439437 return -EINVAL;
440438
441− ret = ttm_mem_io_reserve(bo->bdev, bo->resource);
439+ ret = ttm_mem_io_reserve(bo->bdev, res);
442440 if (ret)
443441 return ret;
444− if (!bo->resource->bus.is_iomem) {
442+ if (!res->bus.is_iomem) {
445443 return ttm_bo_kmap_ttm(bo, start_page, num_pages, map);
446444 } else {
447445 offset = start_page << PAGE_SHIFT;
@@ -530,10 +528,7 @@ int ttm_bo_vmap(struct ttm_buffer_object *bo, struct iosys_map *map) · 82 unmodified lines
530528 iosys_map_set_vaddr_iomem(map, vaddr_iomem);
531529
532530 } else {
533− struct ttm_operation_ctx ctx = {
534− .interruptible = false,
535− .no_wait_gpu = false
536− };
531+ struct ttm_operation_ctx ctx = { };
537532 struct ttm_tt *ttm = bo->ttm;
538533 pgprot_t prot;
539534 void *vaddr;
@@ -581,7 +576,7 @@ void ttm_bo_vunmap(struct ttm_buffer_object *bo, struct iosys_map *map) · 41 unmodified lines
581576 iounmap(map->vaddr_iomem);
582577 iosys_map_clear(map);
583578
584− ttm_mem_io_free(bo->bdev, bo->resource);
579+ ttm_mem_io_free(bo->bdev, mem);
585580 }
586581 EXPORT_SYMBOL(ttm_bo_vunmap);
587582
@@ -644,12 +639,11 @@ static int ttm_bo_move_to_ghost(struct ttm_buffer_object *bo, · 56 unmodified lines
644639 static void ttm_bo_move_pipeline_evict(struct ttm_buffer_object *bo,
645640 struct dma_fence *fence)
646641 {
647− struct ttm_device *bdev = bo->bdev;
648642 struct ttm_resource_manager *from;
649643 struct dma_fence *tmp;
650644 int i;
651645
652− from = ttm_manager_type(bdev, bo->resource->mem_type);
646+ from = ttm_manager_type(bo->bdev, bo->resource->mem_type);
653647
654648 /**
655649 * BO doesn't have a TTM we need to bind/unbind. Just remember
@@ -743,8 +737,8 @@ EXPORT_SYMBOL(ttm_bo_move_accel_cleanup); · 87 unmodified lines
743737 void ttm_bo_move_sync_cleanup(struct ttm_buffer_object *bo,
744738 struct ttm_resource *new_mem)
745739 {
746− struct ttm_device *bdev = bo->bdev;
747− struct ttm_resource_manager *man = ttm_manager_type(bdev, new_mem->mem_type);
740+ struct ttm_resource_manager *man =
741+ ttm_manager_type(bo->bdev, new_mem->mem_type);
748742 int ret;
749743
750744 ret = ttm_bo_wait_free_node(bo, man->use_tt);
@@ -848,13 +842,12 @@ static int ttm_lru_walk_ticketlock(struct ttm_bo_lru_cursor *curs, · 97 unmodified lines
848842 struct ttm_buffer_object *bo)
849843 {
850844 struct ttm_lru_walk_arg *arg = curs->arg;
851− struct dma_resv *resv = bo->base.resv;
852845 int ret;
853846
854847 if (arg->ctx->interruptible)
855− ret = dma_resv_lock_interruptible(resv, arg->ticket);
848+ ret = dma_resv_lock_interruptible(bo->base.resv, arg->ticket);
856849 else
857− ret = dma_resv_lock(resv, arg->ticket);
850+ ret = dma_resv_lock(bo->base.resv, arg->ticket);
858851
859852 if (!ret) {
860853 curs->needs_unlock = true;
@@ -1098,7 +1091,7 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, · 237 unmodified lines
10981091 .num_placement = 1,
10991092 .placement = &sys_placement_flags,
11001093 };
1101− struct ttm_tt *tt = bo->ttm;
1094+ struct ttm_device *bdev = bo->bdev;
11021095 long lret;
11031096
11041097 dma_resv_assert_held(bo->base.resv);
@@ -1120,19 +1113,19 @@ long ttm_bo_shrink(struct ttm_operation_ctx *ctx, struct ttm_buffer_object *bo, · 15 unmodified lines
11201113 return lret;
11211114
11221115 if (bo->bulk_move) {
1123− spin_lock(&bo->bdev->lru_lock);
1116+ spin_lock(&bdev->lru_lock);
11241117 ttm_resource_del_bulk_move(bo->resource, bo);
1125− spin_unlock(&bo->bdev->lru_lock);
1118+ spin_unlock(&bdev->lru_lock);
11261119 }
11271120
1128− lret = ttm_tt_backup(bo->bdev, tt, (struct ttm_backup_flags)
1121+ lret = ttm_tt_backup(bdev, bo->ttm, (struct ttm_backup_flags)
11291122 {.purge = flags.purge,
11301123 .writeback = flags.writeback});
11311124
11321125 if (lret <= 0 && bo->bulk_move) {
1133− spin_lock(&bo->bdev->lru_lock);
1126+ spin_lock(&bdev->lru_lock);
11341127 ttm_resource_add_bulk_move(bo->resource, bo);
1135− spin_unlock(&bo->bdev->lru_lock);
1128+ spin_unlock(&bdev->lru_lock);
11361129 }
11371130
11381131 if (lret < 0 && lret != -EINTR)
drivers/gpu/drm/ttm/ttm_bo_vm.c+5−7
@@ -186,7 +186,6 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, · 185 unmodified lines
186186 {
187187 struct vm_area_struct *vma = vmf->vma;
188188 struct ttm_buffer_object *bo = vma->vm_private_data;
189− struct ttm_device *bdev = bo->bdev;
190189 unsigned long page_offset;
191190 unsigned long page_last;
192191 unsigned long pfn;
@@ -205,7 +204,7 @@ vm_fault_t ttm_bo_vm_fault_reserved(struct vm_fault *vmf, · 12 unmodified lines
205204 if (unlikely(ret != 0))
206205 return ret;
207206
208− err = ttm_mem_io_reserve(bdev, bo->resource);
207+ err = ttm_mem_io_reserve(bo->bdev, bo->resource);
209208 if (unlikely(err != 0))
210209 return VM_FAULT_SIGBUS;
211210
@@ -293,7 +292,6 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) · 81 unmodified lines
293292 {
294293 struct vm_area_struct *vma = vmf->vma;
295294 struct ttm_buffer_object *bo = vma->vm_private_data;
296− struct drm_device *ddev = bo->base.dev;
297295 vm_fault_t ret = VM_FAULT_NOPAGE;
298296 unsigned long address;
299297 unsigned long pfn;
@@ -305,7 +303,8 @@ vm_fault_t ttm_bo_vm_dummy_page(struct vm_fault *vmf, pgprot_t prot) · 5 unmodified lines
305303 return VM_FAULT_OOM;
306304
307305 /* Set the page to be freed using drmm release action */
308− if (drmm_add_action_or_reset(ddev, ttm_bo_release_dummy_page, page))
306+ if (drmm_add_action_or_reset(bo->base.dev, ttm_bo_release_dummy_page,
307+ page))
309308 return VM_FAULT_OOM;
310309
311310 pfn = page_to_pfn(page);
@@ -322,10 +321,9 @@ EXPORT_SYMBOL(ttm_bo_vm_dummy_page); · 10 unmodified lines
322321 vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf)
323322 {
324323 struct vm_area_struct *vma = vmf->vma;
325− pgprot_t prot;
326324 struct ttm_buffer_object *bo = vma->vm_private_data;
327− struct drm_device *ddev = bo->base.dev;
328325 vm_fault_t ret;
326+ pgprot_t prot;
329327 int idx;
330328
331329 ret = ttm_bo_vm_reserve(bo, vmf);
@@ -333,7 +331,7 @@ vm_fault_t ttm_bo_vm_fault(struct vm_fault *vmf) · 1 unmodified line
333331 return ret;
334332
335333 prot = vma->vm_page_prot;
336− if (drm_dev_enter(ddev, &idx)) {
334+ if (drm_dev_enter(bo->base.dev, &idx)) {
337335 ret = ttm_bo_vm_fault_reserved(vmf, prot, TTM_BO_VM_NUM_PREFAULT);
338336 drm_dev_exit(idx);
339337 } else {
drivers/gpu/drm/ttm/ttm_device.c+1−4
@@ -135,10 +135,7 @@ out: · 134 unmodified lines
135135 */
136136 int ttm_device_prepare_hibernation(struct ttm_device *bdev)
137137 {
138− struct ttm_operation_ctx ctx = {
139− .interruptible = false,
140− .no_wait_gpu = false,
141− };
138+ struct ttm_operation_ctx ctx = { };
142139 int ret;
143140
144141 do {
drivers/gpu/drm/ttm/ttm_pool.c+14−12
@@ -845,32 +845,34 @@ EXPORT_SYMBOL(ttm_pool_alloc); · 844 unmodified lines
845845 int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt,
846846 const struct ttm_operation_ctx *ctx)
847847 {
848+ struct ttm_pool_tt_restore *restore = tt->restore;
848849 struct ttm_pool_alloc_state alloc;
849850
850851 if (WARN_ON(!ttm_tt_is_backed_up(tt)))
851852 return -EINVAL;
852853
853− if (!tt->restore) {
854+ if (!restore) {
854855 gfp_t gfp = GFP_KERNEL | __GFP_NOWARN;
855856
856857 ttm_pool_alloc_state_init(tt, &alloc);
857858 if (ctx->gfp_retry_mayfail)
858859 gfp |= __GFP_RETRY_MAYFAIL;
859860
860− tt->restore = kzalloc(sizeof(*tt->restore), gfp);
861− if (!tt->restore)
861+ restore = kzalloc(sizeof(*restore), gfp);
862+ if (!restore)
862863 return -ENOMEM;
863864
864− tt->restore->snapshot_alloc = alloc;
865− tt->restore->pool = pool;
866− tt->restore->restored_pages = 1;
867− } else {
868− struct ttm_pool_tt_restore *restore = tt->restore;
869− int ret;
865+ restore->snapshot_alloc = alloc;
866+ restore->pool = pool;
867+ restore->restored_pages = 1;
870868
869+ tt->restore = restore;
870+ } else {
871871 alloc = restore->snapshot_alloc;
872− if (ttm_pool_restore_valid(tt->restore)) {
873− ret = ttm_pool_restore_commit(restore, tt->backup, ctx, &alloc);
872+ if (ttm_pool_restore_valid(restore)) {
873+ int ret = ttm_pool_restore_commit(restore, tt->backup,
874+ ctx, &alloc);
875+
874876 if (ret)
875877 return ret;
876878 }
@@ -878,7 +880,7 @@ int ttm_pool_restore_and_alloc(struct ttm_pool *pool, struct ttm_tt *tt, · 1 unmodified line
878880 return 0;
879881 }
880882
881− return __ttm_pool_alloc(pool, tt, ctx, &alloc, tt->restore);
883+ return __ttm_pool_alloc(pool, tt, ctx, &alloc, restore);
882884 }
883885
884886 /**
drivers/gpu/drm/ttm/ttm_resource.c+4−10
@@ -446,9 +446,6 @@ bool ttm_resource_intersects(struct ttm_device *bdev, · 445 unmodified lines
446446 {
447447 struct ttm_resource_manager *man;
448448
449− if (!res)
450− return false;
451−
452449 man = ttm_manager_type(bdev, res->mem_type);
453450 if (!place || !man->func->intersects)
454451 return true;
@@ -548,10 +545,7 @@ EXPORT_SYMBOL(ttm_resource_manager_init); · 93 unmodified lines
548545 int ttm_resource_manager_evict_all(struct ttm_device *bdev,
549546 struct ttm_resource_manager *man)
550547 {
551− struct ttm_operation_ctx ctx = {
552− .interruptible = false,
553− .no_wait_gpu = false,
554− };
548+ struct ttm_operation_ctx ctx = { };
555549 struct dma_fence *fence;
556550 int ret, i;
557551
@@ -628,11 +622,11 @@ ttm_resource_cursor_check_bulk(struct ttm_resource_cursor *cursor, · 70 unmodified lines
628622 struct ttm_lru_item *next_lru)
629623 {
630624 struct ttm_resource *next = ttm_lru_item_to_res(next_lru);
631− struct ttm_lru_bulk_move *bulk = NULL;
632− struct ttm_buffer_object *bo = next->bo;
625+ struct ttm_lru_bulk_move *bulk;
633626
634627 lockdep_assert_held(&cursor->man->bdev->lru_lock);
635− bulk = bo->bulk_move;
628+
629+ bulk = next->bo->bulk_move;
636630
637631 if (cursor->bulk != bulk) {
638632 if (bulk) {
drivers/gpu/drm/ttm/ttm_tt.c+1−1
@@ -456,7 +456,7 @@ EXPORT_SYMBOL_FOR_TESTS_ONLY(ttm_tt_unpopulate); · 455 unmodified lines
456456 /* Test the shrinker functions and dump the result */
457457 static int ttm_tt_debugfs_shrink_show(struct seq_file *m, void *data)
458458 {
459− struct ttm_operation_ctx ctx = { false, false };
459+ struct ttm_operation_ctx ctx = { };
460460
461461 seq_printf(m, "%d\n", ttm_global_swapout(&ctx, GFP_KERNEL));
462462 return 0;
drivers/gpu/drm/v3d/Makefile+1−2
@@ -13,8 +13,7 @@ v3d-y := \ · 12 unmodified lines
1313 v3d_trace_points.o \
1414 v3d_sched.o \
1515 v3d_sysfs.o \
16− v3d_submit.o \
17− v3d_gemfs.o
16+ v3d_submit.o
1817
1918 v3d-$(CONFIG_DEBUG_FS) += v3d_debugfs.o
2019
drivers/gpu/drm/v3d/v3d_bo.c+2−4
@@ -114,7 +114,7 @@ v3d_bo_create_finish(struct drm_gem_object *obj) · 113 unmodified lines
114114 if (IS_ERR(sgt))
115115 return PTR_ERR(sgt);
116116
117− if (!v3d->gemfs)
117+ if (!drm_gem_get_huge_mnt(obj->dev))
118118 align = SZ_4K;
119119 else if (obj->size >= SZ_1M)
120120 align = SZ_1M;
@@ -150,12 +150,10 @@ struct v3d_bo *v3d_bo_create(struct drm_device *dev, struct drm_file *file_priv, · 29 unmodified lines
150150 size_t unaligned_size)
151151 {
152152 struct drm_gem_shmem_object *shmem_obj;
153− struct v3d_dev *v3d = to_v3d_dev(dev);
154153 struct v3d_bo *bo;
155154 int ret;
156155
157− shmem_obj = drm_gem_shmem_create_with_mnt(dev, unaligned_size,
158− v3d->gemfs);
156+ shmem_obj = drm_gem_shmem_create(dev, unaligned_size);
159157 if (IS_ERR(shmem_obj))
160158 return ERR_CAST(shmem_obj);
161159 bo = to_v3d_bo(&shmem_obj->base);
drivers/gpu/drm/v3d/v3d_drv.c+1−1
@@ -107,7 +107,7 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, · 106 unmodified lines
107107 args->value = v3d->perfmon_info.max_counters;
108108 return 0;
109109 case DRM_V3D_PARAM_SUPPORTS_SUPER_PAGES:
110− args->value = !!v3d->gemfs;
110+ args->value = !!drm_gem_get_huge_mnt(dev);
111111 return 0;
112112 case DRM_V3D_PARAM_GLOBAL_RESET_COUNTER:
113113 mutex_lock(&v3d->reset_lock);
drivers/gpu/drm/v3d/v3d_drv.h+1−10
@@ -158,11 +158,6 @@ struct v3d_dev { · 157 unmodified lines
158158 struct drm_mm mm;
159159 spinlock_t mm_lock;
160160
161− /*
162− * tmpfs instance used for shmem backed objects
163− */
164− struct vfsmount *gemfs;
165−
166161 struct work_struct overflow_mem_work;
167162
168163 struct v3d_queue_state queue[V3D_MAX_QUEUES];
@@ -569,6 +564,7 @@ extern const struct dma_fence_ops v3d_fence_ops; · 400 unmodified lines
569564 struct dma_fence *v3d_fence_create(struct v3d_dev *v3d, enum v3d_queue q);
570565
571566 /* v3d_gem.c */
567+extern bool super_pages;
572568 int v3d_gem_init(struct drm_device *dev);
573569 void v3d_gem_destroy(struct drm_device *dev);
574570 void v3d_reset_sms(struct v3d_dev *v3d);
@@ -576,11 +572,6 @@ void v3d_reset(struct v3d_dev *v3d); · 1 unmodified line
576572 void v3d_invalidate_caches(struct v3d_dev *v3d);
577573 void v3d_clean_caches(struct v3d_dev *v3d);
578574
579−/* v3d_gemfs.c */
580−extern bool super_pages;
581−void v3d_gemfs_init(struct v3d_dev *v3d);
582−void v3d_gemfs_fini(struct v3d_dev *v3d);
583−
584575 /* v3d_submit.c */
585576 void v3d_job_cleanup(struct v3d_job *job);
586577 void v3d_job_put(struct v3d_job *job);
drivers/gpu/drm/v3d/v3d_gem.c+19−2
@@ -259,6 +259,24 @@ v3d_invalidate_caches(struct v3d_dev *v3d) · 258 unmodified lines
259259 v3d_invalidate_slices(v3d, 0);
260260 }
261261
262+static void
263+v3d_huge_mnt_init(struct v3d_dev *v3d)
264+{
265+ int err = 0;
266+
267+ if (IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE) && super_pages)
268+ err = drm_gem_huge_mnt_create(&v3d->drm, "within_size");
269+
270+ if (drm_gem_get_huge_mnt(&v3d->drm))
271+ drm_info(&v3d->drm, "Using Transparent Hugepages\n");
272+ else if (err)
273+ drm_warn(&v3d->drm, "Can't use Transparent Hugepages (%d)\n",
274+ err);
275+ else
276+ drm_notice(&v3d->drm,
277+ "Transparent Hugepage support is recommended for optimal performance on this platform!\n");
278+}
279+
262280 int
263281 v3d_gem_init(struct drm_device *dev)
264282 {
@@ -310,7 +328,7 @@ v3d_gem_init(struct drm_device *dev) · 45 unmodified lines
310328 v3d_init_hw_state(v3d);
311329 v3d_mmu_set_page_table(v3d);
312330
313− v3d_gemfs_init(v3d);
331+ v3d_huge_mnt_init(v3d);
314332
315333 ret = v3d_sched_init(v3d);
316334 if (ret) {
@@ -330,7 +348,6 @@ v3d_gem_destroy(struct drm_device *dev) · 13 unmodified lines
330348 enum v3d_queue q;
331349
332350 v3d_sched_fini(v3d);
333− v3d_gemfs_fini(v3d);
334351
335352 /* Waiting for jobs to finish would need to be done before
336353 * unregistering V3D.
drivers/gpu/drm/v3d/v3d_gemfs.c+0−62
@@ -1,62 +0,0 @@
1−// SPDX-License-Identifier: GPL-2.0+
2−/* Copyright (C) 2024 Raspberry Pi */
3−
4−#include <linux/fs.h>
5−#include <linux/mount.h>
6−#include <linux/fs_context.h>
7−
8−#include <drm/drm_print.h>
9−
10−#include "v3d_drv.h"
11−
12−void v3d_gemfs_init(struct v3d_dev *v3d)
13−{
14− struct file_system_type *type;
15− struct fs_context *fc;
16− struct vfsmount *gemfs;
17− int ret;
18−
19− /*
20− * By creating our own shmemfs mountpoint, we can pass in
21− * mount flags that better match our usecase. However, we
22− * only do so on platforms which benefit from it.
23− */
24− if (!IS_ENABLED(CONFIG_TRANSPARENT_HUGEPAGE))
25− goto err;
26−
27− /* The user doesn't want to enable Super Pages */
28− if (!super_pages)
29− goto err;
30−
31− type = get_fs_type("tmpfs");
32− if (!type)
33− goto err;
34−
35− fc = fs_context_for_mount(type, SB_KERNMOUNT);
36− if (IS_ERR(fc))
37− goto err;
38− ret = vfs_parse_fs_string(fc, "source", "tmpfs");
39− if (!ret)
40− ret = vfs_parse_fs_string(fc, "huge", "within_size");
41− if (!ret)
42− gemfs = fc_mount_longterm(fc);
43− put_fs_context(fc);
44− if (ret)
45− goto err;
46−
47− v3d->gemfs = gemfs;
48− drm_info(&v3d->drm, "Using Transparent Hugepages\n");
49−
50− return;
51−
52−err:
53− v3d->gemfs = NULL;
54− drm_notice(&v3d->drm,
55− "Transparent Hugepage support is recommended for optimal performance on this platform!\n");
56−}
57−
58−void v3d_gemfs_fini(struct v3d_dev *v3d)
59−{
60− if (v3d->gemfs)
61− kern_unmount(v3d->gemfs);
62−}
drivers/gpu/drm/vgem/Kconfig+9−0
@@ -0,0 +1,9 @@
1+# SPDX-License-Identifier: GPL-2.0-only
2+config DRM_VGEM
3+ tristate "Virtual GEM provider"
4+ depends on DRM && MMU
5+ select DRM_GEM_SHMEM_HELPER
6+ help
7+ Choose this option to get a virtual graphics memory manager,
8+ as used by Mesa's software renderer for enhanced performance.
9+ If M is selected the module will be called vgem.
drivers/gpu/drm/xe/xe_hw_fence.c+1−3
@@ -85,7 +85,6 @@ void xe_hw_fence_irq_finish(struct xe_hw_fence_irq *irq) · 84 unmodified lines
8585 {
8686 struct xe_hw_fence *fence, *next;
8787 unsigned long flags;
88− int err;
8988 bool tmp;
9089
9190 if (XE_WARN_ON(!list_empty(&irq->pending))) {
@@ -93,9 +92,8 @@ void xe_hw_fence_irq_finish(struct xe_hw_fence_irq *irq) · 1 unmodified line
9392 spin_lock_irqsave(&irq->lock, flags);
9493 list_for_each_entry_safe(fence, next, &irq->pending, irq_link) {
9594 list_del_init(&fence->irq_link);
96− err = dma_fence_signal_locked(&fence->dma);
95+ XE_WARN_ON(dma_fence_check_and_signal_locked(&fence->dma));
9796 dma_fence_put(&fence->dma);
98− XE_WARN_ON(err);
9997 }
10098 spin_unlock_irqrestore(&irq->lock, flags);
10199 dma_fence_end_signalling(tmp);
drivers/video/fbdev/core/fbcon.c+0−24
@@ -2289,28 +2289,6 @@ static bool fbcon_blank(struct vc_data *vc, enum vesa_blank_mode blank, · 2288 unmodified lines
22892289 return false;
22902290 }
22912291
2292−static void fbcon_debug_enter(struct vc_data *vc)
2293−{
2294− struct fb_info *info = fbcon_info_from_console(vc->vc_num);
2295− struct fbcon_par *par = info->fbcon_par;
2296−
2297− par->save_graphics = par->graphics;
2298− par->graphics = 0;
2299− if (info->fbops->fb_debug_enter)
2300− info->fbops->fb_debug_enter(info);
2301− fbcon_set_palette(vc, color_table);
2302−}
2303−
2304−static void fbcon_debug_leave(struct vc_data *vc)
2305−{
2306− struct fb_info *info = fbcon_info_from_console(vc->vc_num);
2307− struct fbcon_par *par = info->fbcon_par;
2308−
2309− par->graphics = par->save_graphics;
2310− if (info->fbops->fb_debug_leave)
2311− info->fbops->fb_debug_leave(info);
2312−}
2313−
23142292 static int fbcon_get_font(struct vc_data *vc, struct console_font *font, unsigned int vpitch)
23152293 {
23162294 u8 *fontdata = vc->vc_font.data;
@@ -3214,8 +3192,6 @@ static const struct consw fb_con = { · 897 unmodified lines
32143192 .con_set_palette = fbcon_set_palette,
32153193 .con_invert_region = fbcon_invert_region,
32163194 .con_resize = fbcon_resize,
3217− .con_debug_enter = fbcon_debug_enter,
3218− .con_debug_leave = fbcon_debug_leave,
32193195 };
32203196
32213197 static ssize_t rotate_store(struct device *device,
drivers/video/fbdev/core/fbcon.h+0−1
@@ -79,7 +79,6 @@ struct fbcon_par { · 78 unmodified lines
7979 int cursor_reset;
8080 int blank_state;
8181 int graphics;
82− int save_graphics; /* for debug enter/leave */
8382 bool initialized;
8483 int rotate;
8584 int cur_rotate;
include/drm/drm_atomic.h+5−0
@@ -339,6 +339,11 @@ struct drm_private_state_funcs { · 338 unmodified lines
339339 * drm_atomic_helper_wait_for_dependencies().
340340 */
341341 struct drm_private_obj {
342+ /**
343+ * @dev: parent DRM device
344+ */
345+ struct drm_device *dev;
346+
342347 /**
343348 * @head: List entry used to attach a private object to a &drm_device
344349 * (queued to &drm_mode_config.privobj_list).
include/drm/drm_bridge.h+12−0
@@ -1143,6 +1143,14 @@ struct drm_bridge { · 1142 unmodified lines
11431143 */
11441144 struct kref refcount;
11451145
1146+ /**
1147+ * @unplugged:
1148+ *
1149+ * Flag to tell if the bridge has been unplugged.
1150+ * See drm_bridge_enter() and drm_bridge_unplug().
1151+ */
1152+ bool unplugged;
1153+
11461154 /** @driver_private: pointer to the bridge driver's internal context */
11471155 void *driver_private;
11481156 /** @ops: bitmask of operations supported by the bridge */
@@ -1278,6 +1286,10 @@ drm_priv_to_bridge(struct drm_private_obj *priv) · 129 unmodified lines
12781286 return container_of(priv, struct drm_bridge, base);
12791287 }
12801288
1289+bool drm_bridge_enter(struct drm_bridge *bridge, int *idx);
1290+void drm_bridge_exit(int idx);
1291+void drm_bridge_unplug(struct drm_bridge *bridge);
1292+
12811293 struct drm_bridge *drm_bridge_get(struct drm_bridge *bridge);
12821294 void drm_bridge_put(struct drm_bridge *bridge);
12831295
include/drm/drm_device.h+15−0
@@ -3,6 +3,9 @@ · 2 unmodified lines
33
44 #include <linux/list.h>
55 #include <linux/kref.h>
6+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
7+#include <linux/mount.h>
8+#endif
69 #include <linux/mutex.h>
710 #include <linux/idr.h>
811 #include <linux/sched.h>
@@ -168,6 +171,18 @@ struct drm_device { · 159 unmodified lines
168171 */
169172 struct drm_master *master;
170173
174+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
175+ /**
176+ * @huge_mnt:
177+ *
178+ * Huge tmpfs mountpoint used at GEM object initialization
179+ * drm_gem_object_init(). Drivers can call drm_gem_huge_mnt_create() to
180+ * create, mount and use it. The default tmpfs mountpoint (`shm_mnt`) is
181+ * used if NULL.
182+ */
183+ struct vfsmount *huge_mnt;
184+#endif
185+
171186 /**
172187 * @driver_features: per-device driver features
173188 *
include/drm/drm_fb_helper.h+0−21
@@ -166,13 +166,6 @@ struct drm_fb_helper { · 165 unmodified lines
166166 */
167167 struct mutex lock;
168168
169− /**
170− * @kernel_fb_list:
171− *
172− * Entry on the global kernel_fb_helper_list, used for kgdb entry/exit.
173− */
174− struct list_head kernel_fb_list;
175−
176169 /**
177170 * @delayed_hotplug:
178171 *
@@ -236,8 +229,6 @@ drm_fb_helper_from_client(struct drm_client_dev *client) · 57 unmodified lines
236229 .fb_setcmap = drm_fb_helper_setcmap, \
237230 .fb_blank = drm_fb_helper_blank, \
238231 .fb_pan_display = drm_fb_helper_pan_display, \
239− .fb_debug_enter = drm_fb_helper_debug_enter, \
240− .fb_debug_leave = drm_fb_helper_debug_leave, \
241232 .fb_ioctl = drm_fb_helper_ioctl
242233
243234 #ifdef CONFIG_DRM_FBDEV_EMULATION
@@ -280,8 +271,6 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, · 36 unmodified lines
280271
281272 int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper);
282273 int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper);
283−int drm_fb_helper_debug_enter(struct fb_info *info);
284−int drm_fb_helper_debug_leave(struct fb_info *info);
285274 #else
286275 static inline void drm_fb_helper_prepare(struct drm_device *dev,
287276 struct drm_fb_helper *helper,
@@ -387,16 +376,6 @@ static inline int drm_fb_helper_initial_config(struct drm_fb_helper *fb_helper) · 99 unmodified lines
387376 {
388377 return 0;
389378 }
390−
391−static inline int drm_fb_helper_debug_enter(struct fb_info *info)
392−{
393− return 0;
394−}
395−
396−static inline int drm_fb_helper_debug_leave(struct fb_info *info)
397−{
398− return 0;
399−}
400379 #endif
401380
402381 #endif
include/drm/drm_gem.h+42−3
@@ -40,6 +40,9 @@ · 39 unmodified lines
4040 #include <linux/list.h>
4141 #include <linux/mutex.h>
4242
43+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
44+#include <drm/drm_device.h>
45+#endif
4346 #include <drm/drm_vma_manager.h>
4447
4548 struct iosys_map;
@@ -469,6 +472,7 @@ struct drm_gem_object { · 423 unmodified lines
469472 .poll = drm_poll,\
470473 .read = drm_read,\
471474 .llseek = noop_llseek,\
475+ .get_unmapped_area = drm_gem_get_unmapped_area,\
472476 .mmap = drm_gem_mmap, \
473477 .fop_flags = FOP_UNSIGNED_OFFSET
474478
@@ -491,13 +495,40 @@ struct drm_gem_object { · 16 unmodified lines
491495 DRM_GEM_FOPS,\
492496 }
493497
498+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
499+int drm_gem_huge_mnt_create(struct drm_device *dev, const char *value);
500+#else
501+static inline int drm_gem_huge_mnt_create(struct drm_device *dev,
502+ const char *value)
503+{
504+ return 0;
505+}
506+#endif
507+
508+/**
509+ * drm_gem_get_huge_mnt - Get the huge tmpfs mountpoint used by a DRM device
510+ * @dev: DRM device
511+
512+ * This function gets the huge tmpfs mountpoint used by DRM device @dev. A huge
513+ * tmpfs mountpoint is used instead of `shm_mnt` after a successful call to
514+ * drm_gem_huge_mnt_create() when CONFIG_TRANSPARENT_HUGEPAGE is enabled.
515+
516+ * Returns:
517+ * The huge tmpfs mountpoint in use, NULL otherwise.
518+ */
519+static inline struct vfsmount *drm_gem_get_huge_mnt(struct drm_device *dev)
520+{
521+#ifdef CONFIG_TRANSPARENT_HUGEPAGE
522+ return dev->huge_mnt;
523+#else
524+ return NULL;
525+#endif
526+}
527+
494528 void drm_gem_object_release(struct drm_gem_object *obj);
495529 void drm_gem_object_free(struct kref *kref);
496530 int drm_gem_object_init(struct drm_device *dev,
497531 struct drm_gem_object *obj, size_t size);
498−int drm_gem_object_init_with_mnt(struct drm_device *dev,
499− struct drm_gem_object *obj, size_t size,
500− struct vfsmount *gemfs);
501532 void drm_gem_private_object_init(struct drm_device *dev,
502533 struct drm_gem_object *obj, size_t size);
503534 void drm_gem_private_object_fini(struct drm_gem_object *obj);
@@ -507,6 +538,14 @@ int drm_gem_mmap_obj(struct drm_gem_object *obj, unsigned long obj_size, · 3 unmodified lines
507538 struct vm_area_struct *vma);
508539 int drm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
509540
541+#ifdef CONFIG_MMU
542+unsigned long drm_gem_get_unmapped_area(struct file *filp, unsigned long uaddr,
543+ unsigned long len, unsigned long pgoff,
544+ unsigned long flags);
545+#else
546+#define drm_gem_get_unmapped_area NULL
547+#endif
548+
510549 /**
511550 * drm_gem_object_get - acquire a GEM buffer object reference
512551 * @obj: GEM buffer object
include/drm/drm_gem_shmem_helper.h+0−3
@@ -109,9 +109,6 @@ struct drm_gem_shmem_object { · 108 unmodified lines
109109
110110 int drm_gem_shmem_init(struct drm_device *dev, struct drm_gem_shmem_object *shmem, size_t size);
111111 struct drm_gem_shmem_object *drm_gem_shmem_create(struct drm_device *dev, size_t size);
112−struct drm_gem_shmem_object *drm_gem_shmem_create_with_mnt(struct drm_device *dev,
113− size_t size,
114− struct vfsmount *gemfs);
115112 void drm_gem_shmem_release(struct drm_gem_shmem_object *shmem);
116113 void drm_gem_shmem_free(struct drm_gem_shmem_object *shmem);
117114
include/drm/drm_modeset_helper_vtables.h+0−23
@@ -52,11 +52,6 @@ struct drm_scanout_buffer; · 51 unmodified lines
5252 struct drm_writeback_connector;
5353 struct drm_writeback_job;
5454
55−enum mode_set_atomic {
56− LEAVE_ATOMIC_MODE_SET,
57− ENTER_ATOMIC_MODE_SET,
58−};
59−
6055 /**
6156 * struct drm_crtc_helper_funcs - helper operations for CRTCs
6257 *
@@ -253,24 +248,6 @@ struct drm_crtc_helper_funcs { · 190 unmodified lines
253248 int (*mode_set_base)(struct drm_crtc *crtc, int x, int y,
254249 struct drm_framebuffer *old_fb);
255250
256− /**
257− * @mode_set_base_atomic:
258− *
259− * This callback is used by the fbdev helpers to set a new framebuffer
260− * and scanout without sleeping, i.e. from an atomic calling context. It
261− * is only used to implement kgdb support.
262− *
263− * This callback is optional and only needed for kgdb support in the fbdev
264− * helpers.
265− *
266− * RETURNS:
267− *
268− * 0 on success or a negative error code on failure.
269− */
270− int (*mode_set_base_atomic)(struct drm_crtc *crtc,
271− struct drm_framebuffer *fb, int x, int y,
272− enum mode_set_atomic);
273−
274251 /**
275252 * @disable:
276253 *
include/drm/drm_vblank.h+1−2
@@ -302,8 +302,7 @@ bool drm_handle_vblank(struct drm_device *dev, unsigned int pipe); · 301 unmodified lines
302302 bool drm_crtc_handle_vblank(struct drm_crtc *crtc);
303303 int drm_crtc_vblank_get(struct drm_crtc *crtc);
304304 void drm_crtc_vblank_put(struct drm_crtc *crtc);
305−void drm_wait_one_vblank(struct drm_device *dev, unsigned int pipe);
306−void drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
305+int drm_crtc_wait_one_vblank(struct drm_crtc *crtc);
307306 void drm_crtc_vblank_off(struct drm_crtc *crtc);
308307 void drm_crtc_vblank_reset(struct drm_crtc *crtc);
309308 void drm_crtc_vblank_on_config(struct drm_crtc *crtc,
include/linux/dma-fence.h+28−7
@@ -364,11 +364,12 @@ static inline void dma_fence_end_signalling(bool cookie) {} · 363 unmodified lines
364364 static inline void __dma_fence_might_wait(void) {}
365365 #endif
366366
367−int dma_fence_signal(struct dma_fence *fence);
368−int dma_fence_signal_locked(struct dma_fence *fence);
369−int dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp);
370−int dma_fence_signal_timestamp_locked(struct dma_fence *fence,
371− ktime_t timestamp);
367+void dma_fence_signal(struct dma_fence *fence);
368+bool dma_fence_check_and_signal(struct dma_fence *fence);
369+bool dma_fence_check_and_signal_locked(struct dma_fence *fence);
370+void dma_fence_signal_locked(struct dma_fence *fence);
371+void dma_fence_signal_timestamp(struct dma_fence *fence, ktime_t timestamp);
372+void dma_fence_signal_timestamp_locked(struct dma_fence *fence, ktime_t timestamp);
372373 signed long dma_fence_default_wait(struct dma_fence *fence,
373374 bool intr, signed long timeout);
374375 int dma_fence_add_callback(struct dma_fence *fence,
@@ -401,6 +402,26 @@ void dma_fence_enable_sw_signaling(struct dma_fence *fence); · 26 unmodified lines
401402 const char __rcu *dma_fence_driver_name(struct dma_fence *fence);
402403 const char __rcu *dma_fence_timeline_name(struct dma_fence *fence);
403404
405+/*
406+ * dma_fence_test_signaled_flag - Only check whether a fence is signaled yet.
407+ * @fence: the fence to check
408+ *
409+ * This function just checks whether @fence is signaled, without interacting
410+ * with the fence in any way. The user must, therefore, ensure through other
411+ * means that fences get signaled eventually.
412+ *
413+ * This function uses test_bit(), which is thread-safe. Naturally, this function
414+ * should be used opportunistically; a fence could get signaled at any moment
415+ * after the check is done.
416+ *
417+ * Return: true if signaled, false otherwise.
418+ */
419+static inline bool
420+dma_fence_test_signaled_flag(struct dma_fence *fence)
421+{
422+ return test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags);
423+}
424+
404425 /**
405426 * dma_fence_is_signaled_locked - Return an indication if the fence
406427 * is signaled yet.
@@ -418,7 +439,7 @@ const char __rcu *dma_fence_timeline_name(struct dma_fence *fence); · 11 unmodified lines
418439 static inline bool
419440 dma_fence_is_signaled_locked(struct dma_fence *fence)
420441 {
421− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
442+ if (dma_fence_test_signaled_flag(fence))
422443 return true;
423444
424445 if (fence->ops->signaled && fence->ops->signaled(fence)) {
@@ -448,7 +469,7 @@ dma_fence_is_signaled_locked(struct dma_fence *fence) · 23 unmodified lines
448469 static inline bool
449470 dma_fence_is_signaled(struct dma_fence *fence)
450471 {
451− if (test_bit(DMA_FENCE_FLAG_SIGNALED_BIT, &fence->flags))
472+ if (dma_fence_test_signaled_flag(fence))
452473 return true;
453474
454475 if (fence->ops->signaled && fence->ops->signaled(fence)) {
include/linux/fb.h+0−4
@@ -304,10 +304,6 @@ struct fb_ops { · 303 unmodified lines
304304
305305 /* teardown any resources to do with this framebuffer */
306306 void (*fb_destroy)(struct fb_info *info);
307−
308− /* called at KDB enter and leave time to prepare the console */
309− int (*fb_debug_enter)(struct fb_info *info);
310− int (*fb_debug_leave)(struct fb_info *info);
311307 };
312308
313309 #ifdef CONFIG_FB_TILEBLITTING
include/uapi/drm/panfrost_drm.h+75−1
@@ -24,6 +24,8 @@ extern "C" { · 23 unmodified lines
2424 #define DRM_PANFROST_SET_LABEL_BO 0x09
2525 #define DRM_PANFROST_JM_CTX_CREATE 0x0a
2626 #define DRM_PANFROST_JM_CTX_DESTROY 0x0b
27+#define DRM_PANFROST_SYNC_BO 0x0c
28+#define DRM_PANFROST_QUERY_BO_INFO 0x0d
2729
2830 #define DRM_IOCTL_PANFROST_SUBMIT DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_SUBMIT, struct drm_panfrost_submit)
2931 #define DRM_IOCTL_PANFROST_WAIT_BO DRM_IOW(DRM_COMMAND_BASE + DRM_PANFROST_WAIT_BO, struct drm_panfrost_wait_bo)
@@ -35,6 +37,8 @@ extern "C" { · 5 unmodified lines
3537 #define DRM_IOCTL_PANFROST_SET_LABEL_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_SET_LABEL_BO, struct drm_panfrost_set_label_bo)
3638 #define DRM_IOCTL_PANFROST_JM_CTX_CREATE DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_JM_CTX_CREATE, struct drm_panfrost_jm_ctx_create)
3739 #define DRM_IOCTL_PANFROST_JM_CTX_DESTROY DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_JM_CTX_DESTROY, struct drm_panfrost_jm_ctx_destroy)
40+#define DRM_IOCTL_PANFROST_SYNC_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_SYNC_BO, struct drm_panfrost_sync_bo)
41+#define DRM_IOCTL_PANFROST_QUERY_BO_INFO DRM_IOWR(DRM_COMMAND_BASE + DRM_PANFROST_QUERY_BO_INFO, struct drm_panfrost_query_bo_info)
3842
3943 /*
4044 * Unstable ioctl(s): only exposed when the unsafe unstable_ioctls module
@@ -120,9 +124,12 @@ struct drm_panfrost_wait_bo { · 79 unmodified lines
120124 __s64 timeout_ns;
121125 };
122126
123−/* Valid flags to pass to drm_panfrost_create_bo */
127+/* Valid flags to pass to drm_panfrost_create_bo.
128+ * PANFROST_BO_WB_MMAP can't be set if PANFROST_BO_HEAP is.
129+ */
124130 #define PANFROST_BO_NOEXEC 1
125131 #define PANFROST_BO_HEAP 2
132+#define PANFROST_BO_WB_MMAP 4
126133
127134 /**
128135 * struct drm_panfrost_create_bo - ioctl argument for creating Panfrost BOs.
@@ -228,6 +235,13 @@ enum drm_panfrost_param { · 99 unmodified lines
228235 DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP,
229236 DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP_FREQUENCY,
230237 DRM_PANFROST_PARAM_ALLOWED_JM_CTX_PRIORITIES,
238+ DRM_PANFROST_PARAM_SELECTED_COHERENCY,
239+};
240+
241+enum drm_panfrost_gpu_coherency {
242+ DRM_PANFROST_GPU_COHERENCY_ACE_LITE = 0,
243+ DRM_PANFROST_GPU_COHERENCY_ACE = 1,
244+ DRM_PANFROST_GPU_COHERENCY_NONE = 31,
231245 };
232246
233247 struct drm_panfrost_get_param {
@@ -301,6 +315,66 @@ struct drm_panfrost_set_label_bo { · 67 unmodified lines
301315 __u64 label;
302316 };
303317
318+/* Valid flags to pass to drm_panfrost_bo_sync_op */
319+#define PANFROST_BO_SYNC_CPU_CACHE_FLUSH 0
320+#define PANFROST_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE 1
321+
322+/**
323+ * struct drm_panthor_bo_flush_map_op - BO map sync op
324+ */
325+struct drm_panfrost_bo_sync_op {
326+ /** @handle: Handle of the buffer object to sync. */
327+ __u32 handle;
328+
329+ /** @type: Type of sync operation. */
330+ __u32 type;
331+
332+ /**
333+ * @offset: Offset into the BO at which the sync range starts.
334+ *
335+ * This will be rounded down to the nearest cache line as needed.
336+ */
337+ __u32 offset;
338+
339+ /**
340+ * @size: Size of the range to sync
341+ *
342+ * @size + @offset will be rounded up to the nearest cache line as
343+ * needed.
344+ */
345+ __u32 size;
346+};
347+
348+/**
349+ * struct drm_panfrost_sync_bo - ioctl argument for syncing BO maps
350+ */
351+struct drm_panfrost_sync_bo {
352+ /** Array of struct drm_panfrost_bo_sync_op */
353+ __u64 ops;
354+
355+ /** Number of BO sync ops */
356+ __u32 op_count;
357+
358+ __u32 pad;
359+};
360+
361+/** BO comes from a different subsystem. */
362+#define DRM_PANFROST_BO_IS_IMPORTED (1 << 0)
363+
364+struct drm_panfrost_query_bo_info {
365+ /** Handle of the object being queried. */
366+ __u32 handle;
367+
368+ /** Extra flags that are not coming from the BO_CREATE ioctl(). */
369+ __u32 extra_flags;
370+
371+ /** Flags passed at creation time. */
372+ __u32 create_flags;
373+
374+ /** Will be zero on return. */
375+ __u32 pad;
376+};
377+
304378 /* Definitions for coredump decoding in user space */
305379 #define PANFROSTDUMP_MAJOR 1
306380 #define PANFROSTDUMP_MINOR 0
include/uapi/drm/panthor_drm.h+154−3
@@ -144,6 +144,16 @@ enum drm_panthor_ioctl_id { · 143 unmodified lines
144144 * pgoff_t size.
145145 */
146146 DRM_PANTHOR_SET_USER_MMIO_OFFSET,
147+
148+ /** @DRM_PANTHOR_BO_SYNC: Sync BO data to/from the device */
149+ DRM_PANTHOR_BO_SYNC,
150+
151+ /**
152+ * @DRM_PANTHOR_BO_QUERY_INFO: Query information about a BO.
153+ *
154+ * This is useful for imported BOs.
155+ */
156+ DRM_PANTHOR_BO_QUERY_INFO,
147157 };
148158
149159 /**
@@ -245,6 +255,26 @@ enum drm_panthor_dev_query_type { · 95 unmodified lines
245255 DRM_PANTHOR_DEV_QUERY_GROUP_PRIORITIES_INFO,
246256 };
247257
258+/**
259+ * enum drm_panthor_gpu_coherency: Type of GPU coherency
260+ */
261+enum drm_panthor_gpu_coherency {
262+ /**
263+ * @DRM_PANTHOR_GPU_COHERENCY_ACE_LITE: ACE Lite coherency.
264+ */
265+ DRM_PANTHOR_GPU_COHERENCY_ACE_LITE = 0,
266+
267+ /**
268+ * @DRM_PANTHOR_GPU_COHERENCY_ACE: ACE coherency.
269+ */
270+ DRM_PANTHOR_GPU_COHERENCY_ACE = 1,
271+
272+ /**
273+ * @DRM_PANTHOR_GPU_COHERENCY_NONE: No coherency.
274+ */
275+ DRM_PANTHOR_GPU_COHERENCY_NONE = 31,
276+};
277+
248278 /**
249279 * struct drm_panthor_gpu_info - GPU information
250280 *
@@ -301,7 +331,16 @@ struct drm_panthor_gpu_info { · 50 unmodified lines
301331 */
302332 __u32 thread_max_barrier_size;
303333
304− /** @coherency_features: Coherency features. */
334+ /**
335+ * @coherency_features: Coherency features.
336+ *
337+ * Combination of drm_panthor_gpu_coherency flags.
338+ *
339+ * Note that this is just what the coherency protocols supported by the
340+ * GPU, but the actual coherency in place depends on the SoC
341+ * integration and is reflected by
342+ * drm_panthor_gpu_info::selected_coherency.
343+ */
305344 __u32 coherency_features;
306345
307346 /** @texture_features: Texture features. */
@@ -310,8 +349,12 @@ struct drm_panthor_gpu_info { · 2 unmodified lines
310349 /** @as_present: Bitmask encoding the number of address-space exposed by the MMU. */
311350 __u32 as_present;
312351
313− /** @pad0: MBZ. */
314− __u32 pad0;
352+ /**
353+ * @select_coherency: Coherency selected for this device.
354+ *
355+ * One of drm_panthor_gpu_coherency.
356+ */
357+ __u32 selected_coherency;
315358
316359 /** @shader_present: Bitmask encoding the shader cores exposed by the GPU. */
317360 __u64 shader_present;
@@ -638,6 +681,15 @@ struct drm_panthor_vm_get_state { · 320 unmodified lines
638681 enum drm_panthor_bo_flags {
639682 /** @DRM_PANTHOR_BO_NO_MMAP: The buffer object will never be CPU-mapped in userspace. */
640683 DRM_PANTHOR_BO_NO_MMAP = (1 << 0),
684+
685+ /**
686+ * @DRM_PANTHOR_BO_WB_MMAP: Force "Write-Back Cacheable" CPU mapping.
687+ *
688+ * CPU map the buffer object in userspace by forcing the "Write-Back
689+ * Cacheable" cacheability attribute. The mapping otherwise uses the
690+ * "Non-Cacheable" attribute if the GPU is not IO coherent.
691+ */
692+ DRM_PANTHOR_BO_WB_MMAP = (1 << 1),
641693 };
642694
643695 /**
@@ -1040,6 +1092,101 @@ struct drm_panthor_set_user_mmio_offset { · 396 unmodified lines
10401092 __u64 offset;
10411093 };
10421094
1095+/**
1096+ * enum drm_panthor_bo_sync_op_type - BO sync type
1097+ */
1098+enum drm_panthor_bo_sync_op_type {
1099+ /** @DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH: Flush CPU caches. */
1100+ DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH = 0,
1101+
1102+ /** @DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE: Flush and invalidate CPU caches. */
1103+ DRM_PANTHOR_BO_SYNC_CPU_CACHE_FLUSH_AND_INVALIDATE = 1,
1104+};
1105+
1106+/**
1107+ * struct drm_panthor_bo_sync_op - BO map sync op
1108+ */
1109+struct drm_panthor_bo_sync_op {
1110+ /** @handle: Handle of the buffer object to sync. */
1111+ __u32 handle;
1112+
1113+ /** @type: Type of operation. */
1114+ __u32 type;
1115+
1116+ /**
1117+ * @offset: Offset into the BO at which the sync range starts.
1118+ *
1119+ * This will be rounded down to the nearest cache line as needed.
1120+ */
1121+ __u64 offset;
1122+
1123+ /**
1124+ * @size: Size of the range to sync
1125+ *
1126+ * @size + @offset will be rounded up to the nearest cache line as
1127+ * needed.
1128+ */
1129+ __u64 size;
1130+};
1131+
1132+/**
1133+ * struct drm_panthor_bo_sync - BO map sync request
1134+ */
1135+struct drm_panthor_bo_sync {
1136+ /**
1137+ * @ops: Array of struct drm_panthor_bo_sync_op sync operations.
1138+ */
1139+ struct drm_panthor_obj_array ops;
1140+};
1141+
1142+/**
1143+ * enum drm_panthor_bo_extra_flags - Set of flags returned on a BO_QUERY_INFO request
1144+ *
1145+ * Those are flags reflecting BO properties that are not directly coming from the flags
1146+ * passed are creation time, or information on BOs that were imported from other drivers.
1147+ */
1148+enum drm_panthor_bo_extra_flags {
1149+ /**
1150+ * @DRM_PANTHOR_BO_IS_IMPORTED: BO has been imported from an external driver.
1151+ *
1152+ * Note that imported dma-buf handles are not flagged as imported if they
1153+ * where exported by panthor. Only buffers that are coming from other drivers
1154+ * (dma heaps, other GPUs, display controllers, V4L, ...).
1155+ *
1156+ * It's also important to note that all imported BOs are mapped cached and can't
1157+ * be considered IO-coherent even if the GPU is. This means they require explicit
1158+ * syncs that must go through the DRM_PANTHOR_BO_SYNC ioctl (userland cache
1159+ * maintenance is not allowed in that case, because extra operations might be
1160+ * needed to make changes visible to the CPU/device, like buffer migration when the
1161+ * exporter is a GPU with its own VRAM).
1162+ */
1163+ DRM_PANTHOR_BO_IS_IMPORTED = (1 << 0),
1164+};
1165+
1166+/**
1167+ * struct drm_panthor_bo_query_info - Query BO info
1168+ */
1169+struct drm_panthor_bo_query_info {
1170+ /** @handle: Handle of the buffer object to query flags on. */
1171+ __u32 handle;
1172+
1173+ /**
1174+ * @extra_flags: Combination of enum drm_panthor_bo_extra_flags flags.
1175+ */
1176+ __u32 extra_flags;
1177+
1178+ /**
1179+ * @create_flags: Flags passed at creation time.
1180+ *
1181+ * Combination of enum drm_panthor_bo_flags flags.
1182+ * Will be zero if the buffer comes from a different driver.
1183+ */
1184+ __u32 create_flags;
1185+
1186+ /** @pad: Will be zero on return. */
1187+ __u32 pad;
1188+};
1189+
10431190 /**
10441191 * DRM_IOCTL_PANTHOR() - Build a Panthor IOCTL number
10451192 * @__access: Access type. Must be R, W or RW.
@@ -1086,6 +1233,10 @@ enum { · 40 unmodified lines
10861233 DRM_IOCTL_PANTHOR(WR, BO_SET_LABEL, bo_set_label),
10871234 DRM_IOCTL_PANTHOR_SET_USER_MMIO_OFFSET =
10881235 DRM_IOCTL_PANTHOR(WR, SET_USER_MMIO_OFFSET, set_user_mmio_offset),
1236+ DRM_IOCTL_PANTHOR_BO_SYNC =
1237+ DRM_IOCTL_PANTHOR(WR, BO_SYNC, bo_sync),
1238+ DRM_IOCTL_PANTHOR_BO_QUERY_INFO =
1239+ DRM_IOCTL_PANTHOR(WR, BO_QUERY_INFO, bo_query_info),
10891240 };
10901241
10911242 #if defined(__cplusplus)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t