History

Merge tag 'drm-misc-next-2019-05-24' of git://anongit.freedesktop.org/drm/drm-misc into drm-next

drm-misc-next for v5.3, try #2: UAPI Changes: - Add HDR source metadata property. - Make drm.h compile on GNU/kFreeBSD by including stdint.h - Clarify how the userspace reviewer has to review new kernel UAPI. - Clarify that for using new UAPI, merging to drm-next or drm-misc-next should be enough. Cross-subsystem Changes: - video/hdmi: Add unpack function for DRM infoframes. - Device tree bindings: * Updating a property for Mali Midgard GPUs * Updating a property for STM32 DSI panel * Adding support for FriendlyELEC HD702E 800x1280 panel * Adding support for Evervision VGG804821 800x480 5.0" WVGA TFT panel * Adding support for the EDT ET035012DM6 3.5" 320x240 QVGA 24-bit RGB TFT. * Adding support for Three Five displays TFC S9700RTWV43TR-01B 800x480 panel with resistive touch found on TI's AM335X-EVM. * Adding support for EDT ETM0430G0DH6 480x272 panel. - Add OSD101T2587-53TS driver with DT bindings. - Add Samsung S6E63M0 panel driver with DT bindings. - Add VXT VL050-8048NT-C01 800x480 panel with DT bindings. - Dma-buf: - Make mmap callback actually optional. - Documentation updates. - Fix debugfs refcount inbalance. - Remove unused sync_dump function. - Fix device tree bindings in drm-misc-next after a botched merge. Core Changes: - Add support for HDR infoframes and related EDID parsing. - Remove prime sg_table caching, now done inside dma-buf. - Add shiny new drm_gem_vram helpers for simple VRAM drivers; with some fixes to the new API on top. - Small fix to job cleanup without timeout handler. - Documentation fixes to drm_fourcc. - Replace lookups of drm_format with struct drm_format_info; remove functions that become obsolete by this conversion. - Remove double include in bridge/panel.c and some drivers. - Remove drmP.h include from drm/edid and drm/dp. - Fix null pointer deref in drm_fb_helper_hotplug_event(). - Remove most members from drm_fb_helper_crtc, only mode_set is kept. - Remove race of fb helpers with userspace; only restore mode when userspace is not master. - Move legacy setup from drm_file.c to drm_legacy_misc.c - Rework scheduler job destruction. - drm/bus was removed, remove from TODO. - Add __drm_atomic_helper_crtc_reset() to subclass crtc_state, and convert some drivers to use it (conversion is not complete yet). - Bump vblank timeout wait to 100 ms for atomic. - Docbook fix for drm_hdmi_infoframe_set_hdr_metadata. Driver Changes: - sun4i: Use DRM_GEM_CMA_VMAP_DRIVER_OPS instead of definining manually. - v3d: Small cleanups, adding support for compute shaders, reservation/synchronization fixes and job management refactoring, fixes MMU and debugfs. - lima: Fix null pointer in irq handler on startup, set default timeout for scheduled jobs. - stm/ltdc: Assorted fixes and adding FB modifier support. - amdgpu: Avoid hw reset if guilty job was already signaled. - virtio: Add seqno to fences, add trace events, use correct flags for fence allocation. - Convert AST, bochs, mgag200, vboxvideo, hisilicon to the new drm_gem_vram API. - sun6i_mipi_dsi: Support DSI GENERIC_SHORT_WRITE_2 transfers. - bochs: Small fix to use PTR_RET_OR_ZERO and driver unload. - gma500: header fixes - cirrus: Remove unused files. - mediatek: Fix compiler warning after merging the HDR series. - vc4: Rework binner bo handling. Signed-off-by: Dave Airlie <airlied@redhat.com>

Dave Airlie committed 7 years ago

Commit 88cd7a22 parents cd6c84d 909fa33220 files · +5943 −4593Browse files

Unified · Split

220 files
  1. Documentation/devicetree/bindings/display/panel/edt,et-series.txt +16 −0
  2. Documentation/devicetree/bindings/display/panel/evervision,vgg804821.txt +12 −0
  3. Documentation/devicetree/bindings/display/panel/friendlyarm,hd702e.txt +32 −0
  4. Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2045-53ts.txt +11 −0
  5. Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt +14 −0
  6. Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt +33 −0
  7. Documentation/devicetree/bindings/display/panel/tfc,s9700rtwv43tr-01b.txt +15 −0
  8. Documentation/devicetree/bindings/display/panel/vl050_8048nt_c01.txt +12 −0
  9. Documentation/devicetree/bindings/display/st,stm32-ltdc.txt +3 −0
  10. Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt +18 −1
  11. Documentation/devicetree/bindings/vendor-prefixes.yaml +6 −0
  12. Documentation/gpu/drm-mm.rst +33 −1
  13. Documentation/gpu/drm-uapi.rst +6 −4
  14. Documentation/gpu/todo.rst +8 −19
  15. MAINTAINERS +1 −1
  16. drivers/dma-buf/dma-buf.c +35 −4
  17. drivers/dma-buf/sync_debug.c +0 −26
  18. drivers/dma-buf/sync_debug.h +0 −1
  19. drivers/gpu/drm/Kconfig +7 −0
  20. drivers/gpu/drm/Makefile +5 −0
  21. drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +95 −51
  22. drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c +3 −1
  23. drivers/gpu/drm/arm/malidp_crtc.c +11 −17
  24. drivers/gpu/drm/arm/malidp_hw.c +2 −1
  25. drivers/gpu/drm/arm/malidp_mw.c +1 −1
  26. drivers/gpu/drm/arm/malidp_planes.c +3 −5
  27. drivers/gpu/drm/armada/armada_fb.c +2 −1
  28. drivers/gpu/drm/ast/Kconfig +1 −2
  29. drivers/gpu/drm/ast/ast_drv.c +2 −11
  30. drivers/gpu/drm/ast/ast_drv.h +3 −68
  31. drivers/gpu/drm/ast/ast_fb.c +24 −17
  32. drivers/gpu/drm/ast/ast_main.c +5 −72
  33. drivers/gpu/drm/ast/ast_mode.c +77 −55
  34. drivers/gpu/drm/ast/ast_ttm.c +8 −294
  35. drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c +2 −7
  36. drivers/gpu/drm/bochs/Kconfig +1 −1
  37. drivers/gpu/drm/bochs/bochs.h +2 −52
  38. drivers/gpu/drm/bochs/bochs_drv.c +5 −19
  39. drivers/gpu/drm/bochs/bochs_kms.c +9 −9
  40. drivers/gpu/drm/bochs/bochs_mm.c +7 −420
  41. drivers/gpu/drm/bridge/panel.c +1 −2
  42. drivers/gpu/drm/cirrus/cirrus_drv.h +0 −250
  43. drivers/gpu/drm/cirrus/cirrus_ttm.c +0 −337
  44. drivers/gpu/drm/drm_atomic_helper.c +1 −1
  45. drivers/gpu/drm/drm_atomic_state_helper.c +34 −7
  46. drivers/gpu/drm/drm_atomic_uapi.c +12 −0
  47. drivers/gpu/drm/drm_auth.c +20 −0
  48. drivers/gpu/drm/drm_client.c +2 −1
  49. drivers/gpu/drm/drm_connector.c +6 −0
  50. drivers/gpu/drm/drm_dp_aux_dev.c +5 −3
  51. drivers/gpu/drm/drm_dp_dual_mode_helper.c +3 −1
  52. drivers/gpu/drm/drm_dp_helper.c +7 −5
  53. drivers/gpu/drm/drm_dp_mst_topology.c +7 −6
  54. drivers/gpu/drm/drm_edid.c +131 −4
  55. drivers/gpu/drm/drm_edid_load.c +5 −2
  56. drivers/gpu/drm/drm_fb_helper.c +125 −121
  57. drivers/gpu/drm/drm_file.c +50 −72
  58. drivers/gpu/drm/drm_format_helper.c +2 −2
  59. drivers/gpu/drm/drm_fourcc.c +0 −118
  60. drivers/gpu/drm/drm_gem_vram_helper.c +772 −0
  61. drivers/gpu/drm/drm_internal.h +2 −0
  62. drivers/gpu/drm/drm_legacy.h +2 −0
  63. drivers/gpu/drm/drm_legacy_misc.c +20 −0
  64. drivers/gpu/drm/drm_prime.c +17 −60
  65. drivers/gpu/drm/drm_vram_helper_common.c +96 −0
  66. drivers/gpu/drm/drm_vram_mm_helper.c +295 −0
  67. drivers/gpu/drm/etnaviv/etnaviv_dump.c +0 −5
  68. drivers/gpu/drm/etnaviv/etnaviv_sched.c +1 −1
  69. drivers/gpu/drm/gma500/accel_2d.c +9 −9
  70. drivers/gpu/drm/gma500/blitter.h +2 −0
  71. drivers/gpu/drm/gma500/cdv_device.c +7 −6
  72. drivers/gpu/drm/gma500/cdv_device.h +4 −0
  73. drivers/gpu/drm/gma500/cdv_intel_crt.c +4 −4
  74. drivers/gpu/drm/gma500/cdv_intel_display.c +6 −4
  75. drivers/gpu/drm/gma500/cdv_intel_dp.c +5 −4
  76. drivers/gpu/drm/gma500/cdv_intel_hdmi.c +5 −4
  77. drivers/gpu/drm/gma500/cdv_intel_lvds.c +4 −5
  78. drivers/gpu/drm/gma500/framebuffer.c +13 −13
  79. drivers/gpu/drm/gma500/framebuffer.h +0 −1
  80. drivers/gpu/drm/gma500/gem.c +3 −2
  81. drivers/gpu/drm/gma500/gma_device.c +0 −1
  82. drivers/gpu/drm/gma500/gma_device.h +1 −0
  83. drivers/gpu/drm/gma500/gma_display.c +9 −3
  84. drivers/gpu/drm/gma500/gma_display.h +3 −0
  85. drivers/gpu/drm/gma500/gtt.c +3 −2
  86. drivers/gpu/drm/gma500/gtt.h +0 −1
  87. drivers/gpu/drm/gma500/intel_bios.c +3 −3
  88. drivers/gpu/drm/gma500/intel_bios.h +1 −2
  89. drivers/gpu/drm/gma500/intel_gmbus.c +6 −5
  90. drivers/gpu/drm/gma500/intel_i2c.c +3 −1
  91. drivers/gpu/drm/gma500/mdfld_device.c +9 −7
  92. drivers/gpu/drm/gma500/mdfld_dsi_dpi.c +3 −1
  93. drivers/gpu/drm/gma500/mdfld_dsi_output.c +7 −5
  94. drivers/gpu/drm/gma500/mdfld_dsi_output.h +4 −4
  95. drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c +3 −1
  96. drivers/gpu/drm/gma500/mdfld_intel_display.c +7 −4
  97. drivers/gpu/drm/gma500/mdfld_tmd_vid.c +2 −0
  98. drivers/gpu/drm/gma500/mid_bios.c +2 −3
  99. drivers/gpu/drm/gma500/mid_bios.h +1 −0
  100. drivers/gpu/drm/gma500/mmu.c +4 −2
  101. drivers/gpu/drm/gma500/oaktrail.h +2 −0
  102. drivers/gpu/drm/gma500/oaktrail_crtc.c +5 −3
  103. drivers/gpu/drm/gma500/oaktrail_device.c +11 −9
  104. drivers/gpu/drm/gma500/oaktrail_hdmi.c +5 −3
  105. drivers/gpu/drm/gma500/oaktrail_lvds.c +3 −3
  106. drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c +5 −6
  107. drivers/gpu/drm/gma500/power.h +3 −1
  108. drivers/gpu/drm/gma500/psb_device.c +6 −6
  109. drivers/gpu/drm/gma500/psb_drv.c +21 −12
  110. drivers/gpu/drm/gma500/psb_drv.h +8 −8
  111. drivers/gpu/drm/gma500/psb_intel_display.c +4 −3
  112. drivers/gpu/drm/gma500/psb_intel_lvds.c +2 −3
  113. drivers/gpu/drm/gma500/psb_intel_modes.c +1 −1
  114. drivers/gpu/drm/gma500/psb_intel_sdvo.c +8 −7
  115. drivers/gpu/drm/gma500/psb_irq.c +5 −4
  116. drivers/gpu/drm/gma500/psb_irq.h +1 −1
  117. drivers/gpu/drm/gma500/psb_lid.c +3 −3
  118. drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c +8 −5
  119. drivers/gpu/drm/hisilicon/hibmc/Kconfig +1 −1
  120. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c +9 −10
  121. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +4 −10
  122. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +2 −31
  123. drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c +12 −25
  124. drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c +16 −325
  125. drivers/gpu/drm/i915/intel_display.c +2 −3
  126. drivers/gpu/drm/i915/intel_sprite.c +2 −1
  127. drivers/gpu/drm/imx/ipuv3-plane.c +6 −9
  128. drivers/gpu/drm/lima/lima_drv.c +1 −1
  129. drivers/gpu/drm/lima/lima_pp.c +7 −1
  130. drivers/gpu/drm/lima/lima_sched.c +5 −8
  131. drivers/gpu/drm/mediatek/mtk_drm_fb.c +5 −3
  132. drivers/gpu/drm/mediatek/mtk_hdmi.c +3 −0
  133. drivers/gpu/drm/meson/meson_overlay.c +7 −7
  134. drivers/gpu/drm/mgag200/Kconfig +1 −1
  135. drivers/gpu/drm/mgag200/mgag200_cursor.c +53 −43
  136. drivers/gpu/drm/mgag200/mgag200_drv.c +2 −11
  137. drivers/gpu/drm/mgag200/mgag200_drv.h +10 −64
  138. drivers/gpu/drm/mgag200/mgag200_fb.c +24 −17
  139. drivers/gpu/drm/mgag200/mgag200_main.c +12 −75
  140. drivers/gpu/drm/mgag200/mgag200_mode.c +30 −29
  141. drivers/gpu/drm/mgag200/mgag200_ttm.c +8 −293
  142. drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c +2 −4
  143. drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c +6 −3
  144. drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +2 −7
  145. drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c +13 −18
  146. drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c +10 −14
  147. drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c +4 −3
  148. drivers/gpu/drm/msm/msm_fb.c +9 −9
  149. drivers/gpu/drm/nouveau/dispnv50/head.c +3 −10
  150. drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.c +0 −2
  151. drivers/gpu/drm/omapdrm/omap_fb.c +4 −2
  152. drivers/gpu/drm/panel/Kconfig +18 −0
  153. drivers/gpu/drm/panel/Makefile +2 −0
  154. drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c +254 −0
  155. drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c +0 −1
  156. drivers/gpu/drm/panel/panel-samsung-s6e63m0.c +514 −0
  157. drivers/gpu/drm/panel/panel-simple.c +211 −1
  158. drivers/gpu/drm/panfrost/panfrost_device.c +22 −0
  159. drivers/gpu/drm/panfrost/panfrost_device.h +1 −0
  160. drivers/gpu/drm/panfrost/panfrost_job.c +1 −1
  161. drivers/gpu/drm/radeon/radeon_fb.c +3 −1
  162. drivers/gpu/drm/rockchip/rockchip_drm_fb.c +6 −11
  163. drivers/gpu/drm/rockchip/rockchip_drm_vop.c +17 −22
  164. drivers/gpu/drm/scheduler/sched_main.c +108 −66
  165. drivers/gpu/drm/stm/dw_mipi_dsi-stm.c +49 −11
  166. drivers/gpu/drm/stm/ltdc.c +47 −20
  167. drivers/gpu/drm/sun4i/sun4i_drv.c +1 −15
  168. drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c +1 −0
  169. drivers/gpu/drm/tegra/dc.c +6 −11
  170. drivers/gpu/drm/tegra/fb.c +6 −8
  171. drivers/gpu/drm/v3d/v3d_debugfs.c +32 −3
  172. drivers/gpu/drm/v3d/v3d_drv.c +13 −4
  173. drivers/gpu/drm/v3d/v3d_drv.h +66 −40
  174. drivers/gpu/drm/v3d/v3d_fence.c +2 −0
  175. drivers/gpu/drm/v3d/v3d_gem.c +355 −197
  176. drivers/gpu/drm/v3d/v3d_irq.c +44 −11
  177. drivers/gpu/drm/v3d/v3d_mmu.c +5 −2
  178. drivers/gpu/drm/v3d/v3d_regs.h +121 −1
  179. drivers/gpu/drm/v3d/v3d_sched.c +250 −132
  180. drivers/gpu/drm/v3d/v3d_trace.h +94 −0
  181. drivers/gpu/drm/vboxvideo/Kconfig +1 −1
  182. drivers/gpu/drm/vboxvideo/vbox_drv.c +2 −10
  183. drivers/gpu/drm/vboxvideo/vbox_drv.h +2 −73
  184. drivers/gpu/drm/vboxvideo/vbox_fb.c +11 −11
  185. drivers/gpu/drm/vboxvideo/vbox_main.c +6 −69
  186. drivers/gpu/drm/vboxvideo/vbox_mode.c +19 −17
  187. drivers/gpu/drm/vboxvideo/vbox_ttm.c +8 −347
  188. drivers/gpu/drm/vc4/vc4_bo.c +30 −1
  189. drivers/gpu/drm/vc4/vc4_drv.c +6 −0
  190. drivers/gpu/drm/vc4/vc4_drv.h +14 −0
  191. drivers/gpu/drm/vc4/vc4_gem.c +11 −0
  192. drivers/gpu/drm/vc4/vc4_irq.c +16 −4
  193. drivers/gpu/drm/vc4/vc4_plane.c +5 −10
  194. drivers/gpu/drm/vc4/vc4_v3d.c +55 −17
  195. drivers/gpu/drm/virtio/Makefile +1 −1
  196. drivers/gpu/drm/virtio/virtgpu_drv.h +1 −2
  197. drivers/gpu/drm/virtio/virtgpu_fence.c +15 −10
  198. drivers/gpu/drm/virtio/virtgpu_ioctl.c +9 −9
  199. drivers/gpu/drm/virtio/virtgpu_trace.h +52 −0
  200. drivers/gpu/drm/virtio/virtgpu_trace_points.c +5 −0
  201. drivers/gpu/drm/virtio/virtgpu_vq.c +10 −0
  202. drivers/gpu/drm/vkms/vkms_crtc.c +13 −20
  203. drivers/gpu/drm/zte/zx_plane.c +2 −4
  204. drivers/video/hdmi.c +257 −0
  205. include/drm/drm_atomic_state_helper.h +2 −0
  206. include/drm/drm_connector.h +14 −0
  207. include/drm/drm_device.h +4 −0
  208. include/drm/drm_edid.h +5 −0
  209. include/drm/drm_fb_helper.h +0 −10
  210. include/drm/drm_fourcc.h +44 −6
  211. include/drm/drm_gem_vram_helper.h +162 −0
  212. include/drm/drm_mode_config.h +7 −0
  213. include/drm/drm_vram_mm_helper.h +102 −0
  214. include/drm/gma_drm.h +0 −25
  215. include/drm/gpu_scheduler.h +3 −5
  216. include/linux/dma-buf.h +38 −9
  217. include/linux/hdmi.h +55 −0
  218. include/uapi/drm/drm.h +1 −0
  219. include/uapi/drm/drm_mode.h +23 −0
  220. include/uapi/drm/v3d_drm.h +28 −0
Documentation/devicetree/bindings/display/panel/edt,et-series.txt+16−0
@@ -6,6 +6,22 @@ Display bindings for EDT Display Technology Corp. Displays which are · 5 unmodified lines
66 compatible with the simple-panel binding, which is specified in
77 simple-panel.txt
88
9+3,5" QVGA TFT Panels
10+--------------------
11++-----------------+---------------------+-------------------------------------+
12+| Identifier | compatbile | description |
13++=================+=====================+=====================================+
14+| ET035012DM6 | edt,et035012dm6 | 3.5" QVGA TFT LCD panel |
15++-----------------+---------------------+-------------------------------------+
16+
17+4,3" WVGA TFT Panels
18+--------------------
19+
20++-----------------+---------------------+-------------------------------------+
21+| Identifier | compatbile | description |
22++=================+=====================+=====================================+
23+| ETM0430G0DH6 | edt,etm0430g0dh6 | 480x272 TFT Display |
24++-----------------+---------------------+-------------------------------------+
925
1026 5,7" WVGA TFT Panels
1127 --------------------
Documentation/devicetree/bindings/display/panel/evervision,vgg804821.txt+12−0
@@ -0,0 +1,12 @@
1+Evervision Electronics Co. Ltd. VGG804821 5.0" WVGA TFT LCD Panel
2+
3+Required properties:
4+- compatible: should be "evervision,vgg804821"
5+- power-supply: See simple-panel.txt
6+
7+Optional properties:
8+- backlight: See simple-panel.txt
9+- enable-gpios: See simple-panel.txt
10+
11+This binding is compatible with the simple-panel binding, which is specified
12+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/panel/friendlyarm,hd702e.txt+32−0
@@ -0,0 +1,32 @@
1+FriendlyELEC HD702E 800x1280 LCD panel
2+
3+HD702E lcd is FriendlyELEC developed eDP LCD panel with 800x1280
4+resolution. It has built in Goodix, GT9271 captive touchscreen
5+with backlight adjustable via PWM.
6+
7+Required properties:
8+- compatible: should be "friendlyarm,hd702e"
9+- power-supply: regulator to provide the supply voltage
10+
11+Optional properties:
12+- backlight: phandle of the backlight device attached to the panel
13+
14+Optional nodes:
15+- Video port for LCD panel input.
16+
17+This binding is compatible with the simple-panel binding, which is specified
18+in simple-panel.txt in this directory.
19+
20+Example:
21+
22+ panel {
23+ compatible ="friendlyarm,hd702e", "simple-panel";
24+ backlight = <&backlight>;
25+ power-supply = <&vcc3v3_sys>;
26+
27+ port {
28+ panel_in_edp: endpoint {
29+ remote-endpoint = <&edp_out_panel>;
30+ };
31+ };
32+ };
Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2045-53ts.txt+11−0
@@ -0,0 +1,11 @@
1+One Stop Displays OSD101T2045-53TS 10.1" 1920x1200 panel
2+
3+Required properties:
4+- compatible: should be "osddisplays,osd101t2045-53ts"
5+- power-supply: as specified in the base binding
6+
7+Optional properties:
8+- backlight: as specified in the base binding
9+
10+This binding is compatible with the simple-panel binding, which is specified
11+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/panel/osddisplays,osd101t2587-53ts.txt+14−0
@@ -0,0 +1,14 @@
1+One Stop Displays OSD101T2587-53TS 10.1" 1920x1200 panel
2+
3+The panel is similar to OSD101T2045-53TS, but it needs additional
4+MIPI_DSI_TURN_ON_PERIPHERAL message from the host.
5+
6+Required properties:
7+- compatible: should be "osddisplays,osd101t2587-53ts"
8+- power-supply: as specified in the base binding
9+
10+Optional properties:
11+- backlight: as specified in the base binding
12+
13+This binding is compatible with the simple-panel binding, which is specified
14+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/panel/samsung,s6e63m0.txt+33−0
@@ -0,0 +1,33 @@
1+Samsung s6e63m0 AMOLED LCD panel
2+
3+Required properties:
4+ - compatible: "samsung,s6e63m0"
5+ - reset-gpios: GPIO spec for reset pin
6+ - vdd3-supply: VDD regulator
7+ - vci-supply: VCI regulator
8+
9+The panel must obey rules for SPI slave device specified in document [1].
10+
11+The device node can contain one 'port' child node with one child
12+'endpoint' node, according to the bindings defined in [2]. This
13+node should describe panel's video bus.
14+
15+[1]: Documentation/devicetree/bindings/spi/spi-bus.txt
16+[2]: Documentation/devicetree/bindings/media/video-interfaces.txt
17+
18+Example:
19+
20+ s6e63m0: display@0 {
21+ compatible = "samsung,s6e63m0";
22+ reg = <0>;
23+ reset-gpio = <&mp05 5 1>;
24+ vdd3-supply = <&ldo12_reg>;
25+ vci-supply = <&ldo11_reg>;
26+ spi-max-frequency = <1200000>;
27+
28+ port {
29+ lcd_ep: endpoint {
30+ remote-endpoint = <&fimd_ep>;
31+ };
32+ };
33+ };
Documentation/devicetree/bindings/display/panel/tfc,s9700rtwv43tr-01b.txt+15−0
@@ -0,0 +1,15 @@
1+TFC S9700RTWV43TR-01B 7" Three Five Corp 800x480 LCD panel with
2+resistive touch
3+
4+The panel is found on TI AM335x-evm.
5+
6+Required properties:
7+- compatible: should be "tfc,s9700rtwv43tr-01b"
8+- power-supply: See panel-common.txt
9+
10+Optional properties:
11+- enable-gpios: GPIO pin to enable or disable the panel, if there is one
12+- backlight: phandle of the backlight device attached to the panel
13+
14+This binding is compatible with the simple-panel binding, which is specified
15+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/panel/vl050_8048nt_c01.txt+12−0
@@ -0,0 +1,12 @@
1+VXT 800x480 color TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "vxt,vl050-8048nt-c01"
5+- power-supply: as specified in the base binding
6+
7+Optional properties:
8+- backlight: as specified in the base binding
9+- enable-gpios: as specified in the base binding
10+
11+This binding is compatible with the simple-panel binding, which is specified
12+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/display/st,stm32-ltdc.txt+3−0
@@ -40,6 +40,8 @@ Mandatory nodes specific to STM32 DSI: · 39 unmodified lines
4040 - panel or bridge node: A node containing the panel or bridge description as
4141 documented in [6].
4242 - port: panel or bridge port node, connected to the DSI output port (port@1).
43+Optional properties:
44+- phy-dsi-supply: phandle of the regulator that provides the supply voltage.
4345
4446 Note: You can find more documentation in the following references
4547 [1] Documentation/devicetree/bindings/clock/clock-bindings.txt
@@ -101,6 +103,7 @@ Example 2: DSI panel · 55 unmodified lines
101103 clock-names = "pclk", "ref";
102104 resets = <&rcc STM32F4_APB2_RESET(DSI)>;
103105 reset-names = "apb";
106+ phy-dsi-supply = <&reg18>;
104107
105108 ports {
106109 #address-cells = <1>;
Documentation/devicetree/bindings/gpu/arm,mali-midgard.txt+18−1
@@ -15,6 +15,7 @@ Required properties: · 14 unmodified lines
1515 + "arm,mali-t860"
1616 + "arm,mali-t880"
1717 * which must be preceded by one of the following vendor specifics:
18+ + "allwinner,sun50i-h6-mali"
1819 + "amlogic,meson-gxm-mali"
1920 + "rockchip,rk3288-mali"
2021 + "rockchip,rk3399-mali"
@@ -31,21 +32,36 @@ Optional properties: · 10 unmodified lines
3132
3233 - clocks : Phandle to clock for the Mali Midgard device.
3334
35+- clock-names : Specify the names of the clocks specified in clocks
36+ when multiple clocks are present.
37+ * core: clock driving the GPU itself (When only one clock is present,
38+ assume it's this clock.)
39+ * bus: bus clock for the GPU
40+
3441 - mali-supply : Phandle to regulator for the Mali device. Refer to
3542 Documentation/devicetree/bindings/regulator/regulator.txt for details.
3643
3744 - operating-points-v2 : Refer to Documentation/devicetree/bindings/opp/opp.txt
3845 for details.
3946
47+- #cooling-cells: Refer to Documentation/devicetree/bindings/thermal/thermal.txt
48+ for details.
49+
4050 - resets : Phandle of the GPU reset line.
4151
4252 Vendor-specific bindings
4353 ------------------------
4454
4555 The Mali GPU is integrated very differently from one SoC to
46−another. In order to accomodate those differences, you have the option
56+another. In order to accommodate those differences, you have the option
4757 to specify one more vendor-specific compatible, among:
4858
59+- "allwinner,sun50i-h6-mali"
60+ Required properties:
61+ - clocks : phandles to core and bus clocks
62+ - clock-names : must contain "core" and "bus"
63+ - resets: phandle to GPU reset line
64+
4965 - "amlogic,meson-gxm-mali"
5066 Required properties:
5167 - resets : Should contain phandles of :
@@ -65,6 +81,7 @@ gpu@ffa30000 { · 13 unmodified lines
6581 mali-supply = <&vdd_gpu>;
6682 operating-points-v2 = <&gpu_opp_table>;
6783 power-domains = <&power RK3288_PD_GPU>;
84+ #cooling-cells = <2>;
6885 };
6986
7087 gpu_opp_table: opp_table0 {
Documentation/devicetree/bindings/vendor-prefixes.yaml+6−0
@@ -287,6 +287,8 @@ patternProperties: · 286 unmodified lines
287287 description: Everest Semiconductor Co. Ltd.
288288 "^everspin,.*":
289289 description: Everspin Technologies, Inc.
290+ "^evervision,.*":
291+ description: Evervision Electronics Co. Ltd.
290292 "^exar,.*":
291293 description: Exar Corporation
292294 "^excito,.*":
@@ -849,6 +851,8 @@ patternProperties: · 556 unmodified lines
849851 description: Shenzhen Techstar Electronics Co., Ltd.
850852 "^terasic,.*":
851853 description: Terasic Inc.
854+ "^tfc,.*":
855+ description: Three Five Corp
852856 "^thine,.*":
853857 description: THine Electronics, Inc.
854858 "^ti,.*":
@@ -923,6 +927,8 @@ patternProperties: · 68 unmodified lines
923927 description: Voipac Technologies s.r.o.
924928 "^vot,.*":
925929 description: Vision Optical Technology Co., Ltd.
930+ "^vxt,.*":
931+ description: VXT Ltd
926932 "^wd,.*":
927933 description: Western Digital Corp.
928934 "^wetek,.*":
Documentation/gpu/drm-mm.rst+33−1
@@ -79,7 +79,6 @@ count for the TTM, which will call your initialization function. · 78 unmodified lines
7979
8080 See the radeon_ttm.c file for an example of usage.
8181
82−
8382 The Graphics Execution Manager (GEM)
8483 ====================================
8584
@@ -380,6 +379,39 @@ GEM CMA Helper Functions Reference · 294 unmodified lines
380379 .. kernel-doc:: drivers/gpu/drm/drm_gem_cma_helper.c
381380 :export:
382381
382+VRAM Helper Function Reference
383+==============================
384+
385+.. kernel-doc:: drivers/gpu/drm/drm_vram_helper_common.c
386+ :doc: overview
387+
388+.. kernel-doc:: include/drm/drm_gem_vram_helper.h
389+ :internal:
390+
391+GEM VRAM Helper Functions Reference
392+-----------------------------------
393+
394+.. kernel-doc:: drivers/gpu/drm/drm_gem_vram_helper.c
395+ :doc: overview
396+
397+.. kernel-doc:: include/drm/drm_gem_vram_helper.h
398+ :internal:
399+
400+.. kernel-doc:: drivers/gpu/drm/drm_gem_vram_helper.c
401+ :export:
402+
403+VRAM MM Helper Functions Reference
404+----------------------------------
405+
406+.. kernel-doc:: drivers/gpu/drm/drm_vram_mm_helper.c
407+ :doc: overview
408+
409+.. kernel-doc:: include/drm/drm_vram_mm_helper.h
410+ :internal:
411+
412+.. kernel-doc:: drivers/gpu/drm/drm_vram_mm_helper.c
413+ :export:
414+
383415 VMA Offset Manager
384416 ==================
385417
Documentation/gpu/drm-uapi.rst+6−4
@@ -85,16 +85,18 @@ leads to a few additional requirements: · 84 unmodified lines
8585 - The userspace side must be fully reviewed and tested to the standards of that
8686 userspace project. For e.g. mesa this means piglit testcases and review on the
8787 mailing list. This is again to ensure that the new interface actually gets the
88− job done.
88+ job done. The userspace-side reviewer should also provide at least an
89+ Acked-by on the kernel uAPI patch indicating that they've looked at how the
90+ kernel side is implementing the new feature being used.
8991
9092 - The userspace patches must be against the canonical upstream, not some vendor
9193 fork. This is to make sure that no one cheats on the review and testing
9294 requirements by doing a quick fork.
9395
9496 - The kernel patch can only be merged after all the above requirements are met,
95− but it **must** be merged **before** the userspace patches land. uAPI always flows
96− from the kernel, doing things the other way round risks divergence of the uAPI
97− definitions and header files.
97+ but it **must** be merged to either drm-next or drm-misc-next **before** the
98+ userspace patches land. uAPI always flows from the kernel, doing things the
99+ other way round risks divergence of the uAPI definitions and header files.
98100
99101 These are fairly steep requirements, but have grown out from years of shared
100102 pain and experience with uAPI added hastily, and almost always regretted about
Documentation/gpu/todo.rst+8−19
@@ -10,25 +10,6 @@ graphics subsystem useful as newbie projects. Or for slow rainy days. · 9 unmodified lines
1010 Subsystem-wide refactorings
1111 ===========================
1212
13−De-midlayer drivers
14−-------------------
15−
16−With the recent ``drm_bus`` cleanup patches for 3.17 it is no longer required
17−to have a ``drm_bus`` structure set up. Drivers can directly set up the
18−``drm_device`` structure instead of relying on bus methods in ``drm_usb.c``
19−and ``drm_pci.c``. The goal is to get rid of the driver's ``->load`` /
20−``->unload`` callbacks and open-code the load/unload sequence properly, using
21−the new two-stage ``drm_device`` setup/teardown.
22−
23−Once all existing drivers are converted we can also remove those bus support
24−files for USB and platform devices.
25−
26−All you need is a GPU for a non-converted driver (currently almost all of
27−them, but also all the virtual ones used by KVM, so everyone qualifies).
28−
29−Contact: Daniel Vetter, Thierry Reding, respective driver maintainers
30−
31−
3213 Remove custom dumb_map_offset implementations
3314 ---------------------------------------------
3415
@@ -300,6 +281,14 @@ it to use drm_mode_hsync() instead. · 265 unmodified lines
300281
301282 Contact: Sean Paul
302283
284+drm_fb_helper tasks
285+-------------------
286+
287+- drm_fb_helper_restore_fbdev_mode_unlocked() should call restore_fbdev_mode()
288+ not the _force variant so it can bail out if there is a master. But first
289+ these igt tests need to be fixed: kms_fbcon_fbt@psr and
290+ kms_fbcon_fbt@psr-suspend.
291+
303292 Core refactorings
304293 =================
305294
MAINTAINERS+1−1
@@ -5413,6 +5413,7 @@ T: git git://anongit.freedesktop.org/drm/drm-misc · 5412 unmodified lines
54135413
54145414 DRM PANEL DRIVERS
54155415 M: Thierry Reding <thierry.reding@gmail.com>
5416+R: Sam Ravnborg <sam@ravnborg.org>
54165417 L: dri-devel@lists.freedesktop.org
54175418 T: git git://anongit.freedesktop.org/drm/drm-misc
54185419 S: Maintained
@@ -5441,7 +5442,6 @@ F: Documentation/gpu/xen-front.rst · 22 unmodified lines
54415442 DRM TTM SUBSYSTEM
54425443 M: Christian Koenig <christian.koenig@amd.com>
54435444 M: Huang Rui <ray.huang@amd.com>
5444−M: Junwei Zhang <Jerry.Zhang@amd.com>
54455445 T: git git://people.freedesktop.org/~agd5f/linux
54465446 S: Maintained
54475447 L: dri-devel@lists.freedesktop.org
drivers/dma-buf/dma-buf.c+35−4
@@ -90,6 +90,10 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) · 89 unmodified lines
9090
9191 dmabuf = file->private_data;
9292
93+ /* check if buffer supports mmap */
94+ if (!dmabuf->ops->mmap)
95+ return -EINVAL;
96+
9397 /* check for overflowing the buffer's size */
9498 if (vma->vm_pgoff + vma_pages(vma) >
9599 dmabuf->size >> PAGE_SHIFT)
@@ -404,8 +408,7 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) · 308 unmodified lines
404408 || !exp_info->ops
405409 || !exp_info->ops->map_dma_buf
406410 || !exp_info->ops->unmap_dma_buf
407− || !exp_info->ops->release
408− || !exp_info->ops->mmap)) {
411+ || !exp_info->ops->release)) {
409412 return ERR_PTR(-EINVAL);
410413 }
411414
@@ -573,6 +576,7 @@ struct dma_buf_attachment *dma_buf_attach(struct dma_buf *dmabuf, · 161 unmodified lines
573576 list_add(&attach->node, &dmabuf->attachments);
574577
575578 mutex_unlock(&dmabuf->lock);
579+
576580 return attach;
577581
578582 err_attach:
@@ -595,6 +599,9 @@ void dma_buf_detach(struct dma_buf *dmabuf, struct dma_buf_attachment *attach) · 16 unmodified lines
595599 if (WARN_ON(!dmabuf || !attach))
596600 return;
597601
602+ if (attach->sgt)
603+ dmabuf->ops->unmap_dma_buf(attach, attach->sgt, attach->dir);
604+
598605 mutex_lock(&dmabuf->lock);
599606 list_del(&attach->node);
600607 if (dmabuf->ops->detach)
@@ -630,10 +637,27 @@ struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *attach, · 29 unmodified lines
630637 if (WARN_ON(!attach || !attach->dmabuf))
631638 return ERR_PTR(-EINVAL);
632639
640+ if (attach->sgt) {
641+ /*
642+ * Two mappings with different directions for the same
643+ * attachment are not allowed.
644+ */
645+ if (attach->dir != direction &&
646+ attach->dir != DMA_BIDIRECTIONAL)
647+ return ERR_PTR(-EBUSY);
648+
649+ return attach->sgt;
650+ }
651+
633652 sg_table = attach->dmabuf->ops->map_dma_buf(attach, direction);
634653 if (!sg_table)
635654 sg_table = ERR_PTR(-ENOMEM);
636655
656+ if (!IS_ERR(sg_table) && attach->dmabuf->ops->cache_sgt_mapping) {
657+ attach->sgt = sg_table;
658+ attach->dir = direction;
659+ }
660+
637661 return sg_table;
638662 }
639663 EXPORT_SYMBOL_GPL(dma_buf_map_attachment);
@@ -657,8 +681,10 @@ void dma_buf_unmap_attachment(struct dma_buf_attachment *attach, · 17 unmodified lines
657681 if (WARN_ON(!attach || !attach->dmabuf || !sg_table))
658682 return;
659683
660− attach->dmabuf->ops->unmap_dma_buf(attach, sg_table,
661− direction);
684+ if (attach->sgt == sg_table)
685+ return;
686+
687+ attach->dmabuf->ops->unmap_dma_buf(attach, sg_table, direction);
662688 }
663689 EXPORT_SYMBOL_GPL(dma_buf_unmap_attachment);
664690
@@ -906,6 +932,10 @@ int dma_buf_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma, · 241 unmodified lines
906932 if (WARN_ON(!dmabuf || !vma))
907933 return -EINVAL;
908934
935+ /* check if buffer supports mmap */
936+ if (!dmabuf->ops->mmap)
937+ return -EINVAL;
938+
909939 /* check for offset overflow */
910940 if (pgoff + vma_pages(vma) < pgoff)
911941 return -EOVERFLOW;
@@ -1068,6 +1098,7 @@ static int dma_buf_debug_show(struct seq_file *s, void *unused) · 156 unmodified lines
10681098 fence->ops->get_driver_name(fence),
10691099 fence->ops->get_timeline_name(fence),
10701100 dma_fence_is_signaled(fence) ? "" : "un");
1101+ dma_fence_put(fence);
10711102 }
10721103 rcu_read_unlock();
10731104
drivers/dma-buf/sync_debug.c+0−26
@@ -197,29 +197,3 @@ static __init int sync_debugfs_init(void) · 196 unmodified lines
197197 return 0;
198198 }
199199 late_initcall(sync_debugfs_init);
200−
201−#define DUMP_CHUNK 256
202−static char sync_dump_buf[64 * 1024];
203−void sync_dump(void)
204−{
205− struct seq_file s = {
206− .buf = sync_dump_buf,
207− .size = sizeof(sync_dump_buf) - 1,
208− };
209− int i;
210−
211− sync_info_debugfs_show(&s, NULL);
212−
213− for (i = 0; i < s.count; i += DUMP_CHUNK) {
214− if ((s.count - i) > DUMP_CHUNK) {
215− char c = s.buf[i + DUMP_CHUNK];
216−
217− s.buf[i + DUMP_CHUNK] = 0;
218− pr_cont("%s", s.buf + i);
219− s.buf[i + DUMP_CHUNK] = c;
220− } else {
221− s.buf[s.count] = 0;
222− pr_cont("%s", s.buf + i);
223− }
224− }
225−}
drivers/dma-buf/sync_debug.h+0−1
@@ -68,6 +68,5 @@ void sync_timeline_debug_add(struct sync_timeline *obj); · 67 unmodified lines
6868 void sync_timeline_debug_remove(struct sync_timeline *obj);
6969 void sync_file_debug_add(struct sync_file *fence);
7070 void sync_file_debug_remove(struct sync_file *fence);
71−void sync_dump(void);
7271
7372 #endif /* _LINUX_SYNC_H */
drivers/gpu/drm/Kconfig+7−0
@@ -161,6 +161,13 @@ config DRM_TTM · 160 unmodified lines
161161 GPU memory types. Will be enabled automatically if a device driver
162162 uses it.
163163
164+config DRM_VRAM_HELPER
165+ tristate
166+ depends on DRM
167+ select DRM_TTM
168+ help
169+ Helpers for VRAM memory management
170+
164171 config DRM_GEM_CMA_HELPER
165172 bool
166173 depends on DRM
drivers/gpu/drm/Makefile+5−0
@@ -32,6 +32,11 @@ drm-$(CONFIG_AGP) += drm_agpsupport.o · 31 unmodified lines
3232 drm-$(CONFIG_DEBUG_FS) += drm_debugfs.o drm_debugfs_crc.o
3333 drm-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
3434
35+drm_vram_helper-y := drm_gem_vram_helper.o \
36+ drm_vram_helper_common.o \
37+ drm_vram_mm_helper.o
38+obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
39+
3540 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_dsc.o drm_probe_helper.o \
3641 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o \
3742 drm_kms_helper_common.o drm_dp_dual_mode_helper.o \
drivers/gpu/drm/amd/amdgpu/amdgpu_device.c+95−51
@@ -3341,8 +3341,6 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, · 3340 unmodified lines
33413341 if (!ring || !ring->sched.thread)
33423342 continue;
33433343
3344− drm_sched_stop(&ring->sched);
3345−
33463344 /* after all hw jobs are reset, hw fence is meaningless, so force_completion */
33473345 amdgpu_fence_driver_force_completion(ring);
33483346 }
@@ -3350,8 +3348,7 @@ static int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, · 1 unmodified line
33503348 if(job)
33513349 drm_sched_increase_karma(&job->base);
33523350
3353−
3354−
3351+ /* Don't suspend on bare metal if we are not going to HW reset the ASIC */
33553352 if (!amdgpu_sriov_vf(adev)) {
33563353
33573354 if (!need_full_reset)
@@ -3489,38 +3486,21 @@ end: · 131 unmodified lines
34893486 return r;
34903487 }
34913488
3492−static void amdgpu_device_post_asic_reset(struct amdgpu_device *adev,
3493− struct amdgpu_job *job)
3489+static bool amdgpu_device_lock_adev(struct amdgpu_device *adev, bool trylock)
34943490 {
3495− int i;
3496−
3497− for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
3498− struct amdgpu_ring *ring = adev->rings[i];
3499−
3500− if (!ring || !ring->sched.thread)
3501− continue;
3491+ if (trylock) {
3492+ if (!mutex_trylock(&adev->lock_reset))
3493+ return false;
3494+ } else
3495+ mutex_lock(&adev->lock_reset);
35023496
3503− if (!adev->asic_reset_res)
3504− drm_sched_resubmit_jobs(&ring->sched);
3505−
3506− drm_sched_start(&ring->sched, !adev->asic_reset_res);
3507− }
3508−
3509− if (!amdgpu_device_has_dc_support(adev)) {
3510− drm_helper_resume_force_mode(adev->ddev);
3511− }
3512−
3513− adev->asic_reset_res = 0;
3514−}
3515−
3516−static void amdgpu_device_lock_adev(struct amdgpu_device *adev)
3517−{
3518− mutex_lock(&adev->lock_reset);
35193497 atomic_inc(&adev->gpu_reset_counter);
35203498 adev->in_gpu_reset = 1;
35213499 /* Block kfd: SRIOV would do it separately */
35223500 if (!amdgpu_sriov_vf(adev))
35233501 amdgpu_amdkfd_pre_reset(adev);
3502+
3503+ return true;
35243504 }
35253505
35263506 static void amdgpu_device_unlock_adev(struct amdgpu_device *adev)
@@ -3548,40 +3528,42 @@ static void amdgpu_device_unlock_adev(struct amdgpu_device *adev) · 21 unmodified lines
35483528 int amdgpu_device_gpu_recover(struct amdgpu_device *adev,
35493529 struct amdgpu_job *job)
35503530 {
3551− int r;
3531+ struct list_head device_list, *device_list_handle = NULL;
3532+ bool need_full_reset, job_signaled;
35523533 struct amdgpu_hive_info *hive = NULL;
3553− bool need_full_reset = false;
35543534 struct amdgpu_device *tmp_adev = NULL;
3555− struct list_head device_list, *device_list_handle = NULL;
3535+ int i, r = 0;
35563536
3537+ need_full_reset = job_signaled = false;
35573538 INIT_LIST_HEAD(&device_list);
35583539
35593540 dev_info(adev->dev, "GPU reset begin!\n");
35603541
3542+ hive = amdgpu_get_xgmi_hive(adev, false);
3543+
35613544 /*
3562− * In case of XGMI hive disallow concurrent resets to be triggered
3563− * by different nodes. No point also since the one node already executing
3564− * reset will also reset all the other nodes in the hive.
3545+ * Here we trylock to avoid chain of resets executing from
3546+ * either trigger by jobs on different adevs in XGMI hive or jobs on
3547+ * different schedulers for same device while this TO handler is running.
3548+ * We always reset all schedulers for device and all devices for XGMI
3549+ * hive so that should take care of them too.
35653550 */
3566− hive = amdgpu_get_xgmi_hive(adev, 0);
3567− if (hive && adev->gmc.xgmi.num_physical_nodes > 1 &&
3568− !mutex_trylock(&hive->reset_lock))
3551+
3552+ if (hive && !mutex_trylock(&hive->reset_lock)) {
3553+ DRM_INFO("Bailing on TDR for s_job:%llx, hive: %llx as another already in progress",
3554+ job->base.id, hive->hive_id);
35693555 return 0;
3556+ }
35703557
35713558 /* Start with adev pre asic reset first for soft reset check.*/
3572− amdgpu_device_lock_adev(adev);
3573− r = amdgpu_device_pre_asic_reset(adev,
3574− job,
3575− &need_full_reset);
3576− if (r) {
3577− /*TODO Should we stop ?*/
3578− DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ",
3579− r, adev->ddev->unique);
3580− adev->asic_reset_res = r;
3559+ if (!amdgpu_device_lock_adev(adev, !hive)) {
3560+ DRM_INFO("Bailing on TDR for s_job:%llx, as another already in progress",
3561+ job->base.id);
3562+ return 0;
35813563 }
35823564
35833565 /* Build list of devices to reset */
3584− if (need_full_reset && adev->gmc.xgmi.num_physical_nodes > 1) {
3566+ if (adev->gmc.xgmi.num_physical_nodes > 1) {
35853567 if (!hive) {
35863568 amdgpu_device_unlock_adev(adev);
35873569 return -ENODEV;
@@ -3598,13 +3580,56 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, · 10 unmodified lines
35983580 device_list_handle = &device_list;
35993581 }
36003582
3583+ /* block all schedulers and reset given job's ring */
3584+ list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
3585+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
3586+ struct amdgpu_ring *ring = tmp_adev->rings[i];
3587+
3588+ if (!ring || !ring->sched.thread)
3589+ continue;
3590+
3591+ drm_sched_stop(&ring->sched, &job->base);
3592+ }
3593+ }
3594+
3595+
3596+ /*
3597+ * Must check guilty signal here since after this point all old
3598+ * HW fences are force signaled.
3599+ *
3600+ * job->base holds a reference to parent fence
3601+ */
3602+ if (job && job->base.s_fence->parent &&
3603+ dma_fence_is_signaled(job->base.s_fence->parent))
3604+ job_signaled = true;
3605+
3606+ if (!amdgpu_device_ip_need_full_reset(adev))
3607+ device_list_handle = &device_list;
3608+
3609+ if (job_signaled) {
3610+ dev_info(adev->dev, "Guilty job already signaled, skipping HW reset");
3611+ goto skip_hw_reset;
3612+ }
3613+
3614+
3615+ /* Guilty job will be freed after this*/
3616+ r = amdgpu_device_pre_asic_reset(adev,
3617+ job,
3618+ &need_full_reset);
3619+ if (r) {
3620+ /*TODO Should we stop ?*/
3621+ DRM_ERROR("GPU pre asic reset failed with err, %d for drm dev, %s ",
3622+ r, adev->ddev->unique);
3623+ adev->asic_reset_res = r;
3624+ }
3625+
36013626 retry: /* Rest of adevs pre asic reset from XGMI hive. */
36023627 list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
36033628
36043629 if (tmp_adev == adev)
36053630 continue;
36063631
3607− amdgpu_device_lock_adev(tmp_adev);
3632+ amdgpu_device_lock_adev(tmp_adev, false);
36083633 r = amdgpu_device_pre_asic_reset(tmp_adev,
36093634 NULL,
36103635 &need_full_reset);
@@ -3628,9 +3653,28 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */ · 17 unmodified lines
36283653 goto retry;
36293654 }
36303655
3656+skip_hw_reset:
3657+
36313658 /* Post ASIC reset for all devs .*/
36323659 list_for_each_entry(tmp_adev, device_list_handle, gmc.xgmi.head) {
3633− amdgpu_device_post_asic_reset(tmp_adev, tmp_adev == adev ? job : NULL);
3660+ for (i = 0; i < AMDGPU_MAX_RINGS; ++i) {
3661+ struct amdgpu_ring *ring = tmp_adev->rings[i];
3662+
3663+ if (!ring || !ring->sched.thread)
3664+ continue;
3665+
3666+ /* No point to resubmit jobs if we didn't HW reset*/
3667+ if (!tmp_adev->asic_reset_res && !job_signaled)
3668+ drm_sched_resubmit_jobs(&ring->sched);
3669+
3670+ drm_sched_start(&ring->sched, !tmp_adev->asic_reset_res);
3671+ }
3672+
3673+ if (!amdgpu_device_has_dc_support(tmp_adev) && !job_signaled) {
3674+ drm_helper_resume_force_mode(tmp_adev->ddev);
3675+ }
3676+
3677+ tmp_adev->asic_reset_res = 0;
36343678
36353679 if (r) {
36363680 /* bad news, how to tell it to userspace ? */
@@ -3643,7 +3687,7 @@ retry: /* Rest of adevs pre asic reset from XGMI hive. */ · 6 unmodified lines
36433687 amdgpu_device_unlock_adev(tmp_adev);
36443688 }
36453689
3646− if (hive && adev->gmc.xgmi.num_physical_nodes > 1)
3690+ if (hive)
36473691 mutex_unlock(&hive->reset_lock);
36483692
36493693 if (r)
drivers/gpu/drm/amd/amdgpu/amdgpu_fb.c+3−1
@@ -121,6 +121,7 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, · 120 unmodified lines
121121 struct drm_mode_fb_cmd2 *mode_cmd,
122122 struct drm_gem_object **gobj_p)
123123 {
124+ const struct drm_format_info *info;
124125 struct amdgpu_device *adev = rfbdev->adev;
125126 struct drm_gem_object *gobj = NULL;
126127 struct amdgpu_bo *abo = NULL;
@@ -131,7 +132,8 @@ static int amdgpufb_create_pinned_object(struct amdgpu_fbdev *rfbdev, · 4 unmodified lines
131132 int height = mode_cmd->height;
132133 u32 cpp;
133134
134− cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
135+ info = drm_get_format_info(adev->ddev, mode_cmd);
136+ cpp = info->cpp[0];
135137
136138 /* need to align pitch with crtc limits */
137139 mode_cmd->pitches[0] = amdgpu_align_pitch(adev, mode_cmd->width, cpp,
drivers/gpu/drm/arm/malidp_crtc.c+11−17
@@ -463,23 +463,6 @@ static struct drm_crtc_state *malidp_crtc_duplicate_state(struct drm_crtc *crtc) · 462 unmodified lines
463463 return &state->base;
464464 }
465465
466−static void malidp_crtc_reset(struct drm_crtc *crtc)
467−{
468− struct malidp_crtc_state *state = NULL;
469−
470− if (crtc->state) {
471− state = to_malidp_crtc_state(crtc->state);
472− __drm_atomic_helper_crtc_destroy_state(crtc->state);
473− }
474−
475− kfree(state);
476− state = kzalloc(sizeof(*state), GFP_KERNEL);
477− if (state) {
478− crtc->state = &state->base;
479− crtc->state->crtc = crtc;
480− }
481−}
482−
483466 static void malidp_crtc_destroy_state(struct drm_crtc *crtc,
484467 struct drm_crtc_state *state)
485468 {
@@ -493,6 +476,17 @@ static void malidp_crtc_destroy_state(struct drm_crtc *crtc, · 7 unmodified lines
493476 kfree(mali_state);
494477 }
495478
479+static void malidp_crtc_reset(struct drm_crtc *crtc)
480+{
481+ struct malidp_crtc_state *state =
482+ kzalloc(sizeof(*state), GFP_KERNEL);
483+
484+ if (crtc->state)
485+ malidp_crtc_destroy_state(crtc, crtc->state);
486+
487+ __drm_atomic_helper_crtc_reset(crtc, &state->base);
488+}
489+
496490 static int malidp_crtc_enable_vblank(struct drm_crtc *crtc)
497491 {
498492 struct malidp_drm *malidp = crtc_to_malidp_device(crtc);
drivers/gpu/drm/arm/malidp_hw.c+2−1
@@ -382,7 +382,8 @@ static void malidp500_modeset(struct malidp_hw_device *hwdev, struct videomode * · 381 unmodified lines
382382
383383 int malidp_format_get_bpp(u32 fmt)
384384 {
385− int bpp = drm_format_plane_cpp(fmt, 0) * 8;
385+ const struct drm_format_info *info = drm_format_info(fmt);
386+ int bpp = info->cpp[0] * 8;
386387
387388 if (bpp == 0) {
388389 switch (fmt) {
drivers/gpu/drm/arm/malidp_mw.c+1−1
@@ -158,7 +158,7 @@ malidp_mw_encoder_atomic_check(struct drm_encoder *encoder, · 157 unmodified lines
158158 return -EINVAL;
159159 }
160160
161− n_planes = drm_format_num_planes(fb->format->format);
161+ n_planes = fb->format->num_planes;
162162 for (i = 0; i < n_planes; i++) {
163163 struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i);
164164 /* memory write buffers are never rotated */
drivers/gpu/drm/arm/malidp_planes.c+3−5
@@ -227,14 +227,13 @@ bool malidp_format_mod_supported(struct drm_device *drm, · 226 unmodified lines
227227
228228 if (modifier & AFBC_SPLIT) {
229229 if (!info->is_yuv) {
230− if (drm_format_plane_cpp(format, 0) <= 2) {
230+ if (info->cpp[0] <= 2) {
231231 DRM_DEBUG_KMS("RGB formats <= 16bpp are not supported with SPLIT\n");
232232 return false;
233233 }
234234 }
235235
236− if ((drm_format_horz_chroma_subsampling(format) != 1) ||
237− (drm_format_vert_chroma_subsampling(format) != 1)) {
236+ if ((info->hsub != 1) || (info->vsub != 1)) {
238237 if (!(format == DRM_FORMAT_YUV420_10BIT &&
239238 (map->features & MALIDP_DEVICE_AFBC_YUV_420_10_SUPPORT_SPLIT))) {
240239 DRM_DEBUG_KMS("Formats which are sub-sampled should never be split\n");
@@ -244,8 +243,7 @@ bool malidp_format_mod_supported(struct drm_device *drm, · 3 unmodified lines
244243 }
245244
246245 if (modifier & AFBC_CBR) {
247− if ((drm_format_horz_chroma_subsampling(format) == 1) ||
248− (drm_format_vert_chroma_subsampling(format) == 1)) {
246+ if ((info->hsub == 1) || (info->vsub == 1)) {
249247 DRM_DEBUG_KMS("Formats which are not sub-sampled should not have CBR set\n");
250248 return false;
251249 }
drivers/gpu/drm/armada/armada_fb.c+2−1
@@ -87,6 +87,7 @@ struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev, · 86 unmodified lines
8787 struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
8888 struct drm_file *dfile, const struct drm_mode_fb_cmd2 *mode)
8989 {
90+ const struct drm_format_info *info = drm_get_format_info(dev, mode);
9091 struct armada_gem_object *obj;
9192 struct armada_framebuffer *dfb;
9293 int ret;
@@ -97,7 +98,7 @@ struct drm_framebuffer *armada_fb_create(struct drm_device *dev, · 4 unmodified lines
9798 mode->pitches[2]);
9899
99100 /* We can only handle a single plane at the moment */
100− if (drm_format_num_planes(mode->pixel_format) > 1 &&
101+ if (info->num_planes > 1 &&
101102 (mode->handles[0] != mode->handles[1] ||
102103 mode->handles[0] != mode->handles[2])) {
103104 ret = -EINVAL;
drivers/gpu/drm/ast/Kconfig+1−2
@@ -2,9 +2,8 @@ · 1 unmodified line
22 config DRM_AST
33 tristate "AST server chips"
44 depends on DRM && PCI && MMU
5− select DRM_TTM
65 select DRM_KMS_HELPER
7− select DRM_TTM
6+ select DRM_VRAM_HELPER
87 help
98 Say yes for experimental AST GPU driver. Do not enable
109 this driver without having a working -modesetting,
drivers/gpu/drm/ast/ast_drv.c+2−11
@@ -205,13 +205,7 @@ static struct pci_driver ast_pci_driver = { · 204 unmodified lines
205205
206206 static const struct file_operations ast_fops = {
207207 .owner = THIS_MODULE,
208− .open = drm_open,
209− .release = drm_release,
210− .unlocked_ioctl = drm_ioctl,
211− .mmap = ast_mmap,
212− .poll = drm_poll,
213− .compat_ioctl = drm_compat_ioctl,
214− .read = drm_read,
208+ DRM_VRAM_MM_FILE_OPERATIONS
215209 };
216210
217211 static struct drm_driver driver = {
@@ -228,10 +222,7 @@ static struct drm_driver driver = { · 10 unmodified lines
228222 .minor = DRIVER_MINOR,
229223 .patchlevel = DRIVER_PATCHLEVEL,
230224
231− .gem_free_object_unlocked = ast_gem_free_object,
232− .dumb_create = ast_dumb_create,
233− .dumb_map_offset = ast_dumb_mmap_offset,
234−
225+ DRM_GEM_VRAM_DRIVER
235226 };
236227
237228 static int __init ast_init(void)
drivers/gpu/drm/ast/ast_drv.h+3−68
@@ -31,13 +31,10 @@ · 30 unmodified lines
3131 #include <drm/drm_encoder.h>
3232 #include <drm/drm_fb_helper.h>
3333
34−#include <drm/ttm/ttm_bo_api.h>
35−#include <drm/ttm/ttm_bo_driver.h>
36−#include <drm/ttm/ttm_placement.h>
37−#include <drm/ttm/ttm_memory.h>
38−#include <drm/ttm/ttm_module.h>
39−
4034 #include <drm/drm_gem.h>
35+#include <drm/drm_gem_vram_helper.h>
36+
37+#include <drm/drm_vram_mm_helper.h>
4138
4239 #include <linux/i2c.h>
4340 #include <linux/i2c-algo-bit.h>
@@ -103,10 +100,6 @@ struct ast_private { · 59 unmodified lines
103100
104101 int fb_mtrr;
105102
106− struct {
107− struct ttm_bo_device bdev;
108− } ttm;
109−
110103 struct drm_gem_object *cursor_cache;
111104 uint64_t cursor_cache_gpu_addr;
112105 /* Acces to this cache is protected by the crtc->mutex of the only crtc
@@ -263,7 +256,6 @@ struct ast_fbdev { · 150 unmodified lines
263256 struct ast_framebuffer afb;
264257 void *sysram;
265258 int size;
266− struct ttm_bo_kmap_obj mapping;
267259 int x1, y1, x2, y2; /* dirty rect */
268260 spinlock_t dirty_lock;
269261 };
@@ -321,73 +313,16 @@ void ast_fbdev_fini(struct drm_device *dev); · 51 unmodified lines
321313 void ast_fbdev_set_suspend(struct drm_device *dev, int state);
322314 void ast_fbdev_set_base(struct ast_private *ast, unsigned long gpu_addr);
323315
324−struct ast_bo {
325− struct ttm_buffer_object bo;
326− struct ttm_placement placement;
327− struct ttm_bo_kmap_obj kmap;
328− struct drm_gem_object gem;
329− struct ttm_place placements[3];
330− int pin_count;
331−};
332−#define gem_to_ast_bo(gobj) container_of((gobj), struct ast_bo, gem)
333−
334−static inline struct ast_bo *
335−ast_bo(struct ttm_buffer_object *bo)
336−{
337− return container_of(bo, struct ast_bo, bo);
338−}
339−
340−
341−#define to_ast_obj(x) container_of(x, struct ast_gem_object, base)
342−
343316 #define AST_MM_ALIGN_SHIFT 4
344317 #define AST_MM_ALIGN_MASK ((1 << AST_MM_ALIGN_SHIFT) - 1)
345318
346−extern int ast_dumb_create(struct drm_file *file,
347− struct drm_device *dev,
348− struct drm_mode_create_dumb *args);
349−
350−extern void ast_gem_free_object(struct drm_gem_object *obj);
351−extern int ast_dumb_mmap_offset(struct drm_file *file,
352− struct drm_device *dev,
353− uint32_t handle,
354− uint64_t *offset);
355−
356319 int ast_mm_init(struct ast_private *ast);
357320 void ast_mm_fini(struct ast_private *ast);
358321
359−int ast_bo_create(struct drm_device *dev, int size, int align,
360− uint32_t flags, struct ast_bo **pastbo);
361−
362322 int ast_gem_create(struct drm_device *dev,
363323 u32 size, bool iskernel,
364324 struct drm_gem_object **obj);
365325
366−int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr);
367−int ast_bo_unpin(struct ast_bo *bo);
368−
369−static inline int ast_bo_reserve(struct ast_bo *bo, bool no_wait)
370−{
371− int ret;
372−
373− ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
374− if (ret) {
375− if (ret != -ERESTARTSYS && ret != -EBUSY)
376− DRM_ERROR("reserve failed %p\n", bo);
377− return ret;
378− }
379− return 0;
380−}
381−
382−static inline void ast_bo_unreserve(struct ast_bo *bo)
383−{
384− ttm_bo_unreserve(&bo->bo);
385−}
386−
387−void ast_ttm_placement(struct ast_bo *bo, int domain);
388−int ast_bo_push_sysram(struct ast_bo *bo);
389−int ast_mmap(struct file *filp, struct vm_area_struct *vma);
390−
391326 /* ast post */
392327 void ast_enable_vga(struct drm_device *dev);
393328 void ast_enable_mmio(struct drm_device *dev);
drivers/gpu/drm/ast/ast_fb.c+24−17
@@ -49,25 +49,25 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, · 48 unmodified lines
4949 {
5050 int i;
5151 struct drm_gem_object *obj;
52− struct ast_bo *bo;
52+ struct drm_gem_vram_object *gbo;
5353 int src_offset, dst_offset;
5454 int bpp = afbdev->afb.base.format->cpp[0];
5555 int ret = -EBUSY;
56+ u8 *dst;
5657 bool unmap = false;
5758 bool store_for_later = false;
5859 int x2, y2;
5960 unsigned long flags;
6061
6162 obj = afbdev->afb.obj;
62− bo = gem_to_ast_bo(obj);
63+ gbo = drm_gem_vram_of_gem(obj);
6364
64− /*
65− * try and reserve the BO, if we fail with busy
66− * then the BO is being moved and we should
67− * store up the damage until later.
65+ /* Try to lock the BO. If we fail with -EBUSY then
66+ * the BO is being moved and we should store up the
67+ * damage until later.
6868 */
6969 if (drm_can_sleep())
70− ret = ast_bo_reserve(bo, true);
70+ ret = drm_gem_vram_lock(gbo, true);
7171 if (ret) {
7272 if (ret != -EBUSY)
7373 return;
@@ -101,25 +101,32 @@ static void ast_dirty_update(struct ast_fbdev *afbdev, · 27 unmodified lines
101101 afbdev->x2 = afbdev->y2 = 0;
102102 spin_unlock_irqrestore(&afbdev->dirty_lock, flags);
103103
104− if (!bo->kmap.virtual) {
105− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
106− if (ret) {
104+ dst = drm_gem_vram_kmap(gbo, false, NULL);
105+ if (IS_ERR(dst)) {
106+ DRM_ERROR("failed to kmap fb updates\n");
107+ goto out;
108+ } else if (!dst) {
109+ dst = drm_gem_vram_kmap(gbo, true, NULL);
110+ if (IS_ERR(dst)) {
107111 DRM_ERROR("failed to kmap fb updates\n");
108− ast_bo_unreserve(bo);
109− return;
112+ goto out;
110113 }
111114 unmap = true;
112115 }
116+
113117 for (i = y; i <= y2; i++) {
114118 /* assume equal stride for now */
115− src_offset = dst_offset = i * afbdev->afb.base.pitches[0] + (x * bpp);
116− memcpy_toio(bo->kmap.virtual + src_offset, afbdev->sysram + src_offset, (x2 - x + 1) * bpp);
117−
119+ src_offset = dst_offset =
120+ i * afbdev->afb.base.pitches[0] + (x * bpp);
121+ memcpy_toio(dst + dst_offset, afbdev->sysram + src_offset,
122+ (x2 - x + 1) * bpp);
118123 }
124+
119125 if (unmap)
120− ttm_bo_kunmap(&bo->kmap);
126+ drm_gem_vram_kunmap(gbo);
121127
122− ast_bo_unreserve(bo);
128+out:
129+ drm_gem_vram_unlock(gbo);
123130 }
124131
125132 static void ast_fillrect(struct fb_info *info,
drivers/gpu/drm/ast/ast_main.c+5−72
@@ -593,7 +593,7 @@ int ast_gem_create(struct drm_device *dev, · 592 unmodified lines
593593 u32 size, bool iskernel,
594594 struct drm_gem_object **obj)
595595 {
596− struct ast_bo *astbo;
596+ struct drm_gem_vram_object *gbo;
597597 int ret;
598598
599599 *obj = NULL;
@@ -602,80 +602,13 @@ int ast_gem_create(struct drm_device *dev, · 2 unmodified lines
602602 if (size == 0)
603603 return -EINVAL;
604604
605− ret = ast_bo_create(dev, size, 0, 0, &astbo);
606− if (ret) {
605+ gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false);
606+ if (IS_ERR(gbo)) {
607+ ret = PTR_ERR(gbo);
607608 if (ret != -ERESTARTSYS)
608609 DRM_ERROR("failed to allocate GEM object\n");
609610 return ret;
610611 }
611− *obj = &astbo->gem;
612+ *obj = &gbo->gem;
612613 return 0;
613614 }
614−
615−int ast_dumb_create(struct drm_file *file,
616− struct drm_device *dev,
617− struct drm_mode_create_dumb *args)
618−{
619− int ret;
620− struct drm_gem_object *gobj;
621− u32 handle;
622−
623− args->pitch = args->width * ((args->bpp + 7) / 8);
624− args->size = args->pitch * args->height;
625−
626− ret = ast_gem_create(dev, args->size, false,
627− &gobj);
628− if (ret)
629− return ret;
630−
631− ret = drm_gem_handle_create(file, gobj, &handle);
632− drm_gem_object_put_unlocked(gobj);
633− if (ret)
634− return ret;
635−
636− args->handle = handle;
637− return 0;
638−}
639−
640−static void ast_bo_unref(struct ast_bo **bo)
641−{
642− if ((*bo) == NULL)
643− return;
644− ttm_bo_put(&((*bo)->bo));
645− *bo = NULL;
646−}
647−
648−void ast_gem_free_object(struct drm_gem_object *obj)
649−{
650− struct ast_bo *ast_bo = gem_to_ast_bo(obj);
651−
652− ast_bo_unref(&ast_bo);
653−}
654−
655−
656−static inline u64 ast_bo_mmap_offset(struct ast_bo *bo)
657−{
658− return drm_vma_node_offset_addr(&bo->bo.vma_node);
659−}
660−int
661−ast_dumb_mmap_offset(struct drm_file *file,
662− struct drm_device *dev,
663− uint32_t handle,
664− uint64_t *offset)
665−{
666− struct drm_gem_object *obj;
667− struct ast_bo *bo;
668−
669− obj = drm_gem_object_lookup(file, handle);
670− if (obj == NULL)
671− return -ENOENT;
672−
673− bo = gem_to_ast_bo(obj);
674− *offset = ast_bo_mmap_offset(bo);
675−
676− drm_gem_object_put_unlocked(obj);
677−
678− return 0;
679−
680−}
681−
drivers/gpu/drm/ast/ast_mode.c+77−55
@@ -521,7 +521,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode) · 520 unmodified lines
521521 }
522522 }
523523
524−/* ast is different - we will force move buffers out of VRAM */
525524 static int ast_crtc_do_set_base(struct drm_crtc *crtc,
526525 struct drm_framebuffer *fb,
527526 int x, int y, int atomic)
@@ -529,50 +528,54 @@ static int ast_crtc_do_set_base(struct drm_crtc *crtc, · 1 unmodified line
529528 struct ast_private *ast = crtc->dev->dev_private;
530529 struct drm_gem_object *obj;
531530 struct ast_framebuffer *ast_fb;
532− struct ast_bo *bo;
531+ struct drm_gem_vram_object *gbo;
533532 int ret;
534− u64 gpu_addr;
533+ s64 gpu_addr;
534+ void *base;
535535
536− /* push the previous fb to system ram */
537536 if (!atomic && fb) {
538537 ast_fb = to_ast_framebuffer(fb);
539538 obj = ast_fb->obj;
540− bo = gem_to_ast_bo(obj);
541− ret = ast_bo_reserve(bo, false);
542− if (ret)
543− return ret;
544− ast_bo_push_sysram(bo);
545− ast_bo_unreserve(bo);
539+ gbo = drm_gem_vram_of_gem(obj);
540+
541+ /* unmap if console */
542+ if (&ast->fbdev->afb == ast_fb)
543+ drm_gem_vram_kunmap(gbo);
544+ drm_gem_vram_unpin(gbo);
546545 }
547546
548547 ast_fb = to_ast_framebuffer(crtc->primary->fb);
549548 obj = ast_fb->obj;
550− bo = gem_to_ast_bo(obj);
549+ gbo = drm_gem_vram_of_gem(obj);
551550
552− ret = ast_bo_reserve(bo, false);
551+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
553552 if (ret)
554553 return ret;
555−
556− ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
557− if (ret) {
558− ast_bo_unreserve(bo);
559− return ret;
554+ gpu_addr = drm_gem_vram_offset(gbo);
555+ if (gpu_addr < 0) {
556+ ret = (int)gpu_addr;
557+ goto err_drm_gem_vram_unpin;
560558 }
561559
562560 if (&ast->fbdev->afb == ast_fb) {
563561 /* if pushing console in kmap it */
564− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
565− if (ret)
562+ base = drm_gem_vram_kmap(gbo, true, NULL);
563+ if (IS_ERR(base)) {
564+ ret = PTR_ERR(base);
566565 DRM_ERROR("failed to kmap fbcon\n");
567− else
566+ } else {
568567 ast_fbdev_set_base(ast, gpu_addr);
568+ }
569569 }
570− ast_bo_unreserve(bo);
571570
572571 ast_set_offset_reg(crtc);
573572 ast_set_start_address_crt1(crtc, (u32)gpu_addr);
574573
575574 return 0;
575+
576+err_drm_gem_vram_unpin:
577+ drm_gem_vram_unpin(gbo);
578+ return ret;
576579 }
577580
578581 static int ast_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -618,21 +621,18 @@ static int ast_crtc_mode_set(struct drm_crtc *crtc, · 39 unmodified lines
618621
619622 static void ast_crtc_disable(struct drm_crtc *crtc)
620623 {
621− int ret;
622−
623624 DRM_DEBUG_KMS("\n");
624625 ast_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
625626 if (crtc->primary->fb) {
627+ struct ast_private *ast = crtc->dev->dev_private;
626628 struct ast_framebuffer *ast_fb = to_ast_framebuffer(crtc->primary->fb);
627629 struct drm_gem_object *obj = ast_fb->obj;
628− struct ast_bo *bo = gem_to_ast_bo(obj);
629−
630− ret = ast_bo_reserve(bo, false);
631− if (ret)
632− return;
630+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj);
633631
634− ast_bo_push_sysram(bo);
635− ast_bo_unreserve(bo);
632+ /* unmap if console */
633+ if (&ast->fbdev->afb == ast_fb)
634+ drm_gem_vram_kunmap(gbo);
635+ drm_gem_vram_unpin(gbo);
636636 }
637637 crtc->primary->fb = NULL;
638638 }
@@ -918,28 +918,32 @@ static int ast_cursor_init(struct drm_device *dev) · 279 unmodified lines
918918 int size;
919919 int ret;
920920 struct drm_gem_object *obj;
921− struct ast_bo *bo;
922− uint64_t gpu_addr;
921+ struct drm_gem_vram_object *gbo;
922+ s64 gpu_addr;
923+ void *base;
923924
924925 size = (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE) * AST_DEFAULT_HWC_NUM;
925926
926927 ret = ast_gem_create(dev, size, true, &obj);
927928 if (ret)
928929 return ret;
929− bo = gem_to_ast_bo(obj);
930− ret = ast_bo_reserve(bo, false);
931− if (unlikely(ret != 0))
932− goto fail;
933−
934− ret = ast_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
935− ast_bo_unreserve(bo);
930+ gbo = drm_gem_vram_of_gem(obj);
931+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
936932 if (ret)
937933 goto fail;
934+ gpu_addr = drm_gem_vram_offset(gbo);
935+ if (gpu_addr < 0) {
936+ drm_gem_vram_unpin(gbo);
937+ ret = (int)gpu_addr;
938+ goto fail;
939+ }
938940
939941 /* kmap the object */
940− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &ast->cache_kmap);
941− if (ret)
942+ base = drm_gem_vram_kmap_at(gbo, true, NULL, &ast->cache_kmap);
943+ if (IS_ERR(base)) {
944+ ret = PTR_ERR(base);
942945 goto fail;
946+ }
943947
944948 ast->cursor_cache = obj;
945949 ast->cursor_cache_gpu_addr = gpu_addr;
@@ -952,7 +956,9 @@ fail: · 6 unmodified lines
952956 static void ast_cursor_fini(struct drm_device *dev)
953957 {
954958 struct ast_private *ast = dev->dev_private;
955− ttm_bo_kunmap(&ast->cache_kmap);
959+ struct drm_gem_vram_object *gbo =
960+ drm_gem_vram_of_gem(ast->cursor_cache);
961+ drm_gem_vram_kunmap_at(gbo, &ast->cache_kmap);
956962 drm_gem_object_put_unlocked(ast->cursor_cache);
957963 }
958964
@@ -1173,8 +1179,8 @@ static int ast_cursor_set(struct drm_crtc *crtc, · 214 unmodified lines
11731179 struct ast_private *ast = crtc->dev->dev_private;
11741180 struct ast_crtc *ast_crtc = to_ast_crtc(crtc);
11751181 struct drm_gem_object *obj;
1176− struct ast_bo *bo;
1177− uint64_t gpu_addr;
1182+ struct drm_gem_vram_object *gbo;
1183+ s64 gpu_addr;
11781184 u32 csum;
11791185 int ret;
11801186 struct ttm_bo_kmap_obj uobj_map;
@@ -1193,19 +1199,27 @@ static int ast_cursor_set(struct drm_crtc *crtc, · 12 unmodified lines
11931199 DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
11941200 return -ENOENT;
11951201 }
1196− bo = gem_to_ast_bo(obj);
1202+ gbo = drm_gem_vram_of_gem(obj);
11971203
1198− ret = ast_bo_reserve(bo, false);
1204+ ret = drm_gem_vram_lock(gbo, false);
11991205 if (ret)
12001206 goto fail;
12011207
1202− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
1203−
1204− src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
1205− dst = ttm_kmap_obj_virtual(&ast->cache_kmap, &dst_isiomem);
1206−
1208+ memset(&uobj_map, 0, sizeof(uobj_map));
1209+ src = drm_gem_vram_kmap_at(gbo, true, &src_isiomem, &uobj_map);
1210+ if (IS_ERR(src)) {
1211+ ret = PTR_ERR(src);
1212+ goto fail_unlock;
1213+ }
12071214 if (src_isiomem == true)
12081215 DRM_ERROR("src cursor bo should be in main memory\n");
1216+
1217+ dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache),
1218+ false, &dst_isiomem, &ast->cache_kmap);
1219+ if (IS_ERR(dst)) {
1220+ ret = PTR_ERR(dst);
1221+ goto fail_unlock;
1222+ }
12091223 if (dst_isiomem == false)
12101224 DRM_ERROR("dst bo should be in VRAM\n");
12111225
@@ -1214,11 +1228,14 @@ static int ast_cursor_set(struct drm_crtc *crtc, · 2 unmodified lines
12141228 /* do data transfer to cursor cache */
12151229 csum = copy_cursor_image(src, dst, width, height);
12161230
1231+ drm_gem_vram_kunmap_at(gbo, &uobj_map);
1232+ drm_gem_vram_unlock(gbo);
1233+
12171234 /* write checksum + signature */
1218− ttm_bo_kunmap(&uobj_map);
1219− ast_bo_unreserve(bo);
12201235 {
1221− u8 *dst = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
1236+ u8 *dst = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache),
1237+ false, NULL, &ast->cache_kmap);
1238+ dst += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
12221239 writel(csum, dst);
12231240 writel(width, dst + AST_HWC_SIGNATURE_SizeX);
12241241 writel(height, dst + AST_HWC_SIGNATURE_SizeY);
@@ -1244,6 +1261,9 @@ static int ast_cursor_set(struct drm_crtc *crtc, · 19 unmodified lines
12441261
12451262 drm_gem_object_put_unlocked(obj);
12461263 return 0;
1264+
1265+fail_unlock:
1266+ drm_gem_vram_unlock(gbo);
12471267 fail:
12481268 drm_gem_object_put_unlocked(obj);
12491269 return ret;
@@ -1257,7 +1277,9 @@ static int ast_cursor_move(struct drm_crtc *crtc, · 7 unmodified lines
12571277 int x_offset, y_offset;
12581278 u8 *sig;
12591279
1260− sig = (u8 *)ast->cache_kmap.virtual + (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
1280+ sig = drm_gem_vram_kmap_at(drm_gem_vram_of_gem(ast->cursor_cache),
1281+ false, NULL, &ast->cache_kmap);
1282+ sig += (AST_HWC_SIZE + AST_HWC_SIGNATURE_SIZE)*ast->next_cursor + AST_HWC_SIZE;
12611283 writel(x, sig + AST_HWC_SIGNATURE_X);
12621284 writel(y, sig + AST_HWC_SIGNATURE_Y);
12631285
drivers/gpu/drm/ast/ast_ttm.c+8−294
@@ -26,168 +26,21 @@ · 25 unmodified lines
2626 * Authors: Dave Airlie <airlied@redhat.com>
2727 */
2828 #include <drm/drmP.h>
29−#include <drm/ttm/ttm_page_alloc.h>
3029
3130 #include "ast_drv.h"
3231
33−static inline struct ast_private *
34−ast_bdev(struct ttm_bo_device *bd)
35−{
36− return container_of(bd, struct ast_private, ttm.bdev);
37−}
38−
39−static void ast_bo_ttm_destroy(struct ttm_buffer_object *tbo)
40−{
41− struct ast_bo *bo;
42−
43− bo = container_of(tbo, struct ast_bo, bo);
44−
45− drm_gem_object_release(&bo->gem);
46− kfree(bo);
47−}
48−
49−static bool ast_ttm_bo_is_ast_bo(struct ttm_buffer_object *bo)
50−{
51− if (bo->destroy == &ast_bo_ttm_destroy)
52− return true;
53− return false;
54−}
55−
56−static int
57−ast_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
58− struct ttm_mem_type_manager *man)
59−{
60− switch (type) {
61− case TTM_PL_SYSTEM:
62− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
63− man->available_caching = TTM_PL_MASK_CACHING;
64− man->default_caching = TTM_PL_FLAG_CACHED;
65− break;
66− case TTM_PL_VRAM:
67− man->func = &ttm_bo_manager_func;
68− man->flags = TTM_MEMTYPE_FLAG_FIXED |
69− TTM_MEMTYPE_FLAG_MAPPABLE;
70− man->available_caching = TTM_PL_FLAG_UNCACHED |
71− TTM_PL_FLAG_WC;
72− man->default_caching = TTM_PL_FLAG_WC;
73− break;
74− default:
75− DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
76− return -EINVAL;
77− }
78− return 0;
79−}
80−
81−static void
82−ast_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
83−{
84− struct ast_bo *astbo = ast_bo(bo);
85−
86− if (!ast_ttm_bo_is_ast_bo(bo))
87− return;
88−
89− ast_ttm_placement(astbo, TTM_PL_FLAG_SYSTEM);
90− *pl = astbo->placement;
91−}
92−
93−static int ast_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
94−{
95− struct ast_bo *astbo = ast_bo(bo);
96−
97− return drm_vma_node_verify_access(&astbo->gem.vma_node,
98− filp->private_data);
99−}
100−
101−static int ast_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
102− struct ttm_mem_reg *mem)
103−{
104− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
105− struct ast_private *ast = ast_bdev(bdev);
106−
107− mem->bus.addr = NULL;
108− mem->bus.offset = 0;
109− mem->bus.size = mem->num_pages << PAGE_SHIFT;
110− mem->bus.base = 0;
111− mem->bus.is_iomem = false;
112− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
113− return -EINVAL;
114− switch (mem->mem_type) {
115− case TTM_PL_SYSTEM:
116− /* system memory */
117− return 0;
118− case TTM_PL_VRAM:
119− mem->bus.offset = mem->start << PAGE_SHIFT;
120− mem->bus.base = pci_resource_start(ast->dev->pdev, 0);
121− mem->bus.is_iomem = true;
122− break;
123− default:
124− return -EINVAL;
125− break;
126− }
127− return 0;
128−}
129−
130−static void ast_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
131−{
132−}
133−
134−static void ast_ttm_backend_destroy(struct ttm_tt *tt)
135−{
136− ttm_tt_fini(tt);
137− kfree(tt);
138−}
139−
140−static struct ttm_backend_func ast_tt_backend_func = {
141− .destroy = &ast_ttm_backend_destroy,
142−};
143−
144−
145−static struct ttm_tt *ast_ttm_tt_create(struct ttm_buffer_object *bo,
146− uint32_t page_flags)
147−{
148− struct ttm_tt *tt;
149−
150− tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
151− if (tt == NULL)
152− return NULL;
153− tt->func = &ast_tt_backend_func;
154− if (ttm_tt_init(tt, bo, page_flags)) {
155− kfree(tt);
156− return NULL;
157− }
158− return tt;
159−}
160−
161−struct ttm_bo_driver ast_bo_driver = {
162− .ttm_tt_create = ast_ttm_tt_create,
163− .init_mem_type = ast_bo_init_mem_type,
164− .eviction_valuable = ttm_bo_eviction_valuable,
165− .evict_flags = ast_bo_evict_flags,
166− .move = NULL,
167− .verify_access = ast_bo_verify_access,
168− .io_mem_reserve = &ast_ttm_io_mem_reserve,
169− .io_mem_free = &ast_ttm_io_mem_free,
170−};
171−
17232 int ast_mm_init(struct ast_private *ast)
17333 {
34+ struct drm_vram_mm *vmm;
17435 int ret;
17536 struct drm_device *dev = ast->dev;
176− struct ttm_bo_device *bdev = &ast->ttm.bdev;
177−
178− ret = ttm_bo_device_init(&ast->ttm.bdev,
179− &ast_bo_driver,
180− dev->anon_inode->i_mapping,
181− true);
182− if (ret) {
183− DRM_ERROR("Error initialising bo driver; %d\n", ret);
184− return ret;
185− }
18637
187− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
188− ast->vram_size >> PAGE_SHIFT);
189− if (ret) {
190− DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
38+ vmm = drm_vram_helper_alloc_mm(
39+ dev, pci_resource_start(dev->pdev, 0),
40+ ast->vram_size, &drm_gem_vram_mm_funcs);
41+ if (IS_ERR(vmm)) {
42+ ret = PTR_ERR(vmm);
43+ DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
19144 return ret;
19245 }
19346
@@ -203,148 +56,9 @@ void ast_mm_fini(struct ast_private *ast) · 9 unmodified lines
20356 {
20457 struct drm_device *dev = ast->dev;
20558
206− ttm_bo_device_release(&ast->ttm.bdev);
59+ drm_vram_helper_release_mm(dev);
20760
20861 arch_phys_wc_del(ast->fb_mtrr);
20962 arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
21063 pci_resource_len(dev->pdev, 0));
21164 }
212−
213−void ast_ttm_placement(struct ast_bo *bo, int domain)
214−{
215− u32 c = 0;
216− unsigned i;
217−
218− bo->placement.placement = bo->placements;
219− bo->placement.busy_placement = bo->placements;
220− if (domain & TTM_PL_FLAG_VRAM)
221− bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
222− if (domain & TTM_PL_FLAG_SYSTEM)
223− bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM;
224− if (!c)
225− bo->placements[c++].flags = TTM_PL_FLAG_CACHED | TTM_PL_FLAG_SYSTEM;
226− bo->placement.num_placement = c;
227− bo->placement.num_busy_placement = c;
228− for (i = 0; i < c; ++i) {
229− bo->placements[i].fpfn = 0;
230− bo->placements[i].lpfn = 0;
231− }
232−}
233−
234−int ast_bo_create(struct drm_device *dev, int size, int align,
235− uint32_t flags, struct ast_bo **pastbo)
236−{
237− struct ast_private *ast = dev->dev_private;
238− struct ast_bo *astbo;
239− size_t acc_size;
240− int ret;
241−
242− astbo = kzalloc(sizeof(struct ast_bo), GFP_KERNEL);
243− if (!astbo)
244− return -ENOMEM;
245−
246− ret = drm_gem_object_init(dev, &astbo->gem, size);
247− if (ret)
248− goto error;
249−
250− astbo->bo.bdev = &ast->ttm.bdev;
251−
252− ast_ttm_placement(astbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
253−
254− acc_size = ttm_bo_dma_acc_size(&ast->ttm.bdev, size,
255− sizeof(struct ast_bo));
256−
257− ret = ttm_bo_init(&ast->ttm.bdev, &astbo->bo, size,
258− ttm_bo_type_device, &astbo->placement,
259− align >> PAGE_SHIFT, false, acc_size,
260− NULL, NULL, ast_bo_ttm_destroy);
261− if (ret)
262− goto error;
263−
264− *pastbo = astbo;
265− return 0;
266−error:
267− kfree(astbo);
268− return ret;
269−}
270−
271−static inline u64 ast_bo_gpu_offset(struct ast_bo *bo)
272−{
273− return bo->bo.offset;
274−}
275−
276−int ast_bo_pin(struct ast_bo *bo, u32 pl_flag, u64 *gpu_addr)
277−{
278− struct ttm_operation_ctx ctx = { false, false };
279− int i, ret;
280−
281− if (bo->pin_count) {
282− bo->pin_count++;
283− if (gpu_addr)
284− *gpu_addr = ast_bo_gpu_offset(bo);
285− }
286−
287− ast_ttm_placement(bo, pl_flag);
288− for (i = 0; i < bo->placement.num_placement; i++)
289− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
290− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
291− if (ret)
292− return ret;
293−
294− bo->pin_count = 1;
295− if (gpu_addr)
296− *gpu_addr = ast_bo_gpu_offset(bo);
297− return 0;
298−}
299−
300−int ast_bo_unpin(struct ast_bo *bo)
301−{
302− struct ttm_operation_ctx ctx = { false, false };
303− int i;
304− if (!bo->pin_count) {
305− DRM_ERROR("unpin bad %p\n", bo);
306− return 0;
307− }
308− bo->pin_count--;
309− if (bo->pin_count)
310− return 0;
311−
312− for (i = 0; i < bo->placement.num_placement ; i++)
313− bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
314− return ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
315−}
316−
317−int ast_bo_push_sysram(struct ast_bo *bo)
318−{
319− struct ttm_operation_ctx ctx = { false, false };
320− int i, ret;
321− if (!bo->pin_count) {
322− DRM_ERROR("unpin bad %p\n", bo);
323− return 0;
324− }
325− bo->pin_count--;
326− if (bo->pin_count)
327− return 0;
328−
329− if (bo->kmap.virtual)
330− ttm_bo_kunmap(&bo->kmap);
331−
332− ast_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
333− for (i = 0; i < bo->placement.num_placement ; i++)
334− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
335−
336− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
337− if (ret) {
338− DRM_ERROR("pushing to VRAM failed\n");
339− return ret;
340− }
341− return 0;
342−}
343−
344−int ast_mmap(struct file *filp, struct vm_area_struct *vma)
345−{
346− struct drm_file *file_priv = filp->private_data;
347− struct ast_private *ast = file_priv->minor->dev->dev_private;
348−
349− return ttm_bo_mmap(filp, vma, &ast->ttm.bdev);
350−}
drivers/gpu/drm/atmel-hlcdc/atmel_hlcdc_plane.c+2−7
@@ -603,8 +603,6 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, · 602 unmodified lines
603603 const struct drm_display_mode *mode;
604604 struct drm_crtc_state *crtc_state;
605605 unsigned int tmp;
606− int hsub = 1;
607− int vsub = 1;
608606 int ret;
609607 int i;
610608
@@ -642,13 +640,10 @@ static int atmel_hlcdc_plane_atomic_check(struct drm_plane *p, · 31 unmodified lines
642640 if (state->nplanes > ATMEL_HLCDC_LAYER_MAX_PLANES)
643641 return -EINVAL;
644642
645− hsub = drm_format_horz_chroma_subsampling(fb->format->format);
646− vsub = drm_format_vert_chroma_subsampling(fb->format->format);
647−
648643 for (i = 0; i < state->nplanes; i++) {
649644 unsigned int offset = 0;
650− int xdiv = i ? hsub : 1;
651− int ydiv = i ? vsub : 1;
645+ int xdiv = i ? fb->format->hsub : 1;
646+ int ydiv = i ? fb->format->vsub : 1;
652647
653648 state->bpp[i] = fb->format->cpp[i];
654649 if (!state->bpp[i])
drivers/gpu/drm/bochs/Kconfig+1−1
@@ -3,7 +3,7 @@ config DRM_BOCHS · 2 unmodified lines
33 tristate "DRM Support for bochs dispi vga interface (qemu stdvga)"
44 depends on DRM && PCI && MMU
55 select DRM_KMS_HELPER
6− select DRM_TTM
6+ select DRM_VRAM_HELPER
77 help
88 Choose this option for qemu.
99 If M is selected the module will be called bochs-drm.
drivers/gpu/drm/bochs/bochs.h+2−52
@@ -10,9 +10,9 @@ · 9 unmodified lines
1010 #include <drm/drm_simple_kms_helper.h>
1111
1212 #include <drm/drm_gem.h>
13+#include <drm/drm_gem_vram_helper.h>
1314
14−#include <drm/ttm/ttm_bo_driver.h>
15−#include <drm/ttm/ttm_page_alloc.h>
15+#include <drm/drm_vram_mm_helper.h>
1616
1717 /* ---------------------------------------------------------------------- */
1818
@@ -73,38 +73,8 @@ struct bochs_device { · 54 unmodified lines
7373 struct drm_device *dev;
7474 struct drm_simple_display_pipe pipe;
7575 struct drm_connector connector;
76−
77− /* ttm */
78− struct {
79− struct ttm_bo_device bdev;
80− bool initialized;
81− } ttm;
82−};
83−
84−struct bochs_bo {
85− struct ttm_buffer_object bo;
86− struct ttm_placement placement;
87− struct ttm_bo_kmap_obj kmap;
88− struct drm_gem_object gem;
89− struct ttm_place placements[3];
90− int pin_count;
9176 };
9277
93−static inline struct bochs_bo *bochs_bo(struct ttm_buffer_object *bo)
94−{
95− return container_of(bo, struct bochs_bo, bo);
96−}
97−
98−static inline struct bochs_bo *gem_to_bochs_bo(struct drm_gem_object *gem)
99−{
100− return container_of(gem, struct bochs_bo, gem);
101−}
102−
103−static inline u64 bochs_bo_mmap_offset(struct bochs_bo *bo)
104−{
105− return drm_vma_node_offset_addr(&bo->bo.vma_node);
106−}
107−
10878 /* ---------------------------------------------------------------------- */
10979
11080 /* bochs_hw.c */
@@ -122,26 +92,6 @@ int bochs_hw_load_edid(struct bochs_device *bochs); · 11 unmodified lines
12292 /* bochs_mm.c */
12393 int bochs_mm_init(struct bochs_device *bochs);
12494 void bochs_mm_fini(struct bochs_device *bochs);
125−int bochs_mmap(struct file *filp, struct vm_area_struct *vma);
126−
127−int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel,
128− struct drm_gem_object **obj);
129−int bochs_gem_init_object(struct drm_gem_object *obj);
130−void bochs_gem_free_object(struct drm_gem_object *obj);
131−int bochs_dumb_create(struct drm_file *file, struct drm_device *dev,
132− struct drm_mode_create_dumb *args);
133−int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
134− uint32_t handle, uint64_t *offset);
135−
136−int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag);
137−int bochs_bo_unpin(struct bochs_bo *bo);
138−
139−int bochs_gem_prime_pin(struct drm_gem_object *obj);
140−void bochs_gem_prime_unpin(struct drm_gem_object *obj);
141−void *bochs_gem_prime_vmap(struct drm_gem_object *obj);
142−void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
143−int bochs_gem_prime_mmap(struct drm_gem_object *obj,
144− struct vm_area_struct *vma);
14595
14696 /* bochs_kms.c */
14797 int bochs_kms_init(struct bochs_device *bochs);
drivers/gpu/drm/bochs/bochs_drv.c+5−19
@@ -10,6 +10,7 @@ · 9 unmodified lines
1010 #include <linux/slab.h>
1111 #include <drm/drm_fb_helper.h>
1212 #include <drm/drm_probe_helper.h>
13+#include <drm/drm_atomic_helper.h>
1314
1415 #include "bochs.h"
1516
@@ -63,14 +64,7 @@ err: · 47 unmodified lines
6364
6465 static const struct file_operations bochs_fops = {
6566 .owner = THIS_MODULE,
66− .open = drm_open,
67− .release = drm_release,
68− .unlocked_ioctl = drm_ioctl,
69− .compat_ioctl = drm_compat_ioctl,
70− .poll = drm_poll,
71− .read = drm_read,
72− .llseek = no_llseek,
73− .mmap = bochs_mmap,
67+ DRM_VRAM_MM_FILE_OPERATIONS
7468 };
7569
7670 static struct drm_driver bochs_driver = {
@@ -82,17 +76,8 @@ static struct drm_driver bochs_driver = { · 5 unmodified lines
8276 .date = "20130925",
8377 .major = 1,
8478 .minor = 0,
85− .gem_free_object_unlocked = bochs_gem_free_object,
86− .dumb_create = bochs_dumb_create,
87− .dumb_map_offset = bochs_dumb_mmap_offset,
88−
89− .gem_prime_export = drm_gem_prime_export,
90− .gem_prime_import = drm_gem_prime_import,
91− .gem_prime_pin = bochs_gem_prime_pin,
92− .gem_prime_unpin = bochs_gem_prime_unpin,
93− .gem_prime_vmap = bochs_gem_prime_vmap,
94− .gem_prime_vunmap = bochs_gem_prime_vunmap,
95− .gem_prime_mmap = bochs_gem_prime_mmap,
79+ DRM_GEM_VRAM_DRIVER,
80+ DRM_GEM_VRAM_DRIVER_PRIME,
9681 };
9782
9883 /* ---------------------------------------------------------------------- */
@@ -174,6 +159,7 @@ static void bochs_pci_remove(struct pci_dev *pdev) · 75 unmodified lines
174159 {
175160 struct drm_device *dev = pci_get_drvdata(pdev);
176161
162+ drm_atomic_helper_shutdown(dev);
177163 drm_dev_unregister(dev);
178164 bochs_unload(dev);
179165 drm_dev_put(dev);
drivers/gpu/drm/bochs/bochs_kms.c+9−9
@@ -30,16 +30,16 @@ static const uint32_t bochs_formats[] = { · 29 unmodified lines
3030 static void bochs_plane_update(struct bochs_device *bochs,
3131 struct drm_plane_state *state)
3232 {
33− struct bochs_bo *bo;
33+ struct drm_gem_vram_object *gbo;
3434
3535 if (!state->fb || !bochs->stride)
3636 return;
3737
38− bo = gem_to_bochs_bo(state->fb->obj[0]);
38+ gbo = drm_gem_vram_of_gem(state->fb->obj[0]);
3939 bochs_hw_setbase(bochs,
4040 state->crtc_x,
4141 state->crtc_y,
42− bo->bo.offset);
42+ gbo->bo.offset);
4343 bochs_hw_setformat(bochs, state->fb->format);
4444 }
4545
@@ -72,23 +72,23 @@ static void bochs_pipe_update(struct drm_simple_display_pipe *pipe, · 26 unmodified lines
7272 static int bochs_pipe_prepare_fb(struct drm_simple_display_pipe *pipe,
7373 struct drm_plane_state *new_state)
7474 {
75− struct bochs_bo *bo;
75+ struct drm_gem_vram_object *gbo;
7676
7777 if (!new_state->fb)
7878 return 0;
79− bo = gem_to_bochs_bo(new_state->fb->obj[0]);
80− return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
79+ gbo = drm_gem_vram_of_gem(new_state->fb->obj[0]);
80+ return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
8181 }
8282
8383 static void bochs_pipe_cleanup_fb(struct drm_simple_display_pipe *pipe,
8484 struct drm_plane_state *old_state)
8585 {
86− struct bochs_bo *bo;
86+ struct drm_gem_vram_object *gbo;
8787
8888 if (!old_state->fb)
8989 return;
90− bo = gem_to_bochs_bo(old_state->fb->obj[0]);
91− bochs_bo_unpin(bo);
90+ gbo = drm_gem_vram_of_gem(old_state->fb->obj[0]);
91+ drm_gem_vram_unpin(gbo);
9292 }
9393
9494 static const struct drm_simple_display_pipe_funcs bochs_pipe_funcs = {
drivers/gpu/drm/bochs/bochs_mm.c+7−420
@@ -7,435 +7,22 @@ · 6 unmodified lines
77
88 #include "bochs.h"
99
10−static void bochs_ttm_placement(struct bochs_bo *bo, int domain);
11−
1210 /* ---------------------------------------------------------------------- */
1311
14−static inline struct bochs_device *bochs_bdev(struct ttm_bo_device *bd)
15−{
16− return container_of(bd, struct bochs_device, ttm.bdev);
17−}
18−
19−static void bochs_bo_ttm_destroy(struct ttm_buffer_object *tbo)
20−{
21− struct bochs_bo *bo;
22−
23− bo = container_of(tbo, struct bochs_bo, bo);
24− drm_gem_object_release(&bo->gem);
25− kfree(bo);
26−}
27−
28−static bool bochs_ttm_bo_is_bochs_bo(struct ttm_buffer_object *bo)
29−{
30− if (bo->destroy == &bochs_bo_ttm_destroy)
31− return true;
32− return false;
33−}
34−
35−static int bochs_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
36− struct ttm_mem_type_manager *man)
37−{
38− switch (type) {
39− case TTM_PL_SYSTEM:
40− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
41− man->available_caching = TTM_PL_MASK_CACHING;
42− man->default_caching = TTM_PL_FLAG_CACHED;
43− break;
44− case TTM_PL_VRAM:
45− man->func = &ttm_bo_manager_func;
46− man->flags = TTM_MEMTYPE_FLAG_FIXED |
47− TTM_MEMTYPE_FLAG_MAPPABLE;
48− man->available_caching = TTM_PL_FLAG_UNCACHED |
49− TTM_PL_FLAG_WC;
50− man->default_caching = TTM_PL_FLAG_WC;
51− break;
52− default:
53− DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
54− return -EINVAL;
55− }
56− return 0;
57−}
58−
59−static void
60−bochs_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
61−{
62− struct bochs_bo *bochsbo = bochs_bo(bo);
63−
64− if (!bochs_ttm_bo_is_bochs_bo(bo))
65− return;
66−
67− bochs_ttm_placement(bochsbo, TTM_PL_FLAG_SYSTEM);
68− *pl = bochsbo->placement;
69−}
70−
71−static int bochs_bo_verify_access(struct ttm_buffer_object *bo,
72− struct file *filp)
73−{
74− struct bochs_bo *bochsbo = bochs_bo(bo);
75−
76− return drm_vma_node_verify_access(&bochsbo->gem.vma_node,
77− filp->private_data);
78−}
79−
80−static int bochs_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
81− struct ttm_mem_reg *mem)
82−{
83− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
84− struct bochs_device *bochs = bochs_bdev(bdev);
85−
86− mem->bus.addr = NULL;
87− mem->bus.offset = 0;
88− mem->bus.size = mem->num_pages << PAGE_SHIFT;
89− mem->bus.base = 0;
90− mem->bus.is_iomem = false;
91− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
92− return -EINVAL;
93− switch (mem->mem_type) {
94− case TTM_PL_SYSTEM:
95− /* system memory */
96− return 0;
97− case TTM_PL_VRAM:
98− mem->bus.offset = mem->start << PAGE_SHIFT;
99− mem->bus.base = bochs->fb_base;
100− mem->bus.is_iomem = true;
101− break;
102− default:
103− return -EINVAL;
104− break;
105− }
106− return 0;
107−}
108−
109−static void bochs_ttm_io_mem_free(struct ttm_bo_device *bdev,
110− struct ttm_mem_reg *mem)
111−{
112−}
113−
114−static void bochs_ttm_backend_destroy(struct ttm_tt *tt)
115−{
116− ttm_tt_fini(tt);
117− kfree(tt);
118−}
119−
120−static struct ttm_backend_func bochs_tt_backend_func = {
121− .destroy = &bochs_ttm_backend_destroy,
122−};
123−
124−static struct ttm_tt *bochs_ttm_tt_create(struct ttm_buffer_object *bo,
125− uint32_t page_flags)
126−{
127− struct ttm_tt *tt;
128−
129− tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
130− if (tt == NULL)
131− return NULL;
132− tt->func = &bochs_tt_backend_func;
133− if (ttm_tt_init(tt, bo, page_flags)) {
134− kfree(tt);
135− return NULL;
136− }
137− return tt;
138−}
139−
140−static struct ttm_bo_driver bochs_bo_driver = {
141− .ttm_tt_create = bochs_ttm_tt_create,
142− .init_mem_type = bochs_bo_init_mem_type,
143− .eviction_valuable = ttm_bo_eviction_valuable,
144− .evict_flags = bochs_bo_evict_flags,
145− .move = NULL,
146− .verify_access = bochs_bo_verify_access,
147− .io_mem_reserve = &bochs_ttm_io_mem_reserve,
148− .io_mem_free = &bochs_ttm_io_mem_free,
149−};
150−
15112 int bochs_mm_init(struct bochs_device *bochs)
15213 {
153− struct ttm_bo_device *bdev = &bochs->ttm.bdev;
154− int ret;
14+ struct drm_vram_mm *vmm;
15515
156− ret = ttm_bo_device_init(&bochs->ttm.bdev,
157− &bochs_bo_driver,
158− bochs->dev->anon_inode->i_mapping,
159− true);
160− if (ret) {
161− DRM_ERROR("Error initialising bo driver; %d\n", ret);
162− return ret;
163− }
164−
165− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
166− bochs->fb_size >> PAGE_SHIFT);
167− if (ret) {
168− DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
169− return ret;
170− }
171−
172− bochs->ttm.initialized = true;
173− return 0;
16+ vmm = drm_vram_helper_alloc_mm(bochs->dev, bochs->fb_base,
17+ bochs->fb_size,
18+ &drm_gem_vram_mm_funcs);
19+ return PTR_ERR_OR_ZERO(vmm);
17420 }
17521
17622 void bochs_mm_fini(struct bochs_device *bochs)
17723 {
178− if (!bochs->ttm.initialized)
24+ if (!bochs->dev->vram_mm)
17925 return;
18026
181− ttm_bo_device_release(&bochs->ttm.bdev);
182− bochs->ttm.initialized = false;
183−}
184−
185−static void bochs_ttm_placement(struct bochs_bo *bo, int domain)
186−{
187− unsigned i;
188− u32 c = 0;
189− bo->placement.placement = bo->placements;
190− bo->placement.busy_placement = bo->placements;
191− if (domain & TTM_PL_FLAG_VRAM) {
192− bo->placements[c++].flags = TTM_PL_FLAG_WC
193− | TTM_PL_FLAG_UNCACHED
194− | TTM_PL_FLAG_VRAM;
195− }
196− if (domain & TTM_PL_FLAG_SYSTEM) {
197− bo->placements[c++].flags = TTM_PL_MASK_CACHING
198− | TTM_PL_FLAG_SYSTEM;
199− }
200− if (!c) {
201− bo->placements[c++].flags = TTM_PL_MASK_CACHING
202− | TTM_PL_FLAG_SYSTEM;
203− }
204− for (i = 0; i < c; ++i) {
205− bo->placements[i].fpfn = 0;
206− bo->placements[i].lpfn = 0;
207− }
208− bo->placement.num_placement = c;
209− bo->placement.num_busy_placement = c;
210−}
211−
212−int bochs_bo_pin(struct bochs_bo *bo, u32 pl_flag)
213−{
214− struct ttm_operation_ctx ctx = { false, false };
215− int i, ret;
216−
217− if (bo->pin_count) {
218− bo->pin_count++;
219− return 0;
220− }
221−
222− bochs_ttm_placement(bo, pl_flag);
223− for (i = 0; i < bo->placement.num_placement; i++)
224− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
225− ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
226− if (ret)
227− return ret;
228− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
229− ttm_bo_unreserve(&bo->bo);
230− if (ret)
231− return ret;
232−
233− bo->pin_count = 1;
234− return 0;
235−}
236−
237−int bochs_bo_unpin(struct bochs_bo *bo)
238−{
239− struct ttm_operation_ctx ctx = { false, false };
240− int i, ret;
241−
242− if (!bo->pin_count) {
243− DRM_ERROR("unpin bad %p\n", bo);
244− return 0;
245− }
246− bo->pin_count--;
247−
248− if (bo->pin_count)
249− return 0;
250−
251− for (i = 0; i < bo->placement.num_placement; i++)
252− bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
253− ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
254− if (ret)
255− return ret;
256− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
257− ttm_bo_unreserve(&bo->bo);
258− if (ret)
259− return ret;
260−
261− return 0;
262−}
263−
264−int bochs_mmap(struct file *filp, struct vm_area_struct *vma)
265−{
266− struct drm_file *file_priv = filp->private_data;
267− struct bochs_device *bochs = file_priv->minor->dev->dev_private;
268−
269− return ttm_bo_mmap(filp, vma, &bochs->ttm.bdev);
270−}
271−
272−/* ---------------------------------------------------------------------- */
273−
274−static int bochs_bo_create(struct drm_device *dev, int size, int align,
275− uint32_t flags, struct bochs_bo **pbochsbo)
276−{
277− struct bochs_device *bochs = dev->dev_private;
278− struct bochs_bo *bochsbo;
279− size_t acc_size;
280− int ret;
281−
282− bochsbo = kzalloc(sizeof(struct bochs_bo), GFP_KERNEL);
283− if (!bochsbo)
284− return -ENOMEM;
285−
286− ret = drm_gem_object_init(dev, &bochsbo->gem, size);
287− if (ret) {
288− kfree(bochsbo);
289− return ret;
290− }
291−
292− bochsbo->bo.bdev = &bochs->ttm.bdev;
293− bochsbo->bo.bdev->dev_mapping = dev->anon_inode->i_mapping;
294−
295− bochs_ttm_placement(bochsbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
296−
297− acc_size = ttm_bo_dma_acc_size(&bochs->ttm.bdev, size,
298− sizeof(struct bochs_bo));
299−
300− ret = ttm_bo_init(&bochs->ttm.bdev, &bochsbo->bo, size,
301− ttm_bo_type_device, &bochsbo->placement,
302− align >> PAGE_SHIFT, false, acc_size,
303− NULL, NULL, bochs_bo_ttm_destroy);
304− if (ret)
305− return ret;
306−
307− *pbochsbo = bochsbo;
308− return 0;
309−}
310−
311−int bochs_gem_create(struct drm_device *dev, u32 size, bool iskernel,
312− struct drm_gem_object **obj)
313−{
314− struct bochs_bo *bochsbo;
315− int ret;
316−
317− *obj = NULL;
318−
319− size = PAGE_ALIGN(size);
320− if (size == 0)
321− return -EINVAL;
322−
323− ret = bochs_bo_create(dev, size, 0, 0, &bochsbo);
324− if (ret) {
325− if (ret != -ERESTARTSYS)
326− DRM_ERROR("failed to allocate GEM object\n");
327− return ret;
328− }
329− *obj = &bochsbo->gem;
330− return 0;
331−}
332−
333−int bochs_dumb_create(struct drm_file *file, struct drm_device *dev,
334− struct drm_mode_create_dumb *args)
335−{
336− struct drm_gem_object *gobj;
337− u32 handle;
338− int ret;
339−
340− args->pitch = args->width * ((args->bpp + 7) / 8);
341− args->size = args->pitch * args->height;
342−
343− ret = bochs_gem_create(dev, args->size, false,
344− &gobj);
345− if (ret)
346− return ret;
347−
348− ret = drm_gem_handle_create(file, gobj, &handle);
349− drm_gem_object_put_unlocked(gobj);
350− if (ret)
351− return ret;
352−
353− args->handle = handle;
354− return 0;
355−}
356−
357−static void bochs_bo_unref(struct bochs_bo **bo)
358−{
359− struct ttm_buffer_object *tbo;
360−
361− if ((*bo) == NULL)
362− return;
363−
364− tbo = &((*bo)->bo);
365− ttm_bo_put(tbo);
366− *bo = NULL;
367−}
368−
369−void bochs_gem_free_object(struct drm_gem_object *obj)
370−{
371− struct bochs_bo *bochs_bo = gem_to_bochs_bo(obj);
372−
373− bochs_bo_unref(&bochs_bo);
374−}
375−
376−int bochs_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
377− uint32_t handle, uint64_t *offset)
378−{
379− struct drm_gem_object *obj;
380− struct bochs_bo *bo;
381−
382− obj = drm_gem_object_lookup(file, handle);
383− if (obj == NULL)
384− return -ENOENT;
385−
386− bo = gem_to_bochs_bo(obj);
387− *offset = bochs_bo_mmap_offset(bo);
388−
389− drm_gem_object_put_unlocked(obj);
390− return 0;
391−}
392−
393−/* ---------------------------------------------------------------------- */
394−
395−int bochs_gem_prime_pin(struct drm_gem_object *obj)
396−{
397− struct bochs_bo *bo = gem_to_bochs_bo(obj);
398−
399− return bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
400−}
401−
402−void bochs_gem_prime_unpin(struct drm_gem_object *obj)
403−{
404− struct bochs_bo *bo = gem_to_bochs_bo(obj);
405−
406− bochs_bo_unpin(bo);
407−}
408−
409−void *bochs_gem_prime_vmap(struct drm_gem_object *obj)
410−{
411− struct bochs_bo *bo = gem_to_bochs_bo(obj);
412− bool is_iomem;
413− int ret;
414−
415− ret = bochs_bo_pin(bo, TTM_PL_FLAG_VRAM);
416− if (ret)
417− return NULL;
418− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
419− if (ret) {
420− bochs_bo_unpin(bo);
421− return NULL;
422− }
423− return ttm_kmap_obj_virtual(&bo->kmap, &is_iomem);
424−}
425−
426−void bochs_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
427−{
428− struct bochs_bo *bo = gem_to_bochs_bo(obj);
429−
430− ttm_bo_kunmap(&bo->kmap);
431− bochs_bo_unpin(bo);
432−}
433−
434−int bochs_gem_prime_mmap(struct drm_gem_object *obj,
435− struct vm_area_struct *vma)
436−{
437− struct bochs_bo *bo = gem_to_bochs_bo(obj);
438−
439− bo->gem.vma_node.vm_node.start = bo->bo.vma_node.vm_node.start;
440− return drm_gem_prime_mmap(obj, vma);
27+ drm_vram_helper_release_mm(bochs->dev);
44128 }
drivers/gpu/drm/bridge/panel.c+1−2
@@ -9,13 +9,12 @@ · 8 unmodified lines
99 */
1010
1111 #include <drm/drmP.h>
12−#include <drm/drm_panel.h>
1312 #include <drm/drm_atomic_helper.h>
1413 #include <drm/drm_connector.h>
1514 #include <drm/drm_encoder.h>
1615 #include <drm/drm_modeset_helper_vtables.h>
17−#include <drm/drm_probe_helper.h>
1816 #include <drm/drm_panel.h>
17+#include <drm/drm_probe_helper.h>
1918
2019 struct panel_bridge {
2120 struct drm_bridge bridge;
drivers/gpu/drm/cirrus/cirrus_drv.h+0−250
@@ -1,250 +0,0 @@
1−/*
2− * Copyright 2012 Red Hat
3− *
4− * This file is subject to the terms and conditions of the GNU General
5− * Public License version 2. See the file COPYING in the main
6− * directory of this archive for more details.
7− *
8− * Authors: Matthew Garrett
9− * Dave Airlie
10− */
11−#ifndef __CIRRUS_DRV_H__
12−#define __CIRRUS_DRV_H__
13−
14−#include <video/vga.h>
15−
16−#include <drm/drm_encoder.h>
17−#include <drm/drm_fb_helper.h>
18−
19−#include <drm/ttm/ttm_bo_api.h>
20−#include <drm/ttm/ttm_bo_driver.h>
21−#include <drm/ttm/ttm_placement.h>
22−#include <drm/ttm/ttm_memory.h>
23−#include <drm/ttm/ttm_module.h>
24−
25−#include <drm/drm_gem.h>
26−
27−#define DRIVER_AUTHOR "Matthew Garrett"
28−
29−#define DRIVER_NAME "cirrus"
30−#define DRIVER_DESC "qemu Cirrus emulation"
31−#define DRIVER_DATE "20110418"
32−
33−#define DRIVER_MAJOR 1
34−#define DRIVER_MINOR 0
35−#define DRIVER_PATCHLEVEL 0
36−
37−#define CIRRUSFB_CONN_LIMIT 1
38−
39−#define RREG8(reg) ioread8(((void __iomem *)cdev->rmmio) + (reg))
40−#define WREG8(reg, v) iowrite8(v, ((void __iomem *)cdev->rmmio) + (reg))
41−#define RREG32(reg) ioread32(((void __iomem *)cdev->rmmio) + (reg))
42−#define WREG32(reg, v) iowrite32(v, ((void __iomem *)cdev->rmmio) + (reg))
43−
44−#define SEQ_INDEX 4
45−#define SEQ_DATA 5
46−
47−#define WREG_SEQ(reg, v) \
48− do { \
49− WREG8(SEQ_INDEX, reg); \
50− WREG8(SEQ_DATA, v); \
51− } while (0) \
52−
53−#define CRT_INDEX 0x14
54−#define CRT_DATA 0x15
55−
56−#define WREG_CRT(reg, v) \
57− do { \
58− WREG8(CRT_INDEX, reg); \
59− WREG8(CRT_DATA, v); \
60− } while (0) \
61−
62−#define GFX_INDEX 0xe
63−#define GFX_DATA 0xf
64−
65−#define WREG_GFX(reg, v) \
66− do { \
67− WREG8(GFX_INDEX, reg); \
68− WREG8(GFX_DATA, v); \
69− } while (0) \
70−
71−/*
72− * Cirrus has a "hidden" DAC register that can be accessed by writing to
73− * the pixel mask register to reset the state, then reading from the register
74− * four times. The next write will then pass to the DAC
75− */
76−#define VGA_DAC_MASK 0x6
77−
78−#define WREG_HDR(v) \
79− do { \
80− RREG8(VGA_DAC_MASK); \
81− RREG8(VGA_DAC_MASK); \
82− RREG8(VGA_DAC_MASK); \
83− RREG8(VGA_DAC_MASK); \
84− WREG8(VGA_DAC_MASK, v); \
85− } while (0) \
86−
87−
88−#define CIRRUS_MAX_FB_HEIGHT 4096
89−#define CIRRUS_MAX_FB_WIDTH 4096
90−
91−#define CIRRUS_DPMS_CLEARED (-1)
92−
93−#define to_cirrus_crtc(x) container_of(x, struct cirrus_crtc, base)
94−#define to_cirrus_encoder(x) container_of(x, struct cirrus_encoder, base)
95−
96−struct cirrus_crtc {
97− struct drm_crtc base;
98− int last_dpms;
99− bool enabled;
100−};
101−
102−struct cirrus_fbdev;
103−struct cirrus_mode_info {
104− struct cirrus_crtc *crtc;
105− /* pointer to fbdev info structure */
106− struct cirrus_fbdev *gfbdev;
107−};
108−
109−struct cirrus_encoder {
110− struct drm_encoder base;
111− int last_dpms;
112−};
113−
114−struct cirrus_connector {
115− struct drm_connector base;
116−};
117−
118−struct cirrus_mc {
119− resource_size_t vram_size;
120− resource_size_t vram_base;
121−};
122−
123−struct cirrus_device {
124− struct drm_device *dev;
125− unsigned long flags;
126−
127− resource_size_t rmmio_base;
128− resource_size_t rmmio_size;
129− void __iomem *rmmio;
130−
131− struct cirrus_mc mc;
132− struct cirrus_mode_info mode_info;
133−
134− int num_crtc;
135− int fb_mtrr;
136−
137− struct {
138− struct ttm_bo_device bdev;
139− } ttm;
140− bool mm_inited;
141−};
142−
143−
144−struct cirrus_fbdev {
145− struct drm_fb_helper helper; /* must be first */
146− struct drm_framebuffer *gfb;
147− void *sysram;
148− int size;
149− int x1, y1, x2, y2; /* dirty rect */
150− spinlock_t dirty_lock;
151−};
152−
153−struct cirrus_bo {
154− struct ttm_buffer_object bo;
155− struct ttm_placement placement;
156− struct ttm_bo_kmap_obj kmap;
157− struct drm_gem_object gem;
158− struct ttm_place placements[3];
159− int pin_count;
160−};
161−#define gem_to_cirrus_bo(gobj) container_of((gobj), struct cirrus_bo, gem)
162−
163−static inline struct cirrus_bo *
164−cirrus_bo(struct ttm_buffer_object *bo)
165−{
166− return container_of(bo, struct cirrus_bo, bo);
167−}
168−
169−
170−#define to_cirrus_obj(x) container_of(x, struct cirrus_gem_object, base)
171−
172− /* cirrus_main.c */
173−int cirrus_device_init(struct cirrus_device *cdev,
174− struct drm_device *ddev,
175− struct pci_dev *pdev,
176− uint32_t flags);
177−void cirrus_device_fini(struct cirrus_device *cdev);
178−void cirrus_gem_free_object(struct drm_gem_object *obj);
179−int cirrus_dumb_mmap_offset(struct drm_file *file,
180− struct drm_device *dev,
181− uint32_t handle,
182− uint64_t *offset);
183−int cirrus_gem_create(struct drm_device *dev,
184− u32 size, bool iskernel,
185− struct drm_gem_object **obj);
186−int cirrus_dumb_create(struct drm_file *file,
187− struct drm_device *dev,
188− struct drm_mode_create_dumb *args);
189−
190−int cirrus_framebuffer_init(struct drm_device *dev,
191− struct drm_framebuffer *gfb,
192− const struct drm_mode_fb_cmd2 *mode_cmd,
193− struct drm_gem_object *obj);
194−
195−bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
196− int bpp, int pitch);
197−
198− /* cirrus_display.c */
199−int cirrus_modeset_init(struct cirrus_device *cdev);
200−void cirrus_modeset_fini(struct cirrus_device *cdev);
201−
202− /* cirrus_fbdev.c */
203−int cirrus_fbdev_init(struct cirrus_device *cdev);
204−void cirrus_fbdev_fini(struct cirrus_device *cdev);
205−
206−
207−
208− /* cirrus_irq.c */
209−void cirrus_driver_irq_preinstall(struct drm_device *dev);
210−int cirrus_driver_irq_postinstall(struct drm_device *dev);
211−void cirrus_driver_irq_uninstall(struct drm_device *dev);
212−irqreturn_t cirrus_driver_irq_handler(int irq, void *arg);
213−
214− /* cirrus_kms.c */
215−int cirrus_driver_load(struct drm_device *dev, unsigned long flags);
216−void cirrus_driver_unload(struct drm_device *dev);
217−extern struct drm_ioctl_desc cirrus_ioctls[];
218−extern int cirrus_max_ioctl;
219−
220−int cirrus_mm_init(struct cirrus_device *cirrus);
221−void cirrus_mm_fini(struct cirrus_device *cirrus);
222−void cirrus_ttm_placement(struct cirrus_bo *bo, int domain);
223−int cirrus_bo_create(struct drm_device *dev, int size, int align,
224− uint32_t flags, struct cirrus_bo **pcirrusbo);
225−int cirrus_mmap(struct file *filp, struct vm_area_struct *vma);
226−
227−static inline int cirrus_bo_reserve(struct cirrus_bo *bo, bool no_wait)
228−{
229− int ret;
230−
231− ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
232− if (ret) {
233− if (ret != -ERESTARTSYS && ret != -EBUSY)
234− DRM_ERROR("reserve failed %p\n", bo);
235− return ret;
236− }
237− return 0;
238−}
239−
240−static inline void cirrus_bo_unreserve(struct cirrus_bo *bo)
241−{
242− ttm_bo_unreserve(&bo->bo);
243−}
244−
245−int cirrus_bo_push_sysram(struct cirrus_bo *bo);
246−int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr);
247−
248−extern int cirrus_bpp;
249−
250−#endif /* __CIRRUS_DRV_H__ */
drivers/gpu/drm/cirrus/cirrus_ttm.c+0−337
@@ -1,337 +0,0 @@
1−/*
2− * Copyright 2012 Red Hat Inc.
3− *
4− * Permission is hereby granted, free of charge, to any person obtaining a
5− * copy of this software and associated documentation files (the
6− * "Software"), to deal in the Software without restriction, including
7− * without limitation the rights to use, copy, modify, merge, publish,
8− * distribute, sub license, and/or sell copies of the Software, and to
9− * permit persons to whom the Software is furnished to do so, subject to
10− * the following conditions:
11− *
12− * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13− * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
14− * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
15− * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
16− * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
17− * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
18− * USE OR OTHER DEALINGS IN THE SOFTWARE.
19− *
20− * The above copyright notice and this permission notice (including the
21− * next paragraph) shall be included in all copies or substantial portions
22− * of the Software.
23− *
24− */
25−/*
26− * Authors: Dave Airlie <airlied@redhat.com>
27− */
28−#include <drm/drmP.h>
29−#include <drm/ttm/ttm_page_alloc.h>
30−
31−#include "cirrus_drv.h"
32−
33−static inline struct cirrus_device *
34−cirrus_bdev(struct ttm_bo_device *bd)
35−{
36− return container_of(bd, struct cirrus_device, ttm.bdev);
37−}
38−
39−static void cirrus_bo_ttm_destroy(struct ttm_buffer_object *tbo)
40−{
41− struct cirrus_bo *bo;
42−
43− bo = container_of(tbo, struct cirrus_bo, bo);
44−
45− drm_gem_object_release(&bo->gem);
46− kfree(bo);
47−}
48−
49−static bool cirrus_ttm_bo_is_cirrus_bo(struct ttm_buffer_object *bo)
50−{
51− if (bo->destroy == &cirrus_bo_ttm_destroy)
52− return true;
53− return false;
54−}
55−
56−static int
57−cirrus_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
58− struct ttm_mem_type_manager *man)
59−{
60− switch (type) {
61− case TTM_PL_SYSTEM:
62− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
63− man->available_caching = TTM_PL_MASK_CACHING;
64− man->default_caching = TTM_PL_FLAG_CACHED;
65− break;
66− case TTM_PL_VRAM:
67− man->func = &ttm_bo_manager_func;
68− man->flags = TTM_MEMTYPE_FLAG_FIXED |
69− TTM_MEMTYPE_FLAG_MAPPABLE;
70− man->available_caching = TTM_PL_FLAG_UNCACHED |
71− TTM_PL_FLAG_WC;
72− man->default_caching = TTM_PL_FLAG_WC;
73− break;
74− default:
75− DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
76− return -EINVAL;
77− }
78− return 0;
79−}
80−
81−static void
82−cirrus_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
83−{
84− struct cirrus_bo *cirrusbo = cirrus_bo(bo);
85−
86− if (!cirrus_ttm_bo_is_cirrus_bo(bo))
87− return;
88−
89− cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_SYSTEM);
90− *pl = cirrusbo->placement;
91−}
92−
93−static int cirrus_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
94−{
95− struct cirrus_bo *cirrusbo = cirrus_bo(bo);
96−
97− return drm_vma_node_verify_access(&cirrusbo->gem.vma_node,
98− filp->private_data);
99−}
100−
101−static int cirrus_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
102− struct ttm_mem_reg *mem)
103−{
104− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
105− struct cirrus_device *cirrus = cirrus_bdev(bdev);
106−
107− mem->bus.addr = NULL;
108− mem->bus.offset = 0;
109− mem->bus.size = mem->num_pages << PAGE_SHIFT;
110− mem->bus.base = 0;
111− mem->bus.is_iomem = false;
112− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
113− return -EINVAL;
114− switch (mem->mem_type) {
115− case TTM_PL_SYSTEM:
116− /* system memory */
117− return 0;
118− case TTM_PL_VRAM:
119− mem->bus.offset = mem->start << PAGE_SHIFT;
120− mem->bus.base = pci_resource_start(cirrus->dev->pdev, 0);
121− mem->bus.is_iomem = true;
122− break;
123− default:
124− return -EINVAL;
125− break;
126− }
127− return 0;
128−}
129−
130−static void cirrus_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
131−{
132−}
133−
134−static void cirrus_ttm_backend_destroy(struct ttm_tt *tt)
135−{
136− ttm_tt_fini(tt);
137− kfree(tt);
138−}
139−
140−static struct ttm_backend_func cirrus_tt_backend_func = {
141− .destroy = &cirrus_ttm_backend_destroy,
142−};
143−
144−
145−static struct ttm_tt *cirrus_ttm_tt_create(struct ttm_buffer_object *bo,
146− uint32_t page_flags)
147−{
148− struct ttm_tt *tt;
149−
150− tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
151− if (tt == NULL)
152− return NULL;
153− tt->func = &cirrus_tt_backend_func;
154− if (ttm_tt_init(tt, bo, page_flags)) {
155− kfree(tt);
156− return NULL;
157− }
158− return tt;
159−}
160−
161−struct ttm_bo_driver cirrus_bo_driver = {
162− .ttm_tt_create = cirrus_ttm_tt_create,
163− .init_mem_type = cirrus_bo_init_mem_type,
164− .eviction_valuable = ttm_bo_eviction_valuable,
165− .evict_flags = cirrus_bo_evict_flags,
166− .move = NULL,
167− .verify_access = cirrus_bo_verify_access,
168− .io_mem_reserve = &cirrus_ttm_io_mem_reserve,
169− .io_mem_free = &cirrus_ttm_io_mem_free,
170−};
171−
172−int cirrus_mm_init(struct cirrus_device *cirrus)
173−{
174− int ret;
175− struct drm_device *dev = cirrus->dev;
176− struct ttm_bo_device *bdev = &cirrus->ttm.bdev;
177−
178− ret = ttm_bo_device_init(&cirrus->ttm.bdev,
179− &cirrus_bo_driver,
180− dev->anon_inode->i_mapping,
181− true);
182− if (ret) {
183− DRM_ERROR("Error initialising bo driver; %d\n", ret);
184− return ret;
185− }
186−
187− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
188− cirrus->mc.vram_size >> PAGE_SHIFT);
189− if (ret) {
190− DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
191− return ret;
192− }
193−
194− arch_io_reserve_memtype_wc(pci_resource_start(dev->pdev, 0),
195− pci_resource_len(dev->pdev, 0));
196−
197− cirrus->fb_mtrr = arch_phys_wc_add(pci_resource_start(dev->pdev, 0),
198− pci_resource_len(dev->pdev, 0));
199−
200− cirrus->mm_inited = true;
201− return 0;
202−}
203−
204−void cirrus_mm_fini(struct cirrus_device *cirrus)
205−{
206− struct drm_device *dev = cirrus->dev;
207−
208− if (!cirrus->mm_inited)
209− return;
210−
211− ttm_bo_device_release(&cirrus->ttm.bdev);
212−
213− arch_phys_wc_del(cirrus->fb_mtrr);
214− cirrus->fb_mtrr = 0;
215− arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
216− pci_resource_len(dev->pdev, 0));
217−}
218−
219−void cirrus_ttm_placement(struct cirrus_bo *bo, int domain)
220−{
221− u32 c = 0;
222− unsigned i;
223− bo->placement.placement = bo->placements;
224− bo->placement.busy_placement = bo->placements;
225− if (domain & TTM_PL_FLAG_VRAM)
226− bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
227− if (domain & TTM_PL_FLAG_SYSTEM)
228− bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
229− if (!c)
230− bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
231− bo->placement.num_placement = c;
232− bo->placement.num_busy_placement = c;
233− for (i = 0; i < c; ++i) {
234− bo->placements[i].fpfn = 0;
235− bo->placements[i].lpfn = 0;
236− }
237−}
238−
239−int cirrus_bo_create(struct drm_device *dev, int size, int align,
240− uint32_t flags, struct cirrus_bo **pcirrusbo)
241−{
242− struct cirrus_device *cirrus = dev->dev_private;
243− struct cirrus_bo *cirrusbo;
244− size_t acc_size;
245− int ret;
246−
247− cirrusbo = kzalloc(sizeof(struct cirrus_bo), GFP_KERNEL);
248− if (!cirrusbo)
249− return -ENOMEM;
250−
251− ret = drm_gem_object_init(dev, &cirrusbo->gem, size);
252− if (ret) {
253− kfree(cirrusbo);
254− return ret;
255− }
256−
257− cirrusbo->bo.bdev = &cirrus->ttm.bdev;
258−
259− cirrus_ttm_placement(cirrusbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
260−
261− acc_size = ttm_bo_dma_acc_size(&cirrus->ttm.bdev, size,
262− sizeof(struct cirrus_bo));
263−
264− ret = ttm_bo_init(&cirrus->ttm.bdev, &cirrusbo->bo, size,
265− ttm_bo_type_device, &cirrusbo->placement,
266− align >> PAGE_SHIFT, false, acc_size,
267− NULL, NULL, cirrus_bo_ttm_destroy);
268− if (ret)
269− return ret;
270−
271− *pcirrusbo = cirrusbo;
272− return 0;
273−}
274−
275−static inline u64 cirrus_bo_gpu_offset(struct cirrus_bo *bo)
276−{
277− return bo->bo.offset;
278−}
279−
280−int cirrus_bo_pin(struct cirrus_bo *bo, u32 pl_flag, u64 *gpu_addr)
281−{
282− struct ttm_operation_ctx ctx = { false, false };
283− int i, ret;
284−
285− if (bo->pin_count) {
286− bo->pin_count++;
287− if (gpu_addr)
288− *gpu_addr = cirrus_bo_gpu_offset(bo);
289− }
290−
291− cirrus_ttm_placement(bo, pl_flag);
292− for (i = 0; i < bo->placement.num_placement; i++)
293− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
294− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
295− if (ret)
296− return ret;
297−
298− bo->pin_count = 1;
299− if (gpu_addr)
300− *gpu_addr = cirrus_bo_gpu_offset(bo);
301− return 0;
302−}
303−
304−int cirrus_bo_push_sysram(struct cirrus_bo *bo)
305−{
306− struct ttm_operation_ctx ctx = { false, false };
307− int i, ret;
308− if (!bo->pin_count) {
309− DRM_ERROR("unpin bad %p\n", bo);
310− return 0;
311− }
312− bo->pin_count--;
313− if (bo->pin_count)
314− return 0;
315−
316− if (bo->kmap.virtual)
317− ttm_bo_kunmap(&bo->kmap);
318−
319− cirrus_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
320− for (i = 0; i < bo->placement.num_placement ; i++)
321− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
322−
323− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
324− if (ret) {
325− DRM_ERROR("pushing to VRAM failed\n");
326− return ret;
327− }
328− return 0;
329−}
330−
331−int cirrus_mmap(struct file *filp, struct vm_area_struct *vma)
332−{
333− struct drm_file *file_priv = filp->private_data;
334− struct cirrus_device *cirrus = file_priv->minor->dev->dev_private;
335−
336− return ttm_bo_mmap(filp, vma, &cirrus->ttm.bdev);
337−}
drivers/gpu/drm/drm_atomic_helper.c+1−1
@@ -1423,7 +1423,7 @@ drm_atomic_helper_wait_for_vblanks(struct drm_device *dev, · 1422 unmodified lines
14231423 ret = wait_event_timeout(dev->vblank[i].queue,
14241424 old_state->crtcs[i].last_vblank_count !=
14251425 drm_crtc_vblank_count(crtc),
1426− msecs_to_jiffies(50));
1426+ msecs_to_jiffies(100));
14271427
14281428 WARN(!ret, "[CRTC:%d:%s] vblank wait timed out\n",
14291429 crtc->base.id, crtc->name);
drivers/gpu/drm/drm_atomic_state_helper.c+34−7
@@ -56,6 +56,29 @@ · 55 unmodified lines
5656 * for these functions.
5757 */
5858
59+/**
60+ * __drm_atomic_helper_crtc_reset - reset state on CRTC
61+ * @crtc: drm CRTC
62+ * @crtc_state: CRTC state to assign
63+ *
64+ * Initializes the newly allocated @crtc_state and assigns it to
65+ * the &drm_crtc->state pointer of @crtc, usually required when
66+ * initializing the drivers or when called from the &drm_crtc_funcs.reset
67+ * hook.
68+ *
69+ * This is useful for drivers that subclass the CRTC state.
70+ */
71+void
72+__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
73+ struct drm_crtc_state *crtc_state)
74+{
75+ if (crtc_state)
76+ crtc_state->crtc = crtc;
77+
78+ crtc->state = crtc_state;
79+}
80+EXPORT_SYMBOL(__drm_atomic_helper_crtc_reset);
81+
5982 /**
6083 * drm_atomic_helper_crtc_reset - default &drm_crtc_funcs.reset hook for CRTCs
6184 * @crtc: drm CRTC
@@ -65,14 +88,13 @@ · 3 unmodified lines
6588 */
6689 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
6790 {
68− if (crtc->state)
69− __drm_atomic_helper_crtc_destroy_state(crtc->state);
70−
71− kfree(crtc->state);
72− crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
91+ struct drm_crtc_state *crtc_state =
92+ kzalloc(sizeof(*crtc->state), GFP_KERNEL);
7393
7494 if (crtc->state)
75− crtc->state->crtc = crtc;
95+ crtc->funcs->atomic_destroy_state(crtc, crtc->state);
96+
97+ __drm_atomic_helper_crtc_reset(crtc, crtc_state);
7698 }
7799 EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
78100
@@ -314,7 +336,7 @@ EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state); · 235 unmodified lines
314336 * @conn_state: connector state to assign
315337 *
316338 * Initializes the newly allocated @conn_state and assigns it to
317− * the &drm_conector->state pointer of @connector, usually required when
339+ * the &drm_connector->state pointer of @connector, usually required when
318340 * initializing the drivers or when called from the &drm_connector_funcs.reset
319341 * hook.
320342 *
@@ -369,6 +391,9 @@ __drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector, · 48 unmodified lines
369391 drm_connector_get(connector);
370392 state->commit = NULL;
371393
394+ if (state->hdr_output_metadata)
395+ drm_property_blob_get(state->hdr_output_metadata);
396+
372397 /* Don't copy over a writeback job, they are used only once */
373398 state->writeback_job = NULL;
374399 }
@@ -416,6 +441,8 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state) · 41 unmodified lines
416441
417442 if (state->writeback_job)
418443 drm_writeback_cleanup_job(state->writeback_job);
444+
445+ drm_property_blob_put(state->hdr_output_metadata);
419446 }
420447 EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);
421448
drivers/gpu/drm/drm_atomic_uapi.c+12−0
@@ -676,6 +676,8 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, · 675 unmodified lines
676676 {
677677 struct drm_device *dev = connector->dev;
678678 struct drm_mode_config *config = &dev->mode_config;
679+ bool replaced = false;
680+ int ret;
679681
680682 if (property == config->prop_crtc_id) {
681683 struct drm_crtc *crtc = drm_crtc_find(dev, file_priv, val);
@@ -726,6 +728,13 @@ static int drm_atomic_connector_set_property(struct drm_connector *connector, · 44 unmodified lines
726728 */
727729 if (state->link_status != DRM_LINK_STATUS_GOOD)
728730 state->link_status = val;
731+ } else if (property == config->hdr_output_metadata_property) {
732+ ret = drm_atomic_replace_property_blob_from_id(dev,
733+ &state->hdr_output_metadata,
734+ val,
735+ sizeof(struct hdr_output_metadata), -1,
736+ &replaced);
737+ return ret;
729738 } else if (property == config->aspect_ratio_property) {
730739 state->picture_aspect_ratio = val;
731740 } else if (property == config->content_type_property) {
@@ -814,6 +823,9 @@ drm_atomic_connector_get_property(struct drm_connector *connector, · 82 unmodified lines
814823 *val = state->colorspace;
815824 } else if (property == connector->scaling_mode_property) {
816825 *val = state->scaling_mode;
826+ } else if (property == config->hdr_output_metadata_property) {
827+ *val = state->hdr_output_metadata ?
828+ state->hdr_output_metadata->base.id : 0;
817829 } else if (property == connector->content_protection_property) {
818830 *val = state->content_protection;
819831 } else if (property == config->writeback_fb_id_property) {
drivers/gpu/drm/drm_auth.c+20−0
@@ -351,3 +351,23 @@ void drm_master_put(struct drm_master **master) · 350 unmodified lines
351351 *master = NULL;
352352 }
353353 EXPORT_SYMBOL(drm_master_put);
354+
355+/* Used by drm_client and drm_fb_helper */
356+bool drm_master_internal_acquire(struct drm_device *dev)
357+{
358+ mutex_lock(&dev->master_mutex);
359+ if (dev->master) {
360+ mutex_unlock(&dev->master_mutex);
361+ return false;
362+ }
363+
364+ return true;
365+}
366+EXPORT_SYMBOL(drm_master_internal_acquire);
367+
368+/* Used by drm_client and drm_fb_helper */
369+void drm_master_internal_release(struct drm_device *dev)
370+{
371+ mutex_unlock(&dev->master_mutex);
372+}
373+EXPORT_SYMBOL(drm_master_internal_release);
drivers/gpu/drm/drm_client.c+2−1
@@ -243,6 +243,7 @@ static void drm_client_buffer_delete(struct drm_client_buffer *buffer) · 242 unmodified lines
243243 static struct drm_client_buffer *
244244 drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u32 format)
245245 {
246+ const struct drm_format_info *info = drm_format_info(format);
246247 struct drm_mode_create_dumb dumb_args = { };
247248 struct drm_device *dev = client->dev;
248249 struct drm_client_buffer *buffer;
@@ -258,7 +259,7 @@ drm_client_buffer_create(struct drm_client_dev *client, u32 width, u32 height, u · 9 unmodified lines
258259
259260 dumb_args.width = width;
260261 dumb_args.height = height;
261− dumb_args.bpp = drm_format_plane_cpp(format, 0) * 8;
262+ dumb_args.bpp = info->cpp[0] * 8;
262263 ret = drm_mode_create_dumb(dev, &dumb_args, client->file);
263264 if (ret)
264265 goto err_delete;
drivers/gpu/drm/drm_connector.c+6−0
@@ -1058,6 +1058,12 @@ int drm_connector_create_standard_properties(struct drm_device *dev) · 1057 unmodified lines
10581058 return -ENOMEM;
10591059 dev->mode_config.non_desktop_property = prop;
10601060
1061+ prop = drm_property_create(dev, DRM_MODE_PROP_BLOB,
1062+ "HDR_OUTPUT_METADATA", 0);
1063+ if (!prop)
1064+ return -ENOMEM;
1065+ dev->mode_config.hdr_output_metadata_property = prop;
1066+
10611067 return 0;
10621068 }
10631069
drivers/gpu/drm/drm_dp_aux_dev.c+5−3
@@ -27,15 +27,17 @@ · 26 unmodified lines
2727
2828 #include <linux/device.h>
2929 #include <linux/fs.h>
30−#include <linux/slab.h>
3130 #include <linux/init.h>
3231 #include <linux/kernel.h>
3332 #include <linux/module.h>
33+#include <linux/sched/signal.h>
34+#include <linux/slab.h>
3435 #include <linux/uaccess.h>
3536 #include <linux/uio.h>
36−#include <drm/drm_dp_helper.h>
37+
3738 #include <drm/drm_crtc.h>
38−#include <drm/drmP.h>
39+#include <drm/drm_dp_helper.h>
40+#include <drm/drm_print.h>
3941
4042 #include "drm_crtc_helper_internal.h"
4143
drivers/gpu/drm/drm_dp_dual_mode_helper.c+3−1
@@ -20,13 +20,15 @@ · 19 unmodified lines
2020 * OTHER DEALINGS IN THE SOFTWARE.
2121 */
2222
23+#include <linux/delay.h>
2324 #include <linux/errno.h>
2425 #include <linux/export.h>
2526 #include <linux/i2c.h>
2627 #include <linux/slab.h>
2728 #include <linux/string.h>
29+
2830 #include <drm/drm_dp_dual_mode_helper.h>
29−#include <drm/drmP.h>
31+#include <drm/drm_print.h>
3032
3133 /**
3234 * DOC: dp dual mode helpers
drivers/gpu/drm/drm_dp_helper.c+7−5
@@ -20,16 +20,18 @@ · 19 unmodified lines
2020 * OF THIS SOFTWARE.
2121 */
2222
23−#include <linux/kernel.h>
24−#include <linux/module.h>
2523 #include <linux/delay.h>
26−#include <linux/init.h>
2724 #include <linux/errno.h>
28−#include <linux/sched.h>
2925 #include <linux/i2c.h>
26+#include <linux/init.h>
27+#include <linux/kernel.h>
28+#include <linux/module.h>
29+#include <linux/sched.h>
3030 #include <linux/seq_file.h>
31+
3132 #include <drm/drm_dp_helper.h>
32−#include <drm/drmP.h>
33+#include <drm/drm_print.h>
34+#include <drm/drm_vblank.h>
3335
3436 #include "drm_crtc_helper_internal.h"
3537
drivers/gpu/drm/drm_dp_mst_topology.c+7−6
@@ -20,19 +20,20 @@ · 19 unmodified lines
2020 * OF THIS SOFTWARE.
2121 */
2222
23−#include <linux/kernel.h>
2423 #include <linux/delay.h>
25−#include <linux/init.h>
2624 #include <linux/errno.h>
25+#include <linux/i2c.h>
26+#include <linux/init.h>
27+#include <linux/kernel.h>
2728 #include <linux/sched.h>
2829 #include <linux/seq_file.h>
29−#include <linux/i2c.h>
30−#include <drm/drm_dp_mst_helper.h>
31−#include <drm/drmP.h>
3230
33−#include <drm/drm_fixed.h>
3431 #include <drm/drm_atomic.h>
3532 #include <drm/drm_atomic_helper.h>
33+#include <drm/drm_dp_mst_helper.h>
34+#include <drm/drm_drv.h>
35+#include <drm/drm_fixed.h>
36+#include <drm/drm_print.h>
3637 #include <drm/drm_probe_helper.h>
3738
3839 /**
drivers/gpu/drm/drm_edid.c+131−4
@@ -27,16 +27,19 @@ · 26 unmodified lines
2727 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
2828 * DEALINGS IN THE SOFTWARE.
2929 */
30−#include <linux/kernel.h>
31−#include <linux/slab.h>
30+
3231 #include <linux/hdmi.h>
3332 #include <linux/i2c.h>
33+#include <linux/kernel.h>
3434 #include <linux/module.h>
35+#include <linux/slab.h>
3536 #include <linux/vga_switcheroo.h>
36−#include <drm/drmP.h>
37+
38+#include <drm/drm_displayid.h>
39+#include <drm/drm_drv.h>
3740 #include <drm/drm_edid.h>
3841 #include <drm/drm_encoder.h>
39−#include <drm/drm_displayid.h>
42+#include <drm/drm_print.h>
4043 #include <drm/drm_scdc_helper.h>
4144
4245 #include "drm_crtc_internal.h"
@@ -2849,6 +2852,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, · 2806 unmodified lines
28492852 #define VIDEO_BLOCK 0x02
28502853 #define VENDOR_BLOCK 0x03
28512854 #define SPEAKER_BLOCK 0x04
2855+#define HDR_STATIC_METADATA_BLOCK 0x6
28522856 #define USE_EXTENDED_TAG 0x07
28532857 #define EXT_VIDEO_CAPABILITY_BLOCK 0x00
28542858 #define EXT_VIDEO_DATA_BLOCK_420 0x0E
@@ -3831,6 +3835,55 @@ static void fixup_detailed_cea_mode_clock(struct drm_display_mode *mode) · 976 unmodified lines
38313835 mode->clock = clock;
38323836 }
38333837
3838+static bool cea_db_is_hdmi_hdr_metadata_block(const u8 *db)
3839+{
3840+ if (cea_db_tag(db) != USE_EXTENDED_TAG)
3841+ return false;
3842+
3843+ if (db[1] != HDR_STATIC_METADATA_BLOCK)
3844+ return false;
3845+
3846+ if (cea_db_payload_len(db) < 3)
3847+ return false;
3848+
3849+ return true;
3850+}
3851+
3852+static uint8_t eotf_supported(const u8 *edid_ext)
3853+{
3854+ return edid_ext[2] &
3855+ (BIT(HDMI_EOTF_TRADITIONAL_GAMMA_SDR) |
3856+ BIT(HDMI_EOTF_TRADITIONAL_GAMMA_HDR) |
3857+ BIT(HDMI_EOTF_SMPTE_ST2084) |
3858+ BIT(HDMI_EOTF_BT_2100_HLG));
3859+}
3860+
3861+static uint8_t hdr_metadata_type(const u8 *edid_ext)
3862+{
3863+ return edid_ext[3] &
3864+ BIT(HDMI_STATIC_METADATA_TYPE1);
3865+}
3866+
3867+static void
3868+drm_parse_hdr_metadata_block(struct drm_connector *connector, const u8 *db)
3869+{
3870+ u16 len;
3871+
3872+ len = cea_db_payload_len(db);
3873+
3874+ connector->hdr_sink_metadata.hdmi_type1.eotf =
3875+ eotf_supported(db);
3876+ connector->hdr_sink_metadata.hdmi_type1.metadata_type =
3877+ hdr_metadata_type(db);
3878+
3879+ if (len >= 4)
3880+ connector->hdr_sink_metadata.hdmi_type1.max_cll = db[4];
3881+ if (len >= 5)
3882+ connector->hdr_sink_metadata.hdmi_type1.max_fall = db[5];
3883+ if (len >= 6)
3884+ connector->hdr_sink_metadata.hdmi_type1.min_cll = db[6];
3885+}
3886+
38343887 static void
38353888 drm_parse_hdmi_vsdb_audio(struct drm_connector *connector, const u8 *db)
38363889 {
@@ -4458,6 +4511,8 @@ static void drm_parse_cea_ext(struct drm_connector *connector, · 621 unmodified lines
44584511 drm_parse_y420cmdb_bitmap(connector, db);
44594512 if (cea_db_is_vcdb(db))
44604513 drm_parse_vcdb(connector, db);
4514+ if (cea_db_is_hdmi_hdr_metadata_block(db))
4515+ drm_parse_hdr_metadata_block(connector, db);
44614516 }
44624517 }
44634518
@@ -4850,6 +4905,78 @@ static bool is_hdmi2_sink(struct drm_connector *connector) · 386 unmodified lines
48504905 connector->display_info.color_formats & DRM_COLOR_FORMAT_YCRCB420;
48514906 }
48524907
4908+static inline bool is_eotf_supported(u8 output_eotf, u8 sink_eotf)
4909+{
4910+ return sink_eotf & BIT(output_eotf);
4911+}
4912+
4913+/**
4914+ * drm_hdmi_infoframe_set_hdr_metadata() - fill an HDMI DRM infoframe with
4915+ * HDR metadata from userspace
4916+ * @frame: HDMI DRM infoframe
4917+ * @conn_state: Connector state containing HDR metadata
4918+ *
4919+ * Return: 0 on success or a negative error code on failure.
4920+ */
4921+int
4922+drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
4923+ const struct drm_connector_state *conn_state)
4924+{
4925+ struct drm_connector *connector;
4926+ struct hdr_output_metadata *hdr_metadata;
4927+ int err;
4928+
4929+ if (!frame || !conn_state)
4930+ return -EINVAL;
4931+
4932+ connector = conn_state->connector;
4933+
4934+ if (!conn_state->hdr_output_metadata)
4935+ return -EINVAL;
4936+
4937+ hdr_metadata = conn_state->hdr_output_metadata->data;
4938+
4939+ if (!hdr_metadata || !connector)
4940+ return -EINVAL;
4941+
4942+ /* Sink EOTF is Bit map while infoframe is absolute values */
4943+ if (!is_eotf_supported(hdr_metadata->hdmi_metadata_type1.eotf,
4944+ connector->hdr_sink_metadata.hdmi_type1.eotf)) {
4945+ DRM_DEBUG_KMS("EOTF Not Supported\n");
4946+ return -EINVAL;
4947+ }
4948+
4949+ err = hdmi_drm_infoframe_init(frame);
4950+ if (err < 0)
4951+ return err;
4952+
4953+ frame->eotf = hdr_metadata->hdmi_metadata_type1.eotf;
4954+ frame->metadata_type = hdr_metadata->hdmi_metadata_type1.metadata_type;
4955+
4956+ BUILD_BUG_ON(sizeof(frame->display_primaries) !=
4957+ sizeof(hdr_metadata->hdmi_metadata_type1.display_primaries));
4958+ BUILD_BUG_ON(sizeof(frame->white_point) !=
4959+ sizeof(hdr_metadata->hdmi_metadata_type1.white_point));
4960+
4961+ memcpy(&frame->display_primaries,
4962+ &hdr_metadata->hdmi_metadata_type1.display_primaries,
4963+ sizeof(frame->display_primaries));
4964+
4965+ memcpy(&frame->white_point,
4966+ &hdr_metadata->hdmi_metadata_type1.white_point,
4967+ sizeof(frame->white_point));
4968+
4969+ frame->max_display_mastering_luminance =
4970+ hdr_metadata->hdmi_metadata_type1.max_display_mastering_luminance;
4971+ frame->min_display_mastering_luminance =
4972+ hdr_metadata->hdmi_metadata_type1.min_display_mastering_luminance;
4973+ frame->max_fall = hdr_metadata->hdmi_metadata_type1.max_fall;
4974+ frame->max_cll = hdr_metadata->hdmi_metadata_type1.max_cll;
4975+
4976+ return 0;
4977+}
4978+EXPORT_SYMBOL(drm_hdmi_infoframe_set_hdr_metadata);
4979+
48534980 /**
48544981 * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with
48554982 * data from a DRM display mode
drivers/gpu/drm/drm_edid_load.c+5−2
@@ -7,12 +7,15 @@ · 6 unmodified lines
77
88 */
99
10−#include <linux/module.h>
1110 #include <linux/firmware.h>
12−#include <drm/drmP.h>
11+#include <linux/module.h>
12+#include <linux/platform_device.h>
13+
1314 #include <drm/drm_crtc.h>
1415 #include <drm/drm_crtc_helper.h>
16+#include <drm/drm_drv.h>
1517 #include <drm/drm_edid.h>
18+#include <drm/drm_print.h>
1619
1720 static char edid_firmware[PATH_MAX];
1821 module_param_string(edid_firmware, edid_firmware, sizeof(edid_firmware), 0644);
drivers/gpu/drm/drm_fb_helper.c+125−121
@@ -44,6 +44,7 @@ · 43 unmodified lines
4444
4545 #include "drm_crtc_internal.h"
4646 #include "drm_crtc_helper_internal.h"
47+#include "drm_internal.h"
4748
4849 static bool drm_fbdev_emulation = true;
4950 module_param_named(fbdev_emulation, drm_fbdev_emulation, bool, 0600);
@@ -387,6 +388,49 @@ int drm_fb_helper_debug_leave(struct fb_info *info) · 337 unmodified lines
387388 }
388389 EXPORT_SYMBOL(drm_fb_helper_debug_leave);
389390
391+/* Check if the plane can hw rotate to match panel orientation */
392+static bool drm_fb_helper_panel_rotation(struct drm_mode_set *modeset,
393+ unsigned int *rotation)
394+{
395+ struct drm_connector *connector = modeset->connectors[0];
396+ struct drm_plane *plane = modeset->crtc->primary;
397+ u64 valid_mask = 0;
398+ unsigned int i;
399+
400+ if (!modeset->num_connectors)
401+ return false;
402+
403+ switch (connector->display_info.panel_orientation) {
404+ case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
405+ *rotation = DRM_MODE_ROTATE_180;
406+ break;
407+ case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
408+ *rotation = DRM_MODE_ROTATE_90;
409+ break;
410+ case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
411+ *rotation = DRM_MODE_ROTATE_270;
412+ break;
413+ default:
414+ *rotation = DRM_MODE_ROTATE_0;
415+ }
416+
417+ /*
418+ * TODO: support 90 / 270 degree hardware rotation,
419+ * depending on the hardware this may require the framebuffer
420+ * to be in a specific tiling format.
421+ */
422+ if (*rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property)
423+ return false;
424+
425+ for (i = 0; i < plane->rotation_property->num_values; i++)
426+ valid_mask |= (1ULL << plane->rotation_property->values[i]);
427+
428+ if (!(*rotation & valid_mask))
429+ return false;
430+
431+ return true;
432+}
433+
390434 static int restore_fbdev_mode_atomic(struct drm_fb_helper *fb_helper, bool active)
391435 {
392436 struct drm_device *dev = fb_helper->dev;
@@ -427,10 +471,13 @@ retry: · 34 unmodified lines
427471 for (i = 0; i < fb_helper->crtc_count; i++) {
428472 struct drm_mode_set *mode_set = &fb_helper->crtc_info[i].mode_set;
429473 struct drm_plane *primary = mode_set->crtc->primary;
474+ unsigned int rotation;
430475
431− /* Cannot fail as we've already gotten the plane state above */
432− plane_state = drm_atomic_get_new_plane_state(state, primary);
433− plane_state->rotation = fb_helper->crtc_info[i].rotation;
476+ if (drm_fb_helper_panel_rotation(mode_set, &rotation)) {
477+ /* Cannot fail as we've already gotten the plane state above */
478+ plane_state = drm_atomic_get_new_plane_state(state, primary);
479+ plane_state->rotation = rotation;
480+ }
434481
435482 ret = __drm_atomic_helper_set_config(mode_set, state);
436483 if (ret != 0)
@@ -509,7 +556,7 @@ out: · 72 unmodified lines
509556 return ret;
510557 }
511558
512−static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
559+static int restore_fbdev_mode_force(struct drm_fb_helper *fb_helper)
513560 {
514561 struct drm_device *dev = fb_helper->dev;
515562
@@ -519,6 +566,21 @@ static int restore_fbdev_mode(struct drm_fb_helper *fb_helper) · 3 unmodified lines
519566 return restore_fbdev_mode_legacy(fb_helper);
520567 }
521568
569+static int restore_fbdev_mode(struct drm_fb_helper *fb_helper)
570+{
571+ struct drm_device *dev = fb_helper->dev;
572+ int ret;
573+
574+ if (!drm_master_internal_acquire(dev))
575+ return -EBUSY;
576+
577+ ret = restore_fbdev_mode_force(fb_helper);
578+
579+ drm_master_internal_release(dev);
580+
581+ return ret;
582+}
583+
522584 /**
523585 * drm_fb_helper_restore_fbdev_mode_unlocked - restore fbdev configuration
524586 * @fb_helper: driver-allocated fbdev helper, can be NULL
@@ -542,7 +604,17 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) · 17 unmodified lines
542604 return 0;
543605
544606 mutex_lock(&fb_helper->lock);
545− ret = restore_fbdev_mode(fb_helper);
607+ /*
608+ * TODO:
609+ * We should bail out here if there is a master by dropping _force.
610+ * Currently these igt tests fail if we do that:
611+ * - kms_fbcon_fbt@psr
612+ * - kms_fbcon_fbt@psr-suspend
613+ *
614+ * So first these tests need to be fixed so they drop master or don't
615+ * have an fd open.
616+ */
617+ ret = restore_fbdev_mode_force(fb_helper);
546618
547619 do_delayed = fb_helper->delayed_hotplug;
548620 if (do_delayed)
@@ -556,34 +628,6 @@ int drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) · 7 unmodified lines
556628 }
557629 EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
558630
559−static bool drm_fb_helper_is_bound(struct drm_fb_helper *fb_helper)
560−{
561− struct drm_device *dev = fb_helper->dev;
562− struct drm_crtc *crtc;
563− int bound = 0, crtcs_bound = 0;
564−
565− /*
566− * Sometimes user space wants everything disabled, so don't steal the
567− * display if there's a master.
568− */
569− if (READ_ONCE(dev->master))
570− return false;
571−
572− drm_for_each_crtc(crtc, dev) {
573− drm_modeset_lock(&crtc->mutex, NULL);
574− if (crtc->primary->fb)
575− crtcs_bound++;
576− if (crtc->primary->fb == fb_helper->fb)
577− bound++;
578− drm_modeset_unlock(&crtc->mutex);
579− }
580−
581− if (bound < crtcs_bound)
582− return false;
583−
584− return true;
585−}
586−
587631 #ifdef CONFIG_MAGIC_SYSRQ
588632 /*
589633 * restore fbcon display for all kms driver's using this helper, used for sysrq
@@ -604,7 +648,7 @@ static bool drm_fb_helper_force_kernel_mode(void) · 14 unmodified lines
604648 continue;
605649
606650 mutex_lock(&helper->lock);
607− ret = restore_fbdev_mode(helper);
651+ ret = restore_fbdev_mode_force(helper);
608652 if (ret)
609653 error = true;
610654 mutex_unlock(&helper->lock);
@@ -663,20 +707,22 @@ static void dpms_legacy(struct drm_fb_helper *fb_helper, int dpms_mode) · 52 unmodified lines
663707 static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode)
664708 {
665709 struct drm_fb_helper *fb_helper = info->par;
710+ struct drm_device *dev = fb_helper->dev;
666711
667712 /*
668713 * For each CRTC in this fb, turn the connectors on/off.
669714 */
670715 mutex_lock(&fb_helper->lock);
671− if (!drm_fb_helper_is_bound(fb_helper)) {
672− mutex_unlock(&fb_helper->lock);
673− return;
674− }
716+ if (!drm_master_internal_acquire(dev))
717+ goto unlock;
675718
676− if (drm_drv_uses_atomic_modeset(fb_helper->dev))
719+ if (drm_drv_uses_atomic_modeset(dev))
677720 restore_fbdev_mode_atomic(fb_helper, dpms_mode == DRM_MODE_DPMS_ON);
678721 else
679722 dpms_legacy(fb_helper, dpms_mode);
723+
724+ drm_master_internal_release(dev);
725+unlock:
680726 mutex_unlock(&fb_helper->lock);
681727 }
682728
@@ -767,7 +813,7 @@ static void drm_fb_helper_dirty_blit_real(struct drm_fb_helper *fb_helper, · 84 unmodified lines
767813 struct drm_clip_rect *clip)
768814 {
769815 struct drm_framebuffer *fb = fb_helper->fb;
770− unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
816+ unsigned int cpp = fb->format->cpp[0];
771817 size_t offset = clip->y1 * fb->pitches[0] + clip->x1 * cpp;
772818 void *src = fb_helper->fbdev->screen_buffer + offset;
773819 void *dst = fb_helper->buffer->vaddr + offset;
@@ -881,7 +927,6 @@ int drm_fb_helper_init(struct drm_device *dev, · 107 unmodified lines
881927 if (!fb_helper->crtc_info[i].mode_set.connectors)
882928 goto out_free;
883929 fb_helper->crtc_info[i].mode_set.num_connectors = 0;
884− fb_helper->crtc_info[i].rotation = DRM_MODE_ROTATE_0;
885930 }
886931
887932 i = 0;
@@ -1509,6 +1554,7 @@ backoff: · 621 unmodified lines
15091554 int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info)
15101555 {
15111556 struct drm_fb_helper *fb_helper = info->par;
1557+ struct drm_device *dev = fb_helper->dev;
15121558 int ret;
15131559
15141560 if (oops_in_progress)
@@ -1516,9 +1562,9 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) · 1 unmodified line
15161562
15171563 mutex_lock(&fb_helper->lock);
15181564
1519− if (!drm_fb_helper_is_bound(fb_helper)) {
1565+ if (!drm_master_internal_acquire(dev)) {
15201566 ret = -EBUSY;
1521− goto out;
1567+ goto unlock;
15221568 }
15231569
15241570 if (info->fix.visual == FB_VISUAL_TRUECOLOR)
@@ -1528,7 +1574,8 @@ int drm_fb_helper_setcmap(struct fb_cmap *cmap, struct fb_info *info) · 3 unmodified lines
15281574 else
15291575 ret = setcmap_legacy(cmap, info);
15301576
1531−out:
1577+ drm_master_internal_release(dev);
1578+unlock:
15321579 mutex_unlock(&fb_helper->lock);
15331580
15341581 return ret;
@@ -1548,12 +1595,13 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, · 13 unmodified lines
15481595 unsigned long arg)
15491596 {
15501597 struct drm_fb_helper *fb_helper = info->par;
1598+ struct drm_device *dev = fb_helper->dev;
15511599 struct drm_mode_set *mode_set;
15521600 struct drm_crtc *crtc;
15531601 int ret = 0;
15541602
15551603 mutex_lock(&fb_helper->lock);
1556− if (!drm_fb_helper_is_bound(fb_helper)) {
1604+ if (!drm_master_internal_acquire(dev)) {
15571605 ret = -EBUSY;
15581606 goto unlock;
15591607 }
@@ -1591,11 +1639,12 @@ int drm_fb_helper_ioctl(struct fb_info *info, unsigned int cmd, · 31 unmodified lines
15911639 }
15921640
15931641 ret = 0;
1594− goto unlock;
1642+ break;
15951643 default:
15961644 ret = -ENOTTY;
15971645 }
15981646
1647+ drm_master_internal_release(dev);
15991648 unlock:
16001649 mutex_unlock(&fb_helper->lock);
16011650 return ret;
@@ -1847,15 +1896,18 @@ int drm_fb_helper_pan_display(struct fb_var_screeninfo *var, · 245 unmodified lines
18471896 return -EBUSY;
18481897
18491898 mutex_lock(&fb_helper->lock);
1850− if (!drm_fb_helper_is_bound(fb_helper)) {
1851− mutex_unlock(&fb_helper->lock);
1852− return -EBUSY;
1899+ if (!drm_master_internal_acquire(dev)) {
1900+ ret = -EBUSY;
1901+ goto unlock;
18531902 }
18541903
18551904 if (drm_drv_uses_atomic_modeset(dev))
18561905 ret = pan_display_atomic(var, info);
18571906 else
18581907 ret = pan_display_legacy(var, info);
1908+
1909+ drm_master_internal_release(dev);
1910+unlock:
18591911 mutex_unlock(&fb_helper->lock);
18601912
18611913 return ret;
@@ -1979,16 +2031,16 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, · 117 unmodified lines
19792031 */
19802032 bool lastv = true, lasth = true;
19812033
1982− desired_mode = fb_helper->crtc_info[i].desired_mode;
19832034 mode_set = &fb_helper->crtc_info[i].mode_set;
2035+ desired_mode = mode_set->mode;
19842036
19852037 if (!desired_mode)
19862038 continue;
19872039
19882040 crtc_count++;
19892041
1990− x = fb_helper->crtc_info[i].x;
1991− y = fb_helper->crtc_info[i].y;
2042+ x = mode_set->x;
2043+ y = mode_set->y;
19922044
19932045 sizes.surface_width = max_t(u32, desired_mode->hdisplay + x, sizes.surface_width);
19942046 sizes.surface_height = max_t(u32, desired_mode->vdisplay + y, sizes.surface_height);
@@ -2014,7 +2066,7 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, · 19 unmodified lines
20142066 DRM_INFO("Cannot find any crtc or sizes\n");
20152067
20162068 /* First time: disable all crtc's.. */
2017− if (!fb_helper->deferred_setup && !READ_ONCE(fb_helper->dev->master))
2069+ if (!fb_helper->deferred_setup)
20182070 restore_fbdev_mode(fb_helper);
20192071 return -EAGAIN;
20202072 }
@@ -2503,62 +2555,6 @@ static int drm_pick_crtcs(struct drm_fb_helper *fb_helper, · 482 unmodified lines
25032555 return best_score;
25042556 }
25052557
2506−/*
2507− * This function checks if rotation is necessary because of panel orientation
2508− * and if it is, if it is supported.
2509− * If rotation is necessary and supported, it gets set in fb_crtc.rotation.
2510− * If rotation is necessary but not supported, a DRM_MODE_ROTATE_* flag gets
2511− * or-ed into fb_helper->sw_rotations. In drm_setup_crtcs_fb() we check if only
2512− * one bit is set and then we set fb_info.fbcon_rotate_hint to make fbcon do
2513− * the unsupported rotation.
2514− */
2515−static void drm_setup_crtc_rotation(struct drm_fb_helper *fb_helper,
2516− struct drm_fb_helper_crtc *fb_crtc,
2517− struct drm_connector *connector)
2518−{
2519− struct drm_plane *plane = fb_crtc->mode_set.crtc->primary;
2520− uint64_t valid_mask = 0;
2521− int i, rotation;
2522−
2523− fb_crtc->rotation = DRM_MODE_ROTATE_0;
2524−
2525− switch (connector->display_info.panel_orientation) {
2526− case DRM_MODE_PANEL_ORIENTATION_BOTTOM_UP:
2527− rotation = DRM_MODE_ROTATE_180;
2528− break;
2529− case DRM_MODE_PANEL_ORIENTATION_LEFT_UP:
2530− rotation = DRM_MODE_ROTATE_90;
2531− break;
2532− case DRM_MODE_PANEL_ORIENTATION_RIGHT_UP:
2533− rotation = DRM_MODE_ROTATE_270;
2534− break;
2535− default:
2536− rotation = DRM_MODE_ROTATE_0;
2537− }
2538−
2539− /*
2540− * TODO: support 90 / 270 degree hardware rotation,
2541− * depending on the hardware this may require the framebuffer
2542− * to be in a specific tiling format.
2543− */
2544− if (rotation != DRM_MODE_ROTATE_180 || !plane->rotation_property) {
2545− fb_helper->sw_rotations |= rotation;
2546− return;
2547− }
2548−
2549− for (i = 0; i < plane->rotation_property->num_values; i++)
2550− valid_mask |= (1ULL << plane->rotation_property->values[i]);
2551−
2552− if (!(rotation & valid_mask)) {
2553− fb_helper->sw_rotations |= rotation;
2554− return;
2555− }
2556−
2557− fb_crtc->rotation = rotation;
2558− /* Rotating in hardware, fbcon should not rotate */
2559− fb_helper->sw_rotations |= DRM_MODE_ROTATE_0;
2560−}
2561−
25622558 static struct drm_fb_helper_crtc *
25632559 drm_fb_helper_crtc(struct drm_fb_helper *fb_helper, struct drm_crtc *crtc)
25642560 {
@@ -2805,7 +2801,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, · 240 unmodified lines
28052801 drm_fb_helper_modeset_release(fb_helper,
28062802 &fb_helper->crtc_info[i].mode_set);
28072803
2808− fb_helper->sw_rotations = 0;
28092804 drm_fb_helper_for_each_connector(fb_helper, i) {
28102805 struct drm_display_mode *mode = modes[i];
28112806 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
@@ -2819,13 +2814,8 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper, · 7 unmodified lines
28192814 DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
28202815 mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
28212816
2822− fb_crtc->desired_mode = mode;
2823− fb_crtc->x = offset->x;
2824− fb_crtc->y = offset->y;
2825− modeset->mode = drm_mode_duplicate(dev,
2826− fb_crtc->desired_mode);
2817+ modeset->mode = drm_mode_duplicate(dev, mode);
28272818 drm_connector_get(connector);
2828− drm_setup_crtc_rotation(fb_helper, fb_crtc, connector);
28292819 modeset->connectors[modeset->num_connectors++] = connector;
28302820 modeset->x = offset->x;
28312821 modeset->y = offset->y;
@@ -2848,11 +2838,23 @@ out: · 16 unmodified lines
28482838 static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper)
28492839 {
28502840 struct fb_info *info = fb_helper->fbdev;
2841+ unsigned int rotation, sw_rotations = 0;
28512842 int i;
28522843
2853− for (i = 0; i < fb_helper->crtc_count; i++)
2854− if (fb_helper->crtc_info[i].mode_set.num_connectors)
2855− fb_helper->crtc_info[i].mode_set.fb = fb_helper->fb;
2844+ for (i = 0; i < fb_helper->crtc_count; i++) {
2845+ struct drm_mode_set *modeset = &fb_helper->crtc_info[i].mode_set;
2846+
2847+ if (!modeset->num_connectors)
2848+ continue;
2849+
2850+ modeset->fb = fb_helper->fb;
2851+
2852+ if (drm_fb_helper_panel_rotation(modeset, &rotation))
2853+ /* Rotating in hardware, fbcon should not rotate */
2854+ sw_rotations |= DRM_MODE_ROTATE_0;
2855+ else
2856+ sw_rotations |= rotation;
2857+ }
28562858
28572859 mutex_lock(&fb_helper->dev->mode_config.mutex);
28582860 drm_fb_helper_for_each_connector(fb_helper, i) {
@@ -2868,7 +2870,7 @@ static void drm_setup_crtcs_fb(struct drm_fb_helper *fb_helper) · 9 unmodified lines
28682870 }
28692871 mutex_unlock(&fb_helper->dev->mode_config.mutex);
28702872
2871− switch (fb_helper->sw_rotations) {
2873+ switch (sw_rotations) {
28722874 case DRM_MODE_ROTATE_0:
28732875 info->fbcon_rotate_hint = FB_ROTATE_UR;
28742876 break;
@@ -3041,12 +3043,14 @@ int drm_fb_helper_hotplug_event(struct drm_fb_helper *fb_helper) · 166 unmodified lines
30413043 return err;
30423044 }
30433045
3044− if (!fb_helper->fb || !drm_fb_helper_is_bound(fb_helper)) {
3046+ if (!fb_helper->fb || !drm_master_internal_acquire(fb_helper->dev)) {
30453047 fb_helper->delayed_hotplug = true;
30463048 mutex_unlock(&fb_helper->lock);
30473049 return err;
30483050 }
30493051
3052+ drm_master_internal_release(fb_helper->dev);
3053+
30503054 DRM_DEBUG_KMS("\n");
30513055
30523056 drm_setup_crtcs(fb_helper, fb_helper->fb->width, fb_helper->fb->height);
drivers/gpu/drm/drm_file.c+50−72
@@ -100,8 +100,6 @@ DEFINE_MUTEX(drm_global_mutex); · 99 unmodified lines
100100 * :ref:`IOCTL support in the userland interfaces chapter<drm_driver_ioctl>`.
101101 */
102102
103−static int drm_open_helper(struct file *filp, struct drm_minor *minor);
104−
105103 /**
106104 * drm_file_alloc - allocate file context
107105 * @minor: minor to allocate on
@@ -273,76 +271,6 @@ static void drm_close_helper(struct file *filp) · 165 unmodified lines
273271 drm_file_free(file_priv);
274272 }
275273
276−static int drm_setup(struct drm_device * dev)
277−{
278− int ret;
279−
280− if (dev->driver->firstopen &&
281− drm_core_check_feature(dev, DRIVER_LEGACY)) {
282− ret = dev->driver->firstopen(dev);
283− if (ret != 0)
284− return ret;
285− }
286−
287− ret = drm_legacy_dma_setup(dev);
288− if (ret < 0)
289− return ret;
290−
291−
292− DRM_DEBUG("\n");
293− return 0;
294−}
295−
296−/**
297− * drm_open - open method for DRM file
298− * @inode: device inode
299− * @filp: file pointer.
300− *
301− * This function must be used by drivers as their &file_operations.open method.
302− * It looks up the correct DRM device and instantiates all the per-file
303− * resources for it. It also calls the &drm_driver.open driver callback.
304− *
305− * RETURNS:
306− *
307− * 0 on success or negative errno value on falure.
308− */
309−int drm_open(struct inode *inode, struct file *filp)
310−{
311− struct drm_device *dev;
312− struct drm_minor *minor;
313− int retcode;
314− int need_setup = 0;
315−
316− minor = drm_minor_acquire(iminor(inode));
317− if (IS_ERR(minor))
318− return PTR_ERR(minor);
319−
320− dev = minor->dev;
321− if (!dev->open_count++)
322− need_setup = 1;
323−
324− /* share address_space across all char-devs of a single device */
325− filp->f_mapping = dev->anon_inode->i_mapping;
326−
327− retcode = drm_open_helper(filp, minor);
328− if (retcode)
329− goto err_undo;
330− if (need_setup) {
331− retcode = drm_setup(dev);
332− if (retcode) {
333− drm_close_helper(filp);
334− goto err_undo;
335− }
336− }
337− return 0;
338−
339−err_undo:
340− dev->open_count--;
341− drm_minor_release(minor);
342− return retcode;
343−}
344−EXPORT_SYMBOL(drm_open);
345−
346274 /*
347275 * Check whether DRI will run on this CPU.
348276 *
@@ -424,6 +352,56 @@ static int drm_open_helper(struct file *filp, struct drm_minor *minor) · 75 unmodified lines
424352 return 0;
425353 }
426354
355+/**
356+ * drm_open - open method for DRM file
357+ * @inode: device inode
358+ * @filp: file pointer.
359+ *
360+ * This function must be used by drivers as their &file_operations.open method.
361+ * It looks up the correct DRM device and instantiates all the per-file
362+ * resources for it. It also calls the &drm_driver.open driver callback.
363+ *
364+ * RETURNS:
365+ *
366+ * 0 on success or negative errno value on falure.
367+ */
368+int drm_open(struct inode *inode, struct file *filp)
369+{
370+ struct drm_device *dev;
371+ struct drm_minor *minor;
372+ int retcode;
373+ int need_setup = 0;
374+
375+ minor = drm_minor_acquire(iminor(inode));
376+ if (IS_ERR(minor))
377+ return PTR_ERR(minor);
378+
379+ dev = minor->dev;
380+ if (!dev->open_count++)
381+ need_setup = 1;
382+
383+ /* share address_space across all char-devs of a single device */
384+ filp->f_mapping = dev->anon_inode->i_mapping;
385+
386+ retcode = drm_open_helper(filp, minor);
387+ if (retcode)
388+ goto err_undo;
389+ if (need_setup) {
390+ retcode = drm_legacy_setup(dev);
391+ if (retcode) {
392+ drm_close_helper(filp);
393+ goto err_undo;
394+ }
395+ }
396+ return 0;
397+
398+err_undo:
399+ dev->open_count--;
400+ drm_minor_release(minor);
401+ return retcode;
402+}
403+EXPORT_SYMBOL(drm_open);
404+
427405 void drm_lastclose(struct drm_device * dev)
428406 {
429407 DRM_DEBUG("\n");
drivers/gpu/drm/drm_format_helper.c+2−2
@@ -36,7 +36,7 @@ static unsigned int clip_offset(struct drm_rect *clip, · 35 unmodified lines
3636 void drm_fb_memcpy(void *dst, void *vaddr, struct drm_framebuffer *fb,
3737 struct drm_rect *clip)
3838 {
39− unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
39+ unsigned int cpp = fb->format->cpp[0];
4040 size_t len = (clip->x2 - clip->x1) * cpp;
4141 unsigned int y, lines = clip->y2 - clip->y1;
4242
@@ -63,7 +63,7 @@ void drm_fb_memcpy_dstclip(void __iomem *dst, void *vaddr, · 20 unmodified lines
6363 struct drm_framebuffer *fb,
6464 struct drm_rect *clip)
6565 {
66− unsigned int cpp = drm_format_plane_cpp(fb->format->format, 0);
66+ unsigned int cpp = fb->format->cpp[0];
6767 unsigned int offset = clip_offset(clip, fb->pitches[0], cpp);
6868 size_t len = (clip->x2 - clip->x1) * cpp;
6969 unsigned int y, lines = clip->y2 - clip->y1;
drivers/gpu/drm/drm_fourcc.c+0−118
@@ -332,124 +332,6 @@ drm_get_format_info(struct drm_device *dev, · 331 unmodified lines
332332 }
333333 EXPORT_SYMBOL(drm_get_format_info);
334334
335−/**
336− * drm_format_num_planes - get the number of planes for format
337− * @format: pixel format (DRM_FORMAT_*)
338− *
339− * Returns:
340− * The number of planes used by the specified pixel format.
341− */
342−int drm_format_num_planes(uint32_t format)
343−{
344− const struct drm_format_info *info;
345−
346− info = drm_format_info(format);
347− return info ? info->num_planes : 1;
348−}
349−EXPORT_SYMBOL(drm_format_num_planes);
350−
351−/**
352− * drm_format_plane_cpp - determine the bytes per pixel value
353− * @format: pixel format (DRM_FORMAT_*)
354− * @plane: plane index
355− *
356− * Returns:
357− * The bytes per pixel value for the specified plane.
358− */
359−int drm_format_plane_cpp(uint32_t format, int plane)
360−{
361− const struct drm_format_info *info;
362−
363− info = drm_format_info(format);
364− if (!info || plane >= info->num_planes)
365− return 0;
366−
367− return info->cpp[plane];
368−}
369−EXPORT_SYMBOL(drm_format_plane_cpp);
370−
371−/**
372− * drm_format_horz_chroma_subsampling - get the horizontal chroma subsampling factor
373− * @format: pixel format (DRM_FORMAT_*)
374− *
375− * Returns:
376− * The horizontal chroma subsampling factor for the
377− * specified pixel format.
378− */
379−int drm_format_horz_chroma_subsampling(uint32_t format)
380−{
381− const struct drm_format_info *info;
382−
383− info = drm_format_info(format);
384− return info ? info->hsub : 1;
385−}
386−EXPORT_SYMBOL(drm_format_horz_chroma_subsampling);
387−
388−/**
389− * drm_format_vert_chroma_subsampling - get the vertical chroma subsampling factor
390− * @format: pixel format (DRM_FORMAT_*)
391− *
392− * Returns:
393− * The vertical chroma subsampling factor for the
394− * specified pixel format.
395− */
396−int drm_format_vert_chroma_subsampling(uint32_t format)
397−{
398− const struct drm_format_info *info;
399−
400− info = drm_format_info(format);
401− return info ? info->vsub : 1;
402−}
403−EXPORT_SYMBOL(drm_format_vert_chroma_subsampling);
404−
405−/**
406− * drm_format_plane_width - width of the plane given the first plane
407− * @width: width of the first plane
408− * @format: pixel format
409− * @plane: plane index
410− *
411− * Returns:
412− * The width of @plane, given that the width of the first plane is @width.
413− */
414−int drm_format_plane_width(int width, uint32_t format, int plane)
415−{
416− const struct drm_format_info *info;
417−
418− info = drm_format_info(format);
419− if (!info || plane >= info->num_planes)
420− return 0;
421−
422− if (plane == 0)
423− return width;
424−
425− return width / info->hsub;
426−}
427−EXPORT_SYMBOL(drm_format_plane_width);
428−
429−/**
430− * drm_format_plane_height - height of the plane given the first plane
431− * @height: height of the first plane
432− * @format: pixel format
433− * @plane: plane index
434− *
435− * Returns:
436− * The height of @plane, given that the height of the first plane is @height.
437− */
438−int drm_format_plane_height(int height, uint32_t format, int plane)
439−{
440− const struct drm_format_info *info;
441−
442− info = drm_format_info(format);
443− if (!info || plane >= info->num_planes)
444− return 0;
445−
446− if (plane == 0)
447− return height;
448−
449− return height / info->vsub;
450−}
451−EXPORT_SYMBOL(drm_format_plane_height);
452−
453335 /**
454336 * drm_format_info_block_width - width in pixels of block.
455337 * @info: pixel format info
drivers/gpu/drm/drm_gem_vram_helper.c+772−0
@@ -0,0 +1,772 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+
3+#include <drm/drm_gem_vram_helper.h>
4+#include <drm/drm_device.h>
5+#include <drm/drm_mode.h>
6+#include <drm/drm_prime.h>
7+#include <drm/drm_vram_mm_helper.h>
8+#include <drm/ttm/ttm_page_alloc.h>
9+
10+/**
11+ * DOC: overview
12+ *
13+ * This library provides a GEM buffer object that is backed by video RAM
14+ * (VRAM). It can be used for framebuffer devices with dedicated memory.
15+ */
16+
17+/*
18+ * Buffer-objects helpers
19+ */
20+
21+static void drm_gem_vram_cleanup(struct drm_gem_vram_object *gbo)
22+{
23+ /* We got here via ttm_bo_put(), which means that the
24+ * TTM buffer object in 'bo' has already been cleaned
25+ * up; only release the GEM object.
26+ */
27+ drm_gem_object_release(&gbo->gem);
28+}
29+
30+static void drm_gem_vram_destroy(struct drm_gem_vram_object *gbo)
31+{
32+ drm_gem_vram_cleanup(gbo);
33+ kfree(gbo);
34+}
35+
36+static void ttm_buffer_object_destroy(struct ttm_buffer_object *bo)
37+{
38+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
39+
40+ drm_gem_vram_destroy(gbo);
41+}
42+
43+static void drm_gem_vram_placement(struct drm_gem_vram_object *gbo,
44+ unsigned long pl_flag)
45+{
46+ unsigned int i;
47+ unsigned int c = 0;
48+
49+ gbo->placement.placement = gbo->placements;
50+ gbo->placement.busy_placement = gbo->placements;
51+
52+ if (pl_flag & TTM_PL_FLAG_VRAM)
53+ gbo->placements[c++].flags = TTM_PL_FLAG_WC |
54+ TTM_PL_FLAG_UNCACHED |
55+ TTM_PL_FLAG_VRAM;
56+
57+ if (pl_flag & TTM_PL_FLAG_SYSTEM)
58+ gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
59+ TTM_PL_FLAG_SYSTEM;
60+
61+ if (!c)
62+ gbo->placements[c++].flags = TTM_PL_MASK_CACHING |
63+ TTM_PL_FLAG_SYSTEM;
64+
65+ gbo->placement.num_placement = c;
66+ gbo->placement.num_busy_placement = c;
67+
68+ for (i = 0; i < c; ++i) {
69+ gbo->placements[i].fpfn = 0;
70+ gbo->placements[i].lpfn = 0;
71+ }
72+}
73+
74+static int drm_gem_vram_init(struct drm_device *dev,
75+ struct ttm_bo_device *bdev,
76+ struct drm_gem_vram_object *gbo,
77+ size_t size, unsigned long pg_align,
78+ bool interruptible)
79+{
80+ int ret;
81+ size_t acc_size;
82+
83+ ret = drm_gem_object_init(dev, &gbo->gem, size);
84+ if (ret)
85+ return ret;
86+
87+ acc_size = ttm_bo_dma_acc_size(bdev, size, sizeof(*gbo));
88+
89+ gbo->bo.bdev = bdev;
90+ drm_gem_vram_placement(gbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
91+
92+ ret = ttm_bo_init(bdev, &gbo->bo, size, ttm_bo_type_device,
93+ &gbo->placement, pg_align, interruptible, acc_size,
94+ NULL, NULL, ttm_buffer_object_destroy);
95+ if (ret)
96+ goto err_drm_gem_object_release;
97+
98+ return 0;
99+
100+err_drm_gem_object_release:
101+ drm_gem_object_release(&gbo->gem);
102+ return ret;
103+}
104+
105+/**
106+ * drm_gem_vram_create() - Creates a VRAM-backed GEM object
107+ * @dev: the DRM device
108+ * @bdev: the TTM BO device backing the object
109+ * @size: the buffer size in bytes
110+ * @pg_align: the buffer's alignment in multiples of the page size
111+ * @interruptible: sleep interruptible if waiting for memory
112+ *
113+ * Returns:
114+ * A new instance of &struct drm_gem_vram_object on success, or
115+ * an ERR_PTR()-encoded error code otherwise.
116+ */
117+struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
118+ struct ttm_bo_device *bdev,
119+ size_t size,
120+ unsigned long pg_align,
121+ bool interruptible)
122+{
123+ struct drm_gem_vram_object *gbo;
124+ int ret;
125+
126+ gbo = kzalloc(sizeof(*gbo), GFP_KERNEL);
127+ if (!gbo)
128+ return ERR_PTR(-ENOMEM);
129+
130+ ret = drm_gem_vram_init(dev, bdev, gbo, size, pg_align, interruptible);
131+ if (ret < 0)
132+ goto err_kfree;
133+
134+ return gbo;
135+
136+err_kfree:
137+ kfree(gbo);
138+ return ERR_PTR(ret);
139+}
140+EXPORT_SYMBOL(drm_gem_vram_create);
141+
142+/**
143+ * drm_gem_vram_put() - Releases a reference to a VRAM-backed GEM object
144+ * @gbo: the GEM VRAM object
145+ *
146+ * See ttm_bo_put() for more information.
147+ */
148+void drm_gem_vram_put(struct drm_gem_vram_object *gbo)
149+{
150+ ttm_bo_put(&gbo->bo);
151+}
152+EXPORT_SYMBOL(drm_gem_vram_put);
153+
154+/**
155+ * drm_gem_vram_lock() - Locks a VRAM-backed GEM object
156+ * @gbo: the GEM VRAM object
157+ * @no_wait: don't wait for buffer object to become available
158+ *
159+ * See ttm_bo_reserve() for more information.
160+ *
161+ * Returns:
162+ * 0 on success, or
163+ * a negative error code otherwise
164+ */
165+int drm_gem_vram_lock(struct drm_gem_vram_object *gbo, bool no_wait)
166+{
167+ return ttm_bo_reserve(&gbo->bo, true, no_wait, NULL);
168+}
169+EXPORT_SYMBOL(drm_gem_vram_lock);
170+
171+/**
172+ * drm_gem_vram_unlock() - \
173+ Release a reservation acquired by drm_gem_vram_lock()
174+ * @gbo: the GEM VRAM object
175+ *
176+ * See ttm_bo_unreserve() for more information.
177+ */
178+void drm_gem_vram_unlock(struct drm_gem_vram_object *gbo)
179+{
180+ ttm_bo_unreserve(&gbo->bo);
181+}
182+EXPORT_SYMBOL(drm_gem_vram_unlock);
183+
184+/**
185+ * drm_gem_vram_mmap_offset() - Returns a GEM VRAM object's mmap offset
186+ * @gbo: the GEM VRAM object
187+ *
188+ * See drm_vma_node_offset_addr() for more information.
189+ *
190+ * Returns:
191+ * The buffer object's offset for userspace mappings on success, or
192+ * 0 if no offset is allocated.
193+ */
194+u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo)
195+{
196+ return drm_vma_node_offset_addr(&gbo->bo.vma_node);
197+}
198+EXPORT_SYMBOL(drm_gem_vram_mmap_offset);
199+
200+/**
201+ * drm_gem_vram_offset() - \
202+ Returns a GEM VRAM object's offset in video memory
203+ * @gbo: the GEM VRAM object
204+ *
205+ * This function returns the buffer object's offset in the device's video
206+ * memory. The buffer object has to be pinned to %TTM_PL_VRAM.
207+ *
208+ * Returns:
209+ * The buffer object's offset in video memory on success, or
210+ * a negative errno code otherwise.
211+ */
212+s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo)
213+{
214+ if (WARN_ON_ONCE(!gbo->pin_count))
215+ return (s64)-ENODEV;
216+ return gbo->bo.offset;
217+}
218+EXPORT_SYMBOL(drm_gem_vram_offset);
219+
220+/**
221+ * drm_gem_vram_pin() - Pins a GEM VRAM object in a region.
222+ * @gbo: the GEM VRAM object
223+ * @pl_flag: a bitmask of possible memory regions
224+ *
225+ * Pinning a buffer object ensures that it is not evicted from
226+ * a memory region. A pinned buffer object has to be unpinned before
227+ * it can be pinned to another region.
228+ *
229+ * Returns:
230+ * 0 on success, or
231+ * a negative error code otherwise.
232+ */
233+int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag)
234+{
235+ int i, ret;
236+ struct ttm_operation_ctx ctx = { false, false };
237+
238+ ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
239+ if (ret < 0)
240+ return ret;
241+
242+ if (gbo->pin_count)
243+ goto out;
244+
245+ drm_gem_vram_placement(gbo, pl_flag);
246+ for (i = 0; i < gbo->placement.num_placement; ++i)
247+ gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
248+
249+ ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
250+ if (ret < 0)
251+ goto err_ttm_bo_unreserve;
252+
253+out:
254+ ++gbo->pin_count;
255+ ttm_bo_unreserve(&gbo->bo);
256+
257+ return 0;
258+
259+err_ttm_bo_unreserve:
260+ ttm_bo_unreserve(&gbo->bo);
261+ return ret;
262+}
263+EXPORT_SYMBOL(drm_gem_vram_pin);
264+
265+/**
266+ * drm_gem_vram_pin_locked() - Pins a GEM VRAM object in a region.
267+ * @gbo: the GEM VRAM object
268+ * @pl_flag: a bitmask of possible memory regions
269+ *
270+ * Pinning a buffer object ensures that it is not evicted from
271+ * a memory region. A pinned buffer object has to be unpinned before
272+ * it can be pinned to another region.
273+ *
274+ * This function pins a GEM VRAM object that has already been
275+ * locked. Use drm_gem_vram_pin() if possible.
276+ *
277+ * Returns:
278+ * 0 on success, or
279+ * a negative error code otherwise.
280+ */
281+int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
282+ unsigned long pl_flag)
283+{
284+ int i, ret;
285+ struct ttm_operation_ctx ctx = { false, false };
286+
287+ lockdep_assert_held(&gbo->bo.resv->lock.base);
288+
289+ if (gbo->pin_count) {
290+ ++gbo->pin_count;
291+ return 0;
292+ }
293+
294+ drm_gem_vram_placement(gbo, pl_flag);
295+ for (i = 0; i < gbo->placement.num_placement; ++i)
296+ gbo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
297+
298+ ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
299+ if (ret < 0)
300+ return ret;
301+
302+ gbo->pin_count = 1;
303+
304+ return 0;
305+}
306+EXPORT_SYMBOL(drm_gem_vram_pin_locked);
307+
308+/**
309+ * drm_gem_vram_unpin() - Unpins a GEM VRAM object
310+ * @gbo: the GEM VRAM object
311+ *
312+ * Returns:
313+ * 0 on success, or
314+ * a negative error code otherwise.
315+ */
316+int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
317+{
318+ int i, ret;
319+ struct ttm_operation_ctx ctx = { false, false };
320+
321+ ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
322+ if (ret < 0)
323+ return ret;
324+
325+ if (WARN_ON_ONCE(!gbo->pin_count))
326+ goto out;
327+
328+ --gbo->pin_count;
329+ if (gbo->pin_count)
330+ goto out;
331+
332+ for (i = 0; i < gbo->placement.num_placement ; ++i)
333+ gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
334+
335+ ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
336+ if (ret < 0)
337+ goto err_ttm_bo_unreserve;
338+
339+out:
340+ ttm_bo_unreserve(&gbo->bo);
341+
342+ return 0;
343+
344+err_ttm_bo_unreserve:
345+ ttm_bo_unreserve(&gbo->bo);
346+ return ret;
347+}
348+EXPORT_SYMBOL(drm_gem_vram_unpin);
349+
350+/**
351+ * drm_gem_vram_unpin_locked() - Unpins a GEM VRAM object
352+ * @gbo: the GEM VRAM object
353+ *
354+ * This function unpins a GEM VRAM object that has already been
355+ * locked. Use drm_gem_vram_unpin() if possible.
356+ *
357+ * Returns:
358+ * 0 on success, or
359+ * a negative error code otherwise.
360+ */
361+int drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo)
362+{
363+ int i, ret;
364+ struct ttm_operation_ctx ctx = { false, false };
365+
366+ lockdep_assert_held(&gbo->bo.resv->lock.base);
367+
368+ if (WARN_ON_ONCE(!gbo->pin_count))
369+ return 0;
370+
371+ --gbo->pin_count;
372+ if (gbo->pin_count)
373+ return 0;
374+
375+ for (i = 0; i < gbo->placement.num_placement ; ++i)
376+ gbo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
377+
378+ ret = ttm_bo_validate(&gbo->bo, &gbo->placement, &ctx);
379+ if (ret < 0)
380+ return ret;
381+
382+ return 0;
383+}
384+EXPORT_SYMBOL(drm_gem_vram_unpin_locked);
385+
386+/**
387+ * drm_gem_vram_kmap_at() - Maps a GEM VRAM object into kernel address space
388+ * @gbo: the GEM VRAM object
389+ * @map: establish a mapping if necessary
390+ * @is_iomem: returns true if the mapped memory is I/O memory, or false \
391+ otherwise; can be NULL
392+ * @kmap: the mapping's kmap object
393+ *
394+ * This function maps the buffer object into the kernel's address space
395+ * or returns the current mapping. If the parameter map is false, the
396+ * function only queries the current mapping, but does not establish a
397+ * new one.
398+ *
399+ * Returns:
400+ * The buffers virtual address if mapped, or
401+ * NULL if not mapped, or
402+ * an ERR_PTR()-encoded error code otherwise.
403+ */
404+void *drm_gem_vram_kmap_at(struct drm_gem_vram_object *gbo, bool map,
405+ bool *is_iomem, struct ttm_bo_kmap_obj *kmap)
406+{
407+ int ret;
408+
409+ if (kmap->virtual || !map)
410+ goto out;
411+
412+ ret = ttm_bo_kmap(&gbo->bo, 0, gbo->bo.num_pages, kmap);
413+ if (ret)
414+ return ERR_PTR(ret);
415+
416+out:
417+ if (!is_iomem)
418+ return kmap->virtual;
419+ if (!kmap->virtual) {
420+ *is_iomem = false;
421+ return NULL;
422+ }
423+ return ttm_kmap_obj_virtual(kmap, is_iomem);
424+}
425+EXPORT_SYMBOL(drm_gem_vram_kmap_at);
426+
427+/**
428+ * drm_gem_vram_kmap() - Maps a GEM VRAM object into kernel address space
429+ * @gbo: the GEM VRAM object
430+ * @map: establish a mapping if necessary
431+ * @is_iomem: returns true if the mapped memory is I/O memory, or false \
432+ otherwise; can be NULL
433+ *
434+ * This function maps the buffer object into the kernel's address space
435+ * or returns the current mapping. If the parameter map is false, the
436+ * function only queries the current mapping, but does not establish a
437+ * new one.
438+ *
439+ * Returns:
440+ * The buffers virtual address if mapped, or
441+ * NULL if not mapped, or
442+ * an ERR_PTR()-encoded error code otherwise.
443+ */
444+void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
445+ bool *is_iomem)
446+{
447+ return drm_gem_vram_kmap_at(gbo, map, is_iomem, &gbo->kmap);
448+}
449+EXPORT_SYMBOL(drm_gem_vram_kmap);
450+
451+/**
452+ * drm_gem_vram_kunmap_at() - Unmaps a GEM VRAM object
453+ * @gbo: the GEM VRAM object
454+ * @kmap: the mapping's kmap object
455+ */
456+void drm_gem_vram_kunmap_at(struct drm_gem_vram_object *gbo,
457+ struct ttm_bo_kmap_obj *kmap)
458+{
459+ if (!kmap->virtual)
460+ return;
461+
462+ ttm_bo_kunmap(kmap);
463+ kmap->virtual = NULL;
464+}
465+EXPORT_SYMBOL(drm_gem_vram_kunmap_at);
466+
467+/**
468+ * drm_gem_vram_kunmap() - Unmaps a GEM VRAM object
469+ * @gbo: the GEM VRAM object
470+ */
471+void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo)
472+{
473+ drm_gem_vram_kunmap_at(gbo, &gbo->kmap);
474+}
475+EXPORT_SYMBOL(drm_gem_vram_kunmap);
476+
477+/**
478+ * drm_gem_vram_fill_create_dumb() - \
479+ Helper for implementing &struct drm_driver.dumb_create
480+ * @file: the DRM file
481+ * @dev: the DRM device
482+ * @bdev: the TTM BO device managing the buffer object
483+ * @pg_align: the buffer's alignment in multiples of the page size
484+ * @interruptible: sleep interruptible if waiting for memory
485+ * @args: the arguments as provided to \
486+ &struct drm_driver.dumb_create
487+ *
488+ * This helper function fills &struct drm_mode_create_dumb, which is used
489+ * by &struct drm_driver.dumb_create. Implementations of this interface
490+ * should forwards their arguments to this helper, plus the driver-specific
491+ * parameters.
492+ *
493+ * Returns:
494+ * 0 on success, or
495+ * a negative error code otherwise.
496+ */
497+int drm_gem_vram_fill_create_dumb(struct drm_file *file,
498+ struct drm_device *dev,
499+ struct ttm_bo_device *bdev,
500+ unsigned long pg_align,
501+ bool interruptible,
502+ struct drm_mode_create_dumb *args)
503+{
504+ size_t pitch, size;
505+ struct drm_gem_vram_object *gbo;
506+ int ret;
507+ u32 handle;
508+
509+ pitch = args->width * ((args->bpp + 7) / 8);
510+ size = pitch * args->height;
511+
512+ size = roundup(size, PAGE_SIZE);
513+ if (!size)
514+ return -EINVAL;
515+
516+ gbo = drm_gem_vram_create(dev, bdev, size, pg_align, interruptible);
517+ if (IS_ERR(gbo))
518+ return PTR_ERR(gbo);
519+
520+ ret = drm_gem_handle_create(file, &gbo->gem, &handle);
521+ if (ret)
522+ goto err_drm_gem_object_put_unlocked;
523+
524+ drm_gem_object_put_unlocked(&gbo->gem);
525+
526+ args->pitch = pitch;
527+ args->size = size;
528+ args->handle = handle;
529+
530+ return 0;
531+
532+err_drm_gem_object_put_unlocked:
533+ drm_gem_object_put_unlocked(&gbo->gem);
534+ return ret;
535+}
536+EXPORT_SYMBOL(drm_gem_vram_fill_create_dumb);
537+
538+/*
539+ * Helpers for struct ttm_bo_driver
540+ */
541+
542+static bool drm_is_gem_vram(struct ttm_buffer_object *bo)
543+{
544+ return (bo->destroy == ttm_buffer_object_destroy);
545+}
546+
547+/**
548+ * drm_gem_vram_bo_driver_evict_flags() - \
549+ Implements &struct ttm_bo_driver.evict_flags
550+ * @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
551+ * @pl: TTM placement information.
552+ */
553+void drm_gem_vram_bo_driver_evict_flags(struct ttm_buffer_object *bo,
554+ struct ttm_placement *pl)
555+{
556+ struct drm_gem_vram_object *gbo;
557+
558+ /* TTM may pass BOs that are not GEM VRAM BOs. */
559+ if (!drm_is_gem_vram(bo))
560+ return;
561+
562+ gbo = drm_gem_vram_of_bo(bo);
563+ drm_gem_vram_placement(gbo, TTM_PL_FLAG_SYSTEM);
564+ *pl = gbo->placement;
565+}
566+EXPORT_SYMBOL(drm_gem_vram_bo_driver_evict_flags);
567+
568+/**
569+ * drm_gem_vram_bo_driver_verify_access() - \
570+ Implements &struct ttm_bo_driver.verify_access
571+ * @bo: TTM buffer object. Refers to &struct drm_gem_vram_object.bo
572+ * @filp: File pointer.
573+ *
574+ * Returns:
575+ * 0 on success, or
576+ * a negative errno code otherwise.
577+ */
578+int drm_gem_vram_bo_driver_verify_access(struct ttm_buffer_object *bo,
579+ struct file *filp)
580+{
581+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_bo(bo);
582+
583+ return drm_vma_node_verify_access(&gbo->gem.vma_node,
584+ filp->private_data);
585+}
586+EXPORT_SYMBOL(drm_gem_vram_bo_driver_verify_access);
587+
588+/**
589+ * drm_gem_vram_mm_funcs - Functions for &struct drm_vram_mm
590+ *
591+ * Most users of @struct drm_gem_vram_object will also use
592+ * @struct drm_vram_mm. This instance of &struct drm_vram_mm_funcs
593+ * can be used to connect both.
594+ */
595+const struct drm_vram_mm_funcs drm_gem_vram_mm_funcs = {
596+ .evict_flags = drm_gem_vram_bo_driver_evict_flags,
597+ .verify_access = drm_gem_vram_bo_driver_verify_access
598+};
599+EXPORT_SYMBOL(drm_gem_vram_mm_funcs);
600+
601+/*
602+ * Helpers for struct drm_driver
603+ */
604+
605+/**
606+ * drm_gem_vram_driver_gem_free_object_unlocked() - \
607+ Implements &struct drm_driver.gem_free_object_unlocked
608+ * @gem: GEM object. Refers to &struct drm_gem_vram_object.gem
609+ */
610+void drm_gem_vram_driver_gem_free_object_unlocked(struct drm_gem_object *gem)
611+{
612+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
613+
614+ drm_gem_vram_put(gbo);
615+}
616+EXPORT_SYMBOL(drm_gem_vram_driver_gem_free_object_unlocked);
617+
618+/**
619+ * drm_gem_vram_driver_create_dumb() - \
620+ Implements &struct drm_driver.dumb_create
621+ * @file: the DRM file
622+ * @dev: the DRM device
623+ * @args: the arguments as provided to \
624+ &struct drm_driver.dumb_create
625+ *
626+ * This function requires the driver to use @drm_device.vram_mm for its
627+ * instance of VRAM MM.
628+ *
629+ * Returns:
630+ * 0 on success, or
631+ * a negative error code otherwise.
632+ */
633+int drm_gem_vram_driver_dumb_create(struct drm_file *file,
634+ struct drm_device *dev,
635+ struct drm_mode_create_dumb *args)
636+{
637+ if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
638+ return -EINVAL;
639+
640+ return drm_gem_vram_fill_create_dumb(file, dev, &dev->vram_mm->bdev, 0,
641+ false, args);
642+}
643+EXPORT_SYMBOL(drm_gem_vram_driver_dumb_create);
644+
645+/**
646+ * drm_gem_vram_driver_dumb_mmap_offset() - \
647+ Implements &struct drm_driver.dumb_mmap_offset
648+ * @file: DRM file pointer.
649+ * @dev: DRM device.
650+ * @handle: GEM handle
651+ * @offset: Returns the mapping's memory offset on success
652+ *
653+ * Returns:
654+ * 0 on success, or
655+ * a negative errno code otherwise.
656+ */
657+int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
658+ struct drm_device *dev,
659+ uint32_t handle, uint64_t *offset)
660+{
661+ struct drm_gem_object *gem;
662+ struct drm_gem_vram_object *gbo;
663+
664+ gem = drm_gem_object_lookup(file, handle);
665+ if (!gem)
666+ return -ENOENT;
667+
668+ gbo = drm_gem_vram_of_gem(gem);
669+ *offset = drm_gem_vram_mmap_offset(gbo);
670+
671+ drm_gem_object_put_unlocked(gem);
672+
673+ return 0;
674+}
675+EXPORT_SYMBOL(drm_gem_vram_driver_dumb_mmap_offset);
676+
677+/*
678+ * PRIME helpers for struct drm_driver
679+ */
680+
681+/**
682+ * drm_gem_vram_driver_gem_prime_pin() - \
683+ Implements &struct drm_driver.gem_prime_pin
684+ * @gem: The GEM object to pin
685+ *
686+ * Returns:
687+ * 0 on success, or
688+ * a negative errno code otherwise.
689+ */
690+int drm_gem_vram_driver_gem_prime_pin(struct drm_gem_object *gem)
691+{
692+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
693+
694+ return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
695+}
696+EXPORT_SYMBOL(drm_gem_vram_driver_gem_prime_pin);
697+
698+/**
699+ * drm_gem_vram_driver_gem_prime_unpin() - \
700+ Implements &struct drm_driver.gem_prime_unpin
701+ * @gem: The GEM object to unpin
702+ */
703+void drm_gem_vram_driver_gem_prime_unpin(struct drm_gem_object *gem)
704+{
705+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
706+
707+ drm_gem_vram_unpin(gbo);
708+}
709+EXPORT_SYMBOL(drm_gem_vram_driver_gem_prime_unpin);
710+
711+/**
712+ * drm_gem_vram_driver_gem_prime_vmap() - \
713+ Implements &struct drm_driver.gem_prime_vmap
714+ * @gem: The GEM object to map
715+ *
716+ * Returns:
717+ * The buffers virtual address on success, or
718+ * NULL otherwise.
719+ */
720+void *drm_gem_vram_driver_gem_prime_vmap(struct drm_gem_object *gem)
721+{
722+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
723+ int ret;
724+ void *base;
725+
726+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
727+ if (ret)
728+ return NULL;
729+ base = drm_gem_vram_kmap(gbo, true, NULL);
730+ if (IS_ERR(base)) {
731+ drm_gem_vram_unpin(gbo);
732+ return NULL;
733+ }
734+ return base;
735+}
736+EXPORT_SYMBOL(drm_gem_vram_driver_gem_prime_vmap);
737+
738+/**
739+ * drm_gem_vram_driver_gem_prime_vunmap() - \
740+ Implements &struct drm_driver.gem_prime_vunmap
741+ * @gem: The GEM object to unmap
742+ * @vaddr: The mapping's base address
743+ */
744+void drm_gem_vram_driver_gem_prime_vunmap(struct drm_gem_object *gem,
745+ void *vaddr)
746+{
747+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
748+
749+ drm_gem_vram_kunmap(gbo);
750+ drm_gem_vram_unpin(gbo);
751+}
752+EXPORT_SYMBOL(drm_gem_vram_driver_gem_prime_vunmap);
753+
754+/**
755+ * drm_gem_vram_driver_gem_prime_mmap() - \
756+ Implements &struct drm_driver.gem_prime_mmap
757+ * @gem: The GEM object to map
758+ * @vma: The VMA describing the mapping
759+ *
760+ * Returns:
761+ * 0 on success, or
762+ * a negative errno code otherwise.
763+ */
764+int drm_gem_vram_driver_gem_prime_mmap(struct drm_gem_object *gem,
765+ struct vm_area_struct *vma)
766+{
767+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
768+
769+ gbo->gem.vma_node.vm_node.start = gbo->bo.vma_node.vm_node.start;
770+ return drm_gem_prime_mmap(gem, vma);
771+}
772+EXPORT_SYMBOL(drm_gem_vram_driver_gem_prime_mmap);
drivers/gpu/drm/drm_internal.h+2−0
@@ -93,6 +93,8 @@ int drm_dropmaster_ioctl(struct drm_device *dev, void *data, · 92 unmodified lines
9393 struct drm_file *file_priv);
9494 int drm_master_open(struct drm_file *file_priv);
9595 void drm_master_release(struct drm_file *file_priv);
96+bool drm_master_internal_acquire(struct drm_device *dev);
97+void drm_master_internal_release(struct drm_device *dev);
9698
9799 /* drm_sysfs.c */
98100 extern struct class *drm_class;
drivers/gpu/drm/drm_legacy.h+2−0
@@ -187,10 +187,12 @@ int drm_legacy_sg_free(struct drm_device *dev, void *data, · 186 unmodified lines
187187 void drm_legacy_init_members(struct drm_device *dev);
188188 void drm_legacy_destroy_members(struct drm_device *dev);
189189 void drm_legacy_dev_reinit(struct drm_device *dev);
190+int drm_legacy_setup(struct drm_device * dev);
190191 #else
191192 static inline void drm_legacy_init_members(struct drm_device *dev) {}
192193 static inline void drm_legacy_destroy_members(struct drm_device *dev) {}
193194 static inline void drm_legacy_dev_reinit(struct drm_device *dev) {}
195+static inline int drm_legacy_setup(struct drm_device * dev) { return 0; }
194196 #endif
195197
196198 #if IS_ENABLED(CONFIG_DRM_LEGACY)
drivers/gpu/drm/drm_legacy_misc.c+20−0
@@ -51,6 +51,26 @@ void drm_legacy_destroy_members(struct drm_device *dev) · 50 unmodified lines
5151 mutex_destroy(&dev->ctxlist_mutex);
5252 }
5353
54+int drm_legacy_setup(struct drm_device * dev)
55+{
56+ int ret;
57+
58+ if (dev->driver->firstopen &&
59+ drm_core_check_feature(dev, DRIVER_LEGACY)) {
60+ ret = dev->driver->firstopen(dev);
61+ if (ret != 0)
62+ return ret;
63+ }
64+
65+ ret = drm_legacy_dma_setup(dev);
66+ if (ret < 0)
67+ return ret;
68+
69+
70+ DRM_DEBUG("\n");
71+ return 0;
72+}
73+
5474 void drm_legacy_dev_reinit(struct drm_device *dev)
5575 {
5676 if (dev->irq_enabled)
drivers/gpu/drm/drm_prime.c+17−60
@@ -86,11 +86,6 @@ struct drm_prime_member { · 85 unmodified lines
8686 struct rb_node handle_rb;
8787 };
8888
89−struct drm_prime_attachment {
90− struct sg_table *sgt;
91− enum dma_data_direction dir;
92−};
93−
9489 static int drm_prime_add_buf_handle(struct drm_prime_file_private *prime_fpriv,
9590 struct dma_buf *dma_buf, uint32_t handle)
9691 {
@@ -188,25 +183,16 @@ static int drm_prime_lookup_buf_handle(struct drm_prime_file_private *prime_fpri · 91 unmodified lines
188183 * @dma_buf: buffer to attach device to
189184 * @attach: buffer attachment data
190185 *
191− * Allocates &drm_prime_attachment and calls &drm_driver.gem_prime_pin for
192− * device specific attachment. This can be used as the &dma_buf_ops.attach
193− * callback.
186+ * Calls &drm_driver.gem_prime_pin for device specific handling. This can be
187+ * used as the &dma_buf_ops.attach callback.
194188 *
195189 * Returns 0 on success, negative error code on failure.
196190 */
197191 int drm_gem_map_attach(struct dma_buf *dma_buf,
198192 struct dma_buf_attachment *attach)
199193 {
200− struct drm_prime_attachment *prime_attach;
201194 struct drm_gem_object *obj = dma_buf->priv;
202195
203− prime_attach = kzalloc(sizeof(*prime_attach), GFP_KERNEL);
204− if (!prime_attach)
205− return -ENOMEM;
206−
207− prime_attach->dir = DMA_NONE;
208− attach->priv = prime_attach;
209−
210196 return drm_gem_pin(obj);
211197 }
212198 EXPORT_SYMBOL(drm_gem_map_attach);
@@ -222,26 +208,8 @@ EXPORT_SYMBOL(drm_gem_map_attach); · 9 unmodified lines
222208 void drm_gem_map_detach(struct dma_buf *dma_buf,
223209 struct dma_buf_attachment *attach)
224210 {
225− struct drm_prime_attachment *prime_attach = attach->priv;
226211 struct drm_gem_object *obj = dma_buf->priv;
227212
228− if (prime_attach) {
229− struct sg_table *sgt = prime_attach->sgt;
230−
231− if (sgt) {
232− if (prime_attach->dir != DMA_NONE)
233− dma_unmap_sg_attrs(attach->dev, sgt->sgl,
234− sgt->nents,
235− prime_attach->dir,
236− DMA_ATTR_SKIP_CPU_SYNC);
237− sg_free_table(sgt);
238− }
239−
240− kfree(sgt);
241− kfree(prime_attach);
242− attach->priv = NULL;
243− }
244−
245213 drm_gem_unpin(obj);
246214 }
247215 EXPORT_SYMBOL(drm_gem_map_detach);
@@ -286,39 +254,22 @@ void drm_prime_remove_buf_handle_locked(struct drm_prime_file_private *prime_fpr · 38 unmodified lines
286254 struct sg_table *drm_gem_map_dma_buf(struct dma_buf_attachment *attach,
287255 enum dma_data_direction dir)
288256 {
289− struct drm_prime_attachment *prime_attach = attach->priv;
290257 struct drm_gem_object *obj = attach->dmabuf->priv;
291258 struct sg_table *sgt;
292259
293− if (WARN_ON(dir == DMA_NONE || !prime_attach))
260+ if (WARN_ON(dir == DMA_NONE))
294261 return ERR_PTR(-EINVAL);
295262
296− /* return the cached mapping when possible */
297− if (prime_attach->dir == dir)
298− return prime_attach->sgt;
299−
300− /*
301− * two mappings with different directions for the same attachment are
302− * not allowed
303− */
304− if (WARN_ON(prime_attach->dir != DMA_NONE))
305− return ERR_PTR(-EBUSY);
306−
307263 if (obj->funcs)
308264 sgt = obj->funcs->get_sg_table(obj);
309265 else
310266 sgt = obj->dev->driver->gem_prime_get_sg_table(obj);
311267
312− if (!IS_ERR(sgt)) {
313− if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
314− DMA_ATTR_SKIP_CPU_SYNC)) {
315− sg_free_table(sgt);
316− kfree(sgt);
317− sgt = ERR_PTR(-ENOMEM);
318− } else {
319− prime_attach->sgt = sgt;
320− prime_attach->dir = dir;
321− }
268+ if (!dma_map_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
269+ DMA_ATTR_SKIP_CPU_SYNC)) {
270+ sg_free_table(sgt);
271+ kfree(sgt);
272+ sgt = ERR_PTR(-ENOMEM);
322273 }
323274
324275 return sgt;
@@ -331,14 +282,19 @@ EXPORT_SYMBOL(drm_gem_map_dma_buf); · 6 unmodified lines
331282 * @sgt: scatterlist info of the buffer to unmap
332283 * @dir: direction of DMA transfer
333284 *
334− * Not implemented. The unmap is done at drm_gem_map_detach(). This can be
335− * used as the &dma_buf_ops.unmap_dma_buf callback.
285+ * This can be used as the &dma_buf_ops.unmap_dma_buf callback.
336286 */
337287 void drm_gem_unmap_dma_buf(struct dma_buf_attachment *attach,
338288 struct sg_table *sgt,
339289 enum dma_data_direction dir)
340290 {
341− /* nothing to be done here */
291+ if (!sgt)
292+ return;
293+
294+ dma_unmap_sg_attrs(attach->dev, sgt->sgl, sgt->nents, dir,
295+ DMA_ATTR_SKIP_CPU_SYNC);
296+ sg_free_table(sgt);
297+ kfree(sgt);
342298 }
343299 EXPORT_SYMBOL(drm_gem_unmap_dma_buf);
344300
@@ -452,6 +408,7 @@ int drm_gem_dmabuf_mmap(struct dma_buf *dma_buf, struct vm_area_struct *vma) · 107 unmodified lines
452408 EXPORT_SYMBOL(drm_gem_dmabuf_mmap);
453409
454410 static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = {
411+ .cache_sgt_mapping = true,
455412 .attach = drm_gem_map_attach,
456413 .detach = drm_gem_map_detach,
457414 .map_dma_buf = drm_gem_map_dma_buf,
drivers/gpu/drm/drm_vram_helper_common.c+96−0
@@ -0,0 +1,96 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+
3+#include <linux/module.h>
4+
5+/**
6+ * DOC: overview
7+ *
8+ * This library provides &struct drm_gem_vram_object (GEM VRAM), a GEM
9+ * buffer object that is backed by video RAM. It can be used for
10+ * framebuffer devices with dedicated memory. The video RAM can be
11+ * managed with &struct drm_vram_mm (VRAM MM). Both data structures are
12+ * supposed to be used together, but can also be used individually.
13+ *
14+ * With the GEM interface userspace applications create, manage and destroy
15+ * graphics buffers, such as an on-screen framebuffer. GEM does not provide
16+ * an implementation of these interfaces. It's up to the DRM driver to
17+ * provide an implementation that suits the hardware. If the hardware device
18+ * contains dedicated video memory, the DRM driver can use the VRAM helper
19+ * library. Each active buffer object is stored in video RAM. Active
20+ * buffer are used for drawing the current frame, typically something like
21+ * the frame's scanout buffer or the cursor image. If there's no more space
22+ * left in VRAM, inactive GEM objects can be moved to system memory.
23+ *
24+ * The easiest way to use the VRAM helper library is to call
25+ * drm_vram_helper_alloc_mm(). The function allocates and initializes an
26+ * instance of &struct drm_vram_mm in &struct drm_device.vram_mm . Use
27+ * &DRM_GEM_VRAM_DRIVER to initialize &struct drm_driver and
28+ * &DRM_VRAM_MM_FILE_OPERATIONS to initialize &struct file_operations;
29+ * as illustrated below.
30+ *
31+ * .. code-block:: c
32+ *
33+ * struct file_operations fops ={
34+ * .owner = THIS_MODULE,
35+ * DRM_VRAM_MM_FILE_OPERATION
36+ * };
37+ * struct drm_driver drv = {
38+ * .driver_feature = DRM_ ... ,
39+ * .fops = &fops,
40+ * DRM_GEM_VRAM_DRIVER
41+ * };
42+ *
43+ * int init_drm_driver()
44+ * {
45+ * struct drm_device *dev;
46+ * uint64_t vram_base;
47+ * unsigned long vram_size;
48+ * int ret;
49+ *
50+ * // setup device, vram base and size
51+ * // ...
52+ *
53+ * ret = drm_vram_helper_alloc_mm(dev, vram_base, vram_size,
54+ * &drm_gem_vram_mm_funcs);
55+ * if (ret)
56+ * return ret;
57+ * return 0;
58+ * }
59+ *
60+ * This creates an instance of &struct drm_vram_mm, exports DRM userspace
61+ * interfaces for GEM buffer management and initializes file operations to
62+ * allow for accessing created GEM buffers. With this setup, the DRM driver
63+ * manages an area of video RAM with VRAM MM and provides GEM VRAM objects
64+ * to userspace.
65+ *
66+ * To clean up the VRAM memory management, call drm_vram_helper_release_mm()
67+ * in the driver's clean-up code.
68+ *
69+ * .. code-block:: c
70+ *
71+ * void fini_drm_driver()
72+ * {
73+ * struct drm_device *dev = ...;
74+ *
75+ * drm_vram_helper_release_mm(dev);
76+ * }
77+ *
78+ * For drawing or scanout operations, buffer object have to be pinned in video
79+ * RAM. Call drm_gem_vram_pin() with &DRM_GEM_VRAM_PL_FLAG_VRAM or
80+ * &DRM_GEM_VRAM_PL_FLAG_SYSTEM to pin a buffer object in video RAM or system
81+ * memory. Call drm_gem_vram_unpin() to release the pinned object afterwards.
82+ *
83+ * A buffer object that is pinned in video RAM has a fixed address within that
84+ * memory region. Call drm_gem_vram_offset() to retrieve this value. Typically
85+ * it's used to program the hardware's scanout engine for framebuffers, set
86+ * the cursor overlay's image for a mouse cursor, or use it as input to the
87+ * hardware's draing engine.
88+ *
89+ * To access a buffer object's memory from the DRM driver, call
90+ * drm_gem_vram_kmap(). It (optionally) maps the buffer into kernel address
91+ * space and returns the memory address. Use drm_gem_vram_kunmap() to
92+ * release the mapping.
93+ */
94+
95+MODULE_DESCRIPTION("DRM VRAM memory-management helpers");
96+MODULE_LICENSE("GPL");
drivers/gpu/drm/drm_vram_mm_helper.c+295−0
@@ -0,0 +1,295 @@
1+// SPDX-License-Identifier: GPL-2.0-or-later
2+
3+#include <drm/drm_vram_mm_helper.h>
4+#include <drm/drmP.h>
5+#include <drm/ttm/ttm_page_alloc.h>
6+
7+/**
8+ * DOC: overview
9+ *
10+ * The data structure &struct drm_vram_mm and its helpers implement a memory
11+ * manager for simple framebuffer devices with dedicated video memory. Buffer
12+ * objects are either placed in video RAM or evicted to system memory. These
13+ * helper functions work well with &struct drm_gem_vram_object.
14+ */
15+
16+/*
17+ * TTM TT
18+ */
19+
20+static void backend_func_destroy(struct ttm_tt *tt)
21+{
22+ ttm_tt_fini(tt);
23+ kfree(tt);
24+}
25+
26+static struct ttm_backend_func backend_func = {
27+ .destroy = backend_func_destroy
28+};
29+
30+/*
31+ * TTM BO device
32+ */
33+
34+static struct ttm_tt *bo_driver_ttm_tt_create(struct ttm_buffer_object *bo,
35+ uint32_t page_flags)
36+{
37+ struct ttm_tt *tt;
38+ int ret;
39+
40+ tt = kzalloc(sizeof(*tt), GFP_KERNEL);
41+ if (!tt)
42+ return NULL;
43+
44+ tt->func = &backend_func;
45+
46+ ret = ttm_tt_init(tt, bo, page_flags);
47+ if (ret < 0)
48+ goto err_ttm_tt_init;
49+
50+ return tt;
51+
52+err_ttm_tt_init:
53+ kfree(tt);
54+ return NULL;
55+}
56+
57+static int bo_driver_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
58+ struct ttm_mem_type_manager *man)
59+{
60+ switch (type) {
61+ case TTM_PL_SYSTEM:
62+ man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
63+ man->available_caching = TTM_PL_MASK_CACHING;
64+ man->default_caching = TTM_PL_FLAG_CACHED;
65+ break;
66+ case TTM_PL_VRAM:
67+ man->func = &ttm_bo_manager_func;
68+ man->flags = TTM_MEMTYPE_FLAG_FIXED |
69+ TTM_MEMTYPE_FLAG_MAPPABLE;
70+ man->available_caching = TTM_PL_FLAG_UNCACHED |
71+ TTM_PL_FLAG_WC;
72+ man->default_caching = TTM_PL_FLAG_WC;
73+ break;
74+ default:
75+ return -EINVAL;
76+ }
77+ return 0;
78+}
79+
80+static void bo_driver_evict_flags(struct ttm_buffer_object *bo,
81+ struct ttm_placement *placement)
82+{
83+ struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bo->bdev);
84+
85+ if (vmm->funcs && vmm->funcs->evict_flags)
86+ vmm->funcs->evict_flags(bo, placement);
87+}
88+
89+static int bo_driver_verify_access(struct ttm_buffer_object *bo,
90+ struct file *filp)
91+{
92+ struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bo->bdev);
93+
94+ if (!vmm->funcs || !vmm->funcs->verify_access)
95+ return 0;
96+ return vmm->funcs->verify_access(bo, filp);
97+}
98+
99+static int bo_driver_io_mem_reserve(struct ttm_bo_device *bdev,
100+ struct ttm_mem_reg *mem)
101+{
102+ struct ttm_mem_type_manager *man = bdev->man + mem->mem_type;
103+ struct drm_vram_mm *vmm = drm_vram_mm_of_bdev(bdev);
104+
105+ if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
106+ return -EINVAL;
107+
108+ mem->bus.addr = NULL;
109+ mem->bus.size = mem->num_pages << PAGE_SHIFT;
110+
111+ switch (mem->mem_type) {
112+ case TTM_PL_SYSTEM: /* nothing to do */
113+ mem->bus.offset = 0;
114+ mem->bus.base = 0;
115+ mem->bus.is_iomem = false;
116+ break;
117+ case TTM_PL_VRAM:
118+ mem->bus.offset = mem->start << PAGE_SHIFT;
119+ mem->bus.base = vmm->vram_base;
120+ mem->bus.is_iomem = true;
121+ break;
122+ default:
123+ return -EINVAL;
124+ }
125+
126+ return 0;
127+}
128+
129+static void bo_driver_io_mem_free(struct ttm_bo_device *bdev,
130+ struct ttm_mem_reg *mem)
131+{ }
132+
133+static struct ttm_bo_driver bo_driver = {
134+ .ttm_tt_create = bo_driver_ttm_tt_create,
135+ .ttm_tt_populate = ttm_pool_populate,
136+ .ttm_tt_unpopulate = ttm_pool_unpopulate,
137+ .init_mem_type = bo_driver_init_mem_type,
138+ .eviction_valuable = ttm_bo_eviction_valuable,
139+ .evict_flags = bo_driver_evict_flags,
140+ .verify_access = bo_driver_verify_access,
141+ .io_mem_reserve = bo_driver_io_mem_reserve,
142+ .io_mem_free = bo_driver_io_mem_free,
143+};
144+
145+/*
146+ * struct drm_vram_mm
147+ */
148+
149+/**
150+ * drm_vram_mm_init() - Initialize an instance of VRAM MM.
151+ * @vmm: the VRAM MM instance to initialize
152+ * @dev: the DRM device
153+ * @vram_base: the base address of the video memory
154+ * @vram_size: the size of the video memory in bytes
155+ * @funcs: callback functions for buffer objects
156+ *
157+ * Returns:
158+ * 0 on success, or
159+ * a negative error code otherwise.
160+ */
161+int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
162+ uint64_t vram_base, size_t vram_size,
163+ const struct drm_vram_mm_funcs *funcs)
164+{
165+ int ret;
166+
167+ vmm->vram_base = vram_base;
168+ vmm->vram_size = vram_size;
169+ vmm->funcs = funcs;
170+
171+ ret = ttm_bo_device_init(&vmm->bdev, &bo_driver,
172+ dev->anon_inode->i_mapping,
173+ true);
174+ if (ret)
175+ return ret;
176+
177+ ret = ttm_bo_init_mm(&vmm->bdev, TTM_PL_VRAM, vram_size >> PAGE_SHIFT);
178+ if (ret)
179+ return ret;
180+
181+ return 0;
182+}
183+EXPORT_SYMBOL(drm_vram_mm_init);
184+
185+/**
186+ * drm_vram_mm_cleanup() - Cleans up an initialized instance of VRAM MM.
187+ * @vmm: the VRAM MM instance to clean up
188+ */
189+void drm_vram_mm_cleanup(struct drm_vram_mm *vmm)
190+{
191+ ttm_bo_device_release(&vmm->bdev);
192+}
193+EXPORT_SYMBOL(drm_vram_mm_cleanup);
194+
195+/**
196+ * drm_vram_mm_mmap() - Helper for implementing &struct file_operations.mmap()
197+ * @filp: the mapping's file structure
198+ * @vma: the mapping's memory area
199+ * @vmm: the VRAM MM instance
200+ *
201+ * Returns:
202+ * 0 on success, or
203+ * a negative error code otherwise.
204+ */
205+int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma,
206+ struct drm_vram_mm *vmm)
207+{
208+ return ttm_bo_mmap(filp, vma, &vmm->bdev);
209+}
210+EXPORT_SYMBOL(drm_vram_mm_mmap);
211+
212+/*
213+ * Helpers for integration with struct drm_device
214+ */
215+
216+/**
217+ * drm_vram_helper_alloc_mm - Allocates a device's instance of \
218+ &struct drm_vram_mm
219+ * @dev: the DRM device
220+ * @vram_base: the base address of the video memory
221+ * @vram_size: the size of the video memory in bytes
222+ * @funcs: callback functions for buffer objects
223+ *
224+ * Returns:
225+ * The new instance of &struct drm_vram_mm on success, or
226+ * an ERR_PTR()-encoded errno code otherwise.
227+ */
228+struct drm_vram_mm *drm_vram_helper_alloc_mm(
229+ struct drm_device *dev, uint64_t vram_base, size_t vram_size,
230+ const struct drm_vram_mm_funcs *funcs)
231+{
232+ int ret;
233+
234+ if (WARN_ON(dev->vram_mm))
235+ return dev->vram_mm;
236+
237+ dev->vram_mm = kzalloc(sizeof(*dev->vram_mm), GFP_KERNEL);
238+ if (!dev->vram_mm)
239+ return ERR_PTR(-ENOMEM);
240+
241+ ret = drm_vram_mm_init(dev->vram_mm, dev, vram_base, vram_size, funcs);
242+ if (ret)
243+ goto err_kfree;
244+
245+ return dev->vram_mm;
246+
247+err_kfree:
248+ kfree(dev->vram_mm);
249+ dev->vram_mm = NULL;
250+ return ERR_PTR(ret);
251+}
252+EXPORT_SYMBOL(drm_vram_helper_alloc_mm);
253+
254+/**
255+ * drm_vram_helper_release_mm - Releases a device's instance of \
256+ &struct drm_vram_mm
257+ * @dev: the DRM device
258+ */
259+void drm_vram_helper_release_mm(struct drm_device *dev)
260+{
261+ if (!dev->vram_mm)
262+ return;
263+
264+ drm_vram_mm_cleanup(dev->vram_mm);
265+ kfree(dev->vram_mm);
266+ dev->vram_mm = NULL;
267+}
268+EXPORT_SYMBOL(drm_vram_helper_release_mm);
269+
270+/*
271+ * Helpers for &struct file_operations
272+ */
273+
274+/**
275+ * drm_vram_mm_file_operations_mmap() - \
276+ Implements &struct file_operations.mmap()
277+ * @filp: the mapping's file structure
278+ * @vma: the mapping's memory area
279+ *
280+ * Returns:
281+ * 0 on success, or
282+ * a negative error code otherwise.
283+ */
284+int drm_vram_mm_file_operations_mmap(
285+ struct file *filp, struct vm_area_struct *vma)
286+{
287+ struct drm_file *file_priv = filp->private_data;
288+ struct drm_device *dev = file_priv->minor->dev;
289+
290+ if (WARN_ONCE(!dev->vram_mm, "VRAM MM not initialized"))
291+ return -EINVAL;
292+
293+ return drm_vram_mm_mmap(filp, vma, dev->vram_mm);
294+}
295+EXPORT_SYMBOL(drm_vram_mm_file_operations_mmap);
drivers/gpu/drm/etnaviv/etnaviv_dump.c+0−5
@@ -118,7 +118,6 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) · 117 unmodified lines
118118 unsigned int n_obj, n_bomap_pages;
119119 size_t file_size, mmu_size;
120120 __le64 *bomap, *bomap_start;
121− unsigned long flags;
122121
123122 /* Only catch the first event, or when manually re-armed */
124123 if (!etnaviv_dump_core)
@@ -135,13 +134,11 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) · 10 unmodified lines
135134 mmu_size + gpu->buffer.size;
136135
137136 /* Add in the active command buffers */
138− spin_lock_irqsave(&gpu->sched.job_list_lock, flags);
139137 list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
140138 submit = to_etnaviv_submit(s_job);
141139 file_size += submit->cmdbuf.size;
142140 n_obj++;
143141 }
144− spin_unlock_irqrestore(&gpu->sched.job_list_lock, flags);
145142
146143 /* Add in the active buffer objects */
147144 list_for_each_entry(vram, &gpu->mmu->mappings, mmu_node) {
@@ -183,14 +180,12 @@ void etnaviv_core_dump(struct etnaviv_gpu *gpu) · 35 unmodified lines
183180 gpu->buffer.size,
184181 etnaviv_cmdbuf_get_va(&gpu->buffer));
185182
186− spin_lock_irqsave(&gpu->sched.job_list_lock, flags);
187183 list_for_each_entry(s_job, &gpu->sched.ring_mirror_list, node) {
188184 submit = to_etnaviv_submit(s_job);
189185 etnaviv_core_dump_mem(&iter, ETDUMP_BUF_CMD,
190186 submit->cmdbuf.vaddr, submit->cmdbuf.size,
191187 etnaviv_cmdbuf_get_va(&submit->cmdbuf));
192188 }
193− spin_unlock_irqrestore(&gpu->sched.job_list_lock, flags);
194189
195190 /* Reserve space for the bomap */
196191 if (n_bomap_pages) {
drivers/gpu/drm/etnaviv/etnaviv_sched.c+1−1
@@ -109,7 +109,7 @@ static void etnaviv_sched_timedout_job(struct drm_sched_job *sched_job) · 108 unmodified lines
109109 }
110110
111111 /* block scheduler */
112− drm_sched_stop(&gpu->sched);
112+ drm_sched_stop(&gpu->sched, sched_job);
113113
114114 if(sched_job)
115115 drm_sched_increase_karma(sched_job);
drivers/gpu/drm/gma500/accel_2d.c+9−9
@@ -20,24 +20,24 @@ · 19 unmodified lines
2020 *
2121 **************************************************************************/
2222
23−#include <linux/module.h>
24−#include <linux/kernel.h>
23+#include <linux/console.h>
24+#include <linux/delay.h>
2525 #include <linux/errno.h>
26−#include <linux/string.h>
26+#include <linux/init.h>
27+#include <linux/kernel.h>
2728 #include <linux/mm.h>
28−#include <linux/tty.h>
29+#include <linux/module.h>
2930 #include <linux/slab.h>
30−#include <linux/delay.h>
31−#include <linux/init.h>
32−#include <linux/console.h>
31+#include <linux/string.h>
32+#include <linux/tty.h>
3333
34−#include <drm/drmP.h>
3534 #include <drm/drm.h>
3635 #include <drm/drm_crtc.h>
36+#include <drm/drm_fourcc.h>
3737
38+#include "framebuffer.h"
3839 #include "psb_drv.h"
3940 #include "psb_reg.h"
40−#include "framebuffer.h"
4141
4242 /**
4343 * psb_spank - reset the 2D engine
drivers/gpu/drm/gma500/blitter.h+2−0
@@ -17,6 +17,8 @@ · 16 unmodified lines
1717 #ifndef __BLITTER_H
1818 #define __BLITTER_H
1919
20+struct drm_psb_private;
21+
2022 extern int gma_blt_wait_idle(struct drm_psb_private *dev_priv);
2123
2224 #endif
drivers/gpu/drm/gma500/cdv_device.c+7−6
@@ -18,15 +18,16 @@ · 17 unmodified lines
1818 **************************************************************************/
1919
2020 #include <linux/backlight.h>
21−#include <drm/drmP.h>
21+#include <linux/delay.h>
22+
2223 #include <drm/drm.h>
23−#include <drm/gma_drm.h>
24−#include "psb_drv.h"
25−#include "psb_reg.h"
26−#include "psb_intel_reg.h"
27−#include "intel_bios.h"
24+
2825 #include "cdv_device.h"
2926 #include "gma_device.h"
27+#include "intel_bios.h"
28+#include "psb_drv.h"
29+#include "psb_intel_reg.h"
30+#include "psb_reg.h"
3031
3132 #define VGA_SR_INDEX 0x3c4
3233 #define VGA_SR_DATA 0x3c5
drivers/gpu/drm/gma500/cdv_device.h+4−0
@@ -15,6 +15,10 @@ · 14 unmodified lines
1515 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1616 */
1717
18+struct drm_crtc;
19+struct drm_device;
20+struct psb_intel_mode_device;
21+
1822 extern const struct drm_crtc_helper_funcs cdv_intel_helper_funcs;
1923 extern const struct drm_crtc_funcs cdv_intel_crtc_funcs;
2024 extern const struct gma_clock_funcs cdv_clock_funcs;
drivers/gpu/drm/gma500/cdv_intel_crt.c+4−4
@@ -24,16 +24,16 @@ · 23 unmodified lines
2424 * Eric Anholt <eric@anholt.net>
2525 */
2626
27+#include <linux/delay.h>
2728 #include <linux/i2c.h>
28−#include <drm/drmP.h>
29+#include <linux/pm_runtime.h>
2930
31+#include "cdv_device.h"
3032 #include "intel_bios.h"
33+#include "power.h"
3134 #include "psb_drv.h"
3235 #include "psb_intel_drv.h"
3336 #include "psb_intel_reg.h"
34−#include "power.h"
35−#include "cdv_device.h"
36−#include <linux/pm_runtime.h>
3737
3838
3939 static void cdv_intel_crt_dpms(struct drm_encoder *encoder, int mode)
drivers/gpu/drm/gma500/cdv_intel_display.c+6−4
@@ -18,16 +18,18 @@ · 17 unmodified lines
1818 * Eric Anholt <eric@anholt.net>
1919 */
2020
21+#include <linux/delay.h>
2122 #include <linux/i2c.h>
2223
23−#include <drm/drmP.h>
24+#include <drm/drm_crtc.h>
25+
26+#include "cdv_device.h"
2427 #include "framebuffer.h"
28+#include "gma_display.h"
29+#include "power.h"
2530 #include "psb_drv.h"
2631 #include "psb_intel_drv.h"
2732 #include "psb_intel_reg.h"
28−#include "gma_display.h"
29−#include "power.h"
30−#include "cdv_device.h"
3133
3234 static bool cdv_intel_find_dp_pll(const struct gma_limit_t *limit,
3335 struct drm_crtc *crtc, int target,
drivers/gpu/drm/gma500/cdv_intel_dp.c+5−4
@@ -26,16 +26,17 @@ · 25 unmodified lines
2626 */
2727
2828 #include <linux/i2c.h>
29−#include <linux/slab.h>
3029 #include <linux/module.h>
31−#include <drm/drmP.h>
30+#include <linux/slab.h>
31+
3232 #include <drm/drm_crtc.h>
3333 #include <drm/drm_crtc_helper.h>
34+#include <drm/drm_dp_helper.h>
35+
36+#include "gma_display.h"
3437 #include "psb_drv.h"
3538 #include "psb_intel_drv.h"
3639 #include "psb_intel_reg.h"
37−#include "gma_display.h"
38−#include <drm/drm_dp_helper.h>
3940
4041 /**
4142 * struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp
drivers/gpu/drm/gma500/cdv_intel_hdmi.c+5−4
@@ -27,15 +27,16 @@ · 26 unmodified lines
2727 * We should probably make this generic and share it with Medfield
2828 */
2929
30−#include <drm/drmP.h>
30+#include <linux/pm_runtime.h>
31+
3132 #include <drm/drm.h>
3233 #include <drm/drm_crtc.h>
3334 #include <drm/drm_edid.h>
34−#include "psb_intel_drv.h"
35+
36+#include "cdv_device.h"
3537 #include "psb_drv.h"
38+#include "psb_intel_drv.h"
3639 #include "psb_intel_reg.h"
37−#include "cdv_device.h"
38−#include <linux/pm_runtime.h>
3940
4041 /* hdmi control bits */
4142 #define HDMI_NULL_PACKETS_DURING_VSYNC (1 << 9)
drivers/gpu/drm/gma500/cdv_intel_lvds.c+4−5
@@ -20,17 +20,16 @@ · 19 unmodified lines
2020 * Jesse Barnes <jesse.barnes@intel.com>
2121 */
2222
23−#include <linux/i2c.h>
2423 #include <linux/dmi.h>
25−#include <drm/drmP.h>
24+#include <linux/i2c.h>
25+#include <linux/pm_runtime.h>
2626
27+#include "cdv_device.h"
2728 #include "intel_bios.h"
29+#include "power.h"
2830 #include "psb_drv.h"
2931 #include "psb_intel_drv.h"
3032 #include "psb_intel_reg.h"
31−#include "power.h"
32−#include <linux/pm_runtime.h>
33−#include "cdv_device.h"
3433
3534 /**
3635 * LVDS I2C backlight control macros
drivers/gpu/drm/gma500/framebuffer.c+13−13
@@ -17,29 +17,29 @@ · 16 unmodified lines
1717 *
1818 **************************************************************************/
1919
20−#include <linux/module.h>
21−#include <linux/kernel.h>
20+#include <linux/console.h>
21+#include <linux/delay.h>
2222 #include <linux/errno.h>
23−#include <linux/string.h>
24−#include <linux/pfn_t.h>
23+#include <linux/init.h>
24+#include <linux/kernel.h>
2525 #include <linux/mm.h>
26−#include <linux/tty.h>
26+#include <linux/module.h>
27+#include <linux/pfn_t.h>
2728 #include <linux/slab.h>
28−#include <linux/delay.h>
29−#include <linux/init.h>
30−#include <linux/console.h>
29+#include <linux/string.h>
30+#include <linux/tty.h>
3131
32−#include <drm/drmP.h>
3332 #include <drm/drm.h>
3433 #include <drm/drm_crtc.h>
3534 #include <drm/drm_fb_helper.h>
35+#include <drm/drm_fourcc.h>
3636 #include <drm/drm_gem_framebuffer_helper.h>
3737
38−#include "psb_drv.h"
39−#include "psb_intel_reg.h"
40−#include "psb_intel_drv.h"
4138 #include "framebuffer.h"
4239 #include "gtt.h"
40+#include "psb_drv.h"
41+#include "psb_intel_drv.h"
42+#include "psb_intel_reg.h"
4343
4444 static const struct drm_framebuffer_funcs psb_fb_funcs = {
4545 .destroy = drm_gem_fb_destroy,
@@ -232,7 +232,7 @@ static int psb_framebuffer_init(struct drm_device *dev, · 186 unmodified lines
232232 * Reject unknown formats, YUV formats, and formats with more than
233233 * 4 bytes per pixel.
234234 */
235− info = drm_format_info(mode_cmd->pixel_format);
235+ info = drm_get_format_info(dev, mode_cmd);
236236 if (!info || !info->depth || info->cpp[0] > 4)
237237 return -EINVAL;
238238
drivers/gpu/drm/gma500/framebuffer.h+0−1
@@ -22,7 +22,6 @@ · 21 unmodified lines
2222 #ifndef _FRAMEBUFFER_H_
2323 #define _FRAMEBUFFER_H_
2424
25−#include <drm/drmP.h>
2625 #include <drm/drm_fb_helper.h>
2726
2827 #include "psb_drv.h"
drivers/gpu/drm/gma500/gem.c+3−2
@@ -23,10 +23,11 @@ · 22 unmodified lines
2323 * accelerated operations on a GEM object)
2424 */
2525
26−#include <drm/drmP.h>
26+#include <linux/pagemap.h>
27+
2728 #include <drm/drm.h>
28−#include <drm/gma_drm.h>
2929 #include <drm/drm_vma_manager.h>
30+
3031 #include "psb_drv.h"
3132
3233 void psb_gem_free_object(struct drm_gem_object *obj)
drivers/gpu/drm/gma500/gma_device.c+0−1
@@ -13,7 +13,6 @@ · 12 unmodified lines
1313 *
1414 **************************************************************************/
1515
16−#include <drm/drmP.h>
1716 #include "psb_drv.h"
1817
1918 void gma_get_core_freq(struct drm_device *dev)
drivers/gpu/drm/gma500/gma_device.h+1−0
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515
1616 #ifndef _GMA_DEVICE_H
1717 #define _GMA_DEVICE_H
18+struct drm_device;
1819
1920 extern void gma_get_core_freq(struct drm_device *dev);
2021
drivers/gpu/drm/gma500/gma_display.c+9−3
@@ -19,12 +19,18 @@ · 18 unmodified lines
1919 * Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
2020 */
2121
22−#include <drm/drmP.h>
22+#include <linux/delay.h>
23+#include <linux/highmem.h>
24+
25+#include <drm/drm_crtc.h>
26+#include <drm/drm_fourcc.h>
27+#include <drm/drm_vblank.h>
28+
29+#include "framebuffer.h"
2330 #include "gma_display.h"
31+#include "psb_drv.h"
2432 #include "psb_intel_drv.h"
2533 #include "psb_intel_reg.h"
26−#include "psb_drv.h"
27−#include "framebuffer.h"
2834
2935 /**
3036 * Returns whether any output on the specified pipe is of the specified type
drivers/gpu/drm/gma500/gma_display.h+3−0
@@ -24,6 +24,9 @@ · 23 unmodified lines
2424
2525 #include <linux/pm_runtime.h>
2626
27+struct drm_encoder;
28+struct drm_mode_set;
29+
2730 struct gma_clock_t {
2831 /* given values */
2932 int n;
drivers/gpu/drm/gma500/gtt.c+3−2
@@ -19,11 +19,12 @@ · 18 unmodified lines
1919 * Alan Cox <alan@linux.intel.com>
2020 */
2121
22−#include <drm/drmP.h>
2322 #include <linux/shmem_fs.h>
23+
2424 #include <asm/set_memory.h>
25−#include "psb_drv.h"
25+
2626 #include "blitter.h"
27+#include "psb_drv.h"
2728
2829
2930 /*
drivers/gpu/drm/gma500/gtt.h+0−1
@@ -20,7 +20,6 @@ · 19 unmodified lines
2020 #ifndef _PSB_GTT_H_
2121 #define _PSB_GTT_H_
2222
23−#include <drm/drmP.h>
2423 #include <drm/drm_gem.h>
2524
2625 /* This wants cleaning up with respect to the psb_dev and un-needed stuff */
drivers/gpu/drm/gma500/intel_bios.c+3−3
@@ -18,13 +18,13 @@ · 17 unmodified lines
1818 * Eric Anholt <eric@anholt.net>
1919 *
2020 */
21−#include <drm/drmP.h>
2221 #include <drm/drm.h>
23−#include <drm/gma_drm.h>
22+#include <drm/drm_dp_helper.h>
23+
24+#include "intel_bios.h"
2425 #include "psb_drv.h"
2526 #include "psb_intel_drv.h"
2627 #include "psb_intel_reg.h"
27−#include "intel_bios.h"
2828
2929 #define SLAVE_ADDR1 0x70
3030 #define SLAVE_ADDR2 0x72
drivers/gpu/drm/gma500/intel_bios.h+1−2
@@ -22,8 +22,7 @@ · 21 unmodified lines
2222 #ifndef _INTEL_BIOS_H_
2323 #define _INTEL_BIOS_H_
2424
25−#include <drm/drmP.h>
26−#include <drm/drm_dp_helper.h>
25+struct drm_device;
2726
2827 struct vbt_header {
2928 u8 signature[20]; /**< Always starts with 'VBT$' */
drivers/gpu/drm/gma500/intel_gmbus.c+6−5
@@ -26,13 +26,14 @@ · 25 unmodified lines
2626 * Eric Anholt <eric@anholt.net>
2727 * Chris Wilson <chris@chris-wilson.co.uk>
2828 */
29−#include <linux/module.h>
30−#include <linux/i2c.h>
29+
30+#include <linux/delay.h>
3131 #include <linux/i2c-algo-bit.h>
32−#include <drm/drmP.h>
33−#include "psb_intel_drv.h"
34−#include <drm/gma_drm.h>
32+#include <linux/i2c.h>
33+#include <linux/module.h>
34+
3535 #include "psb_drv.h"
36+#include "psb_intel_drv.h"
3637 #include "psb_intel_reg.h"
3738
3839 #define _wait_for(COND, MS, W) ({ \
drivers/gpu/drm/gma500/intel_i2c.c+3−1
@@ -17,9 +17,11 @@ · 16 unmodified lines
1717 * Authors:
1818 * Eric Anholt <eric@anholt.net>
1919 */
20+
21+#include <linux/delay.h>
2022 #include <linux/export.h>
21−#include <linux/i2c.h>
2223 #include <linux/i2c-algo-bit.h>
24+#include <linux/i2c.h>
2325
2426 #include "psb_drv.h"
2527 #include "psb_intel_reg.h"
drivers/gpu/drm/gma500/mdfld_device.c+9−7
@@ -17,14 +17,16 @@ · 16 unmodified lines
1717 *
1818 **************************************************************************/
1919
20−#include "psb_drv.h"
21−#include "mid_bios.h"
22−#include "mdfld_output.h"
23−#include "mdfld_dsi_output.h"
24−#include "tc35876x-dsi-lvds.h"
20+#include <linux/delay.h>
2521
2622 #include <asm/intel_scu_ipc.h>
2723
24+#include "mdfld_dsi_output.h"
25+#include "mdfld_output.h"
26+#include "mid_bios.h"
27+#include "psb_drv.h"
28+#include "tc35876x-dsi-lvds.h"
29+
2830 #ifdef CONFIG_BACKLIGHT_CLASS_DEVICE
2931
3032 #define MRST_BLC_MAX_PWM_REG_FREQ 0xFFFF
@@ -342,7 +344,7 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) · 311 unmodified lines
342344
343345 if (pipenum == 1) {
344346 /* restore palette (gamma) */
345− /*DRM_UDELAY(50000); */
347+ /* udelay(50000); */
346348 for (i = 0; i < 256; i++)
347349 PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));
348350
@@ -404,7 +406,7 @@ static int mdfld_restore_display_registers(struct drm_device *dev, int pipenum) · 55 unmodified lines
404406 PSB_WVDC32(pipe->conf, map->conf);
405407
406408 /* restore palette (gamma) */
407− /*DRM_UDELAY(50000); */
409+ /* udelay(50000); */
408410 for (i = 0; i < 256; i++)
409411 PSB_WVDC32(pipe->palette[i], map->palette + (i << 2));
410412
drivers/gpu/drm/gma500/mdfld_dsi_dpi.c+3−1
@@ -25,9 +25,11 @@ · 24 unmodified lines
2525 * Jackie Li<yaodong.li@intel.com>
2626 */
2727
28+#include <linux/delay.h>
29+
2830 #include "mdfld_dsi_dpi.h"
29−#include "mdfld_output.h"
3031 #include "mdfld_dsi_pkg_sender.h"
32+#include "mdfld_output.h"
3133 #include "psb_drv.h"
3234 #include "tc35876x-dsi-lvds.h"
3335
drivers/gpu/drm/gma500/mdfld_dsi_output.c+7−5
@@ -25,15 +25,17 @@ · 24 unmodified lines
2525 * Jackie Li<yaodong.li@intel.com>
2626 */
2727
28−#include <linux/module.h>
28+#include <linux/delay.h>
29+#include <linux/moduleparam.h>
30+#include <linux/pm_runtime.h>
31+
32+#include <asm/intel_scu_ipc.h>
2933
30−#include "mdfld_dsi_output.h"
3134 #include "mdfld_dsi_dpi.h"
32−#include "mdfld_output.h"
35+#include "mdfld_dsi_output.h"
3336 #include "mdfld_dsi_pkg_sender.h"
37+#include "mdfld_output.h"
3438 #include "tc35876x-dsi-lvds.h"
35−#include <linux/pm_runtime.h>
36−#include <asm/intel_scu_ipc.h>
3739
3840 /* get the LABC from command line. */
3941 static int LABC_control = 1;
drivers/gpu/drm/gma500/mdfld_dsi_output.h+4−4
@@ -29,17 +29,17 @@ · 28 unmodified lines
2929 #define __MDFLD_DSI_OUTPUT_H__
3030
3131 #include <linux/backlight.h>
32−#include <drm/drmP.h>
32+
33+#include <asm/intel-mid.h>
34+
3335 #include <drm/drm.h>
3436 #include <drm/drm_crtc.h>
3537 #include <drm/drm_edid.h>
3638
39+#include "mdfld_output.h"
3740 #include "psb_drv.h"
3841 #include "psb_intel_drv.h"
3942 #include "psb_intel_reg.h"
40−#include "mdfld_output.h"
41−
42−#include <asm/intel-mid.h>
4343
4444 #define FLD_MASK(start, end) (((1 << ((start) - (end) + 1)) - 1) << (end))
4545 #define FLD_VAL(val, start, end) (((val) << (end)) & FLD_MASK(start, end))
drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c+3−1
@@ -24,12 +24,14 @@ · 23 unmodified lines
2424 * Jackie Li<yaodong.li@intel.com>
2525 */
2626
27+#include <linux/delay.h>
2728 #include <linux/freezer.h>
29+
2830 #include <video/mipi_display.h>
2931
32+#include "mdfld_dsi_dpi.h"
3033 #include "mdfld_dsi_output.h"
3134 #include "mdfld_dsi_pkg_sender.h"
32−#include "mdfld_dsi_dpi.h"
3335
3436 #define MDFLD_DSI_READ_MAX_COUNT 5000
3537
drivers/gpu/drm/gma500/mdfld_intel_display.c+7−4
@@ -18,15 +18,18 @@ · 17 unmodified lines
1818 * Eric Anholt <eric@anholt.net>
1919 */
2020
21+#include <linux/delay.h>
2122 #include <linux/i2c.h>
2223 #include <linux/pm_runtime.h>
2324
24−#include <drm/drmP.h>
25−#include "psb_intel_reg.h"
26−#include "gma_display.h"
25+#include <drm/drm_crtc.h>
26+#include <drm/drm_fourcc.h>
27+
2728 #include "framebuffer.h"
28−#include "mdfld_output.h"
29+#include "gma_display.h"
2930 #include "mdfld_dsi_output.h"
31+#include "mdfld_output.h"
32+#include "psb_intel_reg.h"
3033
3134 /* Hardcoded currently */
3235 static int ksel = KSEL_CRYSTAL_19;
drivers/gpu/drm/gma500/mdfld_tmd_vid.c+2−0
@@ -27,6 +27,8 @@ · 26 unmodified lines
2727 * Scott Rowe <scott.m.rowe@intel.com>
2828 */
2929
30+#include <linux/delay.h>
31+
3032 #include "mdfld_dsi_dpi.h"
3133 #include "mdfld_dsi_pkg_sender.h"
3234
drivers/gpu/drm/gma500/mid_bios.c+2−3
@@ -23,11 +23,10 @@ · 22 unmodified lines
2323 * - Check ioremap failures
2424 */
2525
26−#include <drm/drmP.h>
2726 #include <drm/drm.h>
28−#include <drm/gma_drm.h>
29−#include "psb_drv.h"
27+
3028 #include "mid_bios.h"
29+#include "psb_drv.h"
3130
3231 static void mid_get_fuse_settings(struct drm_device *dev)
3332 {
drivers/gpu/drm/gma500/mid_bios.h+1−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
1616 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1717 *
1818 **************************************************************************/
19+struct drm_device;
1920
2021 extern int mid_chip_setup(struct drm_device *dev);
2122
drivers/gpu/drm/gma500/mmu.c+4−2
@@ -15,10 +15,12 @@ · 14 unmodified lines
1515 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1616 *
1717 **************************************************************************/
18−#include <drm/drmP.h>
18+
19+#include <linux/highmem.h>
20+
21+#include "mmu.h"
1922 #include "psb_drv.h"
2023 #include "psb_reg.h"
21−#include "mmu.h"
2224
2325 /*
2426 * Code for the SGX MMU:
drivers/gpu/drm/gma500/oaktrail.h+2−0
@@ -17,6 +17,8 @@ · 16 unmodified lines
1717 *
1818 **************************************************************************/
1919
20+struct psb_intel_mode_device;
21+
2022 /* MID device specific descriptors */
2123
2224 struct oaktrail_timing_info {
drivers/gpu/drm/gma500/oaktrail_crtc.c+5−3
@@ -15,16 +15,18 @@ · 14 unmodified lines
1515 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
1616 */
1717
18+#include <linux/delay.h>
1819 #include <linux/i2c.h>
1920 #include <linux/pm_runtime.h>
2021
21−#include <drm/drmP.h>
22+#include <drm/drm_fourcc.h>
23+
2224 #include "framebuffer.h"
25+#include "gma_display.h"
26+#include "power.h"
2327 #include "psb_drv.h"
2428 #include "psb_intel_drv.h"
2529 #include "psb_intel_reg.h"
26−#include "gma_display.h"
27−#include "power.h"
2830
2931 #define MRST_LIMIT_LVDS_100L 0
3032 #define MRST_LIMIT_LVDS_83 1
drivers/gpu/drm/gma500/oaktrail_device.c+11−9
@@ -18,18 +18,20 @@ · 17 unmodified lines
1818 **************************************************************************/
1919
2020 #include <linux/backlight.h>
21−#include <linux/module.h>
21+#include <linux/delay.h>
2222 #include <linux/dmi.h>
23−#include <drm/drmP.h>
24−#include <drm/drm.h>
25−#include <drm/gma_drm.h>
26−#include "psb_drv.h"
27−#include "psb_reg.h"
28−#include "psb_intel_reg.h"
23+#include <linux/module.h>
24+
2925 #include <asm/intel-mid.h>
3026 #include <asm/intel_scu_ipc.h>
31−#include "mid_bios.h"
27+
28+#include <drm/drm.h>
29+
3230 #include "intel_bios.h"
31+#include "mid_bios.h"
32+#include "psb_drv.h"
33+#include "psb_intel_reg.h"
34+#include "psb_reg.h"
3335
3436 static int oaktrail_output_init(struct drm_device *dev)
3537 {
@@ -327,7 +329,7 @@ static int oaktrail_restore_display_registers(struct drm_device *dev) · 291 unmodified lines
327329
328330 /* Actually enable it */
329331 PSB_WVDC32(p->dpll, MRST_DPLL_A);
330− DRM_UDELAY(150);
332+ udelay(150);
331333
332334 /* Restore mode */
333335 PSB_WVDC32(p->htotal, HTOTAL_A);
drivers/gpu/drm/gma500/oaktrail_hdmi.c+5−3
@@ -24,11 +24,13 @@ · 23 unmodified lines
2424 * Li Peng <peng.li@intel.com>
2525 */
2626
27−#include <drm/drmP.h>
27+#include <linux/delay.h>
28+
2829 #include <drm/drm.h>
30+
31+#include "psb_drv.h"
2932 #include "psb_intel_drv.h"
3033 #include "psb_intel_reg.h"
31−#include "psb_drv.h"
3234
3335 #define HDMI_READ(reg) readl(hdmi_dev->regs + (reg))
3436 #define HDMI_WRITE(reg, val) writel(val, hdmi_dev->regs + (reg))
@@ -815,7 +817,7 @@ void oaktrail_hdmi_restore(struct drm_device *dev) · 780 unmodified lines
815817 PSB_WVDC32(hdmi_dev->saveDPLL_ADJUST, DPLL_ADJUST);
816818 PSB_WVDC32(hdmi_dev->saveDPLL_UPDATE, DPLL_UPDATE);
817819 PSB_WVDC32(hdmi_dev->saveDPLL_CLK_ENABLE, DPLL_CLK_ENABLE);
818− DRM_UDELAY(150);
820+ udelay(150);
819821
820822 /* pipe */
821823 PSB_WVDC32(pipeb->src, PIPEBSRC);
drivers/gpu/drm/gma500/oaktrail_lvds.c+3−3
@@ -21,15 +21,15 @@ · 20 unmodified lines
2121 */
2222
2323 #include <linux/i2c.h>
24−#include <drm/drmP.h>
24+#include <linux/pm_runtime.h>
25+
2526 #include <asm/intel-mid.h>
2627
2728 #include "intel_bios.h"
29+#include "power.h"
2830 #include "psb_drv.h"
2931 #include "psb_intel_drv.h"
3032 #include "psb_intel_reg.h"
31−#include "power.h"
32−#include <linux/pm_runtime.h>
3333
3434 /* The max/min PWM frequency in BPCR[31:17] - */
3535 /* The smallest number is 1 (not 0) that can fit in the
drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c+5−6
@@ -23,17 +23,16 @@ · 22 unmodified lines
2323 *
2424 */
2525
26+#include <linux/delay.h>
27+#include <linux/i2c-algo-bit.h>
28+#include <linux/i2c.h>
29+#include <linux/init.h>
30+#include <linux/io.h>
2631 #include <linux/kernel.h>
2732 #include <linux/module.h>
2833 #include <linux/pci.h>
2934 #include <linux/types.h>
30−#include <linux/i2c.h>
31−#include <linux/i2c-algo-bit.h>
32−#include <linux/init.h>
33−#include <linux/io.h>
34−#include <linux/delay.h>
3535
36−#include <drm/drmP.h>
3736 #include "psb_drv.h"
3837 #include "psb_intel_reg.h"
3938
drivers/gpu/drm/gma500/power.h+3−1
@@ -31,7 +31,9 @@ · 30 unmodified lines
3131 #define _PSB_POWERMGMT_H_
3232
3333 #include <linux/pci.h>
34−#include <drm/drmP.h>
34+
35+struct device;
36+struct drm_device;
3537
3638 void gma_power_init(struct drm_device *dev);
3739 void gma_power_uninit(struct drm_device *dev);
drivers/gpu/drm/gma500/psb_device.c+6−6
@@ -18,15 +18,15 @@ · 17 unmodified lines
1818 **************************************************************************/
1919
2020 #include <linux/backlight.h>
21−#include <drm/drmP.h>
21+
2222 #include <drm/drm.h>
23−#include <drm/gma_drm.h>
24−#include "psb_drv.h"
25−#include "psb_reg.h"
26−#include "psb_intel_reg.h"
23+
24+#include "gma_device.h"
2725 #include "intel_bios.h"
2826 #include "psb_device.h"
29−#include "gma_device.h"
27+#include "psb_drv.h"
28+#include "psb_intel_reg.h"
29+#include "psb_reg.h"
3030
3131 static int psb_output_init(struct drm_device *dev)
3232 {
drivers/gpu/drm/gma500/psb_drv.c+21−12
@@ -19,23 +19,32 @@ · 18 unmodified lines
1919 *
2020 **************************************************************************/
2121
22−#include <drm/drmP.h>
22+#include <linux/cpu.h>
23+#include <linux/module.h>
24+#include <linux/notifier.h>
25+#include <linux/pm_runtime.h>
26+#include <linux/spinlock.h>
27+
28+#include <asm/set_memory.h>
29+
30+#include <acpi/video.h>
31+
2332 #include <drm/drm.h>
24−#include "psb_drv.h"
33+#include <drm/drm_drv.h>
34+#include <drm/drm_file.h>
35+#include <drm/drm_ioctl.h>
36+#include <drm/drm_irq.h>
37+#include <drm/drm_pci.h>
38+#include <drm/drm_pciids.h>
39+#include <drm/drm_vblank.h>
40+
2541 #include "framebuffer.h"
26−#include "psb_reg.h"
27−#include "psb_intel_reg.h"
2842 #include "intel_bios.h"
2943 #include "mid_bios.h"
30−#include <drm/drm_pciids.h>
3144 #include "power.h"
32−#include <linux/cpu.h>
33−#include <linux/notifier.h>
34−#include <linux/spinlock.h>
35−#include <linux/pm_runtime.h>
36−#include <acpi/video.h>
37−#include <linux/module.h>
38−#include <asm/set_memory.h>
45+#include "psb_drv.h"
46+#include "psb_intel_reg.h"
47+#include "psb_reg.h"
3948
4049 static struct drm_driver driver;
4150 static int psb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
drivers/gpu/drm/gma500/psb_drv.h+8−8
@@ -23,17 +23,17 @@ · 22 unmodified lines
2323 #include <linux/kref.h>
2424 #include <linux/mm_types.h>
2525
26−#include <drm/drmP.h>
27−#include <drm/gma_drm.h>
28−#include "psb_reg.h"
29−#include "psb_intel_drv.h"
26+#include <drm/drm_device.h>
27+
3028 #include "gma_display.h"
31−#include "intel_bios.h"
3229 #include "gtt.h"
33−#include "power.h"
34−#include "opregion.h"
35−#include "oaktrail.h"
30+#include "intel_bios.h"
3631 #include "mmu.h"
32+#include "oaktrail.h"
33+#include "opregion.h"
34+#include "power.h"
35+#include "psb_intel_drv.h"
36+#include "psb_reg.h"
3737
3838 #define DRIVER_AUTHOR "Alan Cox <alan@linux.intel.com> and others"
3939
drivers/gpu/drm/gma500/psb_intel_display.c+4−3
@@ -18,16 +18,17 @@ · 17 unmodified lines
1818 * Eric Anholt <eric@anholt.net>
1919 */
2020
21+#include <linux/delay.h>
2122 #include <linux/i2c.h>
2223
23−#include <drm/drmP.h>
2424 #include <drm/drm_plane_helper.h>
25+
2526 #include "framebuffer.h"
27+#include "gma_display.h"
28+#include "power.h"
2629 #include "psb_drv.h"
2730 #include "psb_intel_drv.h"
2831 #include "psb_intel_reg.h"
29−#include "gma_display.h"
30−#include "power.h"
3132
3233 #define INTEL_LIMIT_I9XX_SDVO_DAC 0
3334 #define INTEL_LIMIT_I9XX_LVDS 1
drivers/gpu/drm/gma500/psb_intel_lvds.c+2−3
@@ -21,14 +21,13 @@ · 20 unmodified lines
2121 */
2222
2323 #include <linux/i2c.h>
24−#include <drm/drmP.h>
24+#include <linux/pm_runtime.h>
2525
2626 #include "intel_bios.h"
27+#include "power.h"
2728 #include "psb_drv.h"
2829 #include "psb_intel_drv.h"
2930 #include "psb_intel_reg.h"
30−#include "power.h"
31−#include <linux/pm_runtime.h>
3231
3332 /*
3433 * LVDS I2C backlight control macros
drivers/gpu/drm/gma500/psb_intel_modes.c+1−1
@@ -18,7 +18,7 @@ · 17 unmodified lines
1818 */
1919
2020 #include <linux/i2c.h>
21−#include <drm/drmP.h>
21+
2222 #include "psb_intel_drv.h"
2323
2424 /**
drivers/gpu/drm/gma500/psb_intel_sdvo.c+8−7
@@ -25,19 +25,20 @@ · 24 unmodified lines
2525 * Authors:
2626 * Eric Anholt <eric@anholt.net>
2727 */
28−#include <linux/module.h>
28+
29+#include <linux/delay.h>
2930 #include <linux/i2c.h>
31+#include <linux/kernel.h>
32+#include <linux/module.h>
3033 #include <linux/slab.h>
31−#include <linux/delay.h>
32−#include <drm/drmP.h>
34+
3335 #include <drm/drm_crtc.h>
3436 #include <drm/drm_edid.h>
35−#include "psb_intel_drv.h"
36−#include <drm/gma_drm.h>
37+
3738 #include "psb_drv.h"
38−#include "psb_intel_sdvo_regs.h"
39+#include "psb_intel_drv.h"
3940 #include "psb_intel_reg.h"
40−#include <linux/kernel.h>
41+#include "psb_intel_sdvo_regs.h"
4142
4243 #define SDVO_TMDS_MASK (SDVO_OUTPUT_TMDS0 | SDVO_OUTPUT_TMDS1)
4344 #define SDVO_RGB_MASK (SDVO_OUTPUT_RGB0 | SDVO_OUTPUT_RGB1)
drivers/gpu/drm/gma500/psb_irq.c+5−4
@@ -22,13 +22,14 @@ · 21 unmodified lines
2222 /*
2323 */
2424
25−#include <drm/drmP.h>
25+#include <drm/drm_vblank.h>
26+
27+#include "mdfld_output.h"
28+#include "power.h"
2629 #include "psb_drv.h"
27−#include "psb_reg.h"
2830 #include "psb_intel_reg.h"
29−#include "power.h"
3031 #include "psb_irq.h"
31−#include "mdfld_output.h"
32+#include "psb_reg.h"
3233
3334 /*
3435 * inline functions
drivers/gpu/drm/gma500/psb_irq.h+1−1
@@ -24,7 +24,7 @@ · 23 unmodified lines
2424 #ifndef _PSB_IRQ_H_
2525 #define _PSB_IRQ_H_
2626
27−#include <drm/drmP.h>
27+struct drm_device;
2828
2929 bool sysirq_init(struct drm_device *dev);
3030 void sysirq_uninit(struct drm_device *dev);
drivers/gpu/drm/gma500/psb_lid.c+3−3
@@ -17,11 +17,11 @@ · 16 unmodified lines
1717 * Authors: Thomas Hellstrom <thomas-at-tungstengraphics-dot-com>
1818 **************************************************************************/
1919
20−#include <drm/drmP.h>
20+#include <linux/spinlock.h>
21+
2122 #include "psb_drv.h"
22−#include "psb_reg.h"
2323 #include "psb_intel_reg.h"
24−#include <linux/spinlock.h>
24+#include "psb_reg.h"
2525
2626 static void psb_lid_timer_func(struct timer_list *t)
2727 {
drivers/gpu/drm/gma500/tc35876x-dsi-lvds.c+8−5
@@ -22,15 +22,18 @@ · 21 unmodified lines
2222 *
2323 */
2424
25−#include "mdfld_dsi_dpi.h"
26−#include "mdfld_output.h"
27−#include "mdfld_dsi_pkg_sender.h"
28−#include "tc35876x-dsi-lvds.h"
29−#include <linux/platform_data/tc35876x.h>
25+#include <linux/delay.h>
3026 #include <linux/kernel.h>
3127 #include <linux/module.h>
28+#include <linux/platform_data/tc35876x.h>
29+
3230 #include <asm/intel_scu_ipc.h>
3331
32+#include "mdfld_dsi_dpi.h"
33+#include "mdfld_dsi_pkg_sender.h"
34+#include "mdfld_output.h"
35+#include "tc35876x-dsi-lvds.h"
36+
3437 static struct i2c_client *tc35876x_client;
3538 static struct i2c_client *cmi_lcd_i2c_client;
3639
drivers/gpu/drm/hisilicon/hibmc/Kconfig+1−1
@@ -3,7 +3,7 @@ config DRM_HISI_HIBMC · 2 unmodified lines
33 tristate "DRM Support for Hisilicon Hibmc"
44 depends on DRM && PCI && MMU
55 select DRM_KMS_HELPER
6− select DRM_TTM
6+ select DRM_VRAM_HELPER
77
88 help
99 Choose this option if you have a Hisilicon Hibmc soc chipset.
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_de.c+9−10
@@ -96,27 +96,26 @@ static void hibmc_plane_atomic_update(struct drm_plane *plane, · 95 unmodified lines
9696 struct drm_plane_state *state = plane->state;
9797 u32 reg;
9898 int ret;
99− u64 gpu_addr = 0;
99+ s64 gpu_addr = 0;
100100 unsigned int line_l;
101101 struct hibmc_drm_private *priv = plane->dev->dev_private;
102102 struct hibmc_framebuffer *hibmc_fb;
103− struct hibmc_bo *bo;
103+ struct drm_gem_vram_object *gbo;
104104
105105 if (!state->fb)
106106 return;
107107
108108 hibmc_fb = to_hibmc_framebuffer(state->fb);
109− bo = gem_to_hibmc_bo(hibmc_fb->obj);
110− ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
109+ gbo = drm_gem_vram_of_gem(hibmc_fb->obj);
110+
111+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
111112 if (ret) {
112− DRM_ERROR("failed to reserve ttm_bo: %d", ret);
113+ DRM_ERROR("failed to pin bo: %d", ret);
113114 return;
114115 }
115−
116− ret = hibmc_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
117− ttm_bo_unreserve(&bo->bo);
118− if (ret) {
119− DRM_ERROR("failed to pin hibmc_bo: %d", ret);
116+ gpu_addr = drm_gem_vram_offset(gbo);
117+ if (gpu_addr < 0) {
118+ drm_gem_vram_unpin(gbo);
120119 return;
121120 }
122121
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c+4−10
@@ -27,14 +27,7 @@ · 26 unmodified lines
2727
2828 static const struct file_operations hibmc_fops = {
2929 .owner = THIS_MODULE,
30− .open = drm_open,
31− .release = drm_release,
32− .unlocked_ioctl = drm_ioctl,
33− .compat_ioctl = drm_compat_ioctl,
34− .mmap = hibmc_mmap,
35− .poll = drm_poll,
36− .read = drm_read,
37− .llseek = no_llseek,
30+ DRM_VRAM_MM_FILE_OPERATIONS
3831 };
3932
4033 static irqreturn_t hibmc_drm_interrupt(int irq, void *arg)
@@ -63,9 +56,10 @@ static struct drm_driver hibmc_driver = { · 22 unmodified lines
6356 .desc = "hibmc drm driver",
6457 .major = 1,
6558 .minor = 0,
66− .gem_free_object_unlocked = hibmc_gem_free_object,
59+ .gem_free_object_unlocked =
60+ drm_gem_vram_driver_gem_free_object_unlocked,
6761 .dumb_create = hibmc_dumb_create,
68− .dumb_map_offset = hibmc_dumb_mmap_offset,
62+ .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset,
6963 .irq_handler = hibmc_drm_interrupt,
7064 };
7165
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h+2−31
@@ -23,7 +23,8 @@ · 22 unmodified lines
2323 #include <drm/drm_atomic.h>
2424 #include <drm/drm_fb_helper.h>
2525 #include <drm/drm_gem.h>
26−#include <drm/ttm/ttm_bo_driver.h>
26+#include <drm/drm_gem_vram_helper.h>
27+#include <drm/drm_vram_mm_helper.h>
2728
2829 struct hibmc_framebuffer {
2930 struct drm_framebuffer fb;
@@ -48,36 +49,12 @@ struct hibmc_drm_private { · 18 unmodified lines
4849 struct drm_device *dev;
4950 bool mode_config_initialized;
5051
51− /* ttm */
52− struct ttm_bo_device bdev;
53− bool initialized;
54−
5552 /* fbdev */
5653 struct hibmc_fbdev *fbdev;
57− bool mm_inited;
5854 };
5955
6056 #define to_hibmc_framebuffer(x) container_of(x, struct hibmc_framebuffer, fb)
6157
62−struct hibmc_bo {
63− struct ttm_buffer_object bo;
64− struct ttm_placement placement;
65− struct ttm_bo_kmap_obj kmap;
66− struct drm_gem_object gem;
67− struct ttm_place placements[3];
68− int pin_count;
69−};
70−
71−static inline struct hibmc_bo *hibmc_bo(struct ttm_buffer_object *bo)
72−{
73− return container_of(bo, struct hibmc_bo, bo);
74−}
75−
76−static inline struct hibmc_bo *gem_to_hibmc_bo(struct drm_gem_object *gem)
77−{
78− return container_of(gem, struct hibmc_bo, gem);
79−}
80−
8158 void hibmc_set_power_mode(struct hibmc_drm_private *priv,
8259 unsigned int power_mode);
8360 void hibmc_set_current_gate(struct hibmc_drm_private *priv,
@@ -97,14 +74,8 @@ hibmc_framebuffer_init(struct drm_device *dev, · 13 unmodified lines
9774
9875 int hibmc_mm_init(struct hibmc_drm_private *hibmc);
9976 void hibmc_mm_fini(struct hibmc_drm_private *hibmc);
100−int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr);
101−int hibmc_bo_unpin(struct hibmc_bo *bo);
102−void hibmc_gem_free_object(struct drm_gem_object *obj);
10377 int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev,
10478 struct drm_mode_create_dumb *args);
105−int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
106− u32 handle, u64 *offset);
107−int hibmc_mmap(struct file *filp, struct vm_area_struct *vma);
10879
10980 extern const struct drm_mode_config_funcs hibmc_mode_funcs;
11081
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_fbdev.c+12−25
@@ -63,10 +63,10 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper, · 62 unmodified lines
6363 struct drm_mode_fb_cmd2 mode_cmd;
6464 struct drm_gem_object *gobj = NULL;
6565 int ret = 0;
66− int ret1;
6766 size_t size;
6867 unsigned int bytes_per_pixel;
69− struct hibmc_bo *bo = NULL;
68+ struct drm_gem_vram_object *gbo = NULL;
69+ void *base;
7070
7171 DRM_DEBUG_DRIVER("surface width(%d), height(%d) and bpp(%d)\n",
7272 sizes->surface_width, sizes->surface_height,
@@ -88,26 +88,20 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper, · 15 unmodified lines
8888 return -ENOMEM;
8989 }
9090
91− bo = gem_to_hibmc_bo(gobj);
91+ gbo = drm_gem_vram_of_gem(gobj);
9292
93− ret = ttm_bo_reserve(&bo->bo, true, false, NULL);
94− if (ret) {
95− DRM_ERROR("failed to reserve ttm_bo: %d\n", ret);
96− goto out_unref_gem;
97− }
98−
99− ret = hibmc_bo_pin(bo, TTM_PL_FLAG_VRAM, NULL);
93+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
10094 if (ret) {
10195 DRM_ERROR("failed to pin fbcon: %d\n", ret);
102− goto out_unreserve_ttm_bo;
96+ goto out_unref_gem;
10397 }
10498
105− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
106− if (ret) {
99+ base = drm_gem_vram_kmap(gbo, true, NULL);
100+ if (IS_ERR(base)) {
101+ ret = PTR_ERR(base);
107102 DRM_ERROR("failed to kmap fbcon: %d\n", ret);
108103 goto out_unpin_bo;
109104 }
110− ttm_bo_unreserve(&bo->bo);
111105
112106 info = drm_fb_helper_alloc_fbi(helper);
113107 if (IS_ERR(info)) {
@@ -131,24 +125,17 @@ static int hibmc_drm_fb_create(struct drm_fb_helper *helper, · 17 unmodified lines
131125
132126 drm_fb_helper_fill_info(info, &priv->fbdev->helper, sizes);
133127
134− info->screen_base = bo->kmap.virtual;
128+ info->screen_base = base;
135129 info->screen_size = size;
136130
137− info->fix.smem_start = bo->bo.mem.bus.offset + bo->bo.mem.bus.base;
131+ info->fix.smem_start = gbo->bo.mem.bus.offset + gbo->bo.mem.bus.base;
138132 info->fix.smem_len = size;
139133 return 0;
140134
141135 out_release_fbi:
142− ret1 = ttm_bo_reserve(&bo->bo, true, false, NULL);
143− if (ret1) {
144− DRM_ERROR("failed to rsv ttm_bo when release fbi: %d\n", ret1);
145− goto out_unref_gem;
146− }
147− ttm_bo_kunmap(&bo->kmap);
136+ drm_gem_vram_kunmap(gbo);
148137 out_unpin_bo:
149− hibmc_bo_unpin(bo);
150−out_unreserve_ttm_bo:
151− ttm_bo_unreserve(&bo->bo);
138+ drm_gem_vram_unpin(gbo);
152139 out_unref_gem:
153140 drm_gem_object_put_unlocked(gobj);
154141
drivers/gpu/drm/hisilicon/hibmc/hibmc_ttm.c+16−325
@@ -17,335 +17,55 @@ · 16 unmodified lines
1717 */
1818
1919 #include <drm/drm_atomic_helper.h>
20−#include <drm/ttm/ttm_page_alloc.h>
2120
2221 #include "hibmc_drm_drv.h"
2322
24−static inline struct hibmc_drm_private *
25−hibmc_bdev(struct ttm_bo_device *bd)
26−{
27− return container_of(bd, struct hibmc_drm_private, bdev);
28−}
29−
30−static void hibmc_bo_ttm_destroy(struct ttm_buffer_object *tbo)
31−{
32− struct hibmc_bo *bo = container_of(tbo, struct hibmc_bo, bo);
33−
34− drm_gem_object_release(&bo->gem);
35− kfree(bo);
36−}
37−
38−static bool hibmc_ttm_bo_is_hibmc_bo(struct ttm_buffer_object *bo)
39−{
40− return bo->destroy == &hibmc_bo_ttm_destroy;
41−}
42−
43−static int
44−hibmc_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
45− struct ttm_mem_type_manager *man)
46−{
47− switch (type) {
48− case TTM_PL_SYSTEM:
49− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
50− man->available_caching = TTM_PL_MASK_CACHING;
51− man->default_caching = TTM_PL_FLAG_CACHED;
52− break;
53− case TTM_PL_VRAM:
54− man->func = &ttm_bo_manager_func;
55− man->flags = TTM_MEMTYPE_FLAG_FIXED |
56− TTM_MEMTYPE_FLAG_MAPPABLE;
57− man->available_caching = TTM_PL_FLAG_UNCACHED |
58− TTM_PL_FLAG_WC;
59− man->default_caching = TTM_PL_FLAG_WC;
60− break;
61− default:
62− DRM_ERROR("unsupported memory type %u\n", type);
63− return -EINVAL;
64− }
65− return 0;
66−}
67−
68−void hibmc_ttm_placement(struct hibmc_bo *bo, int domain)
69−{
70− u32 count = 0;
71− u32 i;
72−
73− bo->placement.placement = bo->placements;
74− bo->placement.busy_placement = bo->placements;
75− if (domain & TTM_PL_FLAG_VRAM)
76− bo->placements[count++].flags = TTM_PL_FLAG_WC |
77− TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
78− if (domain & TTM_PL_FLAG_SYSTEM)
79− bo->placements[count++].flags = TTM_PL_MASK_CACHING |
80− TTM_PL_FLAG_SYSTEM;
81− if (!count)
82− bo->placements[count++].flags = TTM_PL_MASK_CACHING |
83− TTM_PL_FLAG_SYSTEM;
84−
85− bo->placement.num_placement = count;
86− bo->placement.num_busy_placement = count;
87− for (i = 0; i < count; i++) {
88− bo->placements[i].fpfn = 0;
89− bo->placements[i].lpfn = 0;
90− }
91−}
92−
93−static void
94−hibmc_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
95−{
96− struct hibmc_bo *hibmcbo = hibmc_bo(bo);
97−
98− if (!hibmc_ttm_bo_is_hibmc_bo(bo))
99− return;
100−
101− hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_SYSTEM);
102− *pl = hibmcbo->placement;
103−}
104−
105−static int hibmc_bo_verify_access(struct ttm_buffer_object *bo,
106− struct file *filp)
107−{
108− struct hibmc_bo *hibmcbo = hibmc_bo(bo);
109−
110− return drm_vma_node_verify_access(&hibmcbo->gem.vma_node,
111− filp->private_data);
112−}
113−
114−static int hibmc_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
115− struct ttm_mem_reg *mem)
116−{
117− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
118− struct hibmc_drm_private *hibmc = hibmc_bdev(bdev);
119−
120− mem->bus.addr = NULL;
121− mem->bus.offset = 0;
122− mem->bus.size = mem->num_pages << PAGE_SHIFT;
123− mem->bus.base = 0;
124− mem->bus.is_iomem = false;
125− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
126− return -EINVAL;
127− switch (mem->mem_type) {
128− case TTM_PL_SYSTEM:
129− /* system memory */
130− return 0;
131− case TTM_PL_VRAM:
132− mem->bus.offset = mem->start << PAGE_SHIFT;
133− mem->bus.base = pci_resource_start(hibmc->dev->pdev, 0);
134− mem->bus.is_iomem = true;
135− break;
136− default:
137− return -EINVAL;
138− }
139− return 0;
140−}
141−
142−static void hibmc_ttm_backend_destroy(struct ttm_tt *tt)
143−{
144− ttm_tt_fini(tt);
145− kfree(tt);
146−}
147−
148−static struct ttm_backend_func hibmc_tt_backend_func = {
149− .destroy = &hibmc_ttm_backend_destroy,
150−};
151−
152−static struct ttm_tt *hibmc_ttm_tt_create(struct ttm_buffer_object *bo,
153− u32 page_flags)
154−{
155− struct ttm_tt *tt;
156− int ret;
157−
158− tt = kzalloc(sizeof(*tt), GFP_KERNEL);
159− if (!tt) {
160− DRM_ERROR("failed to allocate ttm_tt\n");
161− return NULL;
162− }
163− tt->func = &hibmc_tt_backend_func;
164− ret = ttm_tt_init(tt, bo, page_flags);
165− if (ret) {
166− DRM_ERROR("failed to initialize ttm_tt: %d\n", ret);
167− kfree(tt);
168− return NULL;
169− }
170− return tt;
171−}
172−
173−struct ttm_bo_driver hibmc_bo_driver = {
174− .ttm_tt_create = hibmc_ttm_tt_create,
175− .init_mem_type = hibmc_bo_init_mem_type,
176− .evict_flags = hibmc_bo_evict_flags,
177− .move = NULL,
178− .verify_access = hibmc_bo_verify_access,
179− .io_mem_reserve = &hibmc_ttm_io_mem_reserve,
180− .io_mem_free = NULL,
181−};
182−
18323 int hibmc_mm_init(struct hibmc_drm_private *hibmc)
18424 {
25+ struct drm_vram_mm *vmm;
18526 int ret;
18627 struct drm_device *dev = hibmc->dev;
187− struct ttm_bo_device *bdev = &hibmc->bdev;
18828
189− ret = ttm_bo_device_init(&hibmc->bdev,
190− &hibmc_bo_driver,
191− dev->anon_inode->i_mapping,
192− true);
193− if (ret) {
194− DRM_ERROR("error initializing bo driver: %d\n", ret);
29+ vmm = drm_vram_helper_alloc_mm(dev,
30+ pci_resource_start(dev->pdev, 0),
31+ hibmc->fb_size, &drm_gem_vram_mm_funcs);
32+ if (IS_ERR(vmm)) {
33+ ret = PTR_ERR(vmm);
34+ DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
19535 return ret;
19636 }
19737
198− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
199− hibmc->fb_size >> PAGE_SHIFT);
200− if (ret) {
201− DRM_ERROR("failed ttm VRAM init: %d\n", ret);
202− return ret;
203− }
204−
205− hibmc->mm_inited = true;
20638 return 0;
20739 }
20840
20941 void hibmc_mm_fini(struct hibmc_drm_private *hibmc)
21042 {
211− if (!hibmc->mm_inited)
212− return;
213−
214− ttm_bo_device_release(&hibmc->bdev);
215− hibmc->mm_inited = false;
216−}
217−
218−static void hibmc_bo_unref(struct hibmc_bo **bo)
219−{
220− struct ttm_buffer_object *tbo;
221−
222− if ((*bo) == NULL)
43+ if (!hibmc->dev->vram_mm)
22344 return;
22445
225− tbo = &((*bo)->bo);
226− ttm_bo_put(tbo);
227− *bo = NULL;
228−}
229−
230−int hibmc_bo_create(struct drm_device *dev, int size, int align,
231− u32 flags, struct hibmc_bo **phibmcbo)
232−{
233− struct hibmc_drm_private *hibmc = dev->dev_private;
234− struct hibmc_bo *hibmcbo;
235− size_t acc_size;
236− int ret;
237−
238− hibmcbo = kzalloc(sizeof(*hibmcbo), GFP_KERNEL);
239− if (!hibmcbo) {
240− DRM_ERROR("failed to allocate hibmcbo\n");
241− return -ENOMEM;
242− }
243− ret = drm_gem_object_init(dev, &hibmcbo->gem, size);
244− if (ret) {
245− DRM_ERROR("failed to initialize drm gem object: %d\n", ret);
246− kfree(hibmcbo);
247− return ret;
248− }
249−
250− hibmcbo->bo.bdev = &hibmc->bdev;
251−
252− hibmc_ttm_placement(hibmcbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
253−
254− acc_size = ttm_bo_dma_acc_size(&hibmc->bdev, size,
255− sizeof(struct hibmc_bo));
256−
257− ret = ttm_bo_init(&hibmc->bdev, &hibmcbo->bo, size,
258− ttm_bo_type_device, &hibmcbo->placement,
259− align >> PAGE_SHIFT, false, acc_size,
260− NULL, NULL, hibmc_bo_ttm_destroy);
261− if (ret) {
262− hibmc_bo_unref(&hibmcbo);
263− DRM_ERROR("failed to initialize ttm_bo: %d\n", ret);
264− return ret;
265− }
266−
267− *phibmcbo = hibmcbo;
268− return 0;
269−}
270−
271−int hibmc_bo_pin(struct hibmc_bo *bo, u32 pl_flag, u64 *gpu_addr)
272−{
273− struct ttm_operation_ctx ctx = { false, false };
274− int i, ret;
275−
276− if (bo->pin_count) {
277− bo->pin_count++;
278− if (gpu_addr)
279− *gpu_addr = bo->bo.offset;
280− return 0;
281− }
282−
283− hibmc_ttm_placement(bo, pl_flag);
284− for (i = 0; i < bo->placement.num_placement; i++)
285− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
286− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
287− if (ret)
288− return ret;
289−
290− bo->pin_count = 1;
291− if (gpu_addr)
292− *gpu_addr = bo->bo.offset;
293− return 0;
294−}
295−
296−int hibmc_bo_unpin(struct hibmc_bo *bo)
297−{
298− struct ttm_operation_ctx ctx = { false, false };
299− int i, ret;
300−
301− if (!bo->pin_count) {
302− DRM_ERROR("unpin bad %p\n", bo);
303− return 0;
304− }
305− bo->pin_count--;
306− if (bo->pin_count)
307− return 0;
308−
309− for (i = 0; i < bo->placement.num_placement ; i++)
310− bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
311− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
312− if (ret) {
313− DRM_ERROR("validate failed for unpin: %d\n", ret);
314− return ret;
315− }
316−
317− return 0;
318−}
319−
320−int hibmc_mmap(struct file *filp, struct vm_area_struct *vma)
321−{
322− struct drm_file *file_priv = filp->private_data;
323− struct hibmc_drm_private *hibmc = file_priv->minor->dev->dev_private;
324−
325− return ttm_bo_mmap(filp, vma, &hibmc->bdev);
46+ drm_vram_helper_release_mm(hibmc->dev);
32647 }
32748
32849 int hibmc_gem_create(struct drm_device *dev, u32 size, bool iskernel,
32950 struct drm_gem_object **obj)
33051 {
331− struct hibmc_bo *hibmcbo;
52+ struct drm_gem_vram_object *gbo;
33253 int ret;
33354
33455 *obj = NULL;
33556
336− size = PAGE_ALIGN(size);
337− if (size == 0) {
338− DRM_ERROR("error: zero size\n");
57+ size = roundup(size, PAGE_SIZE);
58+ if (size == 0)
33959 return -EINVAL;
340− }
34160
342− ret = hibmc_bo_create(dev, size, 0, 0, &hibmcbo);
343− if (ret) {
61+ gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false);
62+ if (IS_ERR(gbo)) {
63+ ret = PTR_ERR(gbo);
34464 if (ret != -ERESTARTSYS)
34565 DRM_ERROR("failed to allocate GEM object: %d\n", ret);
34666 return ret;
34767 }
348− *obj = &hibmcbo->gem;
68+ *obj = &gbo->gem;
34969 return 0;
35070 }
35171
@@ -377,35 +97,6 @@ int hibmc_dumb_create(struct drm_file *file, struct drm_device *dev, · 25 unmodified lines
37797 return 0;
37898 }
37999
380−void hibmc_gem_free_object(struct drm_gem_object *obj)
381−{
382− struct hibmc_bo *hibmcbo = gem_to_hibmc_bo(obj);
383−
384− hibmc_bo_unref(&hibmcbo);
385−}
386−
387−static u64 hibmc_bo_mmap_offset(struct hibmc_bo *bo)
388−{
389− return drm_vma_node_offset_addr(&bo->bo.vma_node);
390−}
391−
392−int hibmc_dumb_mmap_offset(struct drm_file *file, struct drm_device *dev,
393− u32 handle, u64 *offset)
394−{
395− struct drm_gem_object *obj;
396− struct hibmc_bo *bo;
397−
398− obj = drm_gem_object_lookup(file, handle);
399− if (!obj)
400− return -ENOENT;
401−
402− bo = gem_to_hibmc_bo(obj);
403− *offset = hibmc_bo_mmap_offset(bo);
404−
405− drm_gem_object_put_unlocked(obj);
406− return 0;
407−}
408−
409100 static void hibmc_user_framebuffer_destroy(struct drm_framebuffer *fb)
410101 {
411102 struct hibmc_framebuffer *hibmc_fb = to_hibmc_framebuffer(fb);
drivers/gpu/drm/i915/intel_display.c+2−3
@@ -14605,9 +14605,8 @@ static int intel_crtc_init(struct drm_i915_private *dev_priv, enum pipe pipe) · 14604 unmodified lines
1460514605 ret = -ENOMEM;
1460614606 goto fail;
1460714607 }
14608+ __drm_atomic_helper_crtc_reset(&intel_crtc->base, &crtc_state->base);
1460814609 intel_crtc->config = crtc_state;
14609− intel_crtc->base.state = &crtc_state->base;
14610− crtc_state->base.crtc = &intel_crtc->base;
1461114610
1461214611 primary = intel_primary_plane_create(dev_priv, pipe);
1461314612 if (IS_ERR(primary)) {
@@ -16149,7 +16148,7 @@ static void intel_modeset_readout_hw_state(struct drm_device *dev) · 1535 unmodified lines
1614916148
1615016149 __drm_atomic_helper_crtc_destroy_state(&crtc_state->base);
1615116150 memset(crtc_state, 0, sizeof(*crtc_state));
16152− crtc_state->base.crtc = &crtc->base;
16151+ __drm_atomic_helper_crtc_reset(&crtc->base, &crtc_state->base);
1615316152
1615416153 crtc_state->base.active = crtc_state->base.enable =
1615516154 dev_priv->display.get_pipe_config(crtc, crtc_state);
drivers/gpu/drm/i915/intel_sprite.c+2−1
@@ -325,7 +325,8 @@ skl_plane_max_stride(struct intel_plane *plane, · 324 unmodified lines
325325 u32 pixel_format, u64 modifier,
326326 unsigned int rotation)
327327 {
328− int cpp = drm_format_plane_cpp(pixel_format, 0);
328+ const struct drm_format_info *info = drm_format_info(pixel_format);
329+ int cpp = info->cpp[0];
329330
330331 /*
331332 * "The stride in bytes must not exceed the
drivers/gpu/drm/imx/ipuv3-plane.c+6−9
@@ -115,8 +115,8 @@ drm_plane_state_to_ubo(struct drm_plane_state *state) · 114 unmodified lines
115115 cma_obj = drm_fb_cma_get_gem_obj(fb, 1);
116116 BUG_ON(!cma_obj);
117117
118− x /= drm_format_horz_chroma_subsampling(fb->format->format);
119− y /= drm_format_vert_chroma_subsampling(fb->format->format);
118+ x /= fb->format->hsub;
119+ y /= fb->format->vsub;
120120
121121 return cma_obj->paddr + fb->offsets[1] + fb->pitches[1] * y +
122122 fb->format->cpp[1] * x - eba;
@@ -134,8 +134,8 @@ drm_plane_state_to_vbo(struct drm_plane_state *state) · 11 unmodified lines
134134 cma_obj = drm_fb_cma_get_gem_obj(fb, 2);
135135 BUG_ON(!cma_obj);
136136
137− x /= drm_format_horz_chroma_subsampling(fb->format->format);
138− y /= drm_format_vert_chroma_subsampling(fb->format->format);
137+ x /= fb->format->hsub;
138+ y /= fb->format->vsub;
139139
140140 return cma_obj->paddr + fb->offsets[2] + fb->pitches[2] * y +
141141 fb->format->cpp[2] * x - eba;
@@ -352,7 +352,6 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, · 210 unmodified lines
352352 struct drm_framebuffer *old_fb = old_state->fb;
353353 unsigned long eba, ubo, vbo, old_ubo, old_vbo, alpha_eba;
354354 bool can_position = (plane->type == DRM_PLANE_TYPE_OVERLAY);
355− int hsub, vsub;
356355 int ret;
357356
358357 /* Ok to disable */
@@ -471,10 +470,8 @@ static int ipu_plane_atomic_check(struct drm_plane *plane, · 112 unmodified lines
471470 * The x/y offsets must be even in case of horizontal/vertical
472471 * chroma subsampling.
473472 */
474− hsub = drm_format_horz_chroma_subsampling(fb->format->format);
475− vsub = drm_format_vert_chroma_subsampling(fb->format->format);
476− if (((state->src.x1 >> 16) & (hsub - 1)) ||
477− ((state->src.y1 >> 16) & (vsub - 1)))
473+ if (((state->src.x1 >> 16) & (fb->format->hsub - 1)) ||
474+ ((state->src.y1 >> 16) & (fb->format->vsub - 1)))
478475 return -EINVAL;
479476 break;
480477 case DRM_FORMAT_RGB565_A8:
drivers/gpu/drm/lima/lima_drv.c+1−1
@@ -17,7 +17,7 @@ · 16 unmodified lines
1717
1818 int lima_sched_timeout_ms;
1919
20−MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms (0 = no timeout (default))");
20+MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms");
2121 module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
2222
2323 static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file)
drivers/gpu/drm/lima/lima_pp.c+7−1
@@ -64,7 +64,13 @@ static irqreturn_t lima_pp_bcast_irq_handler(int irq, void *data) · 63 unmodified lines
6464 struct lima_ip *pp_bcast = data;
6565 struct lima_device *dev = pp_bcast->dev;
6666 struct lima_sched_pipe *pipe = dev->pipe + lima_pipe_pp;
67− struct drm_lima_m450_pp_frame *frame = pipe->current_task->frame;
67+ struct drm_lima_m450_pp_frame *frame;
68+
69+ /* for shared irq case */
70+ if (!pipe->current_task)
71+ return IRQ_NONE;
72+
73+ frame = pipe->current_task->frame;
6874
6975 for (i = 0; i < frame->num_pp; i++) {
7076 struct lima_ip *ip = pipe->processor[i];
drivers/gpu/drm/lima/lima_sched.c+5−8
@@ -258,7 +258,7 @@ static struct dma_fence *lima_sched_run_job(struct drm_sched_job *job) · 257 unmodified lines
258258 static void lima_sched_handle_error_task(struct lima_sched_pipe *pipe,
259259 struct lima_sched_task *task)
260260 {
261− drm_sched_stop(&pipe->base);
261+ drm_sched_stop(&pipe->base, &task->base);
262262
263263 if (task)
264264 drm_sched_increase_karma(&task->base);
@@ -329,19 +329,16 @@ static void lima_sched_error_work(struct work_struct *work) · 64 unmodified lines
329329
330330 int lima_sched_pipe_init(struct lima_sched_pipe *pipe, const char *name)
331331 {
332− long timeout;
333−
334− if (lima_sched_timeout_ms <= 0)
335− timeout = MAX_SCHEDULE_TIMEOUT;
336− else
337− timeout = msecs_to_jiffies(lima_sched_timeout_ms);
332+ unsigned int timeout = lima_sched_timeout_ms > 0 ?
333+ lima_sched_timeout_ms : 500;
338334
339335 pipe->fence_context = dma_fence_context_alloc(1);
340336 spin_lock_init(&pipe->fence_lock);
341337
342338 INIT_WORK(&pipe->error_work, lima_sched_error_work);
343339
344− return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0, timeout, name);
340+ return drm_sched_init(&pipe->base, &lima_sched_ops, 1, 0,
341+ msecs_to_jiffies(timeout), name);
345342 }
346343
347344 void lima_sched_pipe_fini(struct lima_sched_pipe *pipe)
drivers/gpu/drm/mediatek/mtk_drm_fb.c+5−3
@@ -32,10 +32,11 @@ static struct drm_framebuffer *mtk_drm_framebuffer_init(struct drm_device *dev, · 31 unmodified lines
3232 const struct drm_mode_fb_cmd2 *mode,
3333 struct drm_gem_object *obj)
3434 {
35+ const struct drm_format_info *info = drm_get_format_info(dev, mode);
3536 struct drm_framebuffer *fb;
3637 int ret;
3738
38− if (drm_format_num_planes(mode->pixel_format) != 1)
39+ if (info->num_planes != 1)
3940 return ERR_PTR(-EINVAL);
4041
4142 fb = kzalloc(sizeof(*fb), GFP_KERNEL);
@@ -88,6 +89,7 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, · 46 unmodified lines
8889 struct drm_file *file,
8990 const struct drm_mode_fb_cmd2 *cmd)
9091 {
92+ const struct drm_format_info *info = drm_get_format_info(dev, cmd);
9193 struct drm_framebuffer *fb;
9294 struct drm_gem_object *gem;
9395 unsigned int width = cmd->width;
@@ -95,14 +97,14 @@ struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev, · 1 unmodified line
9597 unsigned int size, bpp;
9698 int ret;
9799
98− if (drm_format_num_planes(cmd->pixel_format) != 1)
100+ if (info->num_planes != 1)
99101 return ERR_PTR(-EINVAL);
100102
101103 gem = drm_gem_object_lookup(file, cmd->handles[0]);
102104 if (!gem)
103105 return ERR_PTR(-ENOENT);
104106
105− bpp = drm_format_plane_cpp(cmd->pixel_format, 0);
107+ bpp = info->cpp[0];
106108 size = (height - 1) * cmd->pitches[0] + width * bpp;
107109 size += cmd->offsets[0];
108110
drivers/gpu/drm/mediatek/mtk_hdmi.c+3−0
@@ -341,6 +341,9 @@ static void mtk_hdmi_hw_send_info_frame(struct mtk_hdmi *hdmi, u8 *buffer, · 340 unmodified lines
341341 ctrl_frame_en = VS_EN;
342342 ctrl_reg = GRL_ACP_ISRC_CTRL;
343343 break;
344+ default:
345+ dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type);
346+ return;
344347 }
345348 mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en);
346349 mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type);
drivers/gpu/drm/meson/meson_overlay.c+7−7
@@ -458,7 +458,7 @@ static void meson_overlay_atomic_update(struct drm_plane *plane, · 457 unmodified lines
458458 }
459459
460460 /* Update Canvas with buffer address */
461− priv->viu.vd1_planes = drm_format_num_planes(fb->format->format);
461+ priv->viu.vd1_planes = fb->format->num_planes;
462462
463463 switch (priv->viu.vd1_planes) {
464464 case 3:
@@ -466,8 +466,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane, · 1 unmodified line
466466 priv->viu.vd1_addr2 = gem->paddr + fb->offsets[2];
467467 priv->viu.vd1_stride2 = fb->pitches[2];
468468 priv->viu.vd1_height2 =
469− drm_format_plane_height(fb->height,
470− fb->format->format, 2);
469+ drm_format_info_plane_height(fb->format,
470+ fb->height, 2);
471471 DRM_DEBUG("plane 2 addr 0x%x stride %d height %d\n",
472472 priv->viu.vd1_addr2,
473473 priv->viu.vd1_stride2,
@@ -478,8 +478,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane, · 4 unmodified lines
478478 priv->viu.vd1_addr1 = gem->paddr + fb->offsets[1];
479479 priv->viu.vd1_stride1 = fb->pitches[1];
480480 priv->viu.vd1_height1 =
481− drm_format_plane_height(fb->height,
482− fb->format->format, 1);
481+ drm_format_info_plane_height(fb->format,
482+ fb->height, 1);
483483 DRM_DEBUG("plane 1 addr 0x%x stride %d height %d\n",
484484 priv->viu.vd1_addr1,
485485 priv->viu.vd1_stride1,
@@ -490,8 +490,8 @@ static void meson_overlay_atomic_update(struct drm_plane *plane, · 4 unmodified lines
490490 priv->viu.vd1_addr0 = gem->paddr + fb->offsets[0];
491491 priv->viu.vd1_stride0 = fb->pitches[0];
492492 priv->viu.vd1_height0 =
493− drm_format_plane_height(fb->height,
494− fb->format->format, 0);
493+ drm_format_info_plane_height(fb->format,
494+ fb->height, 0);
495495 DRM_DEBUG("plane 0 addr 0x%x stride %d height %d\n",
496496 priv->viu.vd1_addr0,
497497 priv->viu.vd1_stride0,
drivers/gpu/drm/mgag200/Kconfig+1−1
@@ -3,7 +3,7 @@ config DRM_MGAG200 · 2 unmodified lines
33 tristate "Kernel modesetting driver for MGA G200 server engines"
44 depends on DRM && PCI && MMU
55 select DRM_KMS_HELPER
6− select DRM_TTM
6+ select DRM_VRAM_HELPER
77 help
88 This is a KMS driver for the MGA G200 server chips, it
99 does not support the original MGA G200 or any of the desktop
drivers/gpu/drm/mgag200/mgag200_cursor.c+53−43
@@ -23,9 +23,9 @@ static void mga_hide_cursor(struct mga_device *mdev) · 22 unmodified lines
2323 WREG8(MGA_CURPOSXL, 0);
2424 WREG8(MGA_CURPOSXH, 0);
2525 if (mdev->cursor.pixels_1->pin_count)
26− mgag200_bo_unpin(mdev->cursor.pixels_1);
26+ drm_gem_vram_unpin_locked(mdev->cursor.pixels_1);
2727 if (mdev->cursor.pixels_2->pin_count)
28− mgag200_bo_unpin(mdev->cursor.pixels_2);
28+ drm_gem_vram_unpin_locked(mdev->cursor.pixels_2);
2929 }
3030
3131 int mga_crtc_cursor_set(struct drm_crtc *crtc,
@@ -36,13 +36,14 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 4 unmodified lines
3636 {
3737 struct drm_device *dev = crtc->dev;
3838 struct mga_device *mdev = (struct mga_device *)dev->dev_private;
39− struct mgag200_bo *pixels_1 = mdev->cursor.pixels_1;
40− struct mgag200_bo *pixels_2 = mdev->cursor.pixels_2;
41− struct mgag200_bo *pixels_current = mdev->cursor.pixels_current;
42− struct mgag200_bo *pixels_prev = mdev->cursor.pixels_prev;
39+ struct drm_gem_vram_object *pixels_1 = mdev->cursor.pixels_1;
40+ struct drm_gem_vram_object *pixels_2 = mdev->cursor.pixels_2;
41+ struct drm_gem_vram_object *pixels_current = mdev->cursor.pixels_current;
42+ struct drm_gem_vram_object *pixels_prev = mdev->cursor.pixels_prev;
4343 struct drm_gem_object *obj;
44− struct mgag200_bo *bo = NULL;
44+ struct drm_gem_vram_object *gbo = NULL;
4545 int ret = 0;
46+ u8 *src, *dst;
4647 unsigned int i, row, col;
4748 uint32_t colour_set[16];
4849 uint32_t *next_space = &colour_set[0];
@@ -50,7 +51,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 1 unmodified line
5051 uint32_t this_colour;
5152 bool found = false;
5253 int colour_count = 0;
53− u64 gpu_addr;
54+ s64 gpu_addr;
5455 u8 reg_index;
5556 u8 this_row[48];
5657
@@ -79,54 +80,66 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 22 unmodified lines
7980 if (!obj)
8081 return -ENOENT;
8182
82− ret = mgag200_bo_reserve(pixels_1, true);
83+ ret = drm_gem_vram_lock(pixels_1, true);
8384 if (ret) {
8485 WREG8(MGA_CURPOSXL, 0);
8586 WREG8(MGA_CURPOSXH, 0);
8687 goto out_unref;
8788 }
88− ret = mgag200_bo_reserve(pixels_2, true);
89+ ret = drm_gem_vram_lock(pixels_2, true);
8990 if (ret) {
9091 WREG8(MGA_CURPOSXL, 0);
9192 WREG8(MGA_CURPOSXH, 0);
92− mgag200_bo_unreserve(pixels_1);
93− goto out_unreserve1;
93+ drm_gem_vram_unlock(pixels_1);
94+ goto out_unlock1;
9495 }
9596
9697 /* Move cursor buffers into VRAM if they aren't already */
9798 if (!pixels_1->pin_count) {
98− ret = mgag200_bo_pin(pixels_1, TTM_PL_FLAG_VRAM,
99− &mdev->cursor.pixels_1_gpu_addr);
99+ ret = drm_gem_vram_pin_locked(pixels_1,
100+ DRM_GEM_VRAM_PL_FLAG_VRAM);
100101 if (ret)
101102 goto out1;
103+ gpu_addr = drm_gem_vram_offset(pixels_1);
104+ if (gpu_addr < 0) {
105+ drm_gem_vram_unpin_locked(pixels_1);
106+ goto out1;
107+ }
108+ mdev->cursor.pixels_1_gpu_addr = gpu_addr;
102109 }
103110 if (!pixels_2->pin_count) {
104− ret = mgag200_bo_pin(pixels_2, TTM_PL_FLAG_VRAM,
105− &mdev->cursor.pixels_2_gpu_addr);
111+ ret = drm_gem_vram_pin_locked(pixels_2,
112+ DRM_GEM_VRAM_PL_FLAG_VRAM);
106113 if (ret) {
107− mgag200_bo_unpin(pixels_1);
114+ drm_gem_vram_unpin_locked(pixels_1);
108115 goto out1;
109116 }
117+ gpu_addr = drm_gem_vram_offset(pixels_2);
118+ if (gpu_addr < 0) {
119+ drm_gem_vram_unpin_locked(pixels_1);
120+ drm_gem_vram_unpin_locked(pixels_2);
121+ goto out1;
122+ }
123+ mdev->cursor.pixels_2_gpu_addr = gpu_addr;
110124 }
111125
112− bo = gem_to_mga_bo(obj);
113− ret = mgag200_bo_reserve(bo, true);
126+ gbo = drm_gem_vram_of_gem(obj);
127+ ret = drm_gem_vram_lock(gbo, true);
114128 if (ret) {
115− dev_err(&dev->pdev->dev, "failed to reserve user bo\n");
129+ dev_err(&dev->pdev->dev, "failed to lock user bo\n");
116130 goto out1;
117131 }
118− if (!bo->kmap.virtual) {
119− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
120− if (ret) {
121− dev_err(&dev->pdev->dev, "failed to kmap user buffer updates\n");
122− goto out2;
123− }
132+ src = drm_gem_vram_kmap(gbo, true, NULL);
133+ if (IS_ERR(src)) {
134+ ret = PTR_ERR(src);
135+ dev_err(&dev->pdev->dev, "failed to kmap user buffer updates\n");
136+ goto out2;
124137 }
125138
126139 memset(&colour_set[0], 0, sizeof(uint32_t)*16);
127140 /* width*height*4 = 16384 */
128141 for (i = 0; i < 16384; i += 4) {
129− this_colour = ioread32(bo->kmap.virtual + i);
142+ this_colour = ioread32(src + i);
130143 /* No transparency */
131144 if (this_colour>>24 != 0xff &&
132145 this_colour>>24 != 0x0) {
@@ -178,21 +191,18 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 45 unmodified lines
178191 }
179192
180193 /* Map up-coming buffer to write colour indices */
181− if (!pixels_prev->kmap.virtual) {
182− ret = ttm_bo_kmap(&pixels_prev->bo, 0,
183− pixels_prev->bo.num_pages,
184− &pixels_prev->kmap);
185− if (ret) {
186− dev_err(&dev->pdev->dev, "failed to kmap cursor updates\n");
187− goto out3;
188− }
194+ dst = drm_gem_vram_kmap(pixels_prev, true, NULL);
195+ if (IS_ERR(dst)) {
196+ ret = PTR_ERR(dst);
197+ dev_err(&dev->pdev->dev, "failed to kmap cursor updates\n");
198+ goto out3;
189199 }
190200
191201 /* now write colour indices into hardware cursor buffer */
192202 for (row = 0; row < 64; row++) {
193203 memset(&this_row[0], 0, 48);
194204 for (col = 0; col < 64; col++) {
195− this_colour = ioread32(bo->kmap.virtual + 4*(col + 64*row));
205+ this_colour = ioread32(src + 4*(col + 64*row));
196206 /* write transparent pixels */
197207 if (this_colour>>24 == 0x0) {
198208 this_row[47 - col/8] |= 0x80>>(col%8);
@@ -210,7 +220,7 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 11 unmodified lines
210220 }
211221 }
212222 }
213− memcpy_toio(pixels_prev->kmap.virtual + row*48, &this_row[0], 48);
223+ memcpy_toio(dst + row*48, &this_row[0], 48);
214224 }
215225
216226 /* Program gpu address of cursor buffer */
@@ -236,17 +246,17 @@ int mga_crtc_cursor_set(struct drm_crtc *crtc, · 19 unmodified lines
236246 }
237247 ret = 0;
238248
239− ttm_bo_kunmap(&pixels_prev->kmap);
249+ drm_gem_vram_kunmap(pixels_prev);
240250 out3:
241− ttm_bo_kunmap(&bo->kmap);
251+ drm_gem_vram_kunmap(gbo);
242252 out2:
243− mgag200_bo_unreserve(bo);
253+ drm_gem_vram_unlock(gbo);
244254 out1:
245255 if (ret)
246256 mga_hide_cursor(mdev);
247− mgag200_bo_unreserve(pixels_1);
248−out_unreserve1:
249− mgag200_bo_unreserve(pixels_2);
257+ drm_gem_vram_unlock(pixels_1);
258+out_unlock1:
259+ drm_gem_vram_unlock(pixels_2);
250260 out_unref:
251261 drm_gem_object_put_unlocked(obj);
252262
drivers/gpu/drm/mgag200/mgag200_drv.c+2−11
@@ -59,13 +59,7 @@ static void mga_pci_remove(struct pci_dev *pdev) · 58 unmodified lines
5959
6060 static const struct file_operations mgag200_driver_fops = {
6161 .owner = THIS_MODULE,
62− .open = drm_open,
63− .release = drm_release,
64− .unlocked_ioctl = drm_ioctl,
65− .mmap = mgag200_mmap,
66− .poll = drm_poll,
67− .compat_ioctl = drm_compat_ioctl,
68− .read = drm_read,
62+ DRM_VRAM_MM_FILE_OPERATIONS
6963 };
7064
7165 static struct drm_driver driver = {
@@ -79,10 +73,7 @@ static struct drm_driver driver = { · 7 unmodified lines
7973 .major = DRIVER_MAJOR,
8074 .minor = DRIVER_MINOR,
8175 .patchlevel = DRIVER_PATCHLEVEL,
82−
83− .gem_free_object_unlocked = mgag200_gem_free_object,
84− .dumb_create = mgag200_dumb_create,
85− .dumb_map_offset = mgag200_dumb_mmap_offset,
76+ DRM_GEM_VRAM_DRIVER
8677 };
8778
8879 static struct pci_driver mgag200_pci_driver = {
drivers/gpu/drm/mgag200/mgag200_drv.h+10−64
@@ -1,6 +1,6 @@
11 /*
22 * Copyright 2010 Matt Turner.
3− * Copyright 2012 Red Hat
3+ * Copyright 2012 Red Hat
44 *
55 * This file is subject to the terms and conditions of the GNU General
66 * Public License version 2. See the file COPYING in the main
@@ -17,13 +17,11 @@ · 10 unmodified lines
1717
1818 #include <drm/drm_encoder.h>
1919 #include <drm/drm_fb_helper.h>
20−#include <drm/ttm/ttm_bo_api.h>
21−#include <drm/ttm/ttm_bo_driver.h>
22−#include <drm/ttm/ttm_placement.h>
23−#include <drm/ttm/ttm_memory.h>
24−#include <drm/ttm/ttm_module.h>
2520
2621 #include <drm/drm_gem.h>
22+#include <drm/drm_gem_vram_helper.h>
23+
24+#include <drm/drm_vram_mm_helper.h>
2725
2826 #include <linux/i2c.h>
2927 #include <linux/i2c-algo-bit.h>
@@ -117,7 +115,6 @@ struct mga_fbdev { · 87 unmodified lines
117115 struct mga_framebuffer mfb;
118116 void *sysram;
119117 int size;
120− struct ttm_bo_kmap_obj mapping;
121118 int x1, y1, x2, y2; /* dirty rect */
122119 spinlock_t dirty_lock;
123120 };
@@ -159,13 +156,13 @@ struct mga_cursor { · 35 unmodified lines
159156 If either of these is NULL, then don't do hardware cursors, and
160157 fall back to software.
161158 */
162− struct mgag200_bo *pixels_1;
163− struct mgag200_bo *pixels_2;
159+ struct drm_gem_vram_object *pixels_1;
160+ struct drm_gem_vram_object *pixels_2;
164161 u64 pixels_1_gpu_addr, pixels_2_gpu_addr;
165162 /* The currently displayed icon, this points to one of pixels_1, or pixels_2 */
166− struct mgag200_bo *pixels_current;
163+ struct drm_gem_vram_object *pixels_current;
167164 /* The previously displayed icon */
168− struct mgag200_bo *pixels_prev;
165+ struct drm_gem_vram_object *pixels_prev;
169166 };
170167
171168 struct mga_mc {
@@ -211,31 +208,10 @@ struct mga_device { · 39 unmodified lines
211208
212209 int fb_mtrr;
213210
214− struct {
215− struct ttm_bo_device bdev;
216− } ttm;
217−
218211 /* SE model number stored in reg 0x1e24 */
219212 u32 unique_rev_id;
220213 };
221214
222−
223−struct mgag200_bo {
224− struct ttm_buffer_object bo;
225− struct ttm_placement placement;
226− struct ttm_bo_kmap_obj kmap;
227− struct drm_gem_object gem;
228− struct ttm_place placements[3];
229− int pin_count;
230−};
231−#define gem_to_mga_bo(gobj) container_of((gobj), struct mgag200_bo, gem)
232−
233−static inline struct mgag200_bo *
234−mgag200_bo(struct ttm_buffer_object *bo)
235−{
236− return container_of(bo, struct mgag200_bo, bo);
237−}
238−
239215 /* mgag200_mode.c */
240216 int mgag200_modeset_init(struct mga_device *mdev);
241217 void mgag200_modeset_fini(struct mga_device *mdev);
@@ -259,45 +235,15 @@ int mgag200_gem_create(struct drm_device *dev, · 17 unmodified lines
259235 int mgag200_dumb_create(struct drm_file *file,
260236 struct drm_device *dev,
261237 struct drm_mode_create_dumb *args);
262−void mgag200_gem_free_object(struct drm_gem_object *obj);
263−int
264−mgag200_dumb_mmap_offset(struct drm_file *file,
265− struct drm_device *dev,
266− uint32_t handle,
267− uint64_t *offset);
238+
268239 /* mgag200_i2c.c */
269240 struct mga_i2c_chan *mgag200_i2c_create(struct drm_device *dev);
270241 void mgag200_i2c_destroy(struct mga_i2c_chan *i2c);
271242
272−void mgag200_ttm_placement(struct mgag200_bo *bo, int domain);
273−
274−static inline int mgag200_bo_reserve(struct mgag200_bo *bo, bool no_wait)
275−{
276− int ret;
277−
278− ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
279− if (ret) {
280− if (ret != -ERESTARTSYS && ret != -EBUSY)
281− DRM_ERROR("reserve failed %p\n", bo);
282− return ret;
283− }
284− return 0;
285−}
286−
287−static inline void mgag200_bo_unreserve(struct mgag200_bo *bo)
288−{
289− ttm_bo_unreserve(&bo->bo);
290−}
291−
292−int mgag200_bo_create(struct drm_device *dev, int size, int align,
293− uint32_t flags, struct mgag200_bo **pastbo);
294243 int mgag200_mm_init(struct mga_device *mdev);
295244 void mgag200_mm_fini(struct mga_device *mdev);
296245 int mgag200_mmap(struct file *filp, struct vm_area_struct *vma);
297−int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr);
298−int mgag200_bo_unpin(struct mgag200_bo *bo);
299−int mgag200_bo_push_sysram(struct mgag200_bo *bo);
300− /* mgag200_cursor.c */
246+
301247 int mga_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv,
302248 uint32_t handle, uint32_t width, uint32_t height);
303249 int mga_crtc_cursor_move(struct drm_crtc *crtc, int x, int y);
drivers/gpu/drm/mgag200/mgag200_fb.c+24−17
@@ -23,25 +23,25 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev, · 22 unmodified lines
2323 {
2424 int i;
2525 struct drm_gem_object *obj;
26− struct mgag200_bo *bo;
26+ struct drm_gem_vram_object *gbo;
2727 int src_offset, dst_offset;
2828 int bpp = mfbdev->mfb.base.format->cpp[0];
2929 int ret = -EBUSY;
30+ u8 *dst;
3031 bool unmap = false;
3132 bool store_for_later = false;
3233 int x2, y2;
3334 unsigned long flags;
3435
3536 obj = mfbdev->mfb.obj;
36− bo = gem_to_mga_bo(obj);
37+ gbo = drm_gem_vram_of_gem(obj);
3738
38− /*
39− * try and reserve the BO, if we fail with busy
40− * then the BO is being moved and we should
41− * store up the damage until later.
39+ /* Try to lock the BO. If we fail with -EBUSY then
40+ * the BO is being moved and we should store up the
41+ * damage until later.
4242 */
4343 if (drm_can_sleep())
44− ret = mgag200_bo_reserve(bo, true);
44+ ret = drm_gem_vram_lock(gbo, true);
4545 if (ret) {
4646 if (ret != -EBUSY)
4747 return;
@@ -75,25 +75,32 @@ static void mga_dirty_update(struct mga_fbdev *mfbdev, · 27 unmodified lines
7575 mfbdev->x2 = mfbdev->y2 = 0;
7676 spin_unlock_irqrestore(&mfbdev->dirty_lock, flags);
7777
78− if (!bo->kmap.virtual) {
79− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
80− if (ret) {
78+ dst = drm_gem_vram_kmap(gbo, false, NULL);
79+ if (IS_ERR(dst)) {
80+ DRM_ERROR("failed to kmap fb updates\n");
81+ goto out;
82+ } else if (!dst) {
83+ dst = drm_gem_vram_kmap(gbo, true, NULL);
84+ if (IS_ERR(dst)) {
8185 DRM_ERROR("failed to kmap fb updates\n");
82− mgag200_bo_unreserve(bo);
83− return;
86+ goto out;
8487 }
8588 unmap = true;
8689 }
90+
8791 for (i = y; i <= y2; i++) {
8892 /* assume equal stride for now */
89− src_offset = dst_offset = i * mfbdev->mfb.base.pitches[0] + (x * bpp);
90− memcpy_toio(bo->kmap.virtual + src_offset, mfbdev->sysram + src_offset, (x2 - x + 1) * bpp);
91−
93+ src_offset = dst_offset =
94+ i * mfbdev->mfb.base.pitches[0] + (x * bpp);
95+ memcpy_toio(dst + dst_offset, mfbdev->sysram + src_offset,
96+ (x2 - x + 1) * bpp);
9297 }
98+
9399 if (unmap)
94− ttm_bo_kunmap(&bo->kmap);
100+ drm_gem_vram_kunmap(gbo);
95101
96− mgag200_bo_unreserve(bo);
102+out:
103+ drm_gem_vram_unlock(gbo);
97104 }
98105
99106 static void mga_fillrect(struct fb_info *info,
drivers/gpu/drm/mgag200/mgag200_main.c+12−75
@@ -230,11 +230,13 @@ int mgag200_driver_load(struct drm_device *dev, unsigned long flags) · 229 unmodified lines
230230 }
231231
232232 /* Make small buffers to store a hardware cursor (double buffered icon updates) */
233− mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
234− &mdev->cursor.pixels_1);
235− mgag200_bo_create(dev, roundup(48*64, PAGE_SIZE), 0, 0,
236− &mdev->cursor.pixels_2);
237− if (!mdev->cursor.pixels_2 || !mdev->cursor.pixels_1) {
233+ mdev->cursor.pixels_1 = drm_gem_vram_create(dev, &dev->vram_mm->bdev,
234+ roundup(48*64, PAGE_SIZE),
235+ 0, 0);
236+ mdev->cursor.pixels_2 = drm_gem_vram_create(dev, &dev->vram_mm->bdev,
237+ roundup(48*64, PAGE_SIZE),
238+ 0, 0);
239+ if (IS_ERR(mdev->cursor.pixels_2) || IS_ERR(mdev->cursor.pixels_1)) {
238240 mdev->cursor.pixels_1 = NULL;
239241 mdev->cursor.pixels_2 = NULL;
240242 dev_warn(&dev->pdev->dev,
@@ -272,7 +274,7 @@ int mgag200_gem_create(struct drm_device *dev, · 31 unmodified lines
272274 u32 size, bool iskernel,
273275 struct drm_gem_object **obj)
274276 {
275− struct mgag200_bo *astbo;
277+ struct drm_gem_vram_object *gbo;
276278 int ret;
277279
278280 *obj = NULL;
@@ -281,78 +283,13 @@ int mgag200_gem_create(struct drm_device *dev, · 2 unmodified lines
281283 if (size == 0)
282284 return -EINVAL;
283285
284− ret = mgag200_bo_create(dev, size, 0, 0, &astbo);
285− if (ret) {
286+ gbo = drm_gem_vram_create(dev, &dev->vram_mm->bdev, size, 0, false);
287+ if (IS_ERR(gbo)) {
288+ ret = PTR_ERR(gbo);
286289 if (ret != -ERESTARTSYS)
287290 DRM_ERROR("failed to allocate GEM object\n");
288291 return ret;
289292 }
290− *obj = &astbo->gem;
291− return 0;
292−}
293−
294−int mgag200_dumb_create(struct drm_file *file,
295− struct drm_device *dev,
296− struct drm_mode_create_dumb *args)
297−{
298− int ret;
299− struct drm_gem_object *gobj;
300− u32 handle;
301−
302− args->pitch = args->width * ((args->bpp + 7) / 8);
303− args->size = args->pitch * args->height;
304−
305− ret = mgag200_gem_create(dev, args->size, false,
306− &gobj);
307− if (ret)
308− return ret;
309−
310− ret = drm_gem_handle_create(file, gobj, &handle);
311− drm_gem_object_put_unlocked(gobj);
312− if (ret)
313− return ret;
314−
315− args->handle = handle;
316− return 0;
317−}
318−
319−static void mgag200_bo_unref(struct mgag200_bo **bo)
320−{
321− if ((*bo) == NULL)
322− return;
323− ttm_bo_put(&((*bo)->bo));
324− *bo = NULL;
325−}
326−
327−void mgag200_gem_free_object(struct drm_gem_object *obj)
328−{
329− struct mgag200_bo *mgag200_bo = gem_to_mga_bo(obj);
330−
331− mgag200_bo_unref(&mgag200_bo);
332−}
333−
334−
335−static inline u64 mgag200_bo_mmap_offset(struct mgag200_bo *bo)
336−{
337− return drm_vma_node_offset_addr(&bo->bo.vma_node);
338−}
339−
340−int
341−mgag200_dumb_mmap_offset(struct drm_file *file,
342− struct drm_device *dev,
343− uint32_t handle,
344− uint64_t *offset)
345−{
346− struct drm_gem_object *obj;
347− struct mgag200_bo *bo;
348−
349− obj = drm_gem_object_lookup(file, handle);
350− if (obj == NULL)
351− return -ENOENT;
352−
353− bo = gem_to_mga_bo(obj);
354− *offset = mgag200_bo_mmap_offset(bo);
355−
356− drm_gem_object_put_unlocked(obj);
293+ *obj = &gbo->gem;
357294 return 0;
358295 }
drivers/gpu/drm/mgag200/mgag200_mode.c+30−29
@@ -858,8 +858,6 @@ static void mga_set_start_address(struct drm_crtc *crtc, unsigned offset) · 857 unmodified lines
858858 WREG_ECRT(0x0, ((u8)(addr >> 16) & 0xf) | crtcext0);
859859 }
860860
861−
862−/* ast is different - we will force move buffers out of VRAM */
863861 static int mga_crtc_do_set_base(struct drm_crtc *crtc,
864862 struct drm_framebuffer *fb,
865863 int x, int y, int atomic)
@@ -867,48 +865,51 @@ static int mga_crtc_do_set_base(struct drm_crtc *crtc, · 1 unmodified line
867865 struct mga_device *mdev = crtc->dev->dev_private;
868866 struct drm_gem_object *obj;
869867 struct mga_framebuffer *mga_fb;
870− struct mgag200_bo *bo;
868+ struct drm_gem_vram_object *gbo;
871869 int ret;
872− u64 gpu_addr;
870+ s64 gpu_addr;
871+ void *base;
873872
874− /* push the previous fb to system ram */
875873 if (!atomic && fb) {
876874 mga_fb = to_mga_framebuffer(fb);
877875 obj = mga_fb->obj;
878− bo = gem_to_mga_bo(obj);
879− ret = mgag200_bo_reserve(bo, false);
880− if (ret)
881− return ret;
882− mgag200_bo_push_sysram(bo);
883− mgag200_bo_unreserve(bo);
876+ gbo = drm_gem_vram_of_gem(obj);
877+
878+ /* unmap if console */
879+ if (&mdev->mfbdev->mfb == mga_fb)
880+ drm_gem_vram_kunmap(gbo);
881+ drm_gem_vram_unpin(gbo);
884882 }
885883
886884 mga_fb = to_mga_framebuffer(crtc->primary->fb);
887885 obj = mga_fb->obj;
888− bo = gem_to_mga_bo(obj);
886+ gbo = drm_gem_vram_of_gem(obj);
889887
890− ret = mgag200_bo_reserve(bo, false);
888+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
891889 if (ret)
892890 return ret;
893−
894− ret = mgag200_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
895− if (ret) {
896− mgag200_bo_unreserve(bo);
897− return ret;
891+ gpu_addr = drm_gem_vram_offset(gbo);
892+ if (gpu_addr < 0) {
893+ ret = (int)gpu_addr;
894+ goto err_drm_gem_vram_unpin;
898895 }
899896
900897 if (&mdev->mfbdev->mfb == mga_fb) {
901898 /* if pushing console in kmap it */
902− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
903− if (ret)
899+ base = drm_gem_vram_kmap(gbo, true, NULL);
900+ if (IS_ERR(base)) {
901+ ret = PTR_ERR(base);
904902 DRM_ERROR("failed to kmap fbcon\n");
905−
903+ }
906904 }
907− mgag200_bo_unreserve(bo);
908905
909906 mga_set_start_address(crtc, (u32)gpu_addr);
910907
911908 return 0;
909+
910+err_drm_gem_vram_unpin:
911+ drm_gem_vram_unpin(gbo);
912+ return ret;
912913 }
913914
914915 static int mga_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
@@ -1422,18 +1423,18 @@ static void mga_crtc_destroy(struct drm_crtc *crtc) · 507 unmodified lines
14221423
14231424 static void mga_crtc_disable(struct drm_crtc *crtc)
14241425 {
1425− int ret;
14261426 DRM_DEBUG_KMS("\n");
14271427 mga_crtc_dpms(crtc, DRM_MODE_DPMS_OFF);
14281428 if (crtc->primary->fb) {
1429+ struct mga_device *mdev = crtc->dev->dev_private;
14291430 struct mga_framebuffer *mga_fb = to_mga_framebuffer(crtc->primary->fb);
14301431 struct drm_gem_object *obj = mga_fb->obj;
1431− struct mgag200_bo *bo = gem_to_mga_bo(obj);
1432− ret = mgag200_bo_reserve(bo, false);
1433− if (ret)
1434− return;
1435− mgag200_bo_push_sysram(bo);
1436− mgag200_bo_unreserve(bo);
1432+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(obj);
1433+
1434+ /* unmap if console */
1435+ if (&mdev->mfbdev->mfb == mga_fb)
1436+ drm_gem_vram_kunmap(gbo);
1437+ drm_gem_vram_unpin(gbo);
14371438 }
14381439 crtc->primary->fb = NULL;
14391440 }
drivers/gpu/drm/mgag200/mgag200_ttm.c+8−293
@@ -26,167 +26,21 @@ · 25 unmodified lines
2626 * Authors: Dave Airlie <airlied@redhat.com>
2727 */
2828 #include <drm/drmP.h>
29−#include <drm/ttm/ttm_page_alloc.h>
3029
3130 #include "mgag200_drv.h"
3231
33−static inline struct mga_device *
34−mgag200_bdev(struct ttm_bo_device *bd)
35−{
36− return container_of(bd, struct mga_device, ttm.bdev);
37−}
38−
39−static void mgag200_bo_ttm_destroy(struct ttm_buffer_object *tbo)
40−{
41− struct mgag200_bo *bo;
42−
43− bo = container_of(tbo, struct mgag200_bo, bo);
44−
45− drm_gem_object_release(&bo->gem);
46− kfree(bo);
47−}
48−
49−static bool mgag200_ttm_bo_is_mgag200_bo(struct ttm_buffer_object *bo)
50−{
51− if (bo->destroy == &mgag200_bo_ttm_destroy)
52− return true;
53− return false;
54−}
55−
56−static int
57−mgag200_bo_init_mem_type(struct ttm_bo_device *bdev, uint32_t type,
58− struct ttm_mem_type_manager *man)
59−{
60− switch (type) {
61− case TTM_PL_SYSTEM:
62− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
63− man->available_caching = TTM_PL_MASK_CACHING;
64− man->default_caching = TTM_PL_FLAG_CACHED;
65− break;
66− case TTM_PL_VRAM:
67− man->func = &ttm_bo_manager_func;
68− man->flags = TTM_MEMTYPE_FLAG_FIXED |
69− TTM_MEMTYPE_FLAG_MAPPABLE;
70− man->available_caching = TTM_PL_FLAG_UNCACHED |
71− TTM_PL_FLAG_WC;
72− man->default_caching = TTM_PL_FLAG_WC;
73− break;
74− default:
75− DRM_ERROR("Unsupported memory type %u\n", (unsigned)type);
76− return -EINVAL;
77− }
78− return 0;
79−}
80−
81−static void
82−mgag200_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
83−{
84− struct mgag200_bo *mgabo = mgag200_bo(bo);
85−
86− if (!mgag200_ttm_bo_is_mgag200_bo(bo))
87− return;
88−
89− mgag200_ttm_placement(mgabo, TTM_PL_FLAG_SYSTEM);
90− *pl = mgabo->placement;
91−}
92−
93−static int mgag200_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp)
94−{
95− struct mgag200_bo *mgabo = mgag200_bo(bo);
96−
97− return drm_vma_node_verify_access(&mgabo->gem.vma_node,
98− filp->private_data);
99−}
100−
101−static int mgag200_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
102− struct ttm_mem_reg *mem)
103−{
104− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
105− struct mga_device *mdev = mgag200_bdev(bdev);
106−
107− mem->bus.addr = NULL;
108− mem->bus.offset = 0;
109− mem->bus.size = mem->num_pages << PAGE_SHIFT;
110− mem->bus.base = 0;
111− mem->bus.is_iomem = false;
112− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
113− return -EINVAL;
114− switch (mem->mem_type) {
115− case TTM_PL_SYSTEM:
116− /* system memory */
117− return 0;
118− case TTM_PL_VRAM:
119− mem->bus.offset = mem->start << PAGE_SHIFT;
120− mem->bus.base = pci_resource_start(mdev->dev->pdev, 0);
121− mem->bus.is_iomem = true;
122− break;
123− default:
124− return -EINVAL;
125− break;
126− }
127− return 0;
128−}
129−
130−static void mgag200_ttm_io_mem_free(struct ttm_bo_device *bdev, struct ttm_mem_reg *mem)
131−{
132−}
133−
134−static void mgag200_ttm_backend_destroy(struct ttm_tt *tt)
135−{
136− ttm_tt_fini(tt);
137− kfree(tt);
138−}
139−
140−static struct ttm_backend_func mgag200_tt_backend_func = {
141− .destroy = &mgag200_ttm_backend_destroy,
142−};
143−
144−
145−static struct ttm_tt *mgag200_ttm_tt_create(struct ttm_buffer_object *bo,
146− uint32_t page_flags)
147−{
148− struct ttm_tt *tt;
149−
150− tt = kzalloc(sizeof(struct ttm_tt), GFP_KERNEL);
151− if (tt == NULL)
152− return NULL;
153− tt->func = &mgag200_tt_backend_func;
154− if (ttm_tt_init(tt, bo, page_flags)) {
155− kfree(tt);
156− return NULL;
157− }
158− return tt;
159−}
160−
161−struct ttm_bo_driver mgag200_bo_driver = {
162− .ttm_tt_create = mgag200_ttm_tt_create,
163− .init_mem_type = mgag200_bo_init_mem_type,
164− .eviction_valuable = ttm_bo_eviction_valuable,
165− .evict_flags = mgag200_bo_evict_flags,
166− .move = NULL,
167− .verify_access = mgag200_bo_verify_access,
168− .io_mem_reserve = &mgag200_ttm_io_mem_reserve,
169− .io_mem_free = &mgag200_ttm_io_mem_free,
170−};
171−
17232 int mgag200_mm_init(struct mga_device *mdev)
17333 {
34+ struct drm_vram_mm *vmm;
17435 int ret;
17536 struct drm_device *dev = mdev->dev;
176− struct ttm_bo_device *bdev = &mdev->ttm.bdev;
177−
178− ret = ttm_bo_device_init(&mdev->ttm.bdev,
179− &mgag200_bo_driver,
180− dev->anon_inode->i_mapping,
181− true);
182− if (ret) {
183− DRM_ERROR("Error initialising bo driver; %d\n", ret);
184− return ret;
185− }
18637
187− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM, mdev->mc.vram_size >> PAGE_SHIFT);
188− if (ret) {
189− DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
38+ vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0),
39+ mdev->mc.vram_size,
40+ &drm_gem_vram_mm_funcs);
41+ if (IS_ERR(vmm)) {
42+ ret = PTR_ERR(vmm);
43+ DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
19044 return ret;
19145 }
19246
@@ -203,149 +57,10 @@ void mgag200_mm_fini(struct mga_device *mdev) · 10 unmodified lines
20357 {
20458 struct drm_device *dev = mdev->dev;
20559
206− ttm_bo_device_release(&mdev->ttm.bdev);
60+ drm_vram_helper_release_mm(dev);
20761
20862 arch_io_free_memtype_wc(pci_resource_start(dev->pdev, 0),
20963 pci_resource_len(dev->pdev, 0));
21064 arch_phys_wc_del(mdev->fb_mtrr);
21165 mdev->fb_mtrr = 0;
21266 }
213−
214−void mgag200_ttm_placement(struct mgag200_bo *bo, int domain)
215−{
216− u32 c = 0;
217− unsigned i;
218−
219− bo->placement.placement = bo->placements;
220− bo->placement.busy_placement = bo->placements;
221− if (domain & TTM_PL_FLAG_VRAM)
222− bo->placements[c++].flags = TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
223− if (domain & TTM_PL_FLAG_SYSTEM)
224− bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
225− if (!c)
226− bo->placements[c++].flags = TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
227− bo->placement.num_placement = c;
228− bo->placement.num_busy_placement = c;
229− for (i = 0; i < c; ++i) {
230− bo->placements[i].fpfn = 0;
231− bo->placements[i].lpfn = 0;
232− }
233−}
234−
235−int mgag200_bo_create(struct drm_device *dev, int size, int align,
236− uint32_t flags, struct mgag200_bo **pmgabo)
237−{
238− struct mga_device *mdev = dev->dev_private;
239− struct mgag200_bo *mgabo;
240− size_t acc_size;
241− int ret;
242−
243− mgabo = kzalloc(sizeof(struct mgag200_bo), GFP_KERNEL);
244− if (!mgabo)
245− return -ENOMEM;
246−
247− ret = drm_gem_object_init(dev, &mgabo->gem, size);
248− if (ret) {
249− kfree(mgabo);
250− return ret;
251− }
252−
253− mgabo->bo.bdev = &mdev->ttm.bdev;
254−
255− mgag200_ttm_placement(mgabo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
256−
257− acc_size = ttm_bo_dma_acc_size(&mdev->ttm.bdev, size,
258− sizeof(struct mgag200_bo));
259−
260− ret = ttm_bo_init(&mdev->ttm.bdev, &mgabo->bo, size,
261− ttm_bo_type_device, &mgabo->placement,
262− align >> PAGE_SHIFT, false, acc_size,
263− NULL, NULL, mgag200_bo_ttm_destroy);
264− if (ret)
265− return ret;
266−
267− *pmgabo = mgabo;
268− return 0;
269−}
270−
271−static inline u64 mgag200_bo_gpu_offset(struct mgag200_bo *bo)
272−{
273− return bo->bo.offset;
274−}
275−
276−int mgag200_bo_pin(struct mgag200_bo *bo, u32 pl_flag, u64 *gpu_addr)
277−{
278− struct ttm_operation_ctx ctx = { false, false };
279− int i, ret;
280−
281− if (bo->pin_count) {
282− bo->pin_count++;
283− if (gpu_addr)
284− *gpu_addr = mgag200_bo_gpu_offset(bo);
285− return 0;
286− }
287−
288− mgag200_ttm_placement(bo, pl_flag);
289− for (i = 0; i < bo->placement.num_placement; i++)
290− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
291− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
292− if (ret)
293− return ret;
294−
295− bo->pin_count = 1;
296− if (gpu_addr)
297− *gpu_addr = mgag200_bo_gpu_offset(bo);
298− return 0;
299−}
300−
301−int mgag200_bo_unpin(struct mgag200_bo *bo)
302−{
303− struct ttm_operation_ctx ctx = { false, false };
304− int i;
305− if (!bo->pin_count) {
306− DRM_ERROR("unpin bad %p\n", bo);
307− return 0;
308− }
309− bo->pin_count--;
310− if (bo->pin_count)
311− return 0;
312−
313− for (i = 0; i < bo->placement.num_placement ; i++)
314− bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
315− return ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
316−}
317−
318−int mgag200_bo_push_sysram(struct mgag200_bo *bo)
319−{
320− struct ttm_operation_ctx ctx = { false, false };
321− int i, ret;
322− if (!bo->pin_count) {
323− DRM_ERROR("unpin bad %p\n", bo);
324− return 0;
325− }
326− bo->pin_count--;
327− if (bo->pin_count)
328− return 0;
329−
330− if (bo->kmap.virtual)
331− ttm_bo_kunmap(&bo->kmap);
332−
333− mgag200_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
334− for (i = 0; i < bo->placement.num_placement ; i++)
335− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
336−
337− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
338− if (ret) {
339− DRM_ERROR("pushing to VRAM failed\n");
340− return ret;
341− }
342− return 0;
343−}
344−
345−int mgag200_mmap(struct file *filp, struct vm_area_struct *vma)
346−{
347− struct drm_file *file_priv = filp->private_data;
348− struct mga_device *mdev = file_priv->minor->dev->dev_private;
349−
350− return ttm_bo_mmap(filp, vma, &mdev->ttm.bdev);
351−}
drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c+2−4
@@ -694,14 +694,12 @@ end: · 693 unmodified lines
694694
695695 static void dpu_crtc_reset(struct drm_crtc *crtc)
696696 {
697− struct dpu_crtc_state *cstate;
697+ struct dpu_crtc_state *cstate = kzalloc(sizeof(*cstate), GFP_KERNEL);
698698
699699 if (crtc->state)
700700 dpu_crtc_destroy_state(crtc, crtc->state);
701701
702− crtc->state = kzalloc(sizeof(*cstate), GFP_KERNEL);
703− if (crtc->state)
704− crtc->state->crtc = crtc;
702+ __drm_atomic_helper_crtc_reset(crtc, &cstate->base);
705703 }
706704
707705 /**
drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c+6−3
@@ -1040,10 +1040,11 @@ int dpu_format_check_modified_format( · 1039 unmodified lines
10401040 const struct drm_mode_fb_cmd2 *cmd,
10411041 struct drm_gem_object **bos)
10421042 {
1043− int ret, i, num_base_fmt_planes;
1043+ const struct drm_format_info *info;
10441044 const struct dpu_format *fmt;
10451045 struct dpu_hw_fmt_layout layout;
10461046 uint32_t bos_total_size = 0;
1047+ int ret, i;
10471048
10481049 if (!msm_fmt || !cmd || !bos) {
10491050 DRM_ERROR("invalid arguments\n");
@@ -1051,14 +1052,16 @@ int dpu_format_check_modified_format( · 1 unmodified line
10511052 }
10521053
10531054 fmt = to_dpu_format(msm_fmt);
1054− num_base_fmt_planes = drm_format_num_planes(fmt->base.pixel_format);
1055+ info = drm_format_info(fmt->base.pixel_format);
1056+ if (!info)
1057+ return -EINVAL;
10551058
10561059 ret = dpu_format_get_plane_sizes(fmt, cmd->width, cmd->height,
10571060 &layout, cmd->pitches);
10581061 if (ret)
10591062 return ret;
10601063
1061− for (i = 0; i < num_base_fmt_planes; i++) {
1064+ for (i = 0; i < info->num_planes; i++) {
10621065 if (!bos[i]) {
10631066 DRM_ERROR("invalid handle for plane %d\n", i);
10641067 return -EINVAL;
drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c+2−7
@@ -557,14 +557,9 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, · 556 unmodified lines
557557 struct dpu_plane_state *pstate,
558558 const struct dpu_format *fmt, bool color_fill)
559559 {
560− uint32_t chroma_subsmpl_h, chroma_subsmpl_v;
560+ const struct drm_format_info *info = drm_format_info(fmt->base.pixel_format);
561561
562562 /* don't chroma subsample if decimating */
563− chroma_subsmpl_h =
564− drm_format_horz_chroma_subsampling(fmt->base.pixel_format);
565− chroma_subsmpl_v =
566− drm_format_vert_chroma_subsampling(fmt->base.pixel_format);
567−
568563 /* update scaler. calculate default config for QSEED3 */
569564 _dpu_plane_setup_scaler3(pdpu, pstate,
570565 drm_rect_width(&pdpu->pipe_cfg.src_rect),
@@ -572,7 +567,7 @@ static void _dpu_plane_setup_scaler(struct dpu_plane *pdpu, · 1 unmodified line
572567 drm_rect_width(&pdpu->pipe_cfg.dst_rect),
573568 drm_rect_height(&pdpu->pipe_cfg.dst_rect),
574569 &pstate->scaler3_cfg, fmt,
575− chroma_subsmpl_h, chroma_subsmpl_v);
570+ info->hsub, info->vsub);
576571 }
577572
578573 /**
drivers/gpu/drm/msm/disp/mdp5/mdp5_crtc.c+13−18
@@ -782,6 +782,7 @@ static void get_roi(struct drm_crtc *crtc, uint32_t *roi_w, uint32_t *roi_h) · 781 unmodified lines
782782
783783 static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc)
784784 {
785+ const struct drm_format_info *info = drm_format_info(DRM_FORMAT_ARGB8888);
785786 struct mdp5_crtc_state *mdp5_cstate = to_mdp5_crtc_state(crtc->state);
786787 struct mdp5_crtc *mdp5_crtc = to_mdp5_crtc(crtc);
787788 struct mdp5_kms *mdp5_kms = get_kms(crtc);
@@ -800,7 +801,7 @@ static void mdp5_crtc_restore_cursor(struct drm_crtc *crtc) · 12 unmodified lines
800801 width = mdp5_crtc->cursor.width;
801802 height = mdp5_crtc->cursor.height;
802803
803− stride = width * drm_format_plane_cpp(DRM_FORMAT_ARGB8888, 0);
804+ stride = width * info->cpp[0];
804805
805806 get_roi(crtc, &roi_w, &roi_h);
806807
@@ -1002,23 +1003,6 @@ mdp5_crtc_atomic_print_state(struct drm_printer *p, · 195 unmodified lines
10021003 drm_printf(p, "\tcmd_mode=%d\n", mdp5_cstate->cmd_mode);
10031004 }
10041005
1005−static void mdp5_crtc_reset(struct drm_crtc *crtc)
1006−{
1007− struct mdp5_crtc_state *mdp5_cstate;
1008−
1009− if (crtc->state) {
1010− __drm_atomic_helper_crtc_destroy_state(crtc->state);
1011− kfree(to_mdp5_crtc_state(crtc->state));
1012− }
1013−
1014− mdp5_cstate = kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL);
1015−
1016− if (mdp5_cstate) {
1017− mdp5_cstate->base.crtc = crtc;
1018− crtc->state = &mdp5_cstate->base;
1019− }
1020−}
1021−
10221006 static struct drm_crtc_state *
10231007 mdp5_crtc_duplicate_state(struct drm_crtc *crtc)
10241008 {
@@ -1046,6 +1030,17 @@ static void mdp5_crtc_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state · 21 unmodified lines
10461030 kfree(mdp5_cstate);
10471031 }
10481032
1033+static void mdp5_crtc_reset(struct drm_crtc *crtc)
1034+{
1035+ struct mdp5_crtc_state *mdp5_cstate =
1036+ kzalloc(sizeof(*mdp5_cstate), GFP_KERNEL);
1037+
1038+ if (crtc->state)
1039+ mdp5_crtc_destroy_state(crtc, crtc->state);
1040+
1041+ __drm_atomic_helper_crtc_reset(crtc, &mdp5_cstate->base);
1042+}
1043+
10491044 static const struct drm_crtc_funcs mdp5_crtc_funcs = {
10501045 .set_config = drm_atomic_helper_set_config,
10511046 .destroy = mdp5_crtc_destroy,
drivers/gpu/drm/msm/disp/mdp5/mdp5_plane.c+10−14
@@ -650,10 +650,10 @@ static int calc_scalex_steps(struct drm_plane *plane, · 649 unmodified lines
650650 uint32_t pixel_format, uint32_t src, uint32_t dest,
651651 uint32_t phasex_steps[COMP_MAX])
652652 {
653+ const struct drm_format_info *info = drm_format_info(pixel_format);
653654 struct mdp5_kms *mdp5_kms = get_kms(plane);
654655 struct device *dev = mdp5_kms->dev->dev;
655656 uint32_t phasex_step;
656− unsigned int hsub;
657657 int ret;
658658
659659 ret = calc_phase_step(src, dest, &phasex_step);
@@ -662,11 +662,9 @@ static int calc_scalex_steps(struct drm_plane *plane, · 2 unmodified lines
662662 return ret;
663663 }
664664
665− hsub = drm_format_horz_chroma_subsampling(pixel_format);
666−
667665 phasex_steps[COMP_0] = phasex_step;
668666 phasex_steps[COMP_3] = phasex_step;
669− phasex_steps[COMP_1_2] = phasex_step / hsub;
667+ phasex_steps[COMP_1_2] = phasex_step / info->hsub;
670668
671669 return 0;
672670 }
@@ -675,10 +673,10 @@ static int calc_scaley_steps(struct drm_plane *plane, · 2 unmodified lines
675673 uint32_t pixel_format, uint32_t src, uint32_t dest,
676674 uint32_t phasey_steps[COMP_MAX])
677675 {
676+ const struct drm_format_info *info = drm_format_info(pixel_format);
678677 struct mdp5_kms *mdp5_kms = get_kms(plane);
679678 struct device *dev = mdp5_kms->dev->dev;
680679 uint32_t phasey_step;
681− unsigned int vsub;
682680 int ret;
683681
684682 ret = calc_phase_step(src, dest, &phasey_step);
@@ -687,11 +685,9 @@ static int calc_scaley_steps(struct drm_plane *plane, · 2 unmodified lines
687685 return ret;
688686 }
689687
690− vsub = drm_format_vert_chroma_subsampling(pixel_format);
691−
692688 phasey_steps[COMP_0] = phasey_step;
693689 phasey_steps[COMP_3] = phasey_step;
694− phasey_steps[COMP_1_2] = phasey_step / vsub;
690+ phasey_steps[COMP_1_2] = phasey_step / info->vsub;
695691
696692 return 0;
697693 }
@@ -699,8 +695,9 @@ static int calc_scaley_steps(struct drm_plane *plane, · 1 unmodified line
699695 static uint32_t get_scale_config(const struct mdp_format *format,
700696 uint32_t src, uint32_t dst, bool horz)
701697 {
698+ const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
702699 bool scaling = format->is_yuv ? true : (src != dst);
703− uint32_t sub, pix_fmt = format->base.pixel_format;
700+ uint32_t sub;
704701 uint32_t ya_filter, uv_filter;
705702 bool yuv = format->is_yuv;
706703
@@ -708,8 +705,7 @@ static uint32_t get_scale_config(const struct mdp_format *format, · 1 unmodified line
708705 return 0;
709706
710707 if (yuv) {
711− sub = horz ? drm_format_horz_chroma_subsampling(pix_fmt) :
712− drm_format_vert_chroma_subsampling(pix_fmt);
708+ sub = horz ? info->hsub : info->vsub;
713709 uv_filter = ((src / sub) <= dst) ?
714710 SCALE_FILTER_BIL : SCALE_FILTER_PCMN;
715711 }
@@ -754,7 +750,7 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe, · 38 unmodified lines
754750 uint32_t src_w, int pe_left[COMP_MAX], int pe_right[COMP_MAX],
755751 uint32_t src_h, int pe_top[COMP_MAX], int pe_bottom[COMP_MAX])
756752 {
757− uint32_t pix_fmt = format->base.pixel_format;
753+ const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
758754 uint32_t lr, tb, req;
759755 int i;
760756
@@ -763,8 +759,8 @@ static void mdp5_write_pixel_ext(struct mdp5_kms *mdp5_kms, enum mdp5_pipe pipe, · 2 unmodified lines
763759 uint32_t roi_h = src_h;
764760
765761 if (format->is_yuv && i == COMP_1_2) {
766− roi_w /= drm_format_horz_chroma_subsampling(pix_fmt);
767− roi_h /= drm_format_vert_chroma_subsampling(pix_fmt);
762+ roi_w /= info->hsub;
763+ roi_h /= info->vsub;
768764 }
769765
770766 lr = (pe_left[i] >= 0) ?
drivers/gpu/drm/msm/disp/mdp5/mdp5_smp.c+4−3
@@ -127,14 +127,15 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp, · 126 unmodified lines
127127 const struct mdp_format *format,
128128 u32 width, bool hdecim)
129129 {
130+ const struct drm_format_info *info = drm_format_info(format->base.pixel_format);
130131 struct mdp5_kms *mdp5_kms = get_kms(smp);
131132 int rev = mdp5_cfg_get_hw_rev(mdp5_kms->cfg);
132133 int i, hsub, nplanes, nlines;
133134 u32 fmt = format->base.pixel_format;
134135 uint32_t blkcfg = 0;
135136
136− nplanes = drm_format_num_planes(fmt);
137− hsub = drm_format_horz_chroma_subsampling(fmt);
137+ nplanes = info->num_planes;
138+ hsub = info->hsub;
138139
139140 /* different if BWC (compressed framebuffer?) enabled: */
140141 nlines = 2;
@@ -157,7 +158,7 @@ uint32_t mdp5_smp_calculate(struct mdp5_smp *smp, · 16 unmodified lines
157158 for (i = 0; i < nplanes; i++) {
158159 int n, fetch_stride, cpp;
159160
160− cpp = drm_format_plane_cpp(fmt, i);
161+ cpp = info->cpp[i];
161162 fetch_stride = width * cpp / (i ? hsub : 1);
162163
163164 n = DIV_ROUND_UP(fetch_stride * nlines, smp->blk_size);
drivers/gpu/drm/msm/msm_fb.c+9−9
@@ -106,9 +106,11 @@ const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb) · 105 unmodified lines
106106 struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
107107 struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
108108 {
109+ const struct drm_format_info *info = drm_get_format_info(dev,
110+ mode_cmd);
109111 struct drm_gem_object *bos[4] = {0};
110112 struct drm_framebuffer *fb;
111− int ret, i, n = drm_format_num_planes(mode_cmd->pixel_format);
113+ int ret, i, n = info->num_planes;
112114
113115 for (i = 0; i < n; i++) {
114116 bos[i] = drm_gem_object_lookup(file, mode_cmd->handles[i]);
@@ -135,22 +137,20 @@ out_unref: · 20 unmodified lines
135137 static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
136138 const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
137139 {
140+ const struct drm_format_info *info = drm_get_format_info(dev,
141+ mode_cmd);
138142 struct msm_drm_private *priv = dev->dev_private;
139143 struct msm_kms *kms = priv->kms;
140144 struct msm_framebuffer *msm_fb = NULL;
141145 struct drm_framebuffer *fb;
142146 const struct msm_format *format;
143147 int ret, i, n;
144− unsigned int hsub, vsub;
145148
146149 DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
147150 dev, mode_cmd, mode_cmd->width, mode_cmd->height,
148151 (char *)&mode_cmd->pixel_format);
149152
150− n = drm_format_num_planes(mode_cmd->pixel_format);
151− hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
152− vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
153−
153+ n = info->num_planes;
154154 format = kms->funcs->get_format(kms, mode_cmd->pixel_format,
155155 mode_cmd->modifier[0]);
156156 if (!format) {
@@ -176,12 +176,12 @@ static struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev, · 19 unmodified lines
176176 }
177177
178178 for (i = 0; i < n; i++) {
179− unsigned int width = mode_cmd->width / (i ? hsub : 1);
180− unsigned int height = mode_cmd->height / (i ? vsub : 1);
179+ unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
180+ unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
181181 unsigned int min_size;
182182
183183 min_size = (height - 1) * mode_cmd->pitches[i]
184− + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
184+ + width * info->cpp[i]
185185 + mode_cmd->offsets[i];
186186
187187 if (bos[i]->size < min_size) {
drivers/gpu/drm/nouveau/dispnv50/head.c+3−10
@@ -420,16 +420,6 @@ nv50_head_atomic_duplicate_state(struct drm_crtc *crtc) · 419 unmodified lines
420420 return &asyh->state;
421421 }
422422
423−static void
424−__drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
425− struct drm_crtc_state *state)
426−{
427− if (crtc->state)
428− crtc->funcs->atomic_destroy_state(crtc, crtc->state);
429− crtc->state = state;
430− crtc->state->crtc = crtc;
431−}
432−
433423 static void
434424 nv50_head_reset(struct drm_crtc *crtc)
435425 {
@@ -438,6 +428,9 @@ nv50_head_reset(struct drm_crtc *crtc) · 2 unmodified lines
438428 if (WARN_ON(!(asyh = kzalloc(sizeof(*asyh), GFP_KERNEL))))
439429 return;
440430
431+ if (crtc->state)
432+ nv50_head_atomic_destroy_state(crtc, crtc->state);
433+
441434 __drm_atomic_helper_crtc_reset(crtc, &asyh->state);
442435 }
443436
drivers/gpu/drm/nouveau/nvkm/subdev/bus/nv04.c+0−2
@@ -26,8 +26,6 @@ · 25 unmodified lines
2626
2727 #include <subdev/gpio.h>
2828
29−#include <subdev/gpio.h>
30−
3129 static void
3230 nv04_bus_intr(struct nvkm_bus *bus)
3331 {
drivers/gpu/drm/omapdrm/omap_fb.c+4−2
@@ -298,7 +298,9 @@ void omap_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m) · 297 unmodified lines
298298 struct drm_framebuffer *omap_framebuffer_create(struct drm_device *dev,
299299 struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd)
300300 {
301− unsigned int num_planes = drm_format_num_planes(mode_cmd->pixel_format);
301+ const struct drm_format_info *info = drm_get_format_info(dev,
302+ mode_cmd);
303+ unsigned int num_planes = info->num_planes;
302304 struct drm_gem_object *bos[4];
303305 struct drm_framebuffer *fb;
304306 int i;
@@ -337,7 +339,7 @@ struct drm_framebuffer *omap_framebuffer_init(struct drm_device *dev, · 32 unmodified lines
337339 dev, mode_cmd, mode_cmd->width, mode_cmd->height,
338340 (char *)&mode_cmd->pixel_format);
339341
340− format = drm_format_info(mode_cmd->pixel_format);
342+ format = drm_get_format_info(dev, mode_cmd);
341343
342344 for (i = 0; i < ARRAY_SIZE(formats); i++) {
343345 if (formats[i] == mode_cmd->pixel_format)
drivers/gpu/drm/panel/Kconfig+18−0
@@ -132,6 +132,15 @@ config DRM_PANEL_ORISETECH_OTM8009A · 131 unmodified lines
132132 Say Y here if you want to enable support for Orise Technology
133133 otm8009a 480x800 dsi 2dl panel.
134134
135+config DRM_PANEL_OSD_OSD101T2587_53TS
136+ tristate "OSD OSD101T2587-53TS DSI 1920x1200 video mode panel"
137+ depends on OF
138+ depends on DRM_MIPI_DSI
139+ depends on BACKLIGHT_CLASS_DEVICE
140+ help
141+ Say Y here if you want to enable support for One Stop Displays
142+ OSD101T2587-53TS 10.1" 1920x1200 dsi panel.
143+
135144 config DRM_PANEL_PANASONIC_VVX10F034N00
136145 tristate "Panasonic VVX10F034N00 1920x1200 video mode panel"
137146 depends on OF
@@ -201,6 +210,15 @@ config DRM_PANEL_SAMSUNG_S6E63J0X03 · 63 unmodified lines
201210 depends on BACKLIGHT_CLASS_DEVICE
202211 select VIDEOMODE_HELPERS
203212
213+config DRM_PANEL_SAMSUNG_S6E63M0
214+ tristate "Samsung S6E63M0 RGB/SPI panel"
215+ depends on OF
216+ depends on SPI
217+ depends on BACKLIGHT_CLASS_DEVICE
218+ help
219+ Say Y here if you want to enable support for Samsung S6E63M0
220+ AMOLED LCD panel.
221+
204222 config DRM_PANEL_SAMSUNG_S6E8AA0
205223 tristate "Samsung S6E8AA0 DSI video mode panel"
206224 depends on OF
drivers/gpu/drm/panel/Makefile+2−0
@@ -11,6 +11,7 @@ obj-$(CONFIG_DRM_PANEL_KINGDISPLAY_KD097D04) += panel-kingdisplay-kd097d04.o · 10 unmodified lines
1111 obj-$(CONFIG_DRM_PANEL_LG_LG4573) += panel-lg-lg4573.o
1212 obj-$(CONFIG_DRM_PANEL_OLIMEX_LCD_OLINUXINO) += panel-olimex-lcd-olinuxino.o
1313 obj-$(CONFIG_DRM_PANEL_ORISETECH_OTM8009A) += panel-orisetech-otm8009a.o
14+obj-$(CONFIG_DRM_PANEL_OSD_OSD101T2587_53TS) += panel-osd-osd101t2587-53ts.o
1415 obj-$(CONFIG_DRM_PANEL_PANASONIC_VVX10F034N00) += panel-panasonic-vvx10f034n00.o
1516 obj-$(CONFIG_DRM_PANEL_RASPBERRYPI_TOUCHSCREEN) += panel-raspberrypi-touchscreen.o
1617 obj-$(CONFIG_DRM_PANEL_RAYDIUM_RM68200) += panel-raydium-rm68200.o
@@ -20,6 +21,7 @@ obj-$(CONFIG_DRM_PANEL_SAMSUNG_LD9040) += panel-samsung-ld9040.o · 3 unmodified lines
2021 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6D16D0) += panel-samsung-s6d16d0.o
2122 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E3HA2) += panel-samsung-s6e3ha2.o
2223 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63J0X03) += panel-samsung-s6e63j0x03.o
24+obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E63M0) += panel-samsung-s6e63m0.o
2325 obj-$(CONFIG_DRM_PANEL_SAMSUNG_S6E8AA0) += panel-samsung-s6e8aa0.o
2426 obj-$(CONFIG_DRM_PANEL_SEIKO_43WVF1G) += panel-seiko-43wvf1g.o
2527 obj-$(CONFIG_DRM_PANEL_SHARP_LQ101R1SX01) += panel-sharp-lq101r1sx01.o
drivers/gpu/drm/panel/panel-osd-osd101t2587-53ts.c+254−0
@@ -0,0 +1,254 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com
4+ * Author: Peter Ujfalusi <peter.ujfalusi@ti.com>
5+ */
6+
7+#include <linux/backlight.h>
8+#include <linux/module.h>
9+#include <linux/of.h>
10+#include <linux/regulator/consumer.h>
11+
12+#include <drm/drm_crtc.h>
13+#include <drm/drm_device.h>
14+#include <drm/drm_mipi_dsi.h>
15+#include <drm/drm_panel.h>
16+
17+#include <video/mipi_display.h>
18+
19+struct osd101t2587_panel {
20+ struct drm_panel base;
21+ struct mipi_dsi_device *dsi;
22+
23+ struct backlight_device *backlight;
24+ struct regulator *supply;
25+
26+ bool prepared;
27+ bool enabled;
28+
29+ const struct drm_display_mode *default_mode;
30+};
31+
32+static inline struct osd101t2587_panel *ti_osd_panel(struct drm_panel *panel)
33+{
34+ return container_of(panel, struct osd101t2587_panel, base);
35+}
36+
37+static int osd101t2587_panel_disable(struct drm_panel *panel)
38+{
39+ struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
40+ int ret;
41+
42+ if (!osd101t2587->enabled)
43+ return 0;
44+
45+ backlight_disable(osd101t2587->backlight);
46+
47+ ret = mipi_dsi_shutdown_peripheral(osd101t2587->dsi);
48+
49+ osd101t2587->enabled = false;
50+
51+ return ret;
52+}
53+
54+static int osd101t2587_panel_unprepare(struct drm_panel *panel)
55+{
56+ struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
57+
58+ if (!osd101t2587->prepared)
59+ return 0;
60+
61+ regulator_disable(osd101t2587->supply);
62+ osd101t2587->prepared = false;
63+
64+ return 0;
65+}
66+
67+static int osd101t2587_panel_prepare(struct drm_panel *panel)
68+{
69+ struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
70+ int ret;
71+
72+ if (osd101t2587->prepared)
73+ return 0;
74+
75+ ret = regulator_enable(osd101t2587->supply);
76+ if (!ret)
77+ osd101t2587->prepared = true;
78+
79+ return ret;
80+}
81+
82+static int osd101t2587_panel_enable(struct drm_panel *panel)
83+{
84+ struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
85+ int ret;
86+
87+ if (osd101t2587->enabled)
88+ return 0;
89+
90+ ret = mipi_dsi_turn_on_peripheral(osd101t2587->dsi);
91+ if (ret)
92+ return ret;
93+
94+ backlight_enable(osd101t2587->backlight);
95+
96+ osd101t2587->enabled = true;
97+
98+ return ret;
99+}
100+
101+static const struct drm_display_mode default_mode_osd101t2587 = {
102+ .clock = 164400,
103+ .hdisplay = 1920,
104+ .hsync_start = 1920 + 152,
105+ .hsync_end = 1920 + 152 + 52,
106+ .htotal = 1920 + 152 + 52 + 20,
107+ .vdisplay = 1200,
108+ .vsync_start = 1200 + 24,
109+ .vsync_end = 1200 + 24 + 6,
110+ .vtotal = 1200 + 24 + 6 + 48,
111+ .vrefresh = 60,
112+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
113+};
114+
115+static int osd101t2587_panel_get_modes(struct drm_panel *panel)
116+{
117+ struct osd101t2587_panel *osd101t2587 = ti_osd_panel(panel);
118+ struct drm_display_mode *mode;
119+
120+ mode = drm_mode_duplicate(panel->drm, osd101t2587->default_mode);
121+ if (!mode) {
122+ dev_err(panel->drm->dev, "failed to add mode %ux%ux@%u\n",
123+ osd101t2587->default_mode->hdisplay,
124+ osd101t2587->default_mode->vdisplay,
125+ osd101t2587->default_mode->vrefresh);
126+ return -ENOMEM;
127+ }
128+
129+ drm_mode_set_name(mode);
130+
131+ drm_mode_probed_add(panel->connector, mode);
132+
133+ panel->connector->display_info.width_mm = 217;
134+ panel->connector->display_info.height_mm = 136;
135+
136+ return 1;
137+}
138+
139+static const struct drm_panel_funcs osd101t2587_panel_funcs = {
140+ .disable = osd101t2587_panel_disable,
141+ .unprepare = osd101t2587_panel_unprepare,
142+ .prepare = osd101t2587_panel_prepare,
143+ .enable = osd101t2587_panel_enable,
144+ .get_modes = osd101t2587_panel_get_modes,
145+};
146+
147+static const struct of_device_id osd101t2587_of_match[] = {
148+ {
149+ .compatible = "osddisplays,osd101t2587-53ts",
150+ .data = &default_mode_osd101t2587,
151+ }, {
152+ /* sentinel */
153+ }
154+};
155+MODULE_DEVICE_TABLE(of, osd101t2587_of_match);
156+
157+static int osd101t2587_panel_add(struct osd101t2587_panel *osd101t2587)
158+{
159+ struct device *dev = &osd101t2587->dsi->dev;
160+
161+ osd101t2587->supply = devm_regulator_get(dev, "power");
162+ if (IS_ERR(osd101t2587->supply))
163+ return PTR_ERR(osd101t2587->supply);
164+
165+ osd101t2587->backlight = devm_of_find_backlight(dev);
166+ if (IS_ERR(osd101t2587->backlight))
167+ return PTR_ERR(osd101t2587->backlight);
168+
169+ drm_panel_init(&osd101t2587->base);
170+ osd101t2587->base.funcs = &osd101t2587_panel_funcs;
171+ osd101t2587->base.dev = &osd101t2587->dsi->dev;
172+
173+ return drm_panel_add(&osd101t2587->base);
174+}
175+
176+static int osd101t2587_panel_probe(struct mipi_dsi_device *dsi)
177+{
178+ struct osd101t2587_panel *osd101t2587;
179+ const struct of_device_id *id;
180+ int ret;
181+
182+ id = of_match_node(osd101t2587_of_match, dsi->dev.of_node);
183+ if (!id)
184+ return -ENODEV;
185+
186+ dsi->lanes = 4;
187+ dsi->format = MIPI_DSI_FMT_RGB888;
188+ dsi->mode_flags = MIPI_DSI_MODE_VIDEO |
189+ MIPI_DSI_MODE_VIDEO_BURST |
190+ MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
191+ MIPI_DSI_MODE_EOT_PACKET;
192+
193+ osd101t2587 = devm_kzalloc(&dsi->dev, sizeof(*osd101t2587), GFP_KERNEL);
194+ if (!osd101t2587)
195+ return -ENOMEM;
196+
197+ mipi_dsi_set_drvdata(dsi, osd101t2587);
198+
199+ osd101t2587->dsi = dsi;
200+ osd101t2587->default_mode = id->data;
201+
202+ ret = osd101t2587_panel_add(osd101t2587);
203+ if (ret < 0)
204+ return ret;
205+
206+ ret = mipi_dsi_attach(dsi);
207+ if (ret)
208+ drm_panel_remove(&osd101t2587->base);
209+
210+ return ret;
211+}
212+
213+static int osd101t2587_panel_remove(struct mipi_dsi_device *dsi)
214+{
215+ struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
216+ int ret;
217+
218+ ret = osd101t2587_panel_disable(&osd101t2587->base);
219+ if (ret < 0)
220+ dev_warn(&dsi->dev, "failed to disable panel: %d\n", ret);
221+
222+ osd101t2587_panel_unprepare(&osd101t2587->base);
223+
224+ drm_panel_remove(&osd101t2587->base);
225+
226+ ret = mipi_dsi_detach(dsi);
227+ if (ret < 0)
228+ dev_err(&dsi->dev, "failed to detach from DSI host: %d\n", ret);
229+
230+ return ret;
231+}
232+
233+static void osd101t2587_panel_shutdown(struct mipi_dsi_device *dsi)
234+{
235+ struct osd101t2587_panel *osd101t2587 = mipi_dsi_get_drvdata(dsi);
236+
237+ osd101t2587_panel_disable(&osd101t2587->base);
238+ osd101t2587_panel_unprepare(&osd101t2587->base);
239+}
240+
241+static struct mipi_dsi_driver osd101t2587_panel_driver = {
242+ .driver = {
243+ .name = "panel-osd-osd101t2587-53ts",
244+ .of_match_table = osd101t2587_of_match,
245+ },
246+ .probe = osd101t2587_panel_probe,
247+ .remove = osd101t2587_panel_remove,
248+ .shutdown = osd101t2587_panel_shutdown,
249+};
250+module_mipi_dsi_driver(osd101t2587_panel_driver);
251+
252+MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
253+MODULE_DESCRIPTION("OSD101T2587-53TS DSI panel");
254+MODULE_LICENSE("GPL v2");
drivers/gpu/drm/panel/panel-raspberrypi-touchscreen.c+0−1
@@ -57,7 +57,6 @@ · 56 unmodified lines
5757 #include <drm/drmP.h>
5858 #include <drm/drm_crtc.h>
5959 #include <drm/drm_mipi_dsi.h>
60−#include <drm/drm_panel.h>
6160
6261 #define RPI_DSI_DRIVER_NAME "rpi-ts-dsi"
6362
drivers/gpu/drm/panel/panel-samsung-s6e63m0.c+514−0
@@ -0,0 +1,514 @@
1+// SPDX-License-Identifier: GPL-2.0
2+/*
3+ * S6E63M0 AMOLED LCD drm_panel driver.
4+ *
5+ * Copyright (C) 2019 Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>
6+ * Derived from drivers/gpu/drm/panel-samsung-ld9040.c
7+ *
8+ * Andrzej Hajda <a.hajda@samsung.com>
9+ */
10+
11+#include <drm/drm_modes.h>
12+#include <drm/drm_panel.h>
13+#include <drm/drm_print.h>
14+
15+#include <linux/backlight.h>
16+#include <linux/delay.h>
17+#include <linux/gpio/consumer.h>
18+#include <linux/module.h>
19+#include <linux/regulator/consumer.h>
20+#include <linux/spi/spi.h>
21+
22+#include <video/mipi_display.h>
23+
24+/* Manufacturer Command Set */
25+#define MCS_ELVSS_ON 0xb1
26+#define MCS_MIECTL1 0xc0
27+#define MCS_BCMODE 0xc1
28+#define MCS_DISCTL 0xf2
29+#define MCS_SRCCTL 0xf6
30+#define MCS_IFCTL 0xf7
31+#define MCS_PANELCTL 0xF8
32+#define MCS_PGAMMACTL 0xfa
33+
34+#define NUM_GAMMA_LEVELS 11
35+#define GAMMA_TABLE_COUNT 23
36+
37+#define DATA_MASK 0x100
38+
39+#define MAX_BRIGHTNESS (NUM_GAMMA_LEVELS - 1)
40+
41+/* array of gamma tables for gamma value 2.2 */
42+static u8 const s6e63m0_gamma_22[NUM_GAMMA_LEVELS][GAMMA_TABLE_COUNT] = {
43+ { MCS_PGAMMACTL, 0x00,
44+ 0x18, 0x08, 0x24, 0x78, 0xEC, 0x3D, 0xC8,
45+ 0xC2, 0xB6, 0xC4, 0xC7, 0xB6, 0xD5, 0xD7,
46+ 0xCC, 0x00, 0x39, 0x00, 0x36, 0x00, 0x51 },
47+ { MCS_PGAMMACTL, 0x00,
48+ 0x18, 0x08, 0x24, 0x73, 0x4A, 0x3D, 0xC0,
49+ 0xC2, 0xB1, 0xBB, 0xBE, 0xAC, 0xCE, 0xCF,
50+ 0xC5, 0x00, 0x5D, 0x00, 0x5E, 0x00, 0x82 },
51+ { MCS_PGAMMACTL, 0x00,
52+ 0x18, 0x08, 0x24, 0x70, 0x51, 0x3E, 0xBF,
53+ 0xC1, 0xAF, 0xB9, 0xBC, 0xAB, 0xCC, 0xCC,
54+ 0xC2, 0x00, 0x65, 0x00, 0x67, 0x00, 0x8D },
55+ { MCS_PGAMMACTL, 0x00,
56+ 0x18, 0x08, 0x24, 0x6C, 0x54, 0x3A, 0xBC,
57+ 0xBF, 0xAC, 0xB7, 0xBB, 0xA9, 0xC9, 0xC9,
58+ 0xBE, 0x00, 0x71, 0x00, 0x73, 0x00, 0x9E },
59+ { MCS_PGAMMACTL, 0x00,
60+ 0x18, 0x08, 0x24, 0x69, 0x54, 0x37, 0xBB,
61+ 0xBE, 0xAC, 0xB4, 0xB7, 0xA6, 0xC7, 0xC8,
62+ 0xBC, 0x00, 0x7B, 0x00, 0x7E, 0x00, 0xAB },
63+ { MCS_PGAMMACTL, 0x00,
64+ 0x18, 0x08, 0x24, 0x66, 0x55, 0x34, 0xBA,
65+ 0xBD, 0xAB, 0xB1, 0xB5, 0xA3, 0xC5, 0xC6,
66+ 0xB9, 0x00, 0x85, 0x00, 0x88, 0x00, 0xBA },
67+ { MCS_PGAMMACTL, 0x00,
68+ 0x18, 0x08, 0x24, 0x63, 0x53, 0x31, 0xB8,
69+ 0xBC, 0xA9, 0xB0, 0xB5, 0xA2, 0xC4, 0xC4,
70+ 0xB8, 0x00, 0x8B, 0x00, 0x8E, 0x00, 0xC2 },
71+ { MCS_PGAMMACTL, 0x00,
72+ 0x18, 0x08, 0x24, 0x62, 0x54, 0x30, 0xB9,
73+ 0xBB, 0xA9, 0xB0, 0xB3, 0xA1, 0xC1, 0xC3,
74+ 0xB7, 0x00, 0x91, 0x00, 0x95, 0x00, 0xDA },
75+ { MCS_PGAMMACTL, 0x00,
76+ 0x18, 0x08, 0x24, 0x66, 0x58, 0x34, 0xB6,
77+ 0xBA, 0xA7, 0xAF, 0xB3, 0xA0, 0xC1, 0xC2,
78+ 0xB7, 0x00, 0x97, 0x00, 0x9A, 0x00, 0xD1 },
79+ { MCS_PGAMMACTL, 0x00,
80+ 0x18, 0x08, 0x24, 0x64, 0x56, 0x33, 0xB6,
81+ 0xBA, 0xA8, 0xAC, 0xB1, 0x9D, 0xC1, 0xC1,
82+ 0xB7, 0x00, 0x9C, 0x00, 0x9F, 0x00, 0xD6 },
83+ { MCS_PGAMMACTL, 0x00,
84+ 0x18, 0x08, 0x24, 0x5f, 0x50, 0x2d, 0xB6,
85+ 0xB9, 0xA7, 0xAd, 0xB1, 0x9f, 0xbe, 0xC0,
86+ 0xB5, 0x00, 0xa0, 0x00, 0xa4, 0x00, 0xdb },
87+};
88+
89+struct s6e63m0 {
90+ struct device *dev;
91+ struct drm_panel panel;
92+ struct backlight_device *bl_dev;
93+
94+ struct regulator_bulk_data supplies[2];
95+ struct gpio_desc *reset_gpio;
96+
97+ bool prepared;
98+ bool enabled;
99+
100+ /*
101+ * This field is tested by functions directly accessing bus before
102+ * transfer, transfer is skipped if it is set. In case of transfer
103+ * failure or unexpected response the field is set to error value.
104+ * Such construct allows to eliminate many checks in higher level
105+ * functions.
106+ */
107+ int error;
108+};
109+
110+static const struct drm_display_mode default_mode = {
111+ .clock = 25628,
112+ .hdisplay = 480,
113+ .hsync_start = 480 + 16,
114+ .hsync_end = 480 + 16 + 2,
115+ .htotal = 480 + 16 + 2 + 16,
116+ .vdisplay = 800,
117+ .vsync_start = 800 + 28,
118+ .vsync_end = 800 + 28 + 2,
119+ .vtotal = 800 + 28 + 2 + 1,
120+ .vrefresh = 60,
121+ .width_mm = 53,
122+ .height_mm = 89,
123+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
124+};
125+
126+static inline struct s6e63m0 *panel_to_s6e63m0(struct drm_panel *panel)
127+{
128+ return container_of(panel, struct s6e63m0, panel);
129+}
130+
131+static int s6e63m0_clear_error(struct s6e63m0 *ctx)
132+{
133+ int ret = ctx->error;
134+
135+ ctx->error = 0;
136+ return ret;
137+}
138+
139+static int s6e63m0_spi_write_word(struct s6e63m0 *ctx, u16 data)
140+{
141+ struct spi_device *spi = to_spi_device(ctx->dev);
142+ struct spi_transfer xfer = {
143+ .len = 2,
144+ .tx_buf = &data,
145+ };
146+ struct spi_message msg;
147+
148+ spi_message_init(&msg);
149+ spi_message_add_tail(&xfer, &msg);
150+
151+ return spi_sync(spi, &msg);
152+}
153+
154+static void s6e63m0_dcs_write(struct s6e63m0 *ctx, const u8 *data, size_t len)
155+{
156+ int ret = 0;
157+
158+ if (ctx->error < 0 || len == 0)
159+ return;
160+
161+ DRM_DEV_DEBUG(ctx->dev, "writing dcs seq: %*ph\n", (int)len, data);
162+ ret = s6e63m0_spi_write_word(ctx, *data);
163+
164+ while (!ret && --len) {
165+ ++data;
166+ ret = s6e63m0_spi_write_word(ctx, *data | DATA_MASK);
167+ }
168+
169+ if (ret) {
170+ DRM_DEV_ERROR(ctx->dev, "error %d writing dcs seq: %*ph\n", ret,
171+ (int)len, data);
172+ ctx->error = ret;
173+ }
174+
175+ usleep_range(300, 310);
176+}
177+
178+#define s6e63m0_dcs_write_seq_static(ctx, seq ...) \
179+ ({ \
180+ static const u8 d[] = { seq }; \
181+ s6e63m0_dcs_write(ctx, d, ARRAY_SIZE(d)); \
182+ })
183+
184+static void s6e63m0_init(struct s6e63m0 *ctx)
185+{
186+ s6e63m0_dcs_write_seq_static(ctx, MCS_PANELCTL,
187+ 0x01, 0x27, 0x27, 0x07, 0x07, 0x54, 0x9f,
188+ 0x63, 0x86, 0x1a, 0x33, 0x0d, 0x00, 0x00);
189+
190+ s6e63m0_dcs_write_seq_static(ctx, MCS_DISCTL,
191+ 0x02, 0x03, 0x1c, 0x10, 0x10);
192+ s6e63m0_dcs_write_seq_static(ctx, MCS_IFCTL,
193+ 0x03, 0x00, 0x00);
194+
195+ s6e63m0_dcs_write_seq_static(ctx, MCS_PGAMMACTL,
196+ 0x00, 0x18, 0x08, 0x24, 0x64, 0x56, 0x33,
197+ 0xb6, 0xba, 0xa8, 0xac, 0xb1, 0x9d, 0xc1,
198+ 0xc1, 0xb7, 0x00, 0x9c, 0x00, 0x9f, 0x00,
199+ 0xd6);
200+ s6e63m0_dcs_write_seq_static(ctx, MCS_PGAMMACTL,
201+ 0x01);
202+
203+ s6e63m0_dcs_write_seq_static(ctx, MCS_SRCCTL,
204+ 0x00, 0x8c, 0x07);
205+ s6e63m0_dcs_write_seq_static(ctx, 0xb3,
206+ 0xc);
207+
208+ s6e63m0_dcs_write_seq_static(ctx, 0xb5,
209+ 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17,
210+ 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b,
211+ 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a,
212+ 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23,
213+ 0x21, 0x20, 0x1e, 0x1e);
214+
215+ s6e63m0_dcs_write_seq_static(ctx, 0xb6,
216+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44,
217+ 0x44, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66,
218+ 0x66, 0x66);
219+
220+ s6e63m0_dcs_write_seq_static(ctx, 0xb7,
221+ 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17,
222+ 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b,
223+ 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a,
224+ 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23,
225+ 0x21, 0x20, 0x1e, 0x1e, 0x00, 0x00, 0x11,
226+ 0x22, 0x33, 0x44, 0x44, 0x44, 0x55, 0x55,
227+ 0x66, 0x66, 0x66, 0x66, 0x66, 0x66);
228+
229+ s6e63m0_dcs_write_seq_static(ctx, 0xb9,
230+ 0x2c, 0x12, 0x0c, 0x0a, 0x10, 0x0e, 0x17,
231+ 0x13, 0x1f, 0x1a, 0x2a, 0x24, 0x1f, 0x1b,
232+ 0x1a, 0x17, 0x2b, 0x26, 0x22, 0x20, 0x3a,
233+ 0x34, 0x30, 0x2c, 0x29, 0x26, 0x25, 0x23,
234+ 0x21, 0x20, 0x1e, 0x1e);
235+
236+ s6e63m0_dcs_write_seq_static(ctx, 0xba,
237+ 0x00, 0x00, 0x11, 0x22, 0x33, 0x44, 0x44,
238+ 0x44, 0x55, 0x55, 0x66, 0x66, 0x66, 0x66,
239+ 0x66, 0x66);
240+
241+ s6e63m0_dcs_write_seq_static(ctx, MCS_BCMODE,
242+ 0x4d, 0x96, 0x1d, 0x00, 0x00, 0x01, 0xdf,
243+ 0x00, 0x00, 0x03, 0x1f, 0x00, 0x00, 0x00,
244+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x06,
245+ 0x09, 0x0d, 0x0f, 0x12, 0x15, 0x18);
246+
247+ s6e63m0_dcs_write_seq_static(ctx, 0xb2,
248+ 0x10, 0x10, 0x0b, 0x05);
249+
250+ s6e63m0_dcs_write_seq_static(ctx, MCS_MIECTL1,
251+ 0x01);
252+
253+ s6e63m0_dcs_write_seq_static(ctx, MCS_ELVSS_ON,
254+ 0x0b);
255+
256+ s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_EXIT_SLEEP_MODE);
257+}
258+
259+static int s6e63m0_power_on(struct s6e63m0 *ctx)
260+{
261+ int ret;
262+
263+ ret = regulator_bulk_enable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
264+ if (ret < 0)
265+ return ret;
266+
267+ msleep(25);
268+
269+ gpiod_set_value(ctx->reset_gpio, 0);
270+ msleep(120);
271+
272+ return 0;
273+}
274+
275+static int s6e63m0_power_off(struct s6e63m0 *ctx)
276+{
277+ int ret;
278+
279+ gpiod_set_value(ctx->reset_gpio, 1);
280+ msleep(120);
281+
282+ ret = regulator_bulk_disable(ARRAY_SIZE(ctx->supplies), ctx->supplies);
283+ if (ret < 0)
284+ return ret;
285+
286+ return 0;
287+}
288+
289+static int s6e63m0_disable(struct drm_panel *panel)
290+{
291+ struct s6e63m0 *ctx = panel_to_s6e63m0(panel);
292+
293+ if (!ctx->enabled)
294+ return 0;
295+
296+ backlight_disable(ctx->bl_dev);
297+
298+ s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_ENTER_SLEEP_MODE);
299+ msleep(200);
300+
301+ ctx->enabled = false;
302+
303+ return 0;
304+}
305+
306+static int s6e63m0_unprepare(struct drm_panel *panel)
307+{
308+ struct s6e63m0 *ctx = panel_to_s6e63m0(panel);
309+ int ret;
310+
311+ if (!ctx->prepared)
312+ return 0;
313+
314+ s6e63m0_clear_error(ctx);
315+
316+ ret = s6e63m0_power_off(ctx);
317+ if (ret < 0)
318+ return ret;
319+
320+ ctx->prepared = false;
321+
322+ return 0;
323+}
324+
325+static int s6e63m0_prepare(struct drm_panel *panel)
326+{
327+ struct s6e63m0 *ctx = panel_to_s6e63m0(panel);
328+ int ret;
329+
330+ if (ctx->prepared)
331+ return 0;
332+
333+ ret = s6e63m0_power_on(ctx);
334+ if (ret < 0)
335+ return ret;
336+
337+ s6e63m0_init(ctx);
338+
339+ ret = s6e63m0_clear_error(ctx);
340+
341+ if (ret < 0)
342+ s6e63m0_unprepare(panel);
343+
344+ ctx->prepared = true;
345+
346+ return ret;
347+}
348+
349+static int s6e63m0_enable(struct drm_panel *panel)
350+{
351+ struct s6e63m0 *ctx = panel_to_s6e63m0(panel);
352+
353+ if (ctx->enabled)
354+ return 0;
355+
356+ s6e63m0_dcs_write_seq_static(ctx, MIPI_DCS_SET_DISPLAY_ON);
357+
358+ backlight_enable(ctx->bl_dev);
359+
360+ ctx->enabled = true;
361+
362+ return 0;
363+}
364+
365+static int s6e63m0_get_modes(struct drm_panel *panel)
366+{
367+ struct drm_connector *connector = panel->connector;
368+ struct drm_display_mode *mode;
369+
370+ mode = drm_mode_duplicate(panel->drm, &default_mode);
371+ if (!mode) {
372+ DRM_ERROR("failed to add mode %ux%ux@%u\n",
373+ default_mode.hdisplay, default_mode.vdisplay,
374+ default_mode.vrefresh);
375+ return -ENOMEM;
376+ }
377+
378+ drm_mode_set_name(mode);
379+
380+ mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;
381+ drm_mode_probed_add(connector, mode);
382+
383+ return 1;
384+}
385+
386+static const struct drm_panel_funcs s6e63m0_drm_funcs = {
387+ .disable = s6e63m0_disable,
388+ .unprepare = s6e63m0_unprepare,
389+ .prepare = s6e63m0_prepare,
390+ .enable = s6e63m0_enable,
391+ .get_modes = s6e63m0_get_modes,
392+};
393+
394+static int s6e63m0_set_brightness(struct backlight_device *bd)
395+{
396+ struct s6e63m0 *ctx = bl_get_data(bd);
397+
398+ int brightness = bd->props.brightness;
399+
400+ /* disable and set new gamma */
401+ s6e63m0_dcs_write(ctx, s6e63m0_gamma_22[brightness],
402+ ARRAY_SIZE(s6e63m0_gamma_22[brightness]));
403+
404+ /* update gamma table. */
405+ s6e63m0_dcs_write_seq_static(ctx, MCS_PGAMMACTL, 0x01);
406+
407+ return s6e63m0_clear_error(ctx);
408+}
409+
410+static const struct backlight_ops s6e63m0_backlight_ops = {
411+ .update_status = s6e63m0_set_brightness,
412+};
413+
414+static int s6e63m0_backlight_register(struct s6e63m0 *ctx)
415+{
416+ struct backlight_properties props = {
417+ .type = BACKLIGHT_RAW,
418+ .brightness = MAX_BRIGHTNESS,
419+ .max_brightness = MAX_BRIGHTNESS
420+ };
421+ struct device *dev = ctx->dev;
422+ int ret = 0;
423+
424+ ctx->bl_dev = devm_backlight_device_register(dev, "panel", dev, ctx,
425+ &s6e63m0_backlight_ops,
426+ &props);
427+ if (IS_ERR(ctx->bl_dev)) {
428+ ret = PTR_ERR(ctx->bl_dev);
429+ DRM_DEV_ERROR(dev, "error registering backlight device (%d)\n",
430+ ret);
431+ }
432+
433+ return ret;
434+}
435+
436+static int s6e63m0_probe(struct spi_device *spi)
437+{
438+ struct device *dev = &spi->dev;
439+ struct s6e63m0 *ctx;
440+ int ret;
441+
442+ ctx = devm_kzalloc(dev, sizeof(struct s6e63m0), GFP_KERNEL);
443+ if (!ctx)
444+ return -ENOMEM;
445+
446+ spi_set_drvdata(spi, ctx);
447+
448+ ctx->dev = dev;
449+ ctx->enabled = false;
450+ ctx->prepared = false;
451+
452+ ctx->supplies[0].supply = "vdd3";
453+ ctx->supplies[1].supply = "vci";
454+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(ctx->supplies),
455+ ctx->supplies);
456+ if (ret < 0) {
457+ DRM_DEV_ERROR(dev, "failed to get regulators: %d\n", ret);
458+ return ret;
459+ }
460+
461+ ctx->reset_gpio = devm_gpiod_get(dev, "reset", GPIOD_OUT_HIGH);
462+ if (IS_ERR(ctx->reset_gpio)) {
463+ DRM_DEV_ERROR(dev, "cannot get reset-gpios %ld\n",
464+ PTR_ERR(ctx->reset_gpio));
465+ return PTR_ERR(ctx->reset_gpio);
466+ }
467+
468+ spi->bits_per_word = 9;
469+ spi->mode = SPI_MODE_3;
470+ ret = spi_setup(spi);
471+ if (ret < 0) {
472+ DRM_DEV_ERROR(dev, "spi setup failed.\n");
473+ return ret;
474+ }
475+
476+ drm_panel_init(&ctx->panel);
477+ ctx->panel.dev = dev;
478+ ctx->panel.funcs = &s6e63m0_drm_funcs;
479+
480+ ret = s6e63m0_backlight_register(ctx);
481+ if (ret < 0)
482+ return ret;
483+
484+ return drm_panel_add(&ctx->panel);
485+}
486+
487+static int s6e63m0_remove(struct spi_device *spi)
488+{
489+ struct s6e63m0 *ctx = spi_get_drvdata(spi);
490+
491+ drm_panel_remove(&ctx->panel);
492+
493+ return 0;
494+}
495+
496+static const struct of_device_id s6e63m0_of_match[] = {
497+ { .compatible = "samsung,s6e63m0" },
498+ { /* sentinel */ }
499+};
500+MODULE_DEVICE_TABLE(of, s6e63m0_of_match);
501+
502+static struct spi_driver s6e63m0_driver = {
503+ .probe = s6e63m0_probe,
504+ .remove = s6e63m0_remove,
505+ .driver = {
506+ .name = "panel-samsung-s6e63m0",
507+ .of_match_table = s6e63m0_of_match,
508+ },
509+};
510+module_spi_driver(s6e63m0_driver);
511+
512+MODULE_AUTHOR("Paweł Chmiel <pawel.mikolaj.chmiel@gmail.com>");
513+MODULE_DESCRIPTION("s6e63m0 LCD Driver");
514+MODULE_LICENSE("GPL v2");
drivers/gpu/drm/panel/panel-simple.c+211−1
@@ -1096,6 +1096,56 @@ static const struct panel_desc dlc_dlc1010gig = { · 1095 unmodified lines
10961096 .bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG,
10971097 };
10981098
1099+static const struct drm_display_mode edt_et035012dm6_mode = {
1100+ .clock = 6500,
1101+ .hdisplay = 320,
1102+ .hsync_start = 320 + 20,
1103+ .hsync_end = 320 + 20 + 30,
1104+ .htotal = 320 + 20 + 68,
1105+ .vdisplay = 240,
1106+ .vsync_start = 240 + 4,
1107+ .vsync_end = 240 + 4 + 4,
1108+ .vtotal = 240 + 4 + 4 + 14,
1109+ .vrefresh = 60,
1110+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1111+};
1112+
1113+static const struct panel_desc edt_et035012dm6 = {
1114+ .modes = &edt_et035012dm6_mode,
1115+ .num_modes = 1,
1116+ .bpc = 8,
1117+ .size = {
1118+ .width = 70,
1119+ .height = 52,
1120+ },
1121+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1122+ .bus_flags = DRM_BUS_FLAG_DE_LOW | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
1123+};
1124+
1125+static const struct drm_display_mode edt_etm0430g0dh6_mode = {
1126+ .clock = 9000,
1127+ .hdisplay = 480,
1128+ .hsync_start = 480 + 2,
1129+ .hsync_end = 480 + 2 + 41,
1130+ .htotal = 480 + 2 + 41 + 2,
1131+ .vdisplay = 272,
1132+ .vsync_start = 272 + 2,
1133+ .vsync_end = 272 + 2 + 10,
1134+ .vtotal = 272 + 2 + 10 + 2,
1135+ .vrefresh = 60,
1136+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
1137+};
1138+
1139+static const struct panel_desc edt_etm0430g0dh6 = {
1140+ .modes = &edt_etm0430g0dh6_mode,
1141+ .num_modes = 1,
1142+ .bpc = 6,
1143+ .size = {
1144+ .width = 95,
1145+ .height = 54,
1146+ },
1147+};
1148+
10991149 static const struct drm_display_mode edt_et057090dhu_mode = {
11001150 .clock = 25175,
11011151 .hdisplay = 640,
@@ -1160,6 +1210,33 @@ static const struct panel_desc edt_etm0700g0bdh6 = { · 58 unmodified lines
11601210 .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,
11611211 };
11621212
1213+static const struct display_timing evervision_vgg804821_timing = {
1214+ .pixelclock = { 27600000, 33300000, 50000000 },
1215+ .hactive = { 800, 800, 800 },
1216+ .hfront_porch = { 40, 66, 70 },
1217+ .hback_porch = { 40, 67, 70 },
1218+ .hsync_len = { 40, 67, 70 },
1219+ .vactive = { 480, 480, 480 },
1220+ .vfront_porch = { 6, 10, 10 },
1221+ .vback_porch = { 7, 11, 11 },
1222+ .vsync_len = { 7, 11, 11 },
1223+ .flags = DISPLAY_FLAGS_HSYNC_HIGH | DISPLAY_FLAGS_VSYNC_HIGH |
1224+ DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
1225+ DISPLAY_FLAGS_SYNC_NEGEDGE,
1226+};
1227+
1228+static const struct panel_desc evervision_vgg804821 = {
1229+ .timings = &evervision_vgg804821_timing,
1230+ .num_timings = 1,
1231+ .bpc = 8,
1232+ .size = {
1233+ .width = 108,
1234+ .height = 64,
1235+ },
1236+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
1237+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_NEGEDGE,
1238+};
1239+
11631240 static const struct drm_display_mode foxlink_fl500wvr00_a0t_mode = {
11641241 .clock = 32260,
11651242 .hdisplay = 800,
@@ -1184,6 +1261,29 @@ static const struct panel_desc foxlink_fl500wvr00_a0t = { · 18 unmodified lines
11841261 .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
11851262 };
11861263
1264+static const struct drm_display_mode friendlyarm_hd702e_mode = {
1265+ .clock = 67185,
1266+ .hdisplay = 800,
1267+ .hsync_start = 800 + 20,
1268+ .hsync_end = 800 + 20 + 24,
1269+ .htotal = 800 + 20 + 24 + 20,
1270+ .vdisplay = 1280,
1271+ .vsync_start = 1280 + 4,
1272+ .vsync_end = 1280 + 4 + 8,
1273+ .vtotal = 1280 + 4 + 8 + 4,
1274+ .vrefresh = 60,
1275+ .flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
1276+};
1277+
1278+static const struct panel_desc friendlyarm_hd702e = {
1279+ .modes = &friendlyarm_hd702e_mode,
1280+ .num_modes = 1,
1281+ .size = {
1282+ .width = 94,
1283+ .height = 151,
1284+ },
1285+};
1286+
11871287 static const struct drm_display_mode giantplus_gpg482739qs5_mode = {
11881288 .clock = 9000,
11891289 .hdisplay = 480,
@@ -2355,6 +2455,31 @@ static const struct panel_desc starry_kr122ea0sra = { · 1165 unmodified lines
23552455 },
23562456 };
23572457
2458+static const struct drm_display_mode tfc_s9700rtwv43tr_01b_mode = {
2459+ .clock = 30000,
2460+ .hdisplay = 800,
2461+ .hsync_start = 800 + 39,
2462+ .hsync_end = 800 + 39 + 47,
2463+ .htotal = 800 + 39 + 47 + 39,
2464+ .vdisplay = 480,
2465+ .vsync_start = 480 + 13,
2466+ .vsync_end = 480 + 13 + 2,
2467+ .vtotal = 480 + 13 + 2 + 29,
2468+ .vrefresh = 62,
2469+};
2470+
2471+static const struct panel_desc tfc_s9700rtwv43tr_01b = {
2472+ .modes = &tfc_s9700rtwv43tr_01b_mode,
2473+ .num_modes = 1,
2474+ .bpc = 8,
2475+ .size = {
2476+ .width = 155,
2477+ .height = 90,
2478+ },
2479+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
2480+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
2481+};
2482+
23582483 static const struct display_timing tianma_tm070jdhg30_timing = {
23592484 .pixelclock = { 62600000, 68200000, 78100000 },
23602485 .hactive = { 1280, 1280, 1280 },
@@ -2508,6 +2633,32 @@ static const struct panel_desc urt_umsh_8596md_parallel = { · 147 unmodified lines
25082633 .bus_format = MEDIA_BUS_FMT_RGB666_1X18,
25092634 };
25102635
2636+static const struct drm_display_mode vl050_8048nt_c01_mode = {
2637+ .clock = 33333,
2638+ .hdisplay = 800,
2639+ .hsync_start = 800 + 210,
2640+ .hsync_end = 800 + 210 + 20,
2641+ .htotal = 800 + 210 + 20 + 46,
2642+ .vdisplay = 480,
2643+ .vsync_start = 480 + 22,
2644+ .vsync_end = 480 + 22 + 10,
2645+ .vtotal = 480 + 22 + 10 + 23,
2646+ .vrefresh = 60,
2647+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
2648+};
2649+
2650+static const struct panel_desc vl050_8048nt_c01 = {
2651+ .modes = &vl050_8048nt_c01_mode,
2652+ .num_modes = 1,
2653+ .bpc = 8,
2654+ .size = {
2655+ .width = 120,
2656+ .height = 76,
2657+ },
2658+ .bus_format = MEDIA_BUS_FMT_RGB888_1X24,
2659+ .bus_flags = DRM_BUS_FLAG_DE_HIGH | DRM_BUS_FLAG_PIXDATA_POSEDGE,
2660+};
2661+
25112662 static const struct drm_display_mode winstar_wf35ltiacd_mode = {
25122663 .clock = 6410,
25132664 .hdisplay = 320,
@@ -2645,6 +2796,12 @@ static const struct of_device_id platform_of_match[] = { · 131 unmodified lines
26452796 }, {
26462797 .compatible = "dlc,dlc1010gig",
26472798 .data = &dlc_dlc1010gig,
2799+ }, {
2800+ .compatible = "edt,et035012dm6",
2801+ .data = &edt_et035012dm6,
2802+ }, {
2803+ .compatible = "edt,etm0430g0dh6",
2804+ .data = &edt_etm0430g0dh6,
26482805 }, {
26492806 .compatible = "edt,et057090dhu",
26502807 .data = &edt_et057090dhu,
@@ -2660,9 +2817,15 @@ static const struct of_device_id platform_of_match[] = { · 9 unmodified lines
26602817 }, {
26612818 .compatible = "edt,etm0700g0edh6",
26622819 .data = &edt_etm0700g0bdh6,
2820+ }, {
2821+ .compatible = "evervision,vgg804821",
2822+ .data = &evervision_vgg804821,
26632823 }, {
26642824 .compatible = "foxlink,fl500wvr00-a0t",
26652825 .data = &foxlink_fl500wvr00_a0t,
2826+ }, {
2827+ .compatible = "friendlyarm,hd702e",
2828+ .data = &friendlyarm_hd702e,
26662829 }, {
26672830 .compatible = "giantplus,gpg482739qs5",
26682831 .data = &giantplus_gpg482739qs5
@@ -2801,6 +2964,9 @@ static const struct of_device_id platform_of_match[] = { · 132 unmodified lines
28012964 }, {
28022965 .compatible = "starry,kr122ea0sra",
28032966 .data = &starry_kr122ea0sra,
2967+ }, {
2968+ .compatible = "tfc,s9700rtwv43tr-01b",
2969+ .data = &tfc_s9700rtwv43tr_01b,
28042970 }, {
28052971 .compatible = "tianma,tm070jdhg30",
28062972 .data = &tianma_tm070jdhg30,
@@ -2834,6 +3000,9 @@ static const struct of_device_id platform_of_match[] = { · 27 unmodified lines
28343000 }, {
28353001 .compatible = "urt,umsh-8596md-20t",
28363002 .data = &urt_umsh_8596md_parallel,
3003+ }, {
3004+ .compatible = "vxt,vl050-8048nt-c01",
3005+ .data = &vl050_8048nt_c01,
28373006 }, {
28383007 .compatible = "winstar,wf35ltiacd",
28393008 .data = &winstar_wf35ltiacd,
@@ -3053,6 +3222,37 @@ static const struct panel_desc_dsi lg_acx467akm_7 = { · 213 unmodified lines
30533222 .lanes = 4,
30543223 };
30553224
3225+static const struct drm_display_mode osd101t2045_53ts_mode = {
3226+ .clock = 154500,
3227+ .hdisplay = 1920,
3228+ .hsync_start = 1920 + 112,
3229+ .hsync_end = 1920 + 112 + 16,
3230+ .htotal = 1920 + 112 + 16 + 32,
3231+ .vdisplay = 1200,
3232+ .vsync_start = 1200 + 16,
3233+ .vsync_end = 1200 + 16 + 2,
3234+ .vtotal = 1200 + 16 + 2 + 16,
3235+ .vrefresh = 60,
3236+ .flags = DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC,
3237+};
3238+
3239+static const struct panel_desc_dsi osd101t2045_53ts = {
3240+ .desc = {
3241+ .modes = &osd101t2045_53ts_mode,
3242+ .num_modes = 1,
3243+ .bpc = 8,
3244+ .size = {
3245+ .width = 217,
3246+ .height = 136,
3247+ },
3248+ },
3249+ .flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_BURST |
3250+ MIPI_DSI_MODE_VIDEO_SYNC_PULSE |
3251+ MIPI_DSI_MODE_EOT_PACKET,
3252+ .format = MIPI_DSI_FMT_RGB888,
3253+ .lanes = 4,
3254+};
3255+
30563256 static const struct of_device_id dsi_of_match[] = {
30573257 {
30583258 .compatible = "auo,b080uan01",
@@ -3072,6 +3272,9 @@ static const struct of_device_id dsi_of_match[] = { · 13 unmodified lines
30723272 }, {
30733273 .compatible = "lg,acx467akm-7",
30743274 .data = &lg_acx467akm_7
3275+ }, {
3276+ .compatible = "osddisplays,osd101t2045-53ts",
3277+ .data = &osd101t2045_53ts
30753278 }, {
30763279 /* sentinel */
30773280 }
@@ -3098,7 +3301,14 @@ static int panel_simple_dsi_probe(struct mipi_dsi_device *dsi) · 20 unmodified lines
30983301 dsi->format = desc->format;
30993302 dsi->lanes = desc->lanes;
31003303
3101− return mipi_dsi_attach(dsi);
3304+ err = mipi_dsi_attach(dsi);
3305+ if (err) {
3306+ struct panel_simple *panel = dev_get_drvdata(&dsi->dev);
3307+
3308+ drm_panel_remove(&panel->base);
3309+ }
3310+
3311+ return err;
31023312 }
31033313
31043314 static int panel_simple_dsi_remove(struct mipi_dsi_device *dsi)
drivers/gpu/drm/panfrost/panfrost_device.c+22−0
@@ -55,11 +55,33 @@ static int panfrost_clk_init(struct panfrost_device *pfdev) · 54 unmodified lines
5555 if (err)
5656 return err;
5757
58+ pfdev->bus_clock = devm_clk_get_optional(pfdev->dev, "bus");
59+ if (IS_ERR(pfdev->bus_clock)) {
60+ dev_err(pfdev->dev, "get bus_clock failed %ld\n",
61+ PTR_ERR(pfdev->bus_clock));
62+ return PTR_ERR(pfdev->bus_clock);
63+ }
64+
65+ if (pfdev->bus_clock) {
66+ rate = clk_get_rate(pfdev->bus_clock);
67+ dev_info(pfdev->dev, "bus_clock rate = %lu\n", rate);
68+
69+ err = clk_prepare_enable(pfdev->bus_clock);
70+ if (err)
71+ goto disable_clock;
72+ }
73+
5874 return 0;
75+
76+disable_clock:
77+ clk_disable_unprepare(pfdev->clock);
78+
79+ return err;
5980 }
6081
6182 static void panfrost_clk_fini(struct panfrost_device *pfdev)
6283 {
84+ clk_disable_unprepare(pfdev->bus_clock);
6385 clk_disable_unprepare(pfdev->clock);
6486 }
6587
drivers/gpu/drm/panfrost/panfrost_device.h+1−0
@@ -66,6 +66,7 @@ struct panfrost_device { · 65 unmodified lines
6666
6767 void __iomem *iomem;
6868 struct clk *clock;
69+ struct clk *bus_clock;
6970 struct regulator *regulator;
7071 struct reset_control *rstc;
7172
drivers/gpu/drm/panfrost/panfrost_job.c+1−1
@@ -387,7 +387,7 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job) · 386 unmodified lines
387387 mutex_lock(&pfdev->reset_lock);
388388
389389 for (i = 0; i < NUM_JOB_SLOTS; i++)
390− drm_sched_stop(&pfdev->js->queue[i].sched);
390+ drm_sched_stop(&pfdev->js->queue[i].sched, sched_job);
391391
392392 if (sched_job)
393393 drm_sched_increase_karma(sched_job);
drivers/gpu/drm/radeon/radeon_fb.c+3−1
@@ -125,6 +125,7 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, · 124 unmodified lines
125125 struct drm_mode_fb_cmd2 *mode_cmd,
126126 struct drm_gem_object **gobj_p)
127127 {
128+ const struct drm_format_info *info;
128129 struct radeon_device *rdev = rfbdev->rdev;
129130 struct drm_gem_object *gobj = NULL;
130131 struct radeon_bo *rbo = NULL;
@@ -135,7 +136,8 @@ static int radeonfb_create_pinned_object(struct radeon_fbdev *rfbdev, · 4 unmodified lines
135136 int height = mode_cmd->height;
136137 u32 cpp;
137138
138− cpp = drm_format_plane_cpp(mode_cmd->pixel_format, 0);
139+ info = drm_get_format_info(rdev->ddev, mode_cmd);
140+ cpp = info->cpp[0];
139141
140142 /* need to align pitch with crtc limits */
141143 mode_cmd->pitches[0] = radeon_align_pitch(rdev, mode_cmd->width, cpp,
drivers/gpu/drm/rockchip/rockchip_drm_fb.c+6−11
@@ -74,23 +74,18 @@ static struct drm_framebuffer * · 73 unmodified lines
7474 rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
7575 const struct drm_mode_fb_cmd2 *mode_cmd)
7676 {
77+ const struct drm_format_info *info = drm_get_format_info(dev,
78+ mode_cmd);
7779 struct drm_framebuffer *fb;
7880 struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
7981 struct drm_gem_object *obj;
80− unsigned int hsub;
81− unsigned int vsub;
82− int num_planes;
82+ int num_planes = min_t(int, info->num_planes, ROCKCHIP_MAX_FB_BUFFER);
8383 int ret;
8484 int i;
8585
86− hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
87− vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
88− num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
89− ROCKCHIP_MAX_FB_BUFFER);
90−
9186 for (i = 0; i < num_planes; i++) {
92− unsigned int width = mode_cmd->width / (i ? hsub : 1);
93− unsigned int height = mode_cmd->height / (i ? vsub : 1);
87+ unsigned int width = mode_cmd->width / (i ? info->hsub : 1);
88+ unsigned int height = mode_cmd->height / (i ? info->vsub : 1);
9489 unsigned int min_size;
9590
9691 obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
@@ -103,7 +98,7 @@ rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, · 6 unmodified lines
10398
10499 min_size = (height - 1) * mode_cmd->pitches[i] +
105100 mode_cmd->offsets[i] +
106− width * drm_format_plane_cpp(mode_cmd->pixel_format, i);
101+ width * info->cpp[i];
107102
108103 if (obj->size < min_size) {
109104 drm_gem_object_put_unlocked(obj);
drivers/gpu/drm/rockchip/rockchip_drm_vop.c+17−22
@@ -315,24 +315,19 @@ static uint16_t scl_vop_cal_scale(enum scale_mode mode, uint32_t src, · 314 unmodified lines
315315
316316 static void scl_vop_cal_scl_fac(struct vop *vop, const struct vop_win_data *win,
317317 uint32_t src_w, uint32_t src_h, uint32_t dst_w,
318− uint32_t dst_h, uint32_t pixel_format)
318+ uint32_t dst_h, const struct drm_format_info *info)
319319 {
320320 uint16_t yrgb_hor_scl_mode, yrgb_ver_scl_mode;
321321 uint16_t cbcr_hor_scl_mode = SCALE_NONE;
322322 uint16_t cbcr_ver_scl_mode = SCALE_NONE;
323− int hsub = drm_format_horz_chroma_subsampling(pixel_format);
324− int vsub = drm_format_vert_chroma_subsampling(pixel_format);
325− const struct drm_format_info *info;
326323 bool is_yuv = false;
327− uint16_t cbcr_src_w = src_w / hsub;
328− uint16_t cbcr_src_h = src_h / vsub;
324+ uint16_t cbcr_src_w = src_w / info->hsub;
325+ uint16_t cbcr_src_h = src_h / info->vsub;
329326 uint16_t vsu_mode;
330327 uint16_t lb_mode;
331328 uint32_t val;
332329 int vskiplines;
333330
334− info = drm_format_info(pixel_format);
335−
336331 if (info->is_yuv)
337332 is_yuv = true;
338333
@@ -831,8 +826,8 @@ static void vop_plane_atomic_update(struct drm_plane *plane, · 492 unmodified lines
831826 (state->rotation & DRM_MODE_REFLECT_X) ? 1 : 0);
832827
833828 if (is_yuv) {
834− int hsub = drm_format_horz_chroma_subsampling(fb->format->format);
835− int vsub = drm_format_vert_chroma_subsampling(fb->format->format);
829+ int hsub = fb->format->hsub;
830+ int vsub = fb->format->vsub;
836831 int bpp = fb->format->cpp[1];
837832
838833 uv_obj = fb->obj[1];
@@ -856,7 +851,7 @@ static void vop_plane_atomic_update(struct drm_plane *plane, · 17 unmodified lines
856851 if (win->phy->scl)
857852 scl_vop_cal_scl_fac(vop, win, actual_w, actual_h,
858853 drm_rect_width(dest), drm_rect_height(dest),
859− fb->format->format);
854+ fb->format);
860855
861856 VOP_WIN_SET(vop, win, act_info, act_info);
862857 VOP_WIN_SET(vop, win, dsp_info, dsp_info);
@@ -1222,17 +1217,6 @@ static void vop_crtc_destroy(struct drm_crtc *crtc) · 359 unmodified lines
12221217 drm_crtc_cleanup(crtc);
12231218 }
12241219
1225−static void vop_crtc_reset(struct drm_crtc *crtc)
1226−{
1227− if (crtc->state)
1228− __drm_atomic_helper_crtc_destroy_state(crtc->state);
1229− kfree(crtc->state);
1230−
1231− crtc->state = kzalloc(sizeof(struct rockchip_crtc_state), GFP_KERNEL);
1232− if (crtc->state)
1233− crtc->state->crtc = crtc;
1234−}
1235−
12361220 static struct drm_crtc_state *vop_crtc_duplicate_state(struct drm_crtc *crtc)
12371221 {
12381222 struct rockchip_crtc_state *rockchip_state;
@@ -1254,6 +1238,17 @@ static void vop_crtc_destroy_state(struct drm_crtc *crtc, · 15 unmodified lines
12541238 kfree(s);
12551239 }
12561240
1241+static void vop_crtc_reset(struct drm_crtc *crtc)
1242+{
1243+ struct rockchip_crtc_state *crtc_state =
1244+ kzalloc(sizeof(*crtc_state), GFP_KERNEL);
1245+
1246+ if (crtc->state)
1247+ vop_crtc_destroy_state(crtc, crtc->state);
1248+
1249+ __drm_atomic_helper_crtc_reset(crtc, &crtc_state->base);
1250+}
1251+
12571252 #ifdef CONFIG_DRM_ANALOGIX_DP
12581253 static struct drm_connector *vop_get_edp_connector(struct vop *vop)
12591254 {
drivers/gpu/drm/scheduler/sched_main.c+108−66
@@ -265,32 +265,6 @@ void drm_sched_resume_timeout(struct drm_gpu_scheduler *sched, · 264 unmodified lines
265265 }
266266 EXPORT_SYMBOL(drm_sched_resume_timeout);
267267
268−/* job_finish is called after hw fence signaled
269− */
270−static void drm_sched_job_finish(struct work_struct *work)
271−{
272− struct drm_sched_job *s_job = container_of(work, struct drm_sched_job,
273− finish_work);
274− struct drm_gpu_scheduler *sched = s_job->sched;
275− unsigned long flags;
276−
277− /*
278− * Canceling the timeout without removing our job from the ring mirror
279− * list is safe, as we will only end up in this worker if our jobs
280− * finished fence has been signaled. So even if some another worker
281− * manages to find this job as the next job in the list, the fence
282− * signaled check below will prevent the timeout to be restarted.
283− */
284− cancel_delayed_work_sync(&sched->work_tdr);
285−
286− spin_lock_irqsave(&sched->job_list_lock, flags);
287− /* queue TDR for next job */
288− drm_sched_start_timeout(sched);
289− spin_unlock_irqrestore(&sched->job_list_lock, flags);
290−
291− sched->ops->free_job(s_job);
292−}
293−
294268 static void drm_sched_job_begin(struct drm_sched_job *s_job)
295269 {
296270 struct drm_gpu_scheduler *sched = s_job->sched;
@@ -315,6 +289,15 @@ static void drm_sched_job_timedout(struct work_struct *work) · 18 unmodified lines
315289 if (job)
316290 job->sched->ops->timedout_job(job);
317291
292+ /*
293+ * Guilty job did complete and hence needs to be manually removed
294+ * See drm_sched_stop doc.
295+ */
296+ if (sched->free_guilty) {
297+ job->sched->ops->free_job(job);
298+ sched->free_guilty = false;
299+ }
300+
318301 spin_lock_irqsave(&sched->job_list_lock, flags);
319302 drm_sched_start_timeout(sched);
320303 spin_unlock_irqrestore(&sched->job_list_lock, flags);
@@ -370,40 +353,66 @@ EXPORT_SYMBOL(drm_sched_increase_karma); · 49 unmodified lines
370353 *
371354 * @sched: scheduler instance
372355 *
356+ * Stop the scheduler and also removes and frees all completed jobs.
357+ * Note: bad job will not be freed as it might be used later and so it's
358+ * callers responsibility to release it manually if it's not part of the
359+ * mirror list any more.
360+ *
373361 */
374−void drm_sched_stop(struct drm_gpu_scheduler *sched)
362+void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad)
375363 {
376− struct drm_sched_job *s_job;
364+ struct drm_sched_job *s_job, *tmp;
377365 unsigned long flags;
378− struct dma_fence *last_fence = NULL;
379366
380367 kthread_park(sched->thread);
381368
382369 /*
383− * Verify all the signaled jobs in mirror list are removed from the ring
384− * by waiting for the latest job to enter the list. This should insure that
385− * also all the previous jobs that were in flight also already singaled
386− * and removed from the list.
370+ * Iterate the job list from later to earlier one and either deactive
371+ * their HW callbacks or remove them from mirror list if they already
372+ * signaled.
373+ * This iteration is thread safe as sched thread is stopped.
387374 */
388− spin_lock_irqsave(&sched->job_list_lock, flags);
389− list_for_each_entry_reverse(s_job, &sched->ring_mirror_list, node) {
375+ list_for_each_entry_safe_reverse(s_job, tmp, &sched->ring_mirror_list, node) {
390376 if (s_job->s_fence->parent &&
391377 dma_fence_remove_callback(s_job->s_fence->parent,
392378 &s_job->cb)) {
393− dma_fence_put(s_job->s_fence->parent);
394− s_job->s_fence->parent = NULL;
395379 atomic_dec(&sched->hw_rq_count);
396380 } else {
397− last_fence = dma_fence_get(&s_job->s_fence->finished);
398− break;
381+ /*
382+ * remove job from ring_mirror_list.
383+ * Locking here is for concurrent resume timeout
384+ */
385+ spin_lock_irqsave(&sched->job_list_lock, flags);
386+ list_del_init(&s_job->node);
387+ spin_unlock_irqrestore(&sched->job_list_lock, flags);
388+
389+ /*
390+ * Wait for job's HW fence callback to finish using s_job
391+ * before releasing it.
392+ *
393+ * Job is still alive so fence refcount at least 1
394+ */
395+ dma_fence_wait(&s_job->s_fence->finished, false);
396+
397+ /*
398+ * We must keep bad job alive for later use during
399+ * recovery by some of the drivers but leave a hint
400+ * that the guilty job must be released.
401+ */
402+ if (bad != s_job)
403+ sched->ops->free_job(s_job);
404+ else
405+ sched->free_guilty = true;
399406 }
400407 }
401− spin_unlock_irqrestore(&sched->job_list_lock, flags);
402408
403− if (last_fence) {
404− dma_fence_wait(last_fence, false);
405− dma_fence_put(last_fence);
406− }
409+ /*
410+ * Stop pending timer in flight as we rearm it in drm_sched_start. This
411+ * avoids the pending timeout work in progress to fire right away after
412+ * this TDR finished and before the newly restarted jobs had a
413+ * chance to complete.
414+ */
415+ cancel_delayed_work(&sched->work_tdr);
407416 }
408417
409418 EXPORT_SYMBOL(drm_sched_stop);
@@ -417,21 +426,22 @@ EXPORT_SYMBOL(drm_sched_stop); · 7 unmodified lines
417426 void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery)
418427 {
419428 struct drm_sched_job *s_job, *tmp;
429+ unsigned long flags;
420430 int r;
421431
422− if (!full_recovery)
423− goto unpark;
424−
425432 /*
426433 * Locking the list is not required here as the sched thread is parked
427− * so no new jobs are being pushed in to HW and in drm_sched_stop we
428− * flushed all the jobs who were still in mirror list but who already
429− * signaled and removed them self from the list. Also concurrent
434+ * so no new jobs are being inserted or removed. Also concurrent
430435 * GPU recovers can't run in parallel.
431436 */
432437 list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
433438 struct dma_fence *fence = s_job->s_fence->parent;
434439
440+ atomic_inc(&sched->hw_rq_count);
441+
442+ if (!full_recovery)
443+ continue;
444+
435445 if (fence) {
436446 r = dma_fence_add_callback(fence, &s_job->cb,
437447 drm_sched_process_job);
@@ -444,9 +454,12 @@ void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery) · 6 unmodified lines
444454 drm_sched_process_job(NULL, &s_job->cb);
445455 }
446456
447− drm_sched_start_timeout(sched);
457+ if (full_recovery) {
458+ spin_lock_irqsave(&sched->job_list_lock, flags);
459+ drm_sched_start_timeout(sched);
460+ spin_unlock_irqrestore(&sched->job_list_lock, flags);
461+ }
448462
449−unpark:
450463 kthread_unpark(sched->thread);
451464 }
452465 EXPORT_SYMBOL(drm_sched_start);
@@ -463,7 +476,6 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) · 10 unmodified lines
463476 uint64_t guilty_context;
464477 bool found_guilty = false;
465478
466− /*TODO DO we need spinlock here ? */
467479 list_for_each_entry_safe(s_job, tmp, &sched->ring_mirror_list, node) {
468480 struct drm_sched_fence *s_fence = s_job->s_fence;
469481
@@ -475,8 +487,8 @@ void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched) · 5 unmodified lines
475487 if (found_guilty && s_job->s_fence->scheduled.context == guilty_context)
476488 dma_fence_set_error(&s_fence->finished, -ECANCELED);
477489
490+ dma_fence_put(s_job->s_fence->parent);
478491 s_job->s_fence->parent = sched->ops->run_job(s_job);
479− atomic_inc(&sched->hw_rq_count);
480492 }
481493 }
482494 EXPORT_SYMBOL(drm_sched_resubmit_jobs);
@@ -513,7 +525,6 @@ int drm_sched_job_init(struct drm_sched_job *job, · 30 unmodified lines
513525 return -ENOMEM;
514526 job->id = atomic64_inc_return(&sched->job_id_count);
515527
516− INIT_WORK(&job->finish_work, drm_sched_job_finish);
517528 INIT_LIST_HEAD(&job->node);
518529
519530 return 0;
@@ -596,24 +607,54 @@ static void drm_sched_process_job(struct dma_fence *f, struct dma_fence_cb *cb) · 76 unmodified lines
596607 struct drm_sched_job *s_job = container_of(cb, struct drm_sched_job, cb);
597608 struct drm_sched_fence *s_fence = s_job->s_fence;
598609 struct drm_gpu_scheduler *sched = s_fence->sched;
599− unsigned long flags;
600−
601− cancel_delayed_work(&sched->work_tdr);
602610
603611 atomic_dec(&sched->hw_rq_count);
604612 atomic_dec(&sched->num_jobs);
605613
606− spin_lock_irqsave(&sched->job_list_lock, flags);
607− /* remove job from ring_mirror_list */
608− list_del_init(&s_job->node);
609− spin_unlock_irqrestore(&sched->job_list_lock, flags);
614+ trace_drm_sched_process_job(s_fence);
610615
611616 drm_sched_fence_finished(s_fence);
612−
613− trace_drm_sched_process_job(s_fence);
614617 wake_up_interruptible(&sched->wake_up_worker);
618+}
619+
620+/**
621+ * drm_sched_cleanup_jobs - destroy finished jobs
622+ *
623+ * @sched: scheduler instance
624+ *
625+ * Remove all finished jobs from the mirror list and destroy them.
626+ */
627+static void drm_sched_cleanup_jobs(struct drm_gpu_scheduler *sched)
628+{
629+ unsigned long flags;
630+
631+ /* Don't destroy jobs while the timeout worker is running */
632+ if (sched->timeout != MAX_SCHEDULE_TIMEOUT &&
633+ !cancel_delayed_work(&sched->work_tdr))
634+ return;
635+
636+
637+ while (!list_empty(&sched->ring_mirror_list)) {
638+ struct drm_sched_job *job;
639+
640+ job = list_first_entry(&sched->ring_mirror_list,
641+ struct drm_sched_job, node);
642+ if (!dma_fence_is_signaled(&job->s_fence->finished))
643+ break;
644+
645+ spin_lock_irqsave(&sched->job_list_lock, flags);
646+ /* remove job from ring_mirror_list */
647+ list_del_init(&job->node);
648+ spin_unlock_irqrestore(&sched->job_list_lock, flags);
649+
650+ sched->ops->free_job(job);
651+ }
652+
653+ /* queue timeout for next job */
654+ spin_lock_irqsave(&sched->job_list_lock, flags);
655+ drm_sched_start_timeout(sched);
656+ spin_unlock_irqrestore(&sched->job_list_lock, flags);
615657
616− schedule_work(&s_job->finish_work);
617658 }
618659
619660 /**
@@ -655,9 +696,10 @@ static int drm_sched_main(void *param) · 35 unmodified lines
655696 struct dma_fence *fence;
656697
657698 wait_event_interruptible(sched->wake_up_worker,
699+ (drm_sched_cleanup_jobs(sched),
658700 (!drm_sched_blocked(sched) &&
659701 (entity = drm_sched_select_entity(sched))) ||
660− kthread_should_stop());
702+ kthread_should_stop()));
661703
662704 if (!entity)
663705 continue;
drivers/gpu/drm/stm/dw_mipi_dsi-stm.c+49−11
@@ -9,6 +9,7 @@ · 8 unmodified lines
99 #include <linux/clk.h>
1010 #include <linux/iopoll.h>
1111 #include <linux/module.h>
12+#include <linux/regulator/consumer.h>
1213 #include <drm/drmP.h>
1314 #include <drm/drm_mipi_dsi.h>
1415 #include <drm/bridge/dw_mipi_dsi.h>
@@ -76,6 +77,7 @@ struct dw_mipi_dsi_stm { · 61 unmodified lines
7677 u32 hw_version;
7778 int lane_min_kbps;
7879 int lane_max_kbps;
80+ struct regulator *vdd_supply;
7981 };
8082
8183 static inline void dsi_write(struct dw_mipi_dsi_stm *dsi, u32 reg, u32 val)
@@ -314,21 +316,36 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) · 232 unmodified lines
314316 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
315317 dsi->base = devm_ioremap_resource(dev, res);
316318 if (IS_ERR(dsi->base)) {
317− DRM_ERROR("Unable to get dsi registers\n");
318− return PTR_ERR(dsi->base);
319+ ret = PTR_ERR(dsi->base);
320+ DRM_ERROR("Unable to get dsi registers %d\n", ret);
321+ return ret;
322+ }
323+
324+ dsi->vdd_supply = devm_regulator_get(dev, "phy-dsi");
325+ if (IS_ERR(dsi->vdd_supply)) {
326+ ret = PTR_ERR(dsi->vdd_supply);
327+ if (ret != -EPROBE_DEFER)
328+ DRM_ERROR("Failed to request regulator: %d\n", ret);
329+ return ret;
330+ }
331+
332+ ret = regulator_enable(dsi->vdd_supply);
333+ if (ret) {
334+ DRM_ERROR("Failed to enable regulator: %d\n", ret);
335+ return ret;
319336 }
320337
321338 dsi->pllref_clk = devm_clk_get(dev, "ref");
322339 if (IS_ERR(dsi->pllref_clk)) {
323340 ret = PTR_ERR(dsi->pllref_clk);
324− dev_err(dev, "Unable to get pll reference clock: %d\n", ret);
325− return ret;
341+ DRM_ERROR("Unable to get pll reference clock: %d\n", ret);
342+ goto err_clk_get;
326343 }
327344
328345 ret = clk_prepare_enable(dsi->pllref_clk);
329346 if (ret) {
330− dev_err(dev, "%s: Failed to enable pllref_clk\n", __func__);
331− return ret;
347+ DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
348+ goto err_clk_get;
332349 }
333350
334351 dw_mipi_dsi_stm_plat_data.base = dsi->base;
@@ -338,20 +355,28 @@ static int dw_mipi_dsi_stm_probe(struct platform_device *pdev) · 3 unmodified lines
338355
339356 dsi->dsi = dw_mipi_dsi_probe(pdev, &dw_mipi_dsi_stm_plat_data);
340357 if (IS_ERR(dsi->dsi)) {
341− DRM_ERROR("Failed to initialize mipi dsi host\n");
342− clk_disable_unprepare(dsi->pllref_clk);
343− return PTR_ERR(dsi->dsi);
358+ ret = PTR_ERR(dsi->dsi);
359+ DRM_ERROR("Failed to initialize mipi dsi host: %d\n", ret);
360+ goto err_dsi_probe;
344361 }
345362
346363 return 0;
364+
365+err_dsi_probe:
366+ clk_disable_unprepare(dsi->pllref_clk);
367+err_clk_get:
368+ regulator_disable(dsi->vdd_supply);
369+
370+ return ret;
347371 }
348372
349373 static int dw_mipi_dsi_stm_remove(struct platform_device *pdev)
350374 {
351375 struct dw_mipi_dsi_stm *dsi = platform_get_drvdata(pdev);
352376
353− clk_disable_unprepare(dsi->pllref_clk);
354377 dw_mipi_dsi_remove(dsi->dsi);
378+ clk_disable_unprepare(dsi->pllref_clk);
379+ regulator_disable(dsi->vdd_supply);
355380
356381 return 0;
357382 }
@@ -363,6 +388,7 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev) · 5 unmodified lines
363388 DRM_DEBUG_DRIVER("\n");
364389
365390 clk_disable_unprepare(dsi->pllref_clk);
391+ regulator_disable(dsi->vdd_supply);
366392
367393 return 0;
368394 }
@@ -370,10 +396,22 @@ static int __maybe_unused dw_mipi_dsi_stm_suspend(struct device *dev) · 1 unmodified line
370396 static int __maybe_unused dw_mipi_dsi_stm_resume(struct device *dev)
371397 {
372398 struct dw_mipi_dsi_stm *dsi = dw_mipi_dsi_stm_plat_data.priv_data;
399+ int ret;
373400
374401 DRM_DEBUG_DRIVER("\n");
375402
376− clk_prepare_enable(dsi->pllref_clk);
403+ ret = regulator_enable(dsi->vdd_supply);
404+ if (ret) {
405+ DRM_ERROR("Failed to enable regulator: %d\n", ret);
406+ return ret;
407+ }
408+
409+ ret = clk_prepare_enable(dsi->pllref_clk);
410+ if (ret) {
411+ regulator_disable(dsi->vdd_supply);
412+ DRM_ERROR("Failed to enable pllref_clk: %d\n", ret);
413+ return ret;
414+ }
377415
378416 return 0;
379417 }
drivers/gpu/drm/stm/ltdc.c+47−20
@@ -232,6 +232,11 @@ static const enum ltdc_pix_fmt ltdc_pix_fmt_a1[NB_PF] = { · 231 unmodified lines
232232 PF_ARGB4444 /* 0x07 */
233233 };
234234
235+static const u64 ltdc_format_modifiers[] = {
236+ DRM_FORMAT_MOD_LINEAR,
237+ DRM_FORMAT_MOD_INVALID
238+};
239+
235240 static inline u32 reg_read(void __iomem *base, u32 reg)
236241 {
237242 return readl_relaxed(base + reg);
@@ -426,8 +431,8 @@ static void ltdc_crtc_atomic_enable(struct drm_crtc *crtc, · 188 unmodified lines
426431 /* Enable IRQ */
427432 reg_set(ldev->regs, LTDC_IER, IER_RRIE | IER_FUIE | IER_TERRIE);
428433
429− /* Immediately commit the planes */
430− reg_set(ldev->regs, LTDC_SRCR, SRCR_IMR);
434+ /* Commit shadow registers = update planes at next vblank */
435+ reg_set(ldev->regs, LTDC_SRCR, SRCR_VBR);
431436
432437 /* Enable LTDC */
433438 reg_set(ldev->regs, LTDC_GCR, GCR_LTDCEN);
@@ -555,7 +560,7 @@ static void ltdc_crtc_mode_set_nofb(struct drm_crtc *crtc) · 121 unmodified lines
555560 if (vm.flags & DISPLAY_FLAGS_VSYNC_HIGH)
556561 val |= GCR_VSPOL;
557562
558− if (vm.flags & DISPLAY_FLAGS_DE_HIGH)
563+ if (vm.flags & DISPLAY_FLAGS_DE_LOW)
559564 val |= GCR_DEPOL;
560565
561566 if (vm.flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
@@ -779,7 +784,7 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 217 unmodified lines
779784
780785 /* Configures the color frame buffer pitch in bytes & line length */
781786 pitch_in_bytes = fb->pitches[0];
782− line_length = drm_format_plane_cpp(fb->format->format, 0) *
787+ line_length = fb->format->cpp[0] *
783788 (x1 - x0 + 1) + (ldev->caps.bus_width >> 3) - 1;
784789 val = ((pitch_in_bytes << 16) | line_length);
785790 reg_update_bits(ldev->regs, LTDC_L1CFBLR + lofs,
@@ -822,11 +827,11 @@ static void ltdc_plane_atomic_update(struct drm_plane *plane, · 36 unmodified lines
822827
823828 mutex_lock(&ldev->err_lock);
824829 if (ldev->error_status & ISR_FUIF) {
825− DRM_DEBUG_DRIVER("Fifo underrun\n");
830+ DRM_WARN("ltdc fifo underrun: please verify display mode\n");
826831 ldev->error_status &= ~ISR_FUIF;
827832 }
828833 if (ldev->error_status & ISR_TERRIF) {
829− DRM_DEBUG_DRIVER("Transfer error\n");
834+ DRM_WARN("ltdc transfer error\n");
830835 ldev->error_status &= ~ISR_TERRIF;
831836 }
832837 mutex_unlock(&ldev->err_lock);
@@ -864,6 +869,16 @@ static void ltdc_plane_atomic_print_state(struct drm_printer *p, · 31 unmodified lines
864869 fpsi->counter = 0;
865870 }
866871
872+static bool ltdc_plane_format_mod_supported(struct drm_plane *plane,
873+ u32 format,
874+ u64 modifier)
875+{
876+ if (modifier == DRM_FORMAT_MOD_LINEAR)
877+ return true;
878+
879+ return false;
880+}
881+
867882 static const struct drm_plane_funcs ltdc_plane_funcs = {
868883 .update_plane = drm_atomic_helper_update_plane,
869884 .disable_plane = drm_atomic_helper_disable_plane,
@@ -872,6 +887,7 @@ static const struct drm_plane_funcs ltdc_plane_funcs = { · 2 unmodified lines
872887 .atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state,
873888 .atomic_destroy_state = drm_atomic_helper_plane_destroy_state,
874889 .atomic_print_state = ltdc_plane_atomic_print_state,
890+ .format_mod_supported = ltdc_plane_format_mod_supported,
875891 };
876892
877893 static const struct drm_plane_helper_funcs ltdc_plane_helper_funcs = {
@@ -890,6 +906,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, · 12 unmodified lines
890906 unsigned int i, nb_fmt = 0;
891907 u32 formats[NB_PF * 2];
892908 u32 drm_fmt, drm_fmt_no_alpha;
909+ const u64 *modifiers = ltdc_format_modifiers;
893910 int ret;
894911
895912 /* Get supported pixel formats */
@@ -918,7 +935,7 @@ static struct drm_plane *ltdc_plane_create(struct drm_device *ddev, · 22 unmodified lines
918935
919936 ret = drm_universal_plane_init(ddev, plane, possible_crtcs,
920937 &ltdc_plane_funcs, formats, nb_fmt,
921− NULL, type, NULL);
938+ modifiers, type, NULL);
922939 if (ret < 0)
923940 return NULL;
924941
@@ -1021,10 +1038,13 @@ static int ltdc_get_caps(struct drm_device *ddev) · 96 unmodified lines
10211038 struct ltdc_device *ldev = ddev->dev_private;
10221039 u32 bus_width_log2, lcr, gc2r;
10231040
1024− /* at least 1 layer must be managed */
1041+ /*
1042+ * at least 1 layer must be managed & the number of layers
1043+ * must not exceed LTDC_MAX_LAYER
1044+ */
10251045 lcr = reg_read(ldev->regs, LTDC_LCR);
10261046
1027− ldev->caps.nb_layers = max_t(int, lcr, 1);
1047+ ldev->caps.nb_layers = clamp((int)lcr, 1, LTDC_MAX_LAYER);
10281048
10291049 /* set data bus width */
10301050 gc2r = reg_read(ldev->regs, LTDC_GC2R);
@@ -1125,8 +1145,9 @@ int ltdc_load(struct drm_device *ddev) · 94 unmodified lines
11251145
11261146 ldev->pixel_clk = devm_clk_get(dev, "lcd");
11271147 if (IS_ERR(ldev->pixel_clk)) {
1128− DRM_ERROR("Unable to get lcd clock\n");
1129− return -ENODEV;
1148+ if (PTR_ERR(ldev->pixel_clk) != -EPROBE_DEFER)
1149+ DRM_ERROR("Unable to get lcd clock\n");
1150+ return PTR_ERR(ldev->pixel_clk);
11301151 }
11311152
11321153 if (clk_prepare_enable(ldev->pixel_clk)) {
@@ -1134,6 +1155,12 @@ int ltdc_load(struct drm_device *ddev) · 1 unmodified line
11341155 return -ENODEV;
11351156 }
11361157
1158+ if (!IS_ERR(rstc)) {
1159+ reset_control_assert(rstc);
1160+ usleep_range(10, 20);
1161+ reset_control_deassert(rstc);
1162+ }
1163+
11371164 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
11381165 ldev->regs = devm_ioremap_resource(dev, res);
11391166 if (IS_ERR(ldev->regs)) {
@@ -1142,8 +1169,15 @@ int ltdc_load(struct drm_device *ddev) · 2 unmodified lines
11421169 goto err;
11431170 }
11441171
1172+ /* Disable interrupts */
1173+ reg_clear(ldev->regs, LTDC_IER,
1174+ IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
1175+
11451176 for (i = 0; i < MAX_IRQ; i++) {
11461177 irq = platform_get_irq(pdev, i);
1178+ if (irq == -EPROBE_DEFER)
1179+ goto err;
1180+
11471181 if (irq < 0)
11481182 continue;
11491183
@@ -1156,15 +1190,6 @@ int ltdc_load(struct drm_device *ddev) · 6 unmodified lines
11561190 }
11571191 }
11581192
1159− if (!IS_ERR(rstc)) {
1160− reset_control_assert(rstc);
1161− usleep_range(10, 20);
1162− reset_control_deassert(rstc);
1163− }
1164−
1165− /* Disable interrupts */
1166− reg_clear(ldev->regs, LTDC_IER,
1167− IER_LIE | IER_RRIE | IER_FUIE | IER_TERRIE);
11681193
11691194 ret = ltdc_get_caps(ddev);
11701195 if (ret) {
@@ -1203,6 +1228,8 @@ int ltdc_load(struct drm_device *ddev) · 32 unmodified lines
12031228 goto err;
12041229 }
12051230
1231+ ddev->mode_config.allow_fb_modifiers = true;
1232+
12061233 ret = ltdc_crtc_init(ddev, crtc);
12071234 if (ret) {
12081235 DRM_ERROR("Failed to init crtc\n");
drivers/gpu/drm/sun4i/sun4i_drv.c+1−15
@@ -53,22 +53,8 @@ static struct drm_driver sun4i_drv_driver = { · 52 unmodified lines
5353 .minor = 0,
5454
5555 /* GEM Operations */
56+ DRM_GEM_CMA_VMAP_DRIVER_OPS,
5657 .dumb_create = drm_sun4i_gem_dumb_create,
57− .gem_free_object_unlocked = drm_gem_cma_free_object,
58− .gem_vm_ops = &drm_gem_cma_vm_ops,
59−
60− /* PRIME Operations */
61− .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
62− .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
63− .gem_prime_import = drm_gem_prime_import,
64− .gem_prime_export = drm_gem_prime_export,
65− .gem_prime_get_sg_table = drm_gem_cma_prime_get_sg_table,
66− .gem_prime_import_sg_table = drm_gem_cma_prime_import_sg_table,
67− .gem_prime_vmap = drm_gem_cma_prime_vmap,
68− .gem_prime_vunmap = drm_gem_cma_prime_vunmap,
69− .gem_prime_mmap = drm_gem_cma_prime_mmap,
70−
71− /* Frame Buffer Operations */
7258 };
7359
7460 static int sun4i_drv_bind(struct device *dev)
drivers/gpu/drm/sun4i/sun6i_mipi_dsi.c+1−0
@@ -980,6 +980,7 @@ static ssize_t sun6i_dsi_transfer(struct mipi_dsi_host *host, · 979 unmodified lines
980980 switch (msg->type) {
981981 case MIPI_DSI_DCS_SHORT_WRITE:
982982 case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
983+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
983984 ret = sun6i_dsi_dcs_write_short(dsi, msg);
984985 break;
985986
drivers/gpu/drm/tegra/dc.c+6−11
@@ -26,6 +26,9 @@ · 25 unmodified lines
2626 #include <drm/drm_atomic_helper.h>
2727 #include <drm/drm_plane_helper.h>
2828
29+static void tegra_crtc_atomic_destroy_state(struct drm_crtc *crtc,
30+ struct drm_crtc_state *state);
31+
2932 static void tegra_dc_stats_reset(struct tegra_dc_stats *stats)
3033 {
3134 stats->frames = 0;
@@ -1155,20 +1158,12 @@ static void tegra_dc_destroy(struct drm_crtc *crtc) · 1123 unmodified lines
11551158
11561159 static void tegra_crtc_reset(struct drm_crtc *crtc)
11571160 {
1158− struct tegra_dc_state *state;
1161+ struct tegra_dc_state *state = kzalloc(sizeof(*state), GFP_KERNEL);
11591162
11601163 if (crtc->state)
1161− __drm_atomic_helper_crtc_destroy_state(crtc->state);
1162−
1163− kfree(crtc->state);
1164− crtc->state = NULL;
1165−
1166− state = kzalloc(sizeof(*state), GFP_KERNEL);
1167− if (state) {
1168− crtc->state = &state->base;
1169− crtc->state->crtc = crtc;
1170− }
1164+ tegra_crtc_atomic_destroy_state(crtc, crtc->state);
11711165
1166+ __drm_atomic_helper_crtc_reset(crtc, &state->base);
11721167 drm_crtc_vblank_reset(crtc);
11731168 }
11741169
drivers/gpu/drm/tegra/fb.c+6−8
@@ -131,18 +131,16 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, · 130 unmodified lines
131131 struct drm_file *file,
132132 const struct drm_mode_fb_cmd2 *cmd)
133133 {
134− unsigned int hsub, vsub, i;
134+ const struct drm_format_info *info = drm_get_format_info(drm, cmd);
135135 struct tegra_bo *planes[4];
136136 struct drm_gem_object *gem;
137137 struct drm_framebuffer *fb;
138+ unsigned int i;
138139 int err;
139140
140− hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
141− vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
142−
143− for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) {
144− unsigned int width = cmd->width / (i ? hsub : 1);
145− unsigned int height = cmd->height / (i ? vsub : 1);
141+ for (i = 0; i < info->num_planes; i++) {
142+ unsigned int width = cmd->width / (i ? info->hsub : 1);
143+ unsigned int height = cmd->height / (i ? info->vsub : 1);
146144 unsigned int size, bpp;
147145
148146 gem = drm_gem_object_lookup(file, cmd->handles[i]);
@@ -151,7 +149,7 @@ struct drm_framebuffer *tegra_fb_create(struct drm_device *drm, · 2 unmodified lines
151149 goto unreference;
152150 }
153151
154− bpp = drm_format_plane_cpp(cmd->pixel_format, i);
152+ bpp = info->cpp[i];
155153
156154 size = (height - 1) * cmd->pitches[i] +
157155 width * bpp + cmd->offsets[i];
drivers/gpu/drm/v3d/v3d_debugfs.c+32−3
@@ -26,6 +26,11 @@ static const struct v3d_reg_def v3d_hub_reg_defs[] = { · 25 unmodified lines
2626 REGDEF(V3D_HUB_IDENT3),
2727 REGDEF(V3D_HUB_INT_STS),
2828 REGDEF(V3D_HUB_INT_MSK_STS),
29+
30+ REGDEF(V3D_MMU_CTL),
31+ REGDEF(V3D_MMU_VIO_ADDR),
32+ REGDEF(V3D_MMU_VIO_ID),
33+ REGDEF(V3D_MMU_DEBUG_INFO),
2934 };
3035
3136 static const struct v3d_reg_def v3d_gca_reg_defs[] = {
@@ -50,12 +55,25 @@ static const struct v3d_reg_def v3d_core_reg_defs[] = { · 18 unmodified lines
5055 REGDEF(V3D_PTB_BPCA),
5156 REGDEF(V3D_PTB_BPCS),
5257
53− REGDEF(V3D_MMU_CTL),
54− REGDEF(V3D_MMU_VIO_ADDR),
55−
5658 REGDEF(V3D_GMP_STATUS),
5759 REGDEF(V3D_GMP_CFG),
5860 REGDEF(V3D_GMP_VIO_ADDR),
61+
62+ REGDEF(V3D_ERR_FDBGO),
63+ REGDEF(V3D_ERR_FDBGB),
64+ REGDEF(V3D_ERR_FDBGS),
65+ REGDEF(V3D_ERR_STAT),
66+};
67+
68+static const struct v3d_reg_def v3d_csd_reg_defs[] = {
69+ REGDEF(V3D_CSD_STATUS),
70+ REGDEF(V3D_CSD_CURRENT_CFG0),
71+ REGDEF(V3D_CSD_CURRENT_CFG1),
72+ REGDEF(V3D_CSD_CURRENT_CFG2),
73+ REGDEF(V3D_CSD_CURRENT_CFG3),
74+ REGDEF(V3D_CSD_CURRENT_CFG4),
75+ REGDEF(V3D_CSD_CURRENT_CFG5),
76+ REGDEF(V3D_CSD_CURRENT_CFG6),
5977 };
6078
6179 static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused)
@@ -89,6 +107,17 @@ static int v3d_v3d_debugfs_regs(struct seq_file *m, void *unused) · 27 unmodified lines
89107 V3D_CORE_READ(core,
90108 v3d_core_reg_defs[i].reg));
91109 }
110+
111+ if (v3d_has_csd(v3d)) {
112+ for (i = 0; i < ARRAY_SIZE(v3d_csd_reg_defs); i++) {
113+ seq_printf(m, "core %d %s (0x%04x): 0x%08x\n",
114+ core,
115+ v3d_csd_reg_defs[i].name,
116+ v3d_csd_reg_defs[i].reg,
117+ V3D_CORE_READ(core,
118+ v3d_csd_reg_defs[i].reg));
119+ }
120+ }
92121 }
93122
94123 return 0;
drivers/gpu/drm/v3d/v3d_drv.c+13−4
@@ -7,9 +7,9 @@ · 6 unmodified lines
77 * This driver supports the Broadcom V3D 3.3 and 4.1 OpenGL ES GPUs.
88 * For V3D 2.x support, see the VC4 driver.
99 *
10− * Currently only single-core rendering using the binner and renderer,
11− * along with TFU (texture formatting unit) rendering is supported.
12− * V3D 4.x's CSD (compute shader dispatch) is not yet supported.
10+ * The V3D GPU includes a tiled render (composed of a bin and render
11+ * pipelines), the TFU (texture formatting unit), and the CSD (compute
12+ * shader dispatch).
1313 */
1414
1515 #include <linux/clk.h>
@@ -120,6 +120,9 @@ static int v3d_get_param_ioctl(struct drm_device *dev, void *data, · 104 unmodified lines
120120 case DRM_V3D_PARAM_SUPPORTS_TFU:
121121 args->value = 1;
122122 return 0;
123+ case DRM_V3D_PARAM_SUPPORTS_CSD:
124+ args->value = v3d_has_csd(v3d);
125+ return 0;
123126 default:
124127 DRM_DEBUG("Unknown parameter %d\n", args->param);
125128 return -EINVAL;
@@ -179,6 +182,7 @@ static const struct drm_ioctl_desc v3d_drm_ioctls[] = { · 53 unmodified lines
179182 DRM_IOCTL_DEF_DRV(V3D_GET_PARAM, v3d_get_param_ioctl, DRM_RENDER_ALLOW),
180183 DRM_IOCTL_DEF_DRV(V3D_GET_BO_OFFSET, v3d_get_bo_offset_ioctl, DRM_RENDER_ALLOW),
181184 DRM_IOCTL_DEF_DRV(V3D_SUBMIT_TFU, v3d_submit_tfu_ioctl, DRM_RENDER_ALLOW | DRM_AUTH),
185+ DRM_IOCTL_DEF_DRV(V3D_SUBMIT_CSD, v3d_submit_csd_ioctl, DRM_RENDER_ALLOW | DRM_AUTH),
182186 };
183187
184188 static struct drm_driver v3d_drm_driver = {
@@ -235,9 +239,9 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) · 50 unmodified lines
235239 struct drm_device *drm;
236240 struct v3d_dev *v3d;
237241 int ret;
242+ u32 mmu_debug;
238243 u32 ident1;
239244
240− dev->coherent_dma_mask = DMA_BIT_MASK(36);
241245
242246 v3d = kzalloc(sizeof(*v3d), GFP_KERNEL);
243247 if (!v3d)
@@ -254,6 +258,11 @@ static int v3d_platform_drm_probe(struct platform_device *pdev) · 10 unmodified lines
254258 if (ret)
255259 goto dev_free;
256260
261+ mmu_debug = V3D_READ(V3D_MMU_DEBUG_INFO);
262+ dev->coherent_dma_mask =
263+ DMA_BIT_MASK(30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_PA_WIDTH));
264+ v3d->va_width = 30 + V3D_GET_FIELD(mmu_debug, V3D_MMU_VA_WIDTH);
265+
257266 ident1 = V3D_READ(V3D_HUB_IDENT1);
258267 v3d->ver = (V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_TVER) * 10 +
259268 V3D_GET_FIELD(ident1, V3D_HUB_IDENT1_REV));
drivers/gpu/drm/v3d/v3d_drv.h+66−40
@@ -16,9 +16,11 @@ enum v3d_queue { · 15 unmodified lines
1616 V3D_BIN,
1717 V3D_RENDER,
1818 V3D_TFU,
19+ V3D_CSD,
20+ V3D_CACHE_CLEAN,
1921 };
2022
21−#define V3D_MAX_QUEUES (V3D_TFU + 1)
23+#define V3D_MAX_QUEUES (V3D_CACHE_CLEAN + 1)
2224
2325 struct v3d_queue_state {
2426 struct drm_gpu_scheduler sched;
@@ -55,6 +57,8 @@ struct v3d_dev { · 30 unmodified lines
5557 */
5658 void *mmu_scratch;
5759 dma_addr_t mmu_scratch_paddr;
60+ /* virtual address bits from V3D to the MMU. */
61+ int va_width;
5862
5963 /* Number of V3D cores. */
6064 u32 cores;
@@ -67,9 +71,10 @@ struct v3d_dev { · 6 unmodified lines
6771
6872 struct work_struct overflow_mem_work;
6973
70− struct v3d_exec_info *bin_job;
71− struct v3d_exec_info *render_job;
74+ struct v3d_bin_job *bin_job;
75+ struct v3d_render_job *render_job;
7276 struct v3d_tfu_job *tfu_job;
77+ struct v3d_csd_job *csd_job;
7378
7479 struct v3d_queue_state queue[V3D_MAX_QUEUES];
7580
@@ -92,6 +97,12 @@ struct v3d_dev { · 16 unmodified lines
9297 */
9398 struct mutex sched_lock;
9499
100+ /* Lock taken during a cache clean and when initiating an L2
101+ * flush, to keep L2 flushes from interfering with the
102+ * synchronous L2 cleans.
103+ */
104+ struct mutex cache_clean_lock;
105+
95106 struct {
96107 u32 num_allocated;
97108 u32 pages_allocated;
@@ -104,6 +115,12 @@ to_v3d_dev(struct drm_device *dev) · 6 unmodified lines
104115 return (struct v3d_dev *)dev->dev_private;
105116 }
106117
118+static inline bool
119+v3d_has_csd(struct v3d_dev *v3d)
120+{
121+ return v3d->ver >= 41;
122+}
123+
107124 /* The per-fd struct, which tracks the MMU mappings. */
108125 struct v3d_file_priv {
109126 struct v3d_dev *v3d;
@@ -117,7 +134,7 @@ struct v3d_bo { · 7 unmodified lines
117134 struct drm_mm_node node;
118135
119136 /* List entry for the BO's position in
120− * v3d_exec_info->unref_list
137+ * v3d_render_job->unref_list
121138 */
122139 struct list_head unref_head;
123140 };
@@ -157,67 +174,74 @@ to_v3d_fence(struct dma_fence *fence) · 33 unmodified lines
157174 struct v3d_job {
158175 struct drm_sched_job base;
159176
160− struct v3d_exec_info *exec;
177+ struct kref refcount;
161178
162− /* An optional fence userspace can pass in for the job to depend on. */
163− struct dma_fence *in_fence;
179+ struct v3d_dev *v3d;
180+
181+ /* This is the array of BOs that were looked up at the start
182+ * of submission.
183+ */
184+ struct drm_gem_object **bo;
185+ u32 bo_count;
186+
187+ /* Array of struct dma_fence * to block on before submitting this job.
188+ */
189+ struct xarray deps;
190+ unsigned long last_dep;
164191
165192 /* v3d fence to be signaled by IRQ handler when the job is complete. */
166193 struct dma_fence *irq_fence;
167194
195+ /* scheduler fence for when the job is considered complete and
196+ * the BO reservations can be released.
197+ */
198+ struct dma_fence *done_fence;
199+
200+ /* Callback for the freeing of the job on refcount going to 0. */
201+ void (*free)(struct kref *ref);
202+};
203+
204+struct v3d_bin_job {
205+ struct v3d_job base;
206+
168207 /* GPU virtual addresses of the start/end of the CL job. */
169208 u32 start, end;
170209
171210 u32 timedout_ctca, timedout_ctra;
172−};
173211
174−struct v3d_exec_info {
175− struct v3d_dev *v3d;
212+ /* Corresponding render job, for attaching our overflow memory. */
213+ struct v3d_render_job *render;
176214
177− struct v3d_job bin, render;
178−
179− /* Fence for when the scheduler considers the binner to be
180− * done, for render to depend on.
181− */
182− struct dma_fence *bin_done_fence;
215+ /* Submitted tile memory allocation start/size, tile state. */
216+ u32 qma, qms, qts;
217+};
183218
184− /* Fence for when the scheduler considers the render to be
185− * done, for when the BOs reservations should be complete.
186− */
187− struct dma_fence *render_done_fence;
219+struct v3d_render_job {
220+ struct v3d_job base;
188221
189− struct kref refcount;
222+ /* GPU virtual addresses of the start/end of the CL job. */
223+ u32 start, end;
190224
191− /* This is the array of BOs that were looked up at the start of exec. */
192− struct v3d_bo **bo;
193− u32 bo_count;
225+ u32 timedout_ctca, timedout_ctra;
194226
195227 /* List of overflow BOs used in the job that need to be
196228 * released once the job is complete.
197229 */
198230 struct list_head unref_list;
199−
200− /* Submitted tile memory allocation start/size, tile state. */
201− u32 qma, qms, qts;
202231 };
203232
204233 struct v3d_tfu_job {
205− struct drm_sched_job base;
234+ struct v3d_job base;
206235
207236 struct drm_v3d_submit_tfu args;
237+};
208238
209− /* An optional fence userspace can pass in for the job to depend on. */
210− struct dma_fence *in_fence;
211−
212− /* v3d fence to be signaled by IRQ handler when the job is complete. */
213− struct dma_fence *irq_fence;
214−
215− struct v3d_dev *v3d;
239+struct v3d_csd_job {
240+ struct v3d_job base;
216241
217− struct kref refcount;
242+ u32 timedout_batches;
218243
219− /* This is the array of BOs that were looked up at the start of exec. */
220− struct v3d_bo *bo[4];
244+ struct drm_v3d_submit_csd args;
221245 };
222246
223247 /**
@@ -281,12 +305,14 @@ int v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 57 unmodified lines
281305 struct drm_file *file_priv);
282306 int v3d_submit_tfu_ioctl(struct drm_device *dev, void *data,
283307 struct drm_file *file_priv);
308+int v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
309+ struct drm_file *file_priv);
284310 int v3d_wait_bo_ioctl(struct drm_device *dev, void *data,
285311 struct drm_file *file_priv);
286−void v3d_exec_put(struct v3d_exec_info *exec);
287−void v3d_tfu_job_put(struct v3d_tfu_job *exec);
312+void v3d_job_put(struct v3d_job *job);
288313 void v3d_reset(struct v3d_dev *v3d);
289314 void v3d_invalidate_caches(struct v3d_dev *v3d);
315+void v3d_clean_caches(struct v3d_dev *v3d);
290316
291317 /* v3d_irq.c */
292318 int v3d_irq_init(struct v3d_dev *v3d);
drivers/gpu/drm/v3d/v3d_fence.c+2−0
@@ -36,6 +36,8 @@ static const char *v3d_fence_get_timeline_name(struct dma_fence *fence) · 35 unmodified lines
3636 return "v3d-render";
3737 case V3D_TFU:
3838 return "v3d-tfu";
39+ case V3D_CSD:
40+ return "v3d-csd";
3941 default:
4042 return NULL;
4143 }
drivers/gpu/drm/v3d/v3d_gem.c+355−197
@@ -109,7 +109,9 @@ v3d_reset(struct v3d_dev *v3d) · 108 unmodified lines
109109 {
110110 struct drm_device *dev = &v3d->drm;
111111
112− DRM_ERROR("Resetting GPU.\n");
112+ DRM_DEV_ERROR(dev->dev, "Resetting GPU for hang.\n");
113+ DRM_DEV_ERROR(dev->dev, "V3D_ERR_STAT: 0x%08x\n",
114+ V3D_CORE_READ(0, V3D_ERR_STAT));
113115 trace_v3d_reset_begin(dev);
114116
115117 /* XXX: only needed for safe powerdown, not reset. */
@@ -162,10 +164,52 @@ v3d_flush_l2t(struct v3d_dev *v3d, int core) · 46 unmodified lines
162164 /* While there is a busy bit (V3D_L2TCACTL_L2TFLS), we don't
163165 * need to wait for completion before dispatching the job --
164166 * L2T accesses will be stalled until the flush has completed.
167+ * However, we do need to make sure we don't try to trigger a
168+ * new flush while the L2_CLEAN queue is trying to
169+ * synchronously clean after a job.
165170 */
171+ mutex_lock(&v3d->cache_clean_lock);
166172 V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL,
167173 V3D_L2TCACTL_L2TFLS |
168174 V3D_SET_FIELD(V3D_L2TCACTL_FLM_FLUSH, V3D_L2TCACTL_FLM));
175+ mutex_unlock(&v3d->cache_clean_lock);
176+}
177+
178+/* Cleans texture L1 and L2 cachelines (writing back dirty data).
179+ *
180+ * For cleaning, which happens from the CACHE_CLEAN queue after CSD has
181+ * executed, we need to make sure that the clean is done before
182+ * signaling job completion. So, we synchronously wait before
183+ * returning, and we make sure that L2 invalidates don't happen in the
184+ * meantime to confuse our are-we-done checks.
185+ */
186+void
187+v3d_clean_caches(struct v3d_dev *v3d)
188+{
189+ struct drm_device *dev = &v3d->drm;
190+ int core = 0;
191+
192+ trace_v3d_cache_clean_begin(dev);
193+
194+ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL, V3D_L2TCACTL_TMUWCF);
195+ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
196+ V3D_L2TCACTL_L2TFLS), 100)) {
197+ DRM_ERROR("Timeout waiting for L1T write combiner flush\n");
198+ }
199+
200+ mutex_lock(&v3d->cache_clean_lock);
201+ V3D_CORE_WRITE(core, V3D_CTL_L2TCACTL,
202+ V3D_L2TCACTL_L2TFLS |
203+ V3D_SET_FIELD(V3D_L2TCACTL_FLM_CLEAN, V3D_L2TCACTL_FLM));
204+
205+ if (wait_for(!(V3D_CORE_READ(core, V3D_CTL_L2TCACTL) &
206+ V3D_L2TCACTL_L2TFLS), 100)) {
207+ DRM_ERROR("Timeout waiting for L2T clean\n");
208+ }
209+
210+ mutex_unlock(&v3d->cache_clean_lock);
211+
212+ trace_v3d_cache_clean_end(dev);
169213 }
170214
171215 /* Invalidates the slice caches. These are read-only caches. */
@@ -193,28 +237,6 @@ v3d_invalidate_caches(struct v3d_dev *v3d) · 21 unmodified lines
193237 v3d_invalidate_slices(v3d, 0);
194238 }
195239
196−static void
197−v3d_attach_object_fences(struct v3d_bo **bos, int bo_count,
198− struct dma_fence *fence)
199−{
200− int i;
201−
202− for (i = 0; i < bo_count; i++) {
203− /* XXX: Use shared fences for read-only objects. */
204− reservation_object_add_excl_fence(bos[i]->base.base.resv,
205− fence);
206− }
207−}
208−
209−static void
210−v3d_unlock_bo_reservations(struct v3d_bo **bos,
211− int bo_count,
212− struct ww_acquire_ctx *acquire_ctx)
213−{
214− drm_gem_unlock_reservations((struct drm_gem_object **)bos, bo_count,
215− acquire_ctx);
216−}
217−
218240 /* Takes the reservation lock on all the BOs being referenced, so that
219241 * at queue submit time we can update the reservations.
220242 *
@@ -223,26 +245,21 @@ v3d_unlock_bo_reservations(struct v3d_bo **bos, · 2 unmodified lines
223245 * to v3d, so we don't attach dma-buf fences to them.
224246 */
225247 static int
226−v3d_lock_bo_reservations(struct v3d_bo **bos,
227− int bo_count,
248+v3d_lock_bo_reservations(struct v3d_job *job,
228249 struct ww_acquire_ctx *acquire_ctx)
229250 {
230251 int i, ret;
231252
232− ret = drm_gem_lock_reservations((struct drm_gem_object **)bos,
233− bo_count, acquire_ctx);
253+ ret = drm_gem_lock_reservations(job->bo, job->bo_count, acquire_ctx);
234254 if (ret)
235255 return ret;
236256
237− /* Reserve space for our shared (read-only) fence references,
238− * before we commit the CL to the hardware.
239− */
240− for (i = 0; i < bo_count; i++) {
241− ret = reservation_object_reserve_shared(bos[i]->base.base.resv,
242− 1);
257+ for (i = 0; i < job->bo_count; i++) {
258+ ret = drm_gem_fence_array_add_implicit(&job->deps,
259+ job->bo[i], true);
243260 if (ret) {
244− v3d_unlock_bo_reservations(bos, bo_count,
245− acquire_ctx);
261+ drm_gem_unlock_reservations(job->bo, job->bo_count,
262+ acquire_ctx);
246263 return ret;
247264 }
248265 }
@@ -251,11 +268,11 @@ v3d_lock_bo_reservations(struct v3d_bo **bos, · 2 unmodified lines
251268 }
252269
253270 /**
254− * v3d_cl_lookup_bos() - Sets up exec->bo[] with the GEM objects
271+ * v3d_lookup_bos() - Sets up job->bo[] with the GEM objects
255272 * referenced by the job.
256273 * @dev: DRM device
257274 * @file_priv: DRM file for this fd
258− * @exec: V3D job being set up
275+ * @job: V3D job being set up
259276 *
260277 * The command validator needs to reference BOs by their index within
261278 * the submitted job's BO list. This does the validation of the job's
@@ -265,18 +282,19 @@ v3d_lock_bo_reservations(struct v3d_bo **bos, · 3 unmodified lines
265282 * failure, because that will happen at v3d_exec_cleanup() time.
266283 */
267284 static int
268−v3d_cl_lookup_bos(struct drm_device *dev,
269− struct drm_file *file_priv,
270− struct drm_v3d_submit_cl *args,
271− struct v3d_exec_info *exec)
285+v3d_lookup_bos(struct drm_device *dev,
286+ struct drm_file *file_priv,
287+ struct v3d_job *job,
288+ u64 bo_handles,
289+ u32 bo_count)
272290 {
273291 u32 *handles;
274292 int ret = 0;
275293 int i;
276294
277− exec->bo_count = args->bo_handle_count;
295+ job->bo_count = bo_count;
278296
279− if (!exec->bo_count) {
297+ if (!job->bo_count) {
280298 /* See comment on bo_index for why we have to check
281299 * this.
282300 */
@@ -284,15 +302,15 @@ v3d_cl_lookup_bos(struct drm_device *dev, · 1 unmodified line
284302 return -EINVAL;
285303 }
286304
287− exec->bo = kvmalloc_array(exec->bo_count,
288− sizeof(struct drm_gem_cma_object *),
289− GFP_KERNEL | __GFP_ZERO);
290− if (!exec->bo) {
305+ job->bo = kvmalloc_array(job->bo_count,
306+ sizeof(struct drm_gem_cma_object *),
307+ GFP_KERNEL | __GFP_ZERO);
308+ if (!job->bo) {
291309 DRM_DEBUG("Failed to allocate validated BO pointers\n");
292310 return -ENOMEM;
293311 }
294312
295− handles = kvmalloc_array(exec->bo_count, sizeof(u32), GFP_KERNEL);
313+ handles = kvmalloc_array(job->bo_count, sizeof(u32), GFP_KERNEL);
296314 if (!handles) {
297315 ret = -ENOMEM;
298316 DRM_DEBUG("Failed to allocate incoming GEM handles\n");
@@ -300,15 +318,15 @@ v3d_cl_lookup_bos(struct drm_device *dev, · 1 unmodified line
300318 }
301319
302320 if (copy_from_user(handles,
303− (void __user *)(uintptr_t)args->bo_handles,
304− exec->bo_count * sizeof(u32))) {
321+ (void __user *)(uintptr_t)bo_handles,
322+ job->bo_count * sizeof(u32))) {
305323 ret = -EFAULT;
306324 DRM_DEBUG("Failed to copy in GEM handles\n");
307325 goto fail;
308326 }
309327
310328 spin_lock(&file_priv->table_lock);
311− for (i = 0; i < exec->bo_count; i++) {
329+ for (i = 0; i < job->bo_count; i++) {
312330 struct drm_gem_object *bo = idr_find(&file_priv->object_idr,
313331 handles[i]);
314332 if (!bo) {
@@ -319,7 +337,7 @@ v3d_cl_lookup_bos(struct drm_device *dev, · 4 unmodified lines
319337 goto fail;
320338 }
321339 drm_gem_object_get(bo);
322− exec->bo[i] = to_v3d_bo(bo);
340+ job->bo[i] = bo;
323341 }
324342 spin_unlock(&file_priv->table_lock);
325343
@@ -329,67 +347,50 @@ fail: · 3 unmodified lines
329347 }
330348
331349 static void
332−v3d_exec_cleanup(struct kref *ref)
350+v3d_job_free(struct kref *ref)
333351 {
334− struct v3d_exec_info *exec = container_of(ref, struct v3d_exec_info,
335− refcount);
336− struct v3d_dev *v3d = exec->v3d;
337− unsigned int i;
338− struct v3d_bo *bo, *save;
339−
340− dma_fence_put(exec->bin.in_fence);
341− dma_fence_put(exec->render.in_fence);
342−
343− dma_fence_put(exec->bin.irq_fence);
344− dma_fence_put(exec->render.irq_fence);
345−
346− dma_fence_put(exec->bin_done_fence);
347− dma_fence_put(exec->render_done_fence);
352+ struct v3d_job *job = container_of(ref, struct v3d_job, refcount);
353+ unsigned long index;
354+ struct dma_fence *fence;
355+ int i;
348356
349− for (i = 0; i < exec->bo_count; i++)
350− drm_gem_object_put_unlocked(&exec->bo[i]->base.base);
351− kvfree(exec->bo);
357+ for (i = 0; i < job->bo_count; i++) {
358+ if (job->bo[i])
359+ drm_gem_object_put_unlocked(job->bo[i]);
360+ }
361+ kvfree(job->bo);
352362
353− list_for_each_entry_safe(bo, save, &exec->unref_list, unref_head) {
354− drm_gem_object_put_unlocked(&bo->base.base);
363+ xa_for_each(&job->deps, index, fence) {
364+ dma_fence_put(fence);
355365 }
366+ xa_destroy(&job->deps);
356367
357− pm_runtime_mark_last_busy(v3d->dev);
358− pm_runtime_put_autosuspend(v3d->dev);
368+ dma_fence_put(job->irq_fence);
369+ dma_fence_put(job->done_fence);
359370
360− kfree(exec);
361−}
371+ pm_runtime_mark_last_busy(job->v3d->dev);
372+ pm_runtime_put_autosuspend(job->v3d->dev);
362373
363−void v3d_exec_put(struct v3d_exec_info *exec)
364−{
365− kref_put(&exec->refcount, v3d_exec_cleanup);
374+ kfree(job);
366375 }
367376
368377 static void
369−v3d_tfu_job_cleanup(struct kref *ref)
378+v3d_render_job_free(struct kref *ref)
370379 {
371− struct v3d_tfu_job *job = container_of(ref, struct v3d_tfu_job,
372− refcount);
373− struct v3d_dev *v3d = job->v3d;
374− unsigned int i;
375−
376− dma_fence_put(job->in_fence);
377− dma_fence_put(job->irq_fence);
380+ struct v3d_render_job *job = container_of(ref, struct v3d_render_job,
381+ base.refcount);
382+ struct v3d_bo *bo, *save;
378383
379− for (i = 0; i < ARRAY_SIZE(job->bo); i++) {
380− if (job->bo[i])
381− drm_gem_object_put_unlocked(&job->bo[i]->base.base);
384+ list_for_each_entry_safe(bo, save, &job->unref_list, unref_head) {
385+ drm_gem_object_put_unlocked(&bo->base.base);
382386 }
383387
384− pm_runtime_mark_last_busy(v3d->dev);
385− pm_runtime_put_autosuspend(v3d->dev);
386−
387− kfree(job);
388+ v3d_job_free(ref);
388389 }
389390
390−void v3d_tfu_job_put(struct v3d_tfu_job *job)
391+void v3d_job_put(struct v3d_job *job)
391392 {
392− kref_put(&job->refcount, v3d_tfu_job_cleanup);
393+ kref_put(&job->refcount, job->free);
393394 }
394395
395396 int
@@ -425,6 +426,87 @@ v3d_wait_bo_ioctl(struct drm_device *dev, void *data, · 29 unmodified lines
425426 return ret;
426427 }
427428
429+static int
430+v3d_job_init(struct v3d_dev *v3d, struct drm_file *file_priv,
431+ struct v3d_job *job, void (*free)(struct kref *ref),
432+ u32 in_sync)
433+{
434+ struct dma_fence *in_fence = NULL;
435+ int ret;
436+
437+ job->v3d = v3d;
438+ job->free = free;
439+
440+ ret = pm_runtime_get_sync(v3d->dev);
441+ if (ret < 0)
442+ return ret;
443+
444+ xa_init_flags(&job->deps, XA_FLAGS_ALLOC);
445+
446+ ret = drm_syncobj_find_fence(file_priv, in_sync, 0, 0, &in_fence);
447+ if (ret == -EINVAL)
448+ goto fail;
449+
450+ ret = drm_gem_fence_array_add(&job->deps, in_fence);
451+ if (ret)
452+ goto fail;
453+
454+ kref_init(&job->refcount);
455+
456+ return 0;
457+fail:
458+ xa_destroy(&job->deps);
459+ pm_runtime_put_autosuspend(v3d->dev);
460+ return ret;
461+}
462+
463+static int
464+v3d_push_job(struct v3d_file_priv *v3d_priv,
465+ struct v3d_job *job, enum v3d_queue queue)
466+{
467+ int ret;
468+
469+ ret = drm_sched_job_init(&job->base, &v3d_priv->sched_entity[queue],
470+ v3d_priv);
471+ if (ret)
472+ return ret;
473+
474+ job->done_fence = dma_fence_get(&job->base.s_fence->finished);
475+
476+ /* put by scheduler job completion */
477+ kref_get(&job->refcount);
478+
479+ drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[queue]);
480+
481+ return 0;
482+}
483+
484+static void
485+v3d_attach_fences_and_unlock_reservation(struct drm_file *file_priv,
486+ struct v3d_job *job,
487+ struct ww_acquire_ctx *acquire_ctx,
488+ u32 out_sync,
489+ struct dma_fence *done_fence)
490+{
491+ struct drm_syncobj *sync_out;
492+ int i;
493+
494+ for (i = 0; i < job->bo_count; i++) {
495+ /* XXX: Use shared fences for read-only objects. */
496+ reservation_object_add_excl_fence(job->bo[i]->resv,
497+ job->done_fence);
498+ }
499+
500+ drm_gem_unlock_reservations(job->bo, job->bo_count, acquire_ctx);
501+
502+ /* Update the return sync object for the job */
503+ sync_out = drm_syncobj_find(file_priv, out_sync);
504+ if (sync_out) {
505+ drm_syncobj_replace_fence(sync_out, done_fence);
506+ drm_syncobj_put(sync_out);
507+ }
508+}
509+
428510 /**
429511 * v3d_submit_cl_ioctl() - Submits a job (frame) to the V3D.
430512 * @dev: DRM device
@@ -444,9 +526,9 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines
444526 struct v3d_dev *v3d = to_v3d_dev(dev);
445527 struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
446528 struct drm_v3d_submit_cl *args = data;
447− struct v3d_exec_info *exec;
529+ struct v3d_bin_job *bin = NULL;
530+ struct v3d_render_job *render;
448531 struct ww_acquire_ctx acquire_ctx;
449− struct drm_syncobj *sync_out;
450532 int ret = 0;
451533
452534 trace_v3d_submit_cl_ioctl(&v3d->drm, args->rcl_start, args->rcl_end);
@@ -456,100 +538,87 @@ v3d_submit_cl_ioctl(struct drm_device *dev, void *data, · 3 unmodified lines
456538 return -EINVAL;
457539 }
458540
459− exec = kcalloc(1, sizeof(*exec), GFP_KERNEL);
460− if (!exec)
541+ render = kcalloc(1, sizeof(*render), GFP_KERNEL);
542+ if (!render)
461543 return -ENOMEM;
462544
463− ret = pm_runtime_get_sync(v3d->dev);
464− if (ret < 0) {
465− kfree(exec);
545+ render->start = args->rcl_start;
546+ render->end = args->rcl_end;
547+ INIT_LIST_HEAD(&render->unref_list);
548+
549+ ret = v3d_job_init(v3d, file_priv, &render->base,
550+ v3d_render_job_free, args->in_sync_rcl);
551+ if (ret) {
552+ kfree(render);
466553 return ret;
467554 }
468555
469− kref_init(&exec->refcount);
556+ if (args->bcl_start != args->bcl_end) {
557+ bin = kcalloc(1, sizeof(*bin), GFP_KERNEL);
558+ if (!bin)
559+ return -ENOMEM;
470560
471− ret = drm_syncobj_find_fence(file_priv, args->in_sync_bcl,
472− 0, 0, &exec->bin.in_fence);
473− if (ret == -EINVAL)
474− goto fail;
561+ ret = v3d_job_init(v3d, file_priv, &bin->base,
562+ v3d_job_free, args->in_sync_bcl);
563+ if (ret) {
564+ v3d_job_put(&render->base);
565+ return ret;
566+ }
475567
476− ret = drm_syncobj_find_fence(file_priv, args->in_sync_rcl,
477− 0, 0, &exec->render.in_fence);
478− if (ret == -EINVAL)
479− goto fail;
568+ bin->start = args->bcl_start;
569+ bin->end = args->bcl_end;
570+ bin->qma = args->qma;
571+ bin->qms = args->qms;
572+ bin->qts = args->qts;
573+ bin->render = render;
574+ }
480575
481− exec->qma = args->qma;
482− exec->qms = args->qms;
483− exec->qts = args->qts;
484− exec->bin.exec = exec;
485− exec->bin.start = args->bcl_start;
486− exec->bin.end = args->bcl_end;
487− exec->render.exec = exec;
488− exec->render.start = args->rcl_start;
489− exec->render.end = args->rcl_end;
490− exec->v3d = v3d;
491− INIT_LIST_HEAD(&exec->unref_list);
492−
493− ret = v3d_cl_lookup_bos(dev, file_priv, args, exec);
576+ ret = v3d_lookup_bos(dev, file_priv, &render->base,
577+ args->bo_handles, args->bo_handle_count);
494578 if (ret)
495579 goto fail;
496580
497− ret = v3d_lock_bo_reservations(exec->bo, exec->bo_count,
498− &acquire_ctx);
581+ ret = v3d_lock_bo_reservations(&render->base, &acquire_ctx);
499582 if (ret)
500583 goto fail;
501584
502585 mutex_lock(&v3d->sched_lock);
503− if (exec->bin.start != exec->bin.end) {
504− ret = drm_sched_job_init(&exec->bin.base,
505− &v3d_priv->sched_entity[V3D_BIN],
506− v3d_priv);
586+ if (bin) {
587+ ret = v3d_push_job(v3d_priv, &bin->base, V3D_BIN);
507588 if (ret)
508589 goto fail_unreserve;
509590
510− exec->bin_done_fence =
511− dma_fence_get(&exec->bin.base.s_fence->finished);
512−
513− kref_get(&exec->refcount); /* put by scheduler job completion */
514− drm_sched_entity_push_job(&exec->bin.base,
515− &v3d_priv->sched_entity[V3D_BIN]);
591+ ret = drm_gem_fence_array_add(&render->base.deps,
592+ dma_fence_get(bin->base.done_fence));
593+ if (ret)
594+ goto fail_unreserve;
516595 }
517596
518− ret = drm_sched_job_init(&exec->render.base,
519− &v3d_priv->sched_entity[V3D_RENDER],
520− v3d_priv);
597+ ret = v3d_push_job(v3d_priv, &render->base, V3D_RENDER);
521598 if (ret)
522599 goto fail_unreserve;
523−
524− exec->render_done_fence =
525− dma_fence_get(&exec->render.base.s_fence->finished);
526−
527− kref_get(&exec->refcount); /* put by scheduler job completion */
528− drm_sched_entity_push_job(&exec->render.base,
529− &v3d_priv->sched_entity[V3D_RENDER]);
530600 mutex_unlock(&v3d->sched_lock);
531601
532− v3d_attach_object_fences(exec->bo, exec->bo_count,
533− exec->render_done_fence);
534−
535− v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
536−
537− /* Update the return sync object for the */
538− sync_out = drm_syncobj_find(file_priv, args->out_sync);
539− if (sync_out) {
540− drm_syncobj_replace_fence(sync_out, exec->render_done_fence);
541− drm_syncobj_put(sync_out);
542− }
602+ v3d_attach_fences_and_unlock_reservation(file_priv,
603+ &render->base,
604+ &acquire_ctx,
605+ args->out_sync,
606+ render->base.done_fence);
543607
544− v3d_exec_put(exec);
608+ if (bin)
609+ v3d_job_put(&bin->base);
610+ v3d_job_put(&render->base);
545611
546612 return 0;
547613
548614 fail_unreserve:
549615 mutex_unlock(&v3d->sched_lock);
550− v3d_unlock_bo_reservations(exec->bo, exec->bo_count, &acquire_ctx);
616+ drm_gem_unlock_reservations(render->base.bo,
617+ render->base.bo_count, &acquire_ctx);
551618 fail:
552− v3d_exec_put(exec);
619+ if (bin)
620+ v3d_job_put(&bin->base);
621+ v3d_job_put(&render->base);
553622
554623 return ret;
555624 }
@@ -572,10 +641,7 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, · 16 unmodified lines
572641 struct drm_v3d_submit_tfu *args = data;
573642 struct v3d_tfu_job *job;
574643 struct ww_acquire_ctx acquire_ctx;
575− struct drm_syncobj *sync_out;
576− struct dma_fence *sched_done_fence;
577644 int ret = 0;
578− int bo_count;
579645
580646 trace_v3d_submit_tfu_ioctl(&v3d->drm, args->iia);
581647
@@ -583,81 +649,172 @@ v3d_submit_tfu_ioctl(struct drm_device *dev, void *data, · 1 unmodified line
583649 if (!job)
584650 return -ENOMEM;
585651
586− ret = pm_runtime_get_sync(v3d->dev);
587− if (ret < 0) {
652+ ret = v3d_job_init(v3d, file_priv, &job->base,
653+ v3d_job_free, args->in_sync);
654+ if (ret) {
588655 kfree(job);
589656 return ret;
590657 }
591658
592− kref_init(&job->refcount);
593−
594− ret = drm_syncobj_find_fence(file_priv, args->in_sync,
595− 0, 0, &job->in_fence);
596− if (ret == -EINVAL)
597− goto fail;
659+ job->base.bo = kcalloc(ARRAY_SIZE(args->bo_handles),
660+ sizeof(*job->base.bo), GFP_KERNEL);
661+ if (!job->base.bo) {
662+ v3d_job_put(&job->base);
663+ return -ENOMEM;
664+ }
598665
599666 job->args = *args;
600− job->v3d = v3d;
601667
602668 spin_lock(&file_priv->table_lock);
603− for (bo_count = 0; bo_count < ARRAY_SIZE(job->bo); bo_count++) {
669+ for (job->base.bo_count = 0;
670+ job->base.bo_count < ARRAY_SIZE(args->bo_handles);
671+ job->base.bo_count++) {
604672 struct drm_gem_object *bo;
605673
606− if (!args->bo_handles[bo_count])
674+ if (!args->bo_handles[job->base.bo_count])
607675 break;
608676
609677 bo = idr_find(&file_priv->object_idr,
610− args->bo_handles[bo_count]);
678+ args->bo_handles[job->base.bo_count]);
611679 if (!bo) {
612680 DRM_DEBUG("Failed to look up GEM BO %d: %d\n",
613− bo_count, args->bo_handles[bo_count]);
681+ job->base.bo_count,
682+ args->bo_handles[job->base.bo_count]);
614683 ret = -ENOENT;
615684 spin_unlock(&file_priv->table_lock);
616685 goto fail;
617686 }
618687 drm_gem_object_get(bo);
619− job->bo[bo_count] = to_v3d_bo(bo);
688+ job->base.bo[job->base.bo_count] = bo;
620689 }
621690 spin_unlock(&file_priv->table_lock);
622691
623− ret = v3d_lock_bo_reservations(job->bo, bo_count, &acquire_ctx);
692+ ret = v3d_lock_bo_reservations(&job->base, &acquire_ctx);
624693 if (ret)
625694 goto fail;
626695
627696 mutex_lock(&v3d->sched_lock);
628− ret = drm_sched_job_init(&job->base,
629− &v3d_priv->sched_entity[V3D_TFU],
630− v3d_priv);
697+ ret = v3d_push_job(v3d_priv, &job->base, V3D_TFU);
631698 if (ret)
632699 goto fail_unreserve;
700+ mutex_unlock(&v3d->sched_lock);
633701
634− sched_done_fence = dma_fence_get(&job->base.s_fence->finished);
702+ v3d_attach_fences_and_unlock_reservation(file_priv,
703+ &job->base, &acquire_ctx,
704+ args->out_sync,
705+ job->base.done_fence);
635706
636− kref_get(&job->refcount); /* put by scheduler job completion */
637− drm_sched_entity_push_job(&job->base, &v3d_priv->sched_entity[V3D_TFU]);
707+ v3d_job_put(&job->base);
708+
709+ return 0;
710+
711+fail_unreserve:
638712 mutex_unlock(&v3d->sched_lock);
713+ drm_gem_unlock_reservations(job->base.bo, job->base.bo_count,
714+ &acquire_ctx);
715+fail:
716+ v3d_job_put(&job->base);
639717
640− v3d_attach_object_fences(job->bo, bo_count, sched_done_fence);
718+ return ret;
719+}
641720
642− v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
721+/**
722+ * v3d_submit_csd_ioctl() - Submits a CSD (texture formatting) job to the V3D.
723+ * @dev: DRM device
724+ * @data: ioctl argument
725+ * @file_priv: DRM file for this fd
726+ *
727+ * Userspace provides the register setup for the CSD, which we don't
728+ * need to validate since the CSD is behind the MMU.
729+ */
730+int
731+v3d_submit_csd_ioctl(struct drm_device *dev, void *data,
732+ struct drm_file *file_priv)
733+{
734+ struct v3d_dev *v3d = to_v3d_dev(dev);
735+ struct v3d_file_priv *v3d_priv = file_priv->driver_priv;
736+ struct drm_v3d_submit_csd *args = data;
737+ struct v3d_csd_job *job;
738+ struct v3d_job *clean_job;
739+ struct ww_acquire_ctx acquire_ctx;
740+ int ret;
643741
644− /* Update the return sync object */
645− sync_out = drm_syncobj_find(file_priv, args->out_sync);
646− if (sync_out) {
647− drm_syncobj_replace_fence(sync_out, sched_done_fence);
648− drm_syncobj_put(sync_out);
742+ trace_v3d_submit_csd_ioctl(&v3d->drm, args->cfg[5], args->cfg[6]);
743+
744+ if (!v3d_has_csd(v3d)) {
745+ DRM_DEBUG("Attempting CSD submit on non-CSD hardware\n");
746+ return -EINVAL;
747+ }
748+
749+ job = kcalloc(1, sizeof(*job), GFP_KERNEL);
750+ if (!job)
751+ return -ENOMEM;
752+
753+ ret = v3d_job_init(v3d, file_priv, &job->base,
754+ v3d_job_free, args->in_sync);
755+ if (ret) {
756+ kfree(job);
757+ return ret;
758+ }
759+
760+ clean_job = kcalloc(1, sizeof(*clean_job), GFP_KERNEL);
761+ if (!clean_job) {
762+ v3d_job_put(&job->base);
763+ kfree(job);
764+ return -ENOMEM;
649765 }
650− dma_fence_put(sched_done_fence);
651766
652− v3d_tfu_job_put(job);
767+ ret = v3d_job_init(v3d, file_priv, clean_job, v3d_job_free, 0);
768+ if (ret) {
769+ v3d_job_put(&job->base);
770+ kfree(clean_job);
771+ return ret;
772+ }
773+
774+ job->args = *args;
775+
776+ ret = v3d_lookup_bos(dev, file_priv, clean_job,
777+ args->bo_handles, args->bo_handle_count);
778+ if (ret)
779+ goto fail;
780+
781+ ret = v3d_lock_bo_reservations(clean_job, &acquire_ctx);
782+ if (ret)
783+ goto fail;
784+
785+ mutex_lock(&v3d->sched_lock);
786+ ret = v3d_push_job(v3d_priv, &job->base, V3D_CSD);
787+ if (ret)
788+ goto fail_unreserve;
789+
790+ ret = drm_gem_fence_array_add(&clean_job->deps,
791+ dma_fence_get(job->base.done_fence));
792+ if (ret)
793+ goto fail_unreserve;
794+
795+ ret = v3d_push_job(v3d_priv, clean_job, V3D_CACHE_CLEAN);
796+ if (ret)
797+ goto fail_unreserve;
798+ mutex_unlock(&v3d->sched_lock);
799+
800+ v3d_attach_fences_and_unlock_reservation(file_priv,
801+ clean_job,
802+ &acquire_ctx,
803+ args->out_sync,
804+ clean_job->done_fence);
805+
806+ v3d_job_put(&job->base);
807+ v3d_job_put(clean_job);
653808
654809 return 0;
655810
656811 fail_unreserve:
657812 mutex_unlock(&v3d->sched_lock);
658− v3d_unlock_bo_reservations(job->bo, bo_count, &acquire_ctx);
813+ drm_gem_unlock_reservations(clean_job->bo, clean_job->bo_count,
814+ &acquire_ctx);
659815 fail:
660− v3d_tfu_job_put(job);
816+ v3d_job_put(&job->base);
817+ v3d_job_put(clean_job);
661818
662819 return ret;
663820 }
@@ -677,6 +834,7 @@ v3d_gem_init(struct drm_device *dev) · 13 unmodified lines
677834 mutex_init(&v3d->bo_lock);
678835 mutex_init(&v3d->reset_lock);
679836 mutex_init(&v3d->sched_lock);
837+ mutex_init(&v3d->cache_clean_lock);
680838
681839 /* Note: We don't allocate address 0. Various bits of HW
682840 * treat 0 as special, such as the occlusion query counters
@@ -715,7 +873,7 @@ v3d_gem_destroy(struct drm_device *dev) · 32 unmodified lines
715873
716874 v3d_sched_fini(v3d);
717875
718− /* Waiting for exec to finish would need to be done before
876+ /* Waiting for jobs to finish would need to be done before
719877 * unregistering V3D.
720878 */
721879 WARN_ON(v3d->bin_job);
drivers/gpu/drm/v3d/v3d_irq.c+44−11
@@ -4,9 +4,9 @@ · 3 unmodified lines
44 /**
55 * DOC: Interrupt management for the V3D engine
66 *
7− * When we take a bin, render, or TFU done interrupt, we need to
8− * signal the fence for that job so that the scheduler can queue up
9− * the next one and unblock any waiters.
7+ * When we take a bin, render, TFU done, or CSD done interrupt, we
8+ * need to signal the fence for that job so that the scheduler can
9+ * queue up the next one and unblock any waiters.
1010 *
1111 * When we take the binner out of memory interrupt, we need to
1212 * allocate some new memory and pass it to the binner so that the
@@ -20,6 +20,7 @@ · 7 unmodified lines
2020 #define V3D_CORE_IRQS ((u32)(V3D_INT_OUTOMEM | \
2121 V3D_INT_FLDONE | \
2222 V3D_INT_FRDONE | \
23+ V3D_INT_CSDDONE | \
2324 V3D_INT_GMPV))
2425
2526 #define V3D_HUB_IRQS ((u32)(V3D_HUB_INT_MMU_WRV | \
@@ -62,7 +63,7 @@ v3d_overflow_mem_work(struct work_struct *work) · 36 unmodified lines
6263 }
6364
6465 drm_gem_object_get(obj);
65− list_add_tail(&bo->unref_head, &v3d->bin_job->unref_list);
66+ list_add_tail(&bo->unref_head, &v3d->bin_job->render->unref_list);
6667 spin_unlock_irqrestore(&v3d->job_lock, irqflags);
6768
6869 V3D_CORE_WRITE(0, V3D_PTB_BPOA, bo->node.start << PAGE_SHIFT);
@@ -96,7 +97,7 @@ v3d_irq(int irq, void *arg) · 27 unmodified lines
9697
9798 if (intsts & V3D_INT_FLDONE) {
9899 struct v3d_fence *fence =
99− to_v3d_fence(v3d->bin_job->bin.irq_fence);
100+ to_v3d_fence(v3d->bin_job->base.irq_fence);
100101
101102 trace_v3d_bcl_irq(&v3d->drm, fence->seqno);
102103 dma_fence_signal(&fence->base);
@@ -105,13 +106,22 @@ v3d_irq(int irq, void *arg) · 2 unmodified lines
105106
106107 if (intsts & V3D_INT_FRDONE) {
107108 struct v3d_fence *fence =
108− to_v3d_fence(v3d->render_job->render.irq_fence);
109+ to_v3d_fence(v3d->render_job->base.irq_fence);
109110
110111 trace_v3d_rcl_irq(&v3d->drm, fence->seqno);
111112 dma_fence_signal(&fence->base);
112113 status = IRQ_HANDLED;
113114 }
114115
116+ if (intsts & V3D_INT_CSDDONE) {
117+ struct v3d_fence *fence =
118+ to_v3d_fence(v3d->csd_job->base.irq_fence);
119+
120+ trace_v3d_csd_irq(&v3d->drm, fence->seqno);
121+ dma_fence_signal(&fence->base);
122+ status = IRQ_HANDLED;
123+ }
124+
115125 /* We shouldn't be triggering these if we have GMP in
116126 * always-allowed mode.
117127 */
@@ -141,7 +151,7 @@ v3d_hub_irq(int irq, void *arg) · 23 unmodified lines
141151
142152 if (intsts & V3D_HUB_INT_TFUC) {
143153 struct v3d_fence *fence =
144− to_v3d_fence(v3d->tfu_job->irq_fence);
154+ to_v3d_fence(v3d->tfu_job->base.irq_fence);
145155
146156 trace_v3d_tfu_irq(&v3d->drm, fence->seqno);
147157 dma_fence_signal(&fence->base);
@@ -152,10 +162,33 @@ v3d_hub_irq(int irq, void *arg) · 4 unmodified lines
152162 V3D_HUB_INT_MMU_PTI |
153163 V3D_HUB_INT_MMU_CAP)) {
154164 u32 axi_id = V3D_READ(V3D_MMU_VIO_ID);
155− u64 vio_addr = (u64)V3D_READ(V3D_MMU_VIO_ADDR) << 8;
156−
157− dev_err(v3d->dev, "MMU error from client %d at 0x%08llx%s%s%s\n",
158− axi_id, (long long)vio_addr,
165+ u64 vio_addr = ((u64)V3D_READ(V3D_MMU_VIO_ADDR) <<
166+ (v3d->va_width - 32));
167+ static const char *const v3d41_axi_ids[] = {
168+ "L2T",
169+ "PTB",
170+ "PSE",
171+ "TLB",
172+ "CLE",
173+ "TFU",
174+ "MMU",
175+ "GMP",
176+ };
177+ const char *client = "?";
178+
179+ V3D_WRITE(V3D_MMU_CTL,
180+ V3D_READ(V3D_MMU_CTL) & (V3D_MMU_CTL_CAP_EXCEEDED |
181+ V3D_MMU_CTL_PT_INVALID |
182+ V3D_MMU_CTL_WRITE_VIOLATION));
183+
184+ if (v3d->ver >= 41) {
185+ axi_id = axi_id >> 5;
186+ if (axi_id < ARRAY_SIZE(v3d41_axi_ids))
187+ client = v3d41_axi_ids[axi_id];
188+ }
189+
190+ dev_err(v3d->dev, "MMU error from client %s (%d) at 0x%llx%s%s%s\n",
191+ client, axi_id, (long long)vio_addr,
159192 ((intsts & V3D_HUB_INT_MMU_WRV) ?
160193 ", write violation" : ""),
161194 ((intsts & V3D_HUB_INT_MMU_PTI) ?
drivers/gpu/drm/v3d/v3d_mmu.c+5−2
@@ -69,10 +69,13 @@ int v3d_mmu_set_page_table(struct v3d_dev *v3d) · 68 unmodified lines
6969 V3D_WRITE(V3D_MMU_PT_PA_BASE, v3d->pt_paddr >> V3D_MMU_PAGE_SHIFT);
7070 V3D_WRITE(V3D_MMU_CTL,
7171 V3D_MMU_CTL_ENABLE |
72− V3D_MMU_CTL_PT_INVALID |
72+ V3D_MMU_CTL_PT_INVALID_ENABLE |
7373 V3D_MMU_CTL_PT_INVALID_ABORT |
74+ V3D_MMU_CTL_PT_INVALID_INT |
7475 V3D_MMU_CTL_WRITE_VIOLATION_ABORT |
75− V3D_MMU_CTL_CAP_EXCEEDED_ABORT);
76+ V3D_MMU_CTL_WRITE_VIOLATION_INT |
77+ V3D_MMU_CTL_CAP_EXCEEDED_ABORT |
78+ V3D_MMU_CTL_CAP_EXCEEDED_INT);
7679 V3D_WRITE(V3D_MMU_ILLEGAL_ADDR,
7780 (v3d->mmu_scratch_paddr >> V3D_MMU_PAGE_SHIFT) |
7881 V3D_MMU_ILLEGAL_ADDR_ENABLE);
drivers/gpu/drm/v3d/v3d_regs.h+121−1
@@ -152,7 +152,8 @@ · 151 unmodified lines
152152 # define V3D_MMU_CTL_PT_INVALID_ABORT BIT(19)
153153 # define V3D_MMU_CTL_PT_INVALID_INT BIT(18)
154154 # define V3D_MMU_CTL_PT_INVALID_EXCEPTION BIT(17)
155−# define V3D_MMU_CTL_WRITE_VIOLATION BIT(16)
155+# define V3D_MMU_CTL_PT_INVALID_ENABLE BIT(16)
156+# define V3D_MMU_CTL_WRITE_VIOLATION BIT(12)
156157 # define V3D_MMU_CTL_WRITE_VIOLATION_ABORT BIT(11)
157158 # define V3D_MMU_CTL_WRITE_VIOLATION_INT BIT(10)
158159 # define V3D_MMU_CTL_WRITE_VIOLATION_EXCEPTION BIT(9)
@@ -191,6 +192,14 @@ · 32 unmodified lines
191192 /* Address that faulted */
192193 #define V3D_MMU_VIO_ADDR 0x01234
193194
195+#define V3D_MMU_DEBUG_INFO 0x01238
196+# define V3D_MMU_PA_WIDTH_MASK V3D_MASK(11, 8)
197+# define V3D_MMU_PA_WIDTH_SHIFT 8
198+# define V3D_MMU_VA_WIDTH_MASK V3D_MASK(7, 4)
199+# define V3D_MMU_VA_WIDTH_SHIFT 4
200+# define V3D_MMU_VERSION_MASK V3D_MASK(3, 0)
201+# define V3D_MMU_VERSION_SHIFT 0
202+
194203 /* Per-V3D-core registers */
195204
196205 #define V3D_CTL_IDENT0 0x00000
@@ -238,8 +247,11 @@ · 41 unmodified lines
238247 #define V3D_CTL_L2TCACTL 0x00030
239248 # define V3D_L2TCACTL_TMUWCF BIT(8)
240249 # define V3D_L2TCACTL_L2T_NO_WM BIT(4)
250+/* Invalidates cache lines. */
241251 # define V3D_L2TCACTL_FLM_FLUSH 0
252+/* Removes cachelines without writing dirty lines back. */
242253 # define V3D_L2TCACTL_FLM_CLEAR 1
254+/* Writes out dirty cachelines and marks them clean, but doesn't invalidate. */
243255 # define V3D_L2TCACTL_FLM_CLEAN 2
244256 # define V3D_L2TCACTL_FLM_MASK V3D_MASK(2, 1)
245257 # define V3D_L2TCACTL_FLM_SHIFT 1
@@ -255,6 +267,8 @@ · 9 unmodified lines
255267 #define V3D_CTL_INT_MSK_CLR 0x00064
256268 # define V3D_INT_QPU_MASK V3D_MASK(27, 16)
257269 # define V3D_INT_QPU_SHIFT 16
270+# define V3D_INT_CSDDONE BIT(7)
271+# define V3D_INT_PCTR BIT(6)
258272 # define V3D_INT_GMPV BIT(5)
259273 # define V3D_INT_TRFB BIT(4)
260274 # define V3D_INT_SPILLUSE BIT(3)
@@ -374,4 +388,110 @@ · 113 unmodified lines
374388 #define V3D_GMP_PRESERVE_LOAD 0x00818
375389 #define V3D_GMP_VALID_LINES 0x00820
376390
391+#define V3D_CSD_STATUS 0x00900
392+# define V3D_CSD_STATUS_NUM_COMPLETED_MASK V3D_MASK(11, 4)
393+# define V3D_CSD_STATUS_NUM_COMPLETED_SHIFT 4
394+# define V3D_CSD_STATUS_NUM_ACTIVE_MASK V3D_MASK(3, 2)
395+# define V3D_CSD_STATUS_NUM_ACTIVE_SHIFT 2
396+# define V3D_CSD_STATUS_HAVE_CURRENT_DISPATCH BIT(1)
397+# define V3D_CSD_STATUS_HAVE_QUEUED_DISPATCH BIT(0)
398+
399+#define V3D_CSD_QUEUED_CFG0 0x00904
400+# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_MASK V3D_MASK(31, 16)
401+# define V3D_CSD_QUEUED_CFG0_NUM_WGS_X_SHIFT 16
402+# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_MASK V3D_MASK(15, 0)
403+# define V3D_CSD_QUEUED_CFG0_WG_X_OFFSET_SHIFT 0
404+
405+#define V3D_CSD_QUEUED_CFG1 0x00908
406+# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_MASK V3D_MASK(31, 16)
407+# define V3D_CSD_QUEUED_CFG1_NUM_WGS_Y_SHIFT 16
408+# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_MASK V3D_MASK(15, 0)
409+# define V3D_CSD_QUEUED_CFG1_WG_Y_OFFSET_SHIFT 0
410+
411+#define V3D_CSD_QUEUED_CFG2 0x0090c
412+# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_MASK V3D_MASK(31, 16)
413+# define V3D_CSD_QUEUED_CFG2_NUM_WGS_Z_SHIFT 16
414+# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_MASK V3D_MASK(15, 0)
415+# define V3D_CSD_QUEUED_CFG2_WG_Z_OFFSET_SHIFT 0
416+
417+#define V3D_CSD_QUEUED_CFG3 0x00910
418+# define V3D_CSD_QUEUED_CFG3_OVERLAP_WITH_PREV BIT(26)
419+# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_MASK V3D_MASK(25, 20)
420+# define V3D_CSD_QUEUED_CFG3_MAX_SG_ID_SHIFT 20
421+# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_MASK V3D_MASK(19, 12)
422+# define V3D_CSD_QUEUED_CFG3_BATCHES_PER_SG_M1_SHIFT 12
423+# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_MASK V3D_MASK(11, 8)
424+# define V3D_CSD_QUEUED_CFG3_WGS_PER_SG_SHIFT 8
425+# define V3D_CSD_QUEUED_CFG3_WG_SIZE_MASK V3D_MASK(7, 0)
426+# define V3D_CSD_QUEUED_CFG3_WG_SIZE_SHIFT 0
427+
428+/* Number of batches, minus 1 */
429+#define V3D_CSD_QUEUED_CFG4 0x00914
430+
431+/* Shader address, pnan, singleseg, threading, like a shader record. */
432+#define V3D_CSD_QUEUED_CFG5 0x00918
433+
434+/* Uniforms address (4 byte aligned) */
435+#define V3D_CSD_QUEUED_CFG6 0x0091c
436+
437+#define V3D_CSD_CURRENT_CFG0 0x00920
438+#define V3D_CSD_CURRENT_CFG1 0x00924
439+#define V3D_CSD_CURRENT_CFG2 0x00928
440+#define V3D_CSD_CURRENT_CFG3 0x0092c
441+#define V3D_CSD_CURRENT_CFG4 0x00930
442+#define V3D_CSD_CURRENT_CFG5 0x00934
443+#define V3D_CSD_CURRENT_CFG6 0x00938
444+
445+#define V3D_CSD_CURRENT_ID0 0x0093c
446+# define V3D_CSD_CURRENT_ID0_WG_X_MASK V3D_MASK(31, 16)
447+# define V3D_CSD_CURRENT_ID0_WG_X_SHIFT 16
448+# define V3D_CSD_CURRENT_ID0_WG_IN_SG_MASK V3D_MASK(11, 8)
449+# define V3D_CSD_CURRENT_ID0_WG_IN_SG_SHIFT 8
450+# define V3D_CSD_CURRENT_ID0_L_IDX_MASK V3D_MASK(7, 0)
451+# define V3D_CSD_CURRENT_ID0_L_IDX_SHIFT 0
452+
453+#define V3D_CSD_CURRENT_ID1 0x00940
454+# define V3D_CSD_CURRENT_ID0_WG_Z_MASK V3D_MASK(31, 16)
455+# define V3D_CSD_CURRENT_ID0_WG_Z_SHIFT 16
456+# define V3D_CSD_CURRENT_ID0_WG_Y_MASK V3D_MASK(15, 0)
457+# define V3D_CSD_CURRENT_ID0_WG_Y_SHIFT 0
458+
459+#define V3D_ERR_FDBGO 0x00f04
460+#define V3D_ERR_FDBGB 0x00f08
461+#define V3D_ERR_FDBGR 0x00f0c
462+
463+#define V3D_ERR_FDBGS 0x00f10
464+# define V3D_ERR_FDBGS_INTERPZ_IP_STALL BIT(17)
465+# define V3D_ERR_FDBGS_DEPTHO_FIFO_IP_STALL BIT(16)
466+# define V3D_ERR_FDBGS_XYNRM_IP_STALL BIT(14)
467+# define V3D_ERR_FDBGS_EZREQ_FIFO_OP_VALID BIT(13)
468+# define V3D_ERR_FDBGS_QXYF_FIFO_OP_VALID BIT(12)
469+# define V3D_ERR_FDBGS_QXYF_FIFO_OP_LAST BIT(11)
470+# define V3D_ERR_FDBGS_EZTEST_ANYQVALID BIT(7)
471+# define V3D_ERR_FDBGS_EZTEST_PASS BIT(6)
472+# define V3D_ERR_FDBGS_EZTEST_QREADY BIT(5)
473+# define V3D_ERR_FDBGS_EZTEST_VLF_OKNOVALID BIT(4)
474+# define V3D_ERR_FDBGS_EZTEST_QSTALL BIT(3)
475+# define V3D_ERR_FDBGS_EZTEST_IP_VLFSTALL BIT(2)
476+# define V3D_ERR_FDBGS_EZTEST_IP_PRSTALL BIT(1)
477+# define V3D_ERR_FDBGS_EZTEST_IP_QSTALL BIT(0)
478+
479+#define V3D_ERR_STAT 0x00f20
480+# define V3D_ERR_L2CARE BIT(15)
481+# define V3D_ERR_VCMBE BIT(14)
482+# define V3D_ERR_VCMRE BIT(13)
483+# define V3D_ERR_VCDI BIT(12)
484+# define V3D_ERR_VCDE BIT(11)
485+# define V3D_ERR_VDWE BIT(10)
486+# define V3D_ERR_VPMEAS BIT(9)
487+# define V3D_ERR_VPMEFNA BIT(8)
488+# define V3D_ERR_VPMEWNA BIT(7)
489+# define V3D_ERR_VPMERNA BIT(6)
490+# define V3D_ERR_VPMERR BIT(5)
491+# define V3D_ERR_VPMEWR BIT(4)
492+# define V3D_ERR_VPAERRGL BIT(3)
493+# define V3D_ERR_VPAEBRGL BIT(2)
494+# define V3D_ERR_VPAERGS BIT(1)
495+# define V3D_ERR_VPAEABB BIT(0)
496+
377497 #endif /* V3D_REGS_H */
drivers/gpu/drm/v3d/v3d_sched.c+250−132
@@ -30,158 +30,152 @@ to_v3d_job(struct drm_sched_job *sched_job) · 29 unmodified lines
3030 return container_of(sched_job, struct v3d_job, base);
3131 }
3232
33−static struct v3d_tfu_job *
34−to_tfu_job(struct drm_sched_job *sched_job)
33+static struct v3d_bin_job *
34+to_bin_job(struct drm_sched_job *sched_job)
3535 {
36− return container_of(sched_job, struct v3d_tfu_job, base);
36+ return container_of(sched_job, struct v3d_bin_job, base.base);
3737 }
3838
39−static void
40−v3d_job_free(struct drm_sched_job *sched_job)
39+static struct v3d_render_job *
40+to_render_job(struct drm_sched_job *sched_job)
4141 {
42− struct v3d_job *job = to_v3d_job(sched_job);
42+ return container_of(sched_job, struct v3d_render_job, base.base);
43+}
4344
44− drm_sched_job_cleanup(sched_job);
45+static struct v3d_tfu_job *
46+to_tfu_job(struct drm_sched_job *sched_job)
47+{
48+ return container_of(sched_job, struct v3d_tfu_job, base.base);
49+}
4550
46− v3d_exec_put(job->exec);
51+static struct v3d_csd_job *
52+to_csd_job(struct drm_sched_job *sched_job)
53+{
54+ return container_of(sched_job, struct v3d_csd_job, base.base);
4755 }
4856
4957 static void
50−v3d_tfu_job_free(struct drm_sched_job *sched_job)
58+v3d_job_free(struct drm_sched_job *sched_job)
5159 {
52− struct v3d_tfu_job *job = to_tfu_job(sched_job);
60+ struct v3d_job *job = to_v3d_job(sched_job);
5361
5462 drm_sched_job_cleanup(sched_job);
55−
56− v3d_tfu_job_put(job);
63+ v3d_job_put(job);
5764 }
5865
5966 /**
60− * Returns the fences that the bin or render job depends on, one by one.
61− * v3d_job_run() won't be called until all of them have been signaled.
67+ * Returns the fences that the job depends on, one by one.
68+ *
69+ * If placed in the scheduler's .dependency method, the corresponding
70+ * .run_job won't be called until all of them have been signaled.
6271 */
6372 static struct dma_fence *
6473 v3d_job_dependency(struct drm_sched_job *sched_job,
6574 struct drm_sched_entity *s_entity)
6675 {
6776 struct v3d_job *job = to_v3d_job(sched_job);
68− struct v3d_exec_info *exec = job->exec;
69− enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER;
70− struct dma_fence *fence;
71−
72− fence = job->in_fence;
73− if (fence) {
74− job->in_fence = NULL;
75− return fence;
76− }
77−
78− if (q == V3D_RENDER) {
79− /* If we had a bin job, the render job definitely depends on
80− * it. We first have to wait for bin to be scheduled, so that
81− * its done_fence is created.
82− */
83− fence = exec->bin_done_fence;
84− if (fence) {
85− exec->bin_done_fence = NULL;
86− return fence;
87− }
88− }
8977
9078 /* XXX: Wait on a fence for switching the GMP if necessary,
9179 * and then do so.
9280 */
9381
94− return fence;
95−}
96−
97−/**
98− * Returns the fences that the TFU job depends on, one by one.
99− * v3d_tfu_job_run() won't be called until all of them have been
100− * signaled.
101− */
102−static struct dma_fence *
103−v3d_tfu_job_dependency(struct drm_sched_job *sched_job,
104− struct drm_sched_entity *s_entity)
105−{
106− struct v3d_tfu_job *job = to_tfu_job(sched_job);
107− struct dma_fence *fence;
108−
109− fence = job->in_fence;
110− if (fence) {
111− job->in_fence = NULL;
112− return fence;
113− }
82+ if (!xa_empty(&job->deps))
83+ return xa_erase(&job->deps, job->last_dep++);
11484
11585 return NULL;
11686 }
11787
118−static struct dma_fence *v3d_job_run(struct drm_sched_job *sched_job)
88+static struct dma_fence *v3d_bin_job_run(struct drm_sched_job *sched_job)
11989 {
120− struct v3d_job *job = to_v3d_job(sched_job);
121− struct v3d_exec_info *exec = job->exec;
122− enum v3d_queue q = job == &exec->bin ? V3D_BIN : V3D_RENDER;
123− struct v3d_dev *v3d = exec->v3d;
90+ struct v3d_bin_job *job = to_bin_job(sched_job);
91+ struct v3d_dev *v3d = job->base.v3d;
12492 struct drm_device *dev = &v3d->drm;
12593 struct dma_fence *fence;
12694 unsigned long irqflags;
12795
128− if (unlikely(job->base.s_fence->finished.error))
96+ if (unlikely(job->base.base.s_fence->finished.error))
12997 return NULL;
13098
13199 /* Lock required around bin_job update vs
132100 * v3d_overflow_mem_work().
133101 */
134102 spin_lock_irqsave(&v3d->job_lock, irqflags);
135− if (q == V3D_BIN) {
136− v3d->bin_job = job->exec;
137−
138− /* Clear out the overflow allocation, so we don't
139− * reuse the overflow attached to a previous job.
140− */
141− V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0);
142− } else {
143− v3d->render_job = job->exec;
144− }
103+ v3d->bin_job = job;
104+ /* Clear out the overflow allocation, so we don't
105+ * reuse the overflow attached to a previous job.
106+ */
107+ V3D_CORE_WRITE(0, V3D_PTB_BPOS, 0);
145108 spin_unlock_irqrestore(&v3d->job_lock, irqflags);
146109
147− /* Can we avoid this flush when q==RENDER? We need to be
148− * careful of scheduling, though -- imagine job0 rendering to
149− * texture and job1 reading, and them being executed as bin0,
150− * bin1, render0, render1, so that render1's flush at bin time
110+ v3d_invalidate_caches(v3d);
111+
112+ fence = v3d_fence_create(v3d, V3D_BIN);
113+ if (IS_ERR(fence))
114+ return NULL;
115+
116+ if (job->base.irq_fence)
117+ dma_fence_put(job->base.irq_fence);
118+ job->base.irq_fence = dma_fence_get(fence);
119+
120+ trace_v3d_submit_cl(dev, false, to_v3d_fence(fence)->seqno,
121+ job->start, job->end);
122+
123+ /* Set the current and end address of the control list.
124+ * Writing the end register is what starts the job.
125+ */
126+ if (job->qma) {
127+ V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, job->qma);
128+ V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, job->qms);
129+ }
130+ if (job->qts) {
131+ V3D_CORE_WRITE(0, V3D_CLE_CT0QTS,
132+ V3D_CLE_CT0QTS_ENABLE |
133+ job->qts);
134+ }
135+ V3D_CORE_WRITE(0, V3D_CLE_CT0QBA, job->start);
136+ V3D_CORE_WRITE(0, V3D_CLE_CT0QEA, job->end);
137+
138+ return fence;
139+}
140+
141+static struct dma_fence *v3d_render_job_run(struct drm_sched_job *sched_job)
142+{
143+ struct v3d_render_job *job = to_render_job(sched_job);
144+ struct v3d_dev *v3d = job->base.v3d;
145+ struct drm_device *dev = &v3d->drm;
146+ struct dma_fence *fence;
147+
148+ if (unlikely(job->base.base.s_fence->finished.error))
149+ return NULL;
150+
151+ v3d->render_job = job;
152+
153+ /* Can we avoid this flush? We need to be careful of
154+ * scheduling, though -- imagine job0 rendering to texture and
155+ * job1 reading, and them being executed as bin0, bin1,
156+ * render0, render1, so that render1's flush at bin time
151157 * wasn't enough.
152158 */
153159 v3d_invalidate_caches(v3d);
154160
155− fence = v3d_fence_create(v3d, q);
161+ fence = v3d_fence_create(v3d, V3D_RENDER);
156162 if (IS_ERR(fence))
157163 return NULL;
158164
159− if (job->irq_fence)
160− dma_fence_put(job->irq_fence);
161− job->irq_fence = dma_fence_get(fence);
165+ if (job->base.irq_fence)
166+ dma_fence_put(job->base.irq_fence);
167+ job->base.irq_fence = dma_fence_get(fence);
162168
163− trace_v3d_submit_cl(dev, q == V3D_RENDER, to_v3d_fence(fence)->seqno,
169+ trace_v3d_submit_cl(dev, true, to_v3d_fence(fence)->seqno,
164170 job->start, job->end);
165171
166− if (q == V3D_BIN) {
167− if (exec->qma) {
168− V3D_CORE_WRITE(0, V3D_CLE_CT0QMA, exec->qma);
169− V3D_CORE_WRITE(0, V3D_CLE_CT0QMS, exec->qms);
170− }
171− if (exec->qts) {
172− V3D_CORE_WRITE(0, V3D_CLE_CT0QTS,
173− V3D_CLE_CT0QTS_ENABLE |
174− exec->qts);
175− }
176− } else {
177− /* XXX: Set the QCFG */
178− }
172+ /* XXX: Set the QCFG */
179173
180174 /* Set the current and end address of the control list.
181175 * Writing the end register is what starts the job.
182176 */
183− V3D_CORE_WRITE(0, V3D_CLE_CTNQBA(q), job->start);
184− V3D_CORE_WRITE(0, V3D_CLE_CTNQEA(q), job->end);
177+ V3D_CORE_WRITE(0, V3D_CLE_CT1QBA, job->start);
178+ V3D_CORE_WRITE(0, V3D_CLE_CT1QEA, job->end);
185179
186180 return fence;
187181 }
@@ -190,7 +184,7 @@ static struct dma_fence * · 2 unmodified lines
190184 v3d_tfu_job_run(struct drm_sched_job *sched_job)
191185 {
192186 struct v3d_tfu_job *job = to_tfu_job(sched_job);
193− struct v3d_dev *v3d = job->v3d;
187+ struct v3d_dev *v3d = job->base.v3d;
194188 struct drm_device *dev = &v3d->drm;
195189 struct dma_fence *fence;
196190
@@ -199,9 +193,9 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job) · 2 unmodified lines
199193 return NULL;
200194
201195 v3d->tfu_job = job;
202− if (job->irq_fence)
203− dma_fence_put(job->irq_fence);
204− job->irq_fence = dma_fence_get(fence);
196+ if (job->base.irq_fence)
197+ dma_fence_put(job->base.irq_fence);
198+ job->base.irq_fence = dma_fence_get(fence);
205199
206200 trace_v3d_submit_tfu(dev, to_v3d_fence(fence)->seqno);
207201
@@ -223,6 +217,48 @@ v3d_tfu_job_run(struct drm_sched_job *sched_job) · 15 unmodified lines
223217 return fence;
224218 }
225219
220+static struct dma_fence *
221+v3d_csd_job_run(struct drm_sched_job *sched_job)
222+{
223+ struct v3d_csd_job *job = to_csd_job(sched_job);
224+ struct v3d_dev *v3d = job->base.v3d;
225+ struct drm_device *dev = &v3d->drm;
226+ struct dma_fence *fence;
227+ int i;
228+
229+ v3d->csd_job = job;
230+
231+ v3d_invalidate_caches(v3d);
232+
233+ fence = v3d_fence_create(v3d, V3D_CSD);
234+ if (IS_ERR(fence))
235+ return NULL;
236+
237+ if (job->base.irq_fence)
238+ dma_fence_put(job->base.irq_fence);
239+ job->base.irq_fence = dma_fence_get(fence);
240+
241+ trace_v3d_submit_csd(dev, to_v3d_fence(fence)->seqno);
242+
243+ for (i = 1; i <= 6; i++)
244+ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0 + 4 * i, job->args.cfg[i]);
245+ /* CFG0 write kicks off the job. */
246+ V3D_CORE_WRITE(0, V3D_CSD_QUEUED_CFG0, job->args.cfg[0]);
247+
248+ return fence;
249+}
250+
251+static struct dma_fence *
252+v3d_cache_clean_job_run(struct drm_sched_job *sched_job)
253+{
254+ struct v3d_job *job = to_v3d_job(sched_job);
255+ struct v3d_dev *v3d = job->v3d;
256+
257+ v3d_clean_caches(v3d);
258+
259+ return NULL;
260+}
261+
226262 static void
227263 v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job)
228264 {
@@ -232,7 +268,7 @@ v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) · 3 unmodified lines
232268
233269 /* block scheduler */
234270 for (q = 0; q < V3D_MAX_QUEUES; q++)
235− drm_sched_stop(&v3d->queue[q].sched);
271+ drm_sched_stop(&v3d->queue[q].sched, sched_job);
236272
237273 if (sched_job)
238274 drm_sched_increase_karma(sched_job);
@@ -251,25 +287,23 @@ v3d_gpu_reset_for_timeout(struct v3d_dev *v3d, struct drm_sched_job *sched_job) · 12 unmodified lines
251287 mutex_unlock(&v3d->reset_lock);
252288 }
253289
290+/* If the current address or return address have changed, then the GPU
291+ * has probably made progress and we should delay the reset. This
292+ * could fail if the GPU got in an infinite loop in the CL, but that
293+ * is pretty unlikely outside of an i-g-t testcase.
294+ */
254295 static void
255−v3d_job_timedout(struct drm_sched_job *sched_job)
296+v3d_cl_job_timedout(struct drm_sched_job *sched_job, enum v3d_queue q,
297+ u32 *timedout_ctca, u32 *timedout_ctra)
256298 {
257299 struct v3d_job *job = to_v3d_job(sched_job);
258− struct v3d_exec_info *exec = job->exec;
259− struct v3d_dev *v3d = exec->v3d;
260− enum v3d_queue job_q = job == &exec->bin ? V3D_BIN : V3D_RENDER;
261− u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(job_q));
262− u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(job_q));
263−
264− /* If the current address or return address have changed, then
265− * the GPU has probably made progress and we should delay the
266− * reset. This could fail if the GPU got in an infinite loop
267− * in the CL, but that is pretty unlikely outside of an i-g-t
268− * testcase.
269− */
270− if (job->timedout_ctca != ctca || job->timedout_ctra != ctra) {
271− job->timedout_ctca = ctca;
272− job->timedout_ctra = ctra;
300+ struct v3d_dev *v3d = job->v3d;
301+ u32 ctca = V3D_CORE_READ(0, V3D_CLE_CTNCA(q));
302+ u32 ctra = V3D_CORE_READ(0, V3D_CLE_CTNRA(q));
303+
304+ if (*timedout_ctca != ctca || *timedout_ctra != ctra) {
305+ *timedout_ctca = ctca;
306+ *timedout_ctra = ctra;
273307 return;
274308 }
275309
@@ -277,25 +311,82 @@ v3d_job_timedout(struct drm_sched_job *sched_job) · 1 unmodified line
277311 }
278312
279313 static void
280−v3d_tfu_job_timedout(struct drm_sched_job *sched_job)
314+v3d_bin_job_timedout(struct drm_sched_job *sched_job)
281315 {
282− struct v3d_tfu_job *job = to_tfu_job(sched_job);
316+ struct v3d_bin_job *job = to_bin_job(sched_job);
317+
318+ v3d_cl_job_timedout(sched_job, V3D_BIN,
319+ &job->timedout_ctca, &job->timedout_ctra);
320+}
321+
322+static void
323+v3d_render_job_timedout(struct drm_sched_job *sched_job)
324+{
325+ struct v3d_render_job *job = to_render_job(sched_job);
326+
327+ v3d_cl_job_timedout(sched_job, V3D_RENDER,
328+ &job->timedout_ctca, &job->timedout_ctra);
329+}
330+
331+static void
332+v3d_generic_job_timedout(struct drm_sched_job *sched_job)
333+{
334+ struct v3d_job *job = to_v3d_job(sched_job);
283335
284336 v3d_gpu_reset_for_timeout(job->v3d, sched_job);
285337 }
286338
287−static const struct drm_sched_backend_ops v3d_sched_ops = {
339+static void
340+v3d_csd_job_timedout(struct drm_sched_job *sched_job)
341+{
342+ struct v3d_csd_job *job = to_csd_job(sched_job);
343+ struct v3d_dev *v3d = job->base.v3d;
344+ u32 batches = V3D_CORE_READ(0, V3D_CSD_CURRENT_CFG4);
345+
346+ /* If we've made progress, skip reset and let the timer get
347+ * rearmed.
348+ */
349+ if (job->timedout_batches != batches) {
350+ job->timedout_batches = batches;
351+ return;
352+ }
353+
354+ v3d_gpu_reset_for_timeout(v3d, sched_job);
355+}
356+
357+static const struct drm_sched_backend_ops v3d_bin_sched_ops = {
288358 .dependency = v3d_job_dependency,
289− .run_job = v3d_job_run,
290− .timedout_job = v3d_job_timedout,
291− .free_job = v3d_job_free
359+ .run_job = v3d_bin_job_run,
360+ .timedout_job = v3d_bin_job_timedout,
361+ .free_job = v3d_job_free,
362+};
363+
364+static const struct drm_sched_backend_ops v3d_render_sched_ops = {
365+ .dependency = v3d_job_dependency,
366+ .run_job = v3d_render_job_run,
367+ .timedout_job = v3d_render_job_timedout,
368+ .free_job = v3d_job_free,
292369 };
293370
294371 static const struct drm_sched_backend_ops v3d_tfu_sched_ops = {
295− .dependency = v3d_tfu_job_dependency,
372+ .dependency = v3d_job_dependency,
296373 .run_job = v3d_tfu_job_run,
297− .timedout_job = v3d_tfu_job_timedout,
298− .free_job = v3d_tfu_job_free
374+ .timedout_job = v3d_generic_job_timedout,
375+ .free_job = v3d_job_free,
376+};
377+
378+static const struct drm_sched_backend_ops v3d_csd_sched_ops = {
379+ .dependency = v3d_job_dependency,
380+ .run_job = v3d_csd_job_run,
381+ .timedout_job = v3d_csd_job_timedout,
382+ .free_job = v3d_job_free
383+};
384+
385+static const struct drm_sched_backend_ops v3d_cache_clean_sched_ops = {
386+ .dependency = v3d_job_dependency,
387+ .run_job = v3d_cache_clean_job_run,
388+ .timedout_job = v3d_generic_job_timedout,
389+ .free_job = v3d_job_free
299390 };
300391
301392 int
@@ -307,7 +398,7 @@ v3d_sched_init(struct v3d_dev *v3d) · 5 unmodified lines
307398 int ret;
308399
309400 ret = drm_sched_init(&v3d->queue[V3D_BIN].sched,
310− &v3d_sched_ops,
401+ &v3d_bin_sched_ops,
311402 hw_jobs_limit, job_hang_limit,
312403 msecs_to_jiffies(hang_limit_ms),
313404 "v3d_bin");
@@ -317,14 +408,14 @@ v3d_sched_init(struct v3d_dev *v3d) · 3 unmodified lines
317408 }
318409
319410 ret = drm_sched_init(&v3d->queue[V3D_RENDER].sched,
320− &v3d_sched_ops,
411+ &v3d_render_sched_ops,
321412 hw_jobs_limit, job_hang_limit,
322413 msecs_to_jiffies(hang_limit_ms),
323414 "v3d_render");
324415 if (ret) {
325416 dev_err(v3d->dev, "Failed to create render scheduler: %d.",
326417 ret);
327− drm_sched_fini(&v3d->queue[V3D_BIN].sched);
418+ v3d_sched_fini(v3d);
328419 return ret;
329420 }
330421
@@ -336,11 +427,36 @@ v3d_sched_init(struct v3d_dev *v3d) · 5 unmodified lines
336427 if (ret) {
337428 dev_err(v3d->dev, "Failed to create TFU scheduler: %d.",
338429 ret);
339− drm_sched_fini(&v3d->queue[V3D_RENDER].sched);
340− drm_sched_fini(&v3d->queue[V3D_BIN].sched);
430+ v3d_sched_fini(v3d);
341431 return ret;
342432 }
343433
434+ if (v3d_has_csd(v3d)) {
435+ ret = drm_sched_init(&v3d->queue[V3D_CSD].sched,
436+ &v3d_csd_sched_ops,
437+ hw_jobs_limit, job_hang_limit,
438+ msecs_to_jiffies(hang_limit_ms),
439+ "v3d_csd");
440+ if (ret) {
441+ dev_err(v3d->dev, "Failed to create CSD scheduler: %d.",
442+ ret);
443+ v3d_sched_fini(v3d);
444+ return ret;
445+ }
446+
447+ ret = drm_sched_init(&v3d->queue[V3D_CACHE_CLEAN].sched,
448+ &v3d_cache_clean_sched_ops,
449+ hw_jobs_limit, job_hang_limit,
450+ msecs_to_jiffies(hang_limit_ms),
451+ "v3d_cache_clean");
452+ if (ret) {
453+ dev_err(v3d->dev, "Failed to create CACHE_CLEAN scheduler: %d.",
454+ ret);
455+ v3d_sched_fini(v3d);
456+ return ret;
457+ }
458+ }
459+
344460 return 0;
345461 }
346462
@@ -349,6 +465,8 @@ v3d_sched_fini(struct v3d_dev *v3d) · 2 unmodified lines
349465 {
350466 enum v3d_queue q;
351467
352− for (q = 0; q < V3D_MAX_QUEUES; q++)
353− drm_sched_fini(&v3d->queue[q].sched);
468+ for (q = 0; q < V3D_MAX_QUEUES; q++) {
469+ if (v3d->queue[q].sched.ready)
470+ drm_sched_fini(&v3d->queue[q].sched);
471+ }
354472 }
drivers/gpu/drm/v3d/v3d_trace.h+94−0
@@ -124,6 +124,26 @@ TRACE_EVENT(v3d_tfu_irq, · 123 unmodified lines
124124 __entry->seqno)
125125 );
126126
127+TRACE_EVENT(v3d_csd_irq,
128+ TP_PROTO(struct drm_device *dev,
129+ uint64_t seqno),
130+ TP_ARGS(dev, seqno),
131+
132+ TP_STRUCT__entry(
133+ __field(u32, dev)
134+ __field(u64, seqno)
135+ ),
136+
137+ TP_fast_assign(
138+ __entry->dev = dev->primary->index;
139+ __entry->seqno = seqno;
140+ ),
141+
142+ TP_printk("dev=%u, seqno=%llu",
143+ __entry->dev,
144+ __entry->seqno)
145+);
146+
127147 TRACE_EVENT(v3d_submit_tfu_ioctl,
128148 TP_PROTO(struct drm_device *dev, u32 iia),
129149 TP_ARGS(dev, iia),
@@ -163,6 +183,80 @@ TRACE_EVENT(v3d_submit_tfu, · 33 unmodified lines
163183 __entry->seqno)
164184 );
165185
186+TRACE_EVENT(v3d_submit_csd_ioctl,
187+ TP_PROTO(struct drm_device *dev, u32 cfg5, u32 cfg6),
188+ TP_ARGS(dev, cfg5, cfg6),
189+
190+ TP_STRUCT__entry(
191+ __field(u32, dev)
192+ __field(u32, cfg5)
193+ __field(u32, cfg6)
194+ ),
195+
196+ TP_fast_assign(
197+ __entry->dev = dev->primary->index;
198+ __entry->cfg5 = cfg5;
199+ __entry->cfg6 = cfg6;
200+ ),
201+
202+ TP_printk("dev=%u, CFG5 0x%08x, CFG6 0x%08x",
203+ __entry->dev,
204+ __entry->cfg5,
205+ __entry->cfg6)
206+);
207+
208+TRACE_EVENT(v3d_submit_csd,
209+ TP_PROTO(struct drm_device *dev,
210+ uint64_t seqno),
211+ TP_ARGS(dev, seqno),
212+
213+ TP_STRUCT__entry(
214+ __field(u32, dev)
215+ __field(u64, seqno)
216+ ),
217+
218+ TP_fast_assign(
219+ __entry->dev = dev->primary->index;
220+ __entry->seqno = seqno;
221+ ),
222+
223+ TP_printk("dev=%u, seqno=%llu",
224+ __entry->dev,
225+ __entry->seqno)
226+);
227+
228+TRACE_EVENT(v3d_cache_clean_begin,
229+ TP_PROTO(struct drm_device *dev),
230+ TP_ARGS(dev),
231+
232+ TP_STRUCT__entry(
233+ __field(u32, dev)
234+ ),
235+
236+ TP_fast_assign(
237+ __entry->dev = dev->primary->index;
238+ ),
239+
240+ TP_printk("dev=%u",
241+ __entry->dev)
242+);
243+
244+TRACE_EVENT(v3d_cache_clean_end,
245+ TP_PROTO(struct drm_device *dev),
246+ TP_ARGS(dev),
247+
248+ TP_STRUCT__entry(
249+ __field(u32, dev)
250+ ),
251+
252+ TP_fast_assign(
253+ __entry->dev = dev->primary->index;
254+ ),
255+
256+ TP_printk("dev=%u",
257+ __entry->dev)
258+);
259+
166260 TRACE_EVENT(v3d_reset_begin,
167261 TP_PROTO(struct drm_device *dev),
168262 TP_ARGS(dev),
drivers/gpu/drm/vboxvideo/Kconfig+1−1
@@ -3,7 +3,7 @@ config DRM_VBOXVIDEO · 2 unmodified lines
33 tristate "Virtual Box Graphics Card"
44 depends on DRM && X86 && PCI
55 select DRM_KMS_HELPER
6− select DRM_TTM
6+ select DRM_VRAM_HELPER
77 select GENERIC_ALLOCATOR
88 help
99 This is a KMS driver for the virtual Graphics Card used in
drivers/gpu/drm/vboxvideo/vbox_drv.c+2−10
@@ -191,13 +191,7 @@ static struct pci_driver vbox_pci_driver = { · 190 unmodified lines
191191
192192 static const struct file_operations vbox_fops = {
193193 .owner = THIS_MODULE,
194− .open = drm_open,
195− .release = drm_release,
196− .unlocked_ioctl = drm_ioctl,
197− .compat_ioctl = drm_compat_ioctl,
198− .mmap = vbox_mmap,
199− .poll = drm_poll,
200− .read = drm_read,
194+ DRM_VRAM_MM_FILE_OPERATIONS
201195 };
202196
203197 static struct drm_driver driver = {
@@ -215,9 +209,7 @@ static struct drm_driver driver = { · 11 unmodified lines
215209 .minor = DRIVER_MINOR,
216210 .patchlevel = DRIVER_PATCHLEVEL,
217211
218− .gem_free_object_unlocked = vbox_gem_free_object,
219− .dumb_create = vbox_dumb_create,
220− .dumb_map_offset = vbox_dumb_mmap_offset,
212+ DRM_GEM_VRAM_DRIVER,
221213 .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
222214 .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
223215 .gem_prime_export = drm_gem_prime_export,
drivers/gpu/drm/vboxvideo/vbox_drv.h+2−73
@@ -18,12 +18,9 @@ · 17 unmodified lines
1818 #include <drm/drm_encoder.h>
1919 #include <drm/drm_fb_helper.h>
2020 #include <drm/drm_gem.h>
21+#include <drm/drm_gem_vram_helper.h>
2122
22−#include <drm/ttm/ttm_bo_api.h>
23−#include <drm/ttm/ttm_bo_driver.h>
24−#include <drm/ttm/ttm_placement.h>
25−#include <drm/ttm/ttm_memory.h>
26−#include <drm/ttm/ttm_module.h>
23+#include <drm/drm_vram_mm_helper.h>
2724
2825 #include "vboxvideo_guest.h"
2926 #include "vboxvideo_vbe.h"
@@ -77,10 +74,6 @@ struct vbox_private { · 47 unmodified lines
7774
7875 int fb_mtrr;
7976
80− struct {
81− struct ttm_bo_device bdev;
82− } ttm;
83−
8477 struct mutex hw_mutex; /* protects modeset and accel/vbva accesses */
8578 struct work_struct hotplug_work;
8679 u32 input_mapping_width;
@@ -96,8 +89,6 @@ struct vbox_private { · 9 unmodified lines
9689 #undef CURSOR_PIXEL_COUNT
9790 #undef CURSOR_DATA_SIZE
9891
99−struct vbox_gem_object;
100−
10192 struct vbox_connector {
10293 struct drm_connector base;
10394 char name[32];
@@ -170,74 +161,12 @@ int vboxfb_create(struct drm_fb_helper *helper, · 66 unmodified lines
170161 struct drm_fb_helper_surface_size *sizes);
171162 void vbox_fbdev_fini(struct vbox_private *vbox);
172163
173−struct vbox_bo {
174− struct ttm_buffer_object bo;
175− struct ttm_placement placement;
176− struct ttm_bo_kmap_obj kmap;
177− struct drm_gem_object gem;
178− struct ttm_place placements[3];
179− int pin_count;
180−};
181−
182−#define gem_to_vbox_bo(gobj) container_of((gobj), struct vbox_bo, gem)
183−
184−static inline struct vbox_bo *vbox_bo(struct ttm_buffer_object *bo)
185−{
186− return container_of(bo, struct vbox_bo, bo);
187−}
188−
189−#define to_vbox_obj(x) container_of(x, struct vbox_gem_object, base)
190−
191−static inline u64 vbox_bo_gpu_offset(struct vbox_bo *bo)
192−{
193− return bo->bo.offset;
194−}
195−
196−int vbox_dumb_create(struct drm_file *file,
197− struct drm_device *dev,
198− struct drm_mode_create_dumb *args);
199−
200−void vbox_gem_free_object(struct drm_gem_object *obj);
201−int vbox_dumb_mmap_offset(struct drm_file *file,
202− struct drm_device *dev,
203− u32 handle, u64 *offset);
204−
205164 int vbox_mm_init(struct vbox_private *vbox);
206165 void vbox_mm_fini(struct vbox_private *vbox);
207166
208−int vbox_bo_create(struct vbox_private *vbox, int size, int align,
209− u32 flags, struct vbox_bo **pvboxbo);
210−
211167 int vbox_gem_create(struct vbox_private *vbox,
212168 u32 size, bool iskernel, struct drm_gem_object **obj);
213169
214−int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag);
215−int vbox_bo_unpin(struct vbox_bo *bo);
216−
217−static inline int vbox_bo_reserve(struct vbox_bo *bo, bool no_wait)
218−{
219− int ret;
220−
221− ret = ttm_bo_reserve(&bo->bo, true, no_wait, NULL);
222− if (ret) {
223− if (ret != -ERESTARTSYS && ret != -EBUSY)
224− DRM_ERROR("reserve failed %p\n", bo);
225− return ret;
226− }
227− return 0;
228−}
229−
230−static inline void vbox_bo_unreserve(struct vbox_bo *bo)
231−{
232− ttm_bo_unreserve(&bo->bo);
233−}
234−
235−void vbox_ttm_placement(struct vbox_bo *bo, int domain);
236−int vbox_bo_push_sysram(struct vbox_bo *bo);
237−int vbox_mmap(struct file *filp, struct vm_area_struct *vma);
238−void *vbox_bo_kmap(struct vbox_bo *bo);
239−void vbox_bo_kunmap(struct vbox_bo *bo);
240−
241170 /* vbox_prime.c */
242171 int vbox_gem_prime_pin(struct drm_gem_object *obj);
243172 void vbox_gem_prime_unpin(struct drm_gem_object *obj);
drivers/gpu/drm/vboxvideo/vbox_fb.c+11−11
@@ -51,9 +51,9 @@ int vboxfb_create(struct drm_fb_helper *helper, · 50 unmodified lines
5151 struct drm_framebuffer *fb;
5252 struct fb_info *info;
5353 struct drm_gem_object *gobj;
54− struct vbox_bo *bo;
54+ struct drm_gem_vram_object *gbo;
5555 int size, ret;
56− u64 gpu_addr;
56+ s64 gpu_addr;
5757 u32 pitch;
5858
5959 mode_cmd.width = sizes->surface_width;
@@ -75,9 +75,9 @@ int vboxfb_create(struct drm_fb_helper *helper, · 15 unmodified lines
7575 if (ret)
7676 return ret;
7777
78− bo = gem_to_vbox_bo(gobj);
78+ gbo = drm_gem_vram_of_gem(gobj);
7979
80− ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
80+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
8181 if (ret)
8282 return ret;
8383
@@ -86,7 +86,7 @@ int vboxfb_create(struct drm_fb_helper *helper, · 2 unmodified lines
8686 return PTR_ERR(info);
8787
8888 info->screen_size = size;
89− info->screen_base = (char __iomem *)vbox_bo_kmap(bo);
89+ info->screen_base = (char __iomem *)drm_gem_vram_kmap(gbo, true, NULL);
9090 if (IS_ERR(info->screen_base))
9191 return PTR_ERR(info->screen_base);
9292
@@ -104,7 +104,9 @@ int vboxfb_create(struct drm_fb_helper *helper, · 11 unmodified lines
104104
105105 drm_fb_helper_fill_info(info, helper, sizes);
106106
107− gpu_addr = vbox_bo_gpu_offset(bo);
107+ gpu_addr = drm_gem_vram_offset(gbo);
108+ if (gpu_addr < 0)
109+ return (int)gpu_addr;
108110 info->fix.smem_start = info->apertures->ranges[0].base + gpu_addr;
109111 info->fix.smem_len = vbox->available_vram_size - gpu_addr;
110112
@@ -132,12 +134,10 @@ void vbox_fbdev_fini(struct vbox_private *vbox) · 21 unmodified lines
132134 drm_fb_helper_unregister_fbi(&vbox->fb_helper);
133135
134136 if (afb->obj) {
135− struct vbox_bo *bo = gem_to_vbox_bo(afb->obj);
137+ struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(afb->obj);
136138
137− vbox_bo_kunmap(bo);
138−
139− if (bo->pin_count)
140− vbox_bo_unpin(bo);
139+ drm_gem_vram_kunmap(gbo);
140+ drm_gem_vram_unpin(gbo);
141141
142142 drm_gem_object_put_unlocked(afb->obj);
143143 afb->obj = NULL;
drivers/gpu/drm/vboxvideo/vbox_main.c+6−69
@@ -274,7 +274,7 @@ void vbox_hw_fini(struct vbox_private *vbox) · 273 unmodified lines
274274 int vbox_gem_create(struct vbox_private *vbox,
275275 u32 size, bool iskernel, struct drm_gem_object **obj)
276276 {
277− struct vbox_bo *vboxbo;
277+ struct drm_gem_vram_object *gbo;
278278 int ret;
279279
280280 *obj = NULL;
@@ -283,79 +283,16 @@ int vbox_gem_create(struct vbox_private *vbox, · 2 unmodified lines
283283 if (size == 0)
284284 return -EINVAL;
285285
286− ret = vbox_bo_create(vbox, size, 0, 0, &vboxbo);
287− if (ret) {
286+ gbo = drm_gem_vram_create(&vbox->ddev, &vbox->ddev.vram_mm->bdev,
287+ size, 0, false);
288+ if (IS_ERR(gbo)) {
289+ ret = PTR_ERR(gbo);
288290 if (ret != -ERESTARTSYS)
289291 DRM_ERROR("failed to allocate GEM object\n");
290292 return ret;
291293 }
292294
293− *obj = &vboxbo->gem;
294−
295− return 0;
296−}
297−
298−int vbox_dumb_create(struct drm_file *file,
299− struct drm_device *dev, struct drm_mode_create_dumb *args)
300−{
301− struct vbox_private *vbox =
302− container_of(dev, struct vbox_private, ddev);
303− struct drm_gem_object *gobj;
304− u32 handle;
305− int ret;
306−
307− args->pitch = args->width * ((args->bpp + 7) / 8);
308− args->size = args->pitch * args->height;
309−
310− ret = vbox_gem_create(vbox, args->size, false, &gobj);
311− if (ret)
312− return ret;
313−
314− ret = drm_gem_handle_create(file, gobj, &handle);
315− drm_gem_object_put_unlocked(gobj);
316− if (ret)
317− return ret;
318−
319− args->handle = handle;
295+ *obj = &gbo->gem;
320296
321297 return 0;
322298 }
323−
324−void vbox_gem_free_object(struct drm_gem_object *obj)
325−{
326− struct vbox_bo *vbox_bo = gem_to_vbox_bo(obj);
327−
328− ttm_bo_put(&vbox_bo->bo);
329−}
330−
331−static inline u64 vbox_bo_mmap_offset(struct vbox_bo *bo)
332−{
333− return drm_vma_node_offset_addr(&bo->bo.vma_node);
334−}
335−
336−int
337−vbox_dumb_mmap_offset(struct drm_file *file,
338− struct drm_device *dev,
339− u32 handle, u64 *offset)
340−{
341− struct drm_gem_object *obj;
342− int ret;
343− struct vbox_bo *bo;
344−
345− mutex_lock(&dev->struct_mutex);
346− obj = drm_gem_object_lookup(file, handle);
347− if (!obj) {
348− ret = -ENOENT;
349− goto out_unlock;
350− }
351−
352− bo = gem_to_vbox_bo(obj);
353− *offset = vbox_bo_mmap_offset(bo);
354−
355− drm_gem_object_put(obj);
356− ret = 0;
357−
358−out_unlock:
359− mutex_unlock(&dev->struct_mutex);
360− return ret;
361−}
drivers/gpu/drm/vboxvideo/vbox_mode.c+19−17
@@ -172,7 +172,8 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, · 171 unmodified lines
172172 struct drm_framebuffer *fb,
173173 int x, int y)
174174 {
175− struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
175+ struct drm_gem_vram_object *gbo =
176+ drm_gem_vram_of_gem(to_vbox_framebuffer(fb)->obj);
176177 struct vbox_private *vbox = crtc->dev->dev_private;
177178 struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
178179 bool needs_modeset = drm_atomic_crtc_needs_modeset(crtc->state);
@@ -186,7 +187,7 @@ static void vbox_crtc_set_base_and_mode(struct drm_crtc *crtc, · 7 unmodified lines
186187
187188 vbox_crtc->x = x;
188189 vbox_crtc->y = y;
189− vbox_crtc->fb_offset = vbox_bo_gpu_offset(bo);
190+ vbox_crtc->fb_offset = drm_gem_vram_offset(gbo);
190191
191192 /* vbox_do_modeset() checks vbox->single_framebuffer so update it now */
192193 if (needs_modeset && vbox_set_up_input_mapping(vbox)) {
@@ -302,14 +303,14 @@ static void vbox_primary_atomic_disable(struct drm_plane *plane, · 109 unmodified lines
302303 static int vbox_primary_prepare_fb(struct drm_plane *plane,
303304 struct drm_plane_state *new_state)
304305 {
305− struct vbox_bo *bo;
306+ struct drm_gem_vram_object *gbo;
306307 int ret;
307308
308309 if (!new_state->fb)
309310 return 0;
310311
311− bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
312− ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM);
312+ gbo = drm_gem_vram_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
313+ ret = drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_VRAM);
313314 if (ret)
314315 DRM_WARN("Error %d pinning new fb, out of video mem?\n", ret);
315316
@@ -319,13 +320,13 @@ static int vbox_primary_prepare_fb(struct drm_plane *plane, · 3 unmodified lines
319320 static void vbox_primary_cleanup_fb(struct drm_plane *plane,
320321 struct drm_plane_state *old_state)
321322 {
322− struct vbox_bo *bo;
323+ struct drm_gem_vram_object *gbo;
323324
324325 if (!old_state->fb)
325326 return;
326327
327− bo = gem_to_vbox_bo(to_vbox_framebuffer(old_state->fb)->obj);
328− vbox_bo_unpin(bo);
328+ gbo = drm_gem_vram_of_gem(to_vbox_framebuffer(old_state->fb)->obj);
329+ drm_gem_vram_unpin(gbo);
329330 }
330331
331332 static int vbox_cursor_atomic_check(struct drm_plane *plane,
@@ -385,7 +386,8 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane, · 53 unmodified lines
385386 container_of(plane->dev, struct vbox_private, ddev);
386387 struct vbox_crtc *vbox_crtc = to_vbox_crtc(plane->state->crtc);
387388 struct drm_framebuffer *fb = plane->state->fb;
388− struct vbox_bo *bo = gem_to_vbox_bo(to_vbox_framebuffer(fb)->obj);
389+ struct drm_gem_vram_object *gbo =
390+ drm_gem_vram_of_gem(to_vbox_framebuffer(fb)->obj);
389391 u32 width = plane->state->crtc_w;
390392 u32 height = plane->state->crtc_h;
391393 size_t data_size, mask_size;
@@ -404,7 +406,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane, · 12 unmodified lines
404406 vbox_crtc->cursor_enabled = true;
405407
406408 /* pinning is done in prepare/cleanup framebuffer */
407− src = vbox_bo_kmap(bo);
409+ src = drm_gem_vram_kmap(gbo, true, NULL);
408410 if (IS_ERR(src)) {
409411 mutex_unlock(&vbox->hw_mutex);
410412 DRM_WARN("Could not kmap cursor bo, skipping update\n");
@@ -420,7 +422,7 @@ static void vbox_cursor_atomic_update(struct drm_plane *plane, · 9 unmodified lines
420422 data_size = width * height * 4 + mask_size;
421423
422424 copy_cursor_image(src, vbox->cursor_data, width, height, mask_size);
423− vbox_bo_kunmap(bo);
425+ drm_gem_vram_kunmap(gbo);
424426
425427 flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
426428 VBOX_MOUSE_POINTER_ALPHA;
@@ -460,25 +462,25 @@ static void vbox_cursor_atomic_disable(struct drm_plane *plane, · 33 unmodified lines
460462 static int vbox_cursor_prepare_fb(struct drm_plane *plane,
461463 struct drm_plane_state *new_state)
462464 {
463− struct vbox_bo *bo;
465+ struct drm_gem_vram_object *gbo;
464466
465467 if (!new_state->fb)
466468 return 0;
467469
468− bo = gem_to_vbox_bo(to_vbox_framebuffer(new_state->fb)->obj);
469− return vbox_bo_pin(bo, TTM_PL_FLAG_SYSTEM);
470+ gbo = drm_gem_vram_of_gem(to_vbox_framebuffer(new_state->fb)->obj);
471+ return drm_gem_vram_pin(gbo, DRM_GEM_VRAM_PL_FLAG_SYSTEM);
470472 }
471473
472474 static void vbox_cursor_cleanup_fb(struct drm_plane *plane,
473475 struct drm_plane_state *old_state)
474476 {
475− struct vbox_bo *bo;
477+ struct drm_gem_vram_object *gbo;
476478
477479 if (!plane->state->fb)
478480 return;
479481
480− bo = gem_to_vbox_bo(to_vbox_framebuffer(plane->state->fb)->obj);
481− vbox_bo_unpin(bo);
482+ gbo = drm_gem_vram_of_gem(to_vbox_framebuffer(plane->state->fb)->obj);
483+ drm_gem_vram_unpin(gbo);
482484 }
483485
484486 static const u32 vbox_cursor_plane_formats[] = {
drivers/gpu/drm/vboxvideo/vbox_ttm.c+8−347
@@ -8,167 +8,23 @@ · 7 unmodified lines
88 */
99 #include <linux/pci.h>
1010 #include <drm/drm_file.h>
11−#include <drm/ttm/ttm_page_alloc.h>
1211 #include "vbox_drv.h"
1312
14−static inline struct vbox_private *vbox_bdev(struct ttm_bo_device *bd)
15−{
16− return container_of(bd, struct vbox_private, ttm.bdev);
17−}
18−
19−static void vbox_bo_ttm_destroy(struct ttm_buffer_object *tbo)
20−{
21− struct vbox_bo *bo;
22−
23− bo = container_of(tbo, struct vbox_bo, bo);
24−
25− drm_gem_object_release(&bo->gem);
26− kfree(bo);
27−}
28−
29−static bool vbox_ttm_bo_is_vbox_bo(struct ttm_buffer_object *bo)
30−{
31− if (bo->destroy == &vbox_bo_ttm_destroy)
32− return true;
33−
34− return false;
35−}
36−
37−static int
38−vbox_bo_init_mem_type(struct ttm_bo_device *bdev, u32 type,
39− struct ttm_mem_type_manager *man)
40−{
41− switch (type) {
42− case TTM_PL_SYSTEM:
43− man->flags = TTM_MEMTYPE_FLAG_MAPPABLE;
44− man->available_caching = TTM_PL_MASK_CACHING;
45− man->default_caching = TTM_PL_FLAG_CACHED;
46− break;
47− case TTM_PL_VRAM:
48− man->func = &ttm_bo_manager_func;
49− man->flags = TTM_MEMTYPE_FLAG_FIXED | TTM_MEMTYPE_FLAG_MAPPABLE;
50− man->available_caching = TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_WC;
51− man->default_caching = TTM_PL_FLAG_WC;
52− break;
53− default:
54− DRM_ERROR("Unsupported memory type %u\n", (unsigned int)type);
55− return -EINVAL;
56− }
57−
58− return 0;
59−}
60−
61−static void
62−vbox_bo_evict_flags(struct ttm_buffer_object *bo, struct ttm_placement *pl)
63−{
64− struct vbox_bo *vboxbo = vbox_bo(bo);
65−
66− if (!vbox_ttm_bo_is_vbox_bo(bo))
67− return;
68−
69− vbox_ttm_placement(vboxbo, TTM_PL_FLAG_SYSTEM);
70− *pl = vboxbo->placement;
71−}
72−
73−static int vbox_bo_verify_access(struct ttm_buffer_object *bo,
74− struct file *filp)
75−{
76− return 0;
77−}
78−
79−static int vbox_ttm_io_mem_reserve(struct ttm_bo_device *bdev,
80− struct ttm_mem_reg *mem)
81−{
82− struct ttm_mem_type_manager *man = &bdev->man[mem->mem_type];
83− struct vbox_private *vbox = vbox_bdev(bdev);
84−
85− mem->bus.addr = NULL;
86− mem->bus.offset = 0;
87− mem->bus.size = mem->num_pages << PAGE_SHIFT;
88− mem->bus.base = 0;
89− mem->bus.is_iomem = false;
90− if (!(man->flags & TTM_MEMTYPE_FLAG_MAPPABLE))
91− return -EINVAL;
92− switch (mem->mem_type) {
93− case TTM_PL_SYSTEM:
94− /* system memory */
95− return 0;
96− case TTM_PL_VRAM:
97− mem->bus.offset = mem->start << PAGE_SHIFT;
98− mem->bus.base = pci_resource_start(vbox->ddev.pdev, 0);
99− mem->bus.is_iomem = true;
100− break;
101− default:
102− return -EINVAL;
103− }
104− return 0;
105−}
106−
107−static void vbox_ttm_io_mem_free(struct ttm_bo_device *bdev,
108− struct ttm_mem_reg *mem)
109−{
110−}
111−
112−static void vbox_ttm_backend_destroy(struct ttm_tt *tt)
113−{
114− ttm_tt_fini(tt);
115− kfree(tt);
116−}
117−
118−static struct ttm_backend_func vbox_tt_backend_func = {
119− .destroy = &vbox_ttm_backend_destroy,
120−};
121−
122−static struct ttm_tt *vbox_ttm_tt_create(struct ttm_buffer_object *bo,
123− u32 page_flags)
124−{
125− struct ttm_tt *tt;
126−
127− tt = kzalloc(sizeof(*tt), GFP_KERNEL);
128− if (!tt)
129− return NULL;
130−
131− tt->func = &vbox_tt_backend_func;
132− if (ttm_tt_init(tt, bo, page_flags)) {
133− kfree(tt);
134− return NULL;
135− }
136−
137− return tt;
138−}
139−
140−static struct ttm_bo_driver vbox_bo_driver = {
141− .ttm_tt_create = vbox_ttm_tt_create,
142− .init_mem_type = vbox_bo_init_mem_type,
143− .eviction_valuable = ttm_bo_eviction_valuable,
144− .evict_flags = vbox_bo_evict_flags,
145− .verify_access = vbox_bo_verify_access,
146− .io_mem_reserve = &vbox_ttm_io_mem_reserve,
147− .io_mem_free = &vbox_ttm_io_mem_free,
148−};
149−
15013 int vbox_mm_init(struct vbox_private *vbox)
15114 {
15+ struct drm_vram_mm *vmm;
15216 int ret;
15317 struct drm_device *dev = &vbox->ddev;
154− struct ttm_bo_device *bdev = &vbox->ttm.bdev;
15518
156− ret = ttm_bo_device_init(&vbox->ttm.bdev,
157− &vbox_bo_driver,
158− dev->anon_inode->i_mapping,
159− true);
160− if (ret) {
161− DRM_ERROR("Error initialising bo driver; %d\n", ret);
19+ vmm = drm_vram_helper_alloc_mm(dev, pci_resource_start(dev->pdev, 0),
20+ vbox->available_vram_size,
21+ &drm_gem_vram_mm_funcs);
22+ if (IS_ERR(vmm)) {
23+ ret = PTR_ERR(vmm);
24+ DRM_ERROR("Error initializing VRAM MM; %d\n", ret);
16225 return ret;
16326 }
16427
165− ret = ttm_bo_init_mm(bdev, TTM_PL_VRAM,
166− vbox->available_vram_size >> PAGE_SHIFT);
167− if (ret) {
168− DRM_ERROR("Failed ttm VRAM init: %d\n", ret);
169− goto err_device_release;
170− }
171−
17228 #ifdef DRM_MTRR_WC
17329 vbox->fb_mtrr = drm_mtrr_add(pci_resource_start(dev->pdev, 0),
17430 pci_resource_len(dev->pdev, 0),
@@ -178,10 +34,6 @@ int vbox_mm_init(struct vbox_private *vbox) · 3 unmodified lines
17834 pci_resource_len(dev->pdev, 0));
17935 #endif
18036 return 0;
181−
182−err_device_release:
183− ttm_bo_device_release(&vbox->ttm.bdev);
184− return ret;
18537 }
18638
18739 void vbox_mm_fini(struct vbox_private *vbox)
@@ -193,196 +45,5 @@ void vbox_mm_fini(struct vbox_private *vbox) · 5 unmodified lines
19345 #else
19446 arch_phys_wc_del(vbox->fb_mtrr);
19547 #endif
196− ttm_bo_device_release(&vbox->ttm.bdev);
197−}
198−
199−void vbox_ttm_placement(struct vbox_bo *bo, int domain)
200−{
201− unsigned int i;
202− u32 c = 0;
203−
204− bo->placement.placement = bo->placements;
205− bo->placement.busy_placement = bo->placements;
206−
207− if (domain & TTM_PL_FLAG_VRAM)
208− bo->placements[c++].flags =
209− TTM_PL_FLAG_WC | TTM_PL_FLAG_UNCACHED | TTM_PL_FLAG_VRAM;
210− if (domain & TTM_PL_FLAG_SYSTEM)
211− bo->placements[c++].flags =
212− TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
213− if (!c)
214− bo->placements[c++].flags =
215− TTM_PL_MASK_CACHING | TTM_PL_FLAG_SYSTEM;
216−
217− bo->placement.num_placement = c;
218− bo->placement.num_busy_placement = c;
219−
220− for (i = 0; i < c; ++i) {
221− bo->placements[i].fpfn = 0;
222− bo->placements[i].lpfn = 0;
223− }
224−}
225−
226−int vbox_bo_create(struct vbox_private *vbox, int size, int align,
227− u32 flags, struct vbox_bo **pvboxbo)
228−{
229− struct vbox_bo *vboxbo;
230− size_t acc_size;
231− int ret;
232−
233− vboxbo = kzalloc(sizeof(*vboxbo), GFP_KERNEL);
234− if (!vboxbo)
235− return -ENOMEM;
236−
237− ret = drm_gem_object_init(&vbox->ddev, &vboxbo->gem, size);
238− if (ret)
239− goto err_free_vboxbo;
240−
241− vboxbo->bo.bdev = &vbox->ttm.bdev;
242−
243− vbox_ttm_placement(vboxbo, TTM_PL_FLAG_VRAM | TTM_PL_FLAG_SYSTEM);
244−
245− acc_size = ttm_bo_dma_acc_size(&vbox->ttm.bdev, size,
246− sizeof(struct vbox_bo));
247−
248− ret = ttm_bo_init(&vbox->ttm.bdev, &vboxbo->bo, size,
249− ttm_bo_type_device, &vboxbo->placement,
250− align >> PAGE_SHIFT, false, acc_size,
251− NULL, NULL, vbox_bo_ttm_destroy);
252− if (ret)
253− goto err_free_vboxbo;
254−
255− *pvboxbo = vboxbo;
256−
257− return 0;
258−
259−err_free_vboxbo:
260− kfree(vboxbo);
261− return ret;
262−}
263−
264−int vbox_bo_pin(struct vbox_bo *bo, u32 pl_flag)
265−{
266− struct ttm_operation_ctx ctx = { false, false };
267− int i, ret;
268−
269− if (bo->pin_count) {
270− bo->pin_count++;
271− return 0;
272− }
273−
274− ret = vbox_bo_reserve(bo, false);
275− if (ret)
276− return ret;
277−
278− vbox_ttm_placement(bo, pl_flag);
279−
280− for (i = 0; i < bo->placement.num_placement; i++)
281− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
282−
283− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
284− if (ret == 0)
285− bo->pin_count = 1;
286−
287− vbox_bo_unreserve(bo);
288−
289− return ret;
290−}
291−
292−int vbox_bo_unpin(struct vbox_bo *bo)
293−{
294− struct ttm_operation_ctx ctx = { false, false };
295− int i, ret;
296−
297− if (!bo->pin_count) {
298− DRM_ERROR("unpin bad %p\n", bo);
299− return 0;
300− }
301− bo->pin_count--;
302− if (bo->pin_count)
303− return 0;
304−
305− ret = vbox_bo_reserve(bo, false);
306− if (ret) {
307− DRM_ERROR("Error %d reserving bo, leaving it pinned\n", ret);
308− return ret;
309− }
310−
311− for (i = 0; i < bo->placement.num_placement; i++)
312− bo->placements[i].flags &= ~TTM_PL_FLAG_NO_EVICT;
313−
314− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
315−
316− vbox_bo_unreserve(bo);
317−
318− return ret;
319−}
320−
321−/*
322− * Move a vbox-owned buffer object to system memory if no one else has it
323− * pinned. The caller must have pinned it previously, and this call will
324− * release the caller's pin.
325− */
326−int vbox_bo_push_sysram(struct vbox_bo *bo)
327−{
328− struct ttm_operation_ctx ctx = { false, false };
329− int i, ret;
330−
331− if (!bo->pin_count) {
332− DRM_ERROR("unpin bad %p\n", bo);
333− return 0;
334− }
335− bo->pin_count--;
336− if (bo->pin_count)
337− return 0;
338−
339− if (bo->kmap.virtual) {
340− ttm_bo_kunmap(&bo->kmap);
341− bo->kmap.virtual = NULL;
342− }
343−
344− vbox_ttm_placement(bo, TTM_PL_FLAG_SYSTEM);
345−
346− for (i = 0; i < bo->placement.num_placement; i++)
347− bo->placements[i].flags |= TTM_PL_FLAG_NO_EVICT;
348−
349− ret = ttm_bo_validate(&bo->bo, &bo->placement, &ctx);
350− if (ret) {
351− DRM_ERROR("pushing to VRAM failed\n");
352− return ret;
353− }
354−
355− return 0;
356−}
357−
358−int vbox_mmap(struct file *filp, struct vm_area_struct *vma)
359−{
360− struct drm_file *file_priv = filp->private_data;
361− struct vbox_private *vbox = file_priv->minor->dev->dev_private;
362−
363− return ttm_bo_mmap(filp, vma, &vbox->ttm.bdev);
364−}
365−
366−void *vbox_bo_kmap(struct vbox_bo *bo)
367−{
368− int ret;
369−
370− if (bo->kmap.virtual)
371− return bo->kmap.virtual;
372−
373− ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &bo->kmap);
374− if (ret) {
375− DRM_ERROR("Error kmapping bo: %d\n", ret);
376− return NULL;
377− }
378−
379− return bo->kmap.virtual;
380−}
381−
382−void vbox_bo_kunmap(struct vbox_bo *bo)
383−{
384− if (bo->kmap.virtual) {
385− ttm_bo_kunmap(&bo->kmap);
386− bo->kmap.virtual = NULL;
387− }
48+ drm_vram_helper_release_mm(&vbox->ddev);
38849 }
drivers/gpu/drm/vc4/vc4_bo.c+30−1
@@ -799,13 +799,36 @@ vc4_prime_import_sg_table(struct drm_device *dev, · 798 unmodified lines
799799 return obj;
800800 }
801801
802+static int vc4_grab_bin_bo(struct vc4_dev *vc4, struct vc4_file *vc4file)
803+{
804+ int ret;
805+
806+ if (!vc4->v3d)
807+ return -ENODEV;
808+
809+ if (vc4file->bin_bo_used)
810+ return 0;
811+
812+ ret = vc4_v3d_bin_bo_get(vc4, &vc4file->bin_bo_used);
813+ if (ret)
814+ return ret;
815+
816+ return 0;
817+}
818+
802819 int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
803820 struct drm_file *file_priv)
804821 {
805822 struct drm_vc4_create_bo *args = data;
823+ struct vc4_file *vc4file = file_priv->driver_priv;
824+ struct vc4_dev *vc4 = to_vc4_dev(dev);
806825 struct vc4_bo *bo = NULL;
807826 int ret;
808827
828+ ret = vc4_grab_bin_bo(vc4, vc4file);
829+ if (ret)
830+ return ret;
831+
809832 /*
810833 * We can't allocate from the BO cache, because the BOs don't
811834 * get zeroed, and that might leak data between users.
@@ -846,6 +869,8 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, · 34 unmodified lines
846869 struct drm_file *file_priv)
847870 {
848871 struct drm_vc4_create_shader_bo *args = data;
872+ struct vc4_file *vc4file = file_priv->driver_priv;
873+ struct vc4_dev *vc4 = to_vc4_dev(dev);
849874 struct vc4_bo *bo = NULL;
850875 int ret;
851876
@@ -865,6 +890,10 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, · 13 unmodified lines
865890 return -EINVAL;
866891 }
867892
893+ ret = vc4_grab_bin_bo(vc4, vc4file);
894+ if (ret)
895+ return ret;
896+
868897 bo = vc4_bo_create(dev, args->size, true, VC4_BO_TYPE_V3D_SHADER);
869898 if (IS_ERR(bo))
870899 return PTR_ERR(bo);
@@ -894,7 +923,7 @@ vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, · 23 unmodified lines
894923 */
895924 ret = drm_gem_handle_create(file_priv, &bo->base.base, &args->handle);
896925
897− fail:
926+fail:
898927 drm_gem_object_put_unlocked(&bo->base.base);
899928
900929 return ret;
drivers/gpu/drm/vc4/vc4_drv.c+6−0
@@ -128,8 +128,12 @@ static int vc4_open(struct drm_device *dev, struct drm_file *file) · 127 unmodified lines
128128
129129 static void vc4_close(struct drm_device *dev, struct drm_file *file)
130130 {
131+ struct vc4_dev *vc4 = to_vc4_dev(dev);
131132 struct vc4_file *vc4file = file->driver_priv;
132133
134+ if (vc4file->bin_bo_used)
135+ vc4_v3d_bin_bo_put(vc4);
136+
133137 vc4_perfmon_close_file(vc4file);
134138 kfree(vc4file);
135139 }
@@ -274,6 +278,8 @@ static int vc4_drm_bind(struct device *dev) · 138 unmodified lines
274278 drm->dev_private = vc4;
275279 INIT_LIST_HEAD(&vc4->debugfs_list);
276280
281+ mutex_init(&vc4->bin_bo_lock);
282+
277283 ret = vc4_bo_cache_init(drm);
278284 if (ret)
279285 goto dev_put;
drivers/gpu/drm/vc4/vc4_drv.h+14−0
@@ -216,6 +216,11 @@ struct vc4_dev { · 215 unmodified lines
216216 * the minor is available (after drm_dev_register()).
217217 */
218218 struct list_head debugfs_list;
219+
220+ /* Mutex for binner bo allocation. */
221+ struct mutex bin_bo_lock;
222+ /* Reference count for our binner bo. */
223+ struct kref bin_bo_kref;
219224 };
220225
221226 static inline struct vc4_dev *
@@ -584,6 +589,11 @@ struct vc4_exec_info { · 362 unmodified lines
584589 * NULL otherwise.
585590 */
586591 struct vc4_perfmon *perfmon;
592+
593+ /* Whether the exec has taken a reference to the binner BO, which should
594+ * happen with a VC4_PACKET_TILE_BINNING_MODE_CONFIG packet.
595+ */
596+ bool bin_bo_used;
587597 };
588598
589599 /* Per-open file private data. Any driver-specific resource that has to be
@@ -594,6 +604,8 @@ struct vc4_file { · 4 unmodified lines
594604 struct idr idr;
595605 struct mutex lock;
596606 } perfmon;
607+
608+ bool bin_bo_used;
597609 };
598610
599611 static inline struct vc4_exec_info *
@@ -833,6 +845,8 @@ void vc4_plane_async_set_fb(struct drm_plane *plane, · 233 unmodified lines
833845 extern struct platform_driver vc4_v3d_driver;
834846 extern const struct of_device_id vc4_v3d_dt_match[];
835847 int vc4_v3d_get_bin_slot(struct vc4_dev *vc4);
848+int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used);
849+void vc4_v3d_bin_bo_put(struct vc4_dev *vc4);
836850 int vc4_v3d_pm_get(struct vc4_dev *vc4);
837851 void vc4_v3d_pm_put(struct vc4_dev *vc4);
838852
drivers/gpu/drm/vc4/vc4_gem.c+11−0
@@ -820,6 +820,7 @@ static int · 819 unmodified lines
820820 vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec)
821821 {
822822 struct drm_vc4_submit_cl *args = exec->args;
823+ struct vc4_dev *vc4 = to_vc4_dev(dev);
823824 void *temp = NULL;
824825 void *bin;
825826 int ret = 0;
@@ -918,6 +919,12 @@ vc4_get_bcl(struct drm_device *dev, struct vc4_exec_info *exec) · 92 unmodified lines
918919 if (ret)
919920 goto fail;
920921
922+ if (exec->found_tile_binning_mode_config_packet) {
923+ ret = vc4_v3d_bin_bo_get(vc4, &exec->bin_bo_used);
924+ if (ret)
925+ goto fail;
926+ }
927+
921928 /* Block waiting on any previous rendering into the CS's VBO,
922929 * IB, or textures, so that pixels are actually written by the
923930 * time we try to read them.
@@ -966,6 +973,10 @@ vc4_complete_exec(struct drm_device *dev, struct vc4_exec_info *exec) · 42 unmodified lines
966973 vc4->bin_alloc_used &= ~exec->bin_slots;
967974 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
968975
976+ /* Release the reference on the binner BO if needed. */
977+ if (exec->bin_bo_used)
978+ vc4_v3d_bin_bo_put(vc4);
979+
969980 /* Release the reference we had on the perf monitor. */
970981 vc4_perfmon_put(exec->perfmon);
971982
drivers/gpu/drm/vc4/vc4_irq.c+16−4
@@ -59,15 +59,22 @@ vc4_overflow_mem_work(struct work_struct *work) · 58 unmodified lines
5959 {
6060 struct vc4_dev *vc4 =
6161 container_of(work, struct vc4_dev, overflow_mem_work);
62− struct vc4_bo *bo = vc4->bin_bo;
62+ struct vc4_bo *bo;
6363 int bin_bo_slot;
6464 struct vc4_exec_info *exec;
6565 unsigned long irqflags;
6666
67+ mutex_lock(&vc4->bin_bo_lock);
68+
69+ if (!vc4->bin_bo)
70+ goto complete;
71+
72+ bo = vc4->bin_bo;
73+
6774 bin_bo_slot = vc4_v3d_get_bin_slot(vc4);
6875 if (bin_bo_slot < 0) {
6976 DRM_ERROR("Couldn't allocate binner overflow mem\n");
70− return;
77+ goto complete;
7178 }
7279
7380 spin_lock_irqsave(&vc4->job_lock, irqflags);
@@ -98,6 +105,9 @@ vc4_overflow_mem_work(struct work_struct *work) · 24 unmodified lines
98105 V3D_WRITE(V3D_INTCTL, V3D_INT_OUTOMEM);
99106 V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
100107 spin_unlock_irqrestore(&vc4->job_lock, irqflags);
108+
109+complete:
110+ mutex_unlock(&vc4->bin_bo_lock);
101111 }
102112
103113 static void
@@ -249,8 +259,10 @@ vc4_irq_postinstall(struct drm_device *dev) · 145 unmodified lines
249259 if (!vc4->v3d)
250260 return 0;
251261
252− /* Enable both the render done and out of memory interrupts. */
253− V3D_WRITE(V3D_INTENA, V3D_DRIVER_IRQS);
262+ /* Enable the render done interrupts. The out-of-memory interrupt is
263+ * enabled as soon as we have a binner BO allocated.
264+ */
265+ V3D_WRITE(V3D_INTENA, V3D_INT_FLDONE | V3D_INT_FRDONE);
254266
255267 return 0;
256268 }
drivers/gpu/drm/vc4/vc4_plane.c+5−10
@@ -310,10 +310,10 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) · 309 unmodified lines
310310 struct drm_framebuffer *fb = state->fb;
311311 struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
312312 u32 subpixel_src_mask = (1 << 16) - 1;
313− u32 format = fb->format->format;
314313 int num_planes = fb->format->num_planes;
315314 struct drm_crtc_state *crtc_state;
316− u32 h_subsample, v_subsample;
315+ u32 h_subsample = fb->format->hsub;
316+ u32 v_subsample = fb->format->vsub;
317317 int i, ret;
318318
319319 crtc_state = drm_atomic_get_existing_crtc_state(state->state,
@@ -328,9 +328,6 @@ static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state) · 8 unmodified lines
328328 if (ret)
329329 return ret;
330330
331− h_subsample = drm_format_horz_chroma_subsampling(format);
332− v_subsample = drm_format_vert_chroma_subsampling(format);
333−
334331 for (i = 0; i < num_planes; i++)
335332 vc4_state->offsets[i] = bo->paddr + fb->offsets[i];
336333
@@ -592,8 +589,9 @@ static int vc4_plane_mode_set(struct drm_plane *plane, · 255 unmodified lines
592589 u32 ctl0_offset = vc4_state->dlist_count;
593590 const struct hvs_format *format = vc4_get_hvs_format(fb->format->format);
594591 u64 base_format_mod = fourcc_mod_broadcom_mod(fb->modifier);
595− int num_planes = drm_format_num_planes(format->drm);
596− u32 h_subsample, v_subsample;
592+ int num_planes = fb->format->num_planes;
593+ u32 h_subsample = fb->format->hsub;
594+ u32 v_subsample = fb->format->vsub;
597595 bool mix_plane_alpha;
598596 bool covers_screen;
599597 u32 scl0, scl1, pitch0;
@@ -623,9 +621,6 @@ static int vc4_plane_mode_set(struct drm_plane *plane, · 23 unmodified lines
623621 scl1 = vc4_get_scl_field(state, 0);
624622 }
625623
626− h_subsample = drm_format_horz_chroma_subsampling(format->drm);
627− v_subsample = drm_format_vert_chroma_subsampling(format->drm);
628−
629624 rotation = drm_rotation_simplify(state->rotation,
630625 DRM_MODE_ROTATE_0 |
631626 DRM_MODE_REFLECT_X |
drivers/gpu/drm/vc4/vc4_v3d.c+55−17
@@ -213,7 +213,7 @@ try_again: · 212 unmodified lines
213213 }
214214
215215 /**
216− * vc4_allocate_bin_bo() - allocates the memory that will be used for
216+ * bin_bo_alloc() - allocates the memory that will be used for
217217 * tile binning.
218218 *
219219 * The binner has a limitation that the addresses in the tile state
@@ -234,14 +234,16 @@ try_again: · 14 unmodified lines
234234 * overall CMA pool before they make scenes complicated enough to run
235235 * out of bin space.
236236 */
237−static int vc4_allocate_bin_bo(struct drm_device *drm)
237+static int bin_bo_alloc(struct vc4_dev *vc4)
238238 {
239− struct vc4_dev *vc4 = to_vc4_dev(drm);
240239 struct vc4_v3d *v3d = vc4->v3d;
241240 uint32_t size = 16 * 1024 * 1024;
242241 int ret = 0;
243242 struct list_head list;
244243
244+ if (!v3d)
245+ return -ENODEV;
246+
245247 /* We may need to try allocating more than once to get a BO
246248 * that doesn't cross 256MB. Track the ones we've allocated
247249 * that failed so far, so that we can free them when we've got
@@ -251,7 +253,7 @@ static int vc4_allocate_bin_bo(struct drm_device *drm) · 3 unmodified lines
251253 INIT_LIST_HEAD(&list);
252254
253255 while (true) {
254− struct vc4_bo *bo = vc4_bo_create(drm, size, true,
256+ struct vc4_bo *bo = vc4_bo_create(vc4->dev, size, true,
255257 VC4_BO_TYPE_BIN);
256258
257259 if (IS_ERR(bo)) {
@@ -292,6 +294,14 @@ static int vc4_allocate_bin_bo(struct drm_device *drm) · 34 unmodified lines
292294 WARN_ON_ONCE(sizeof(vc4->bin_alloc_used) * 8 !=
293295 bo->base.base.size / vc4->bin_alloc_size);
294296
297+ kref_init(&vc4->bin_bo_kref);
298+
299+ /* Enable the out-of-memory interrupt to set our
300+ * newly-allocated binner BO, potentially from an
301+ * already-pending-but-masked interrupt.
302+ */
303+ V3D_WRITE(V3D_INTENA, V3D_INT_OUTOMEM);
304+
295305 break;
296306 }
297307
@@ -311,6 +321,47 @@ static int vc4_allocate_bin_bo(struct drm_device *drm) · 13 unmodified lines
311321 return ret;
312322 }
313323
324+int vc4_v3d_bin_bo_get(struct vc4_dev *vc4, bool *used)
325+{
326+ int ret = 0;
327+
328+ mutex_lock(&vc4->bin_bo_lock);
329+
330+ if (used && *used)
331+ goto complete;
332+
333+ if (vc4->bin_bo)
334+ kref_get(&vc4->bin_bo_kref);
335+ else
336+ ret = bin_bo_alloc(vc4);
337+
338+ if (ret == 0 && used)
339+ *used = true;
340+
341+complete:
342+ mutex_unlock(&vc4->bin_bo_lock);
343+
344+ return ret;
345+}
346+
347+static void bin_bo_release(struct kref *ref)
348+{
349+ struct vc4_dev *vc4 = container_of(ref, struct vc4_dev, bin_bo_kref);
350+
351+ if (WARN_ON_ONCE(!vc4->bin_bo))
352+ return;
353+
354+ drm_gem_object_put_unlocked(&vc4->bin_bo->base.base);
355+ vc4->bin_bo = NULL;
356+}
357+
358+void vc4_v3d_bin_bo_put(struct vc4_dev *vc4)
359+{
360+ mutex_lock(&vc4->bin_bo_lock);
361+ kref_put(&vc4->bin_bo_kref, bin_bo_release);
362+ mutex_unlock(&vc4->bin_bo_lock);
363+}
364+
314365 #ifdef CONFIG_PM
315366 static int vc4_v3d_runtime_suspend(struct device *dev)
316367 {
@@ -319,9 +370,6 @@ static int vc4_v3d_runtime_suspend(struct device *dev) · 2 unmodified lines
319370
320371 vc4_irq_uninstall(vc4->dev);
321372
322− drm_gem_object_put_unlocked(&vc4->bin_bo->base.base);
323− vc4->bin_bo = NULL;
324−
325373 clk_disable_unprepare(v3d->clk);
326374
327375 return 0;
@@ -333,10 +381,6 @@ static int vc4_v3d_runtime_resume(struct device *dev) · 5 unmodified lines
333381 struct vc4_dev *vc4 = v3d->vc4;
334382 int ret;
335383
336− ret = vc4_allocate_bin_bo(vc4->dev);
337− if (ret)
338− return ret;
339−
340384 ret = clk_prepare_enable(v3d->clk);
341385 if (ret != 0)
342386 return ret;
@@ -403,12 +447,6 @@ static int vc4_v3d_bind(struct device *dev, struct device *master, void *data) · 60 unmodified lines
403447 if (ret != 0)
404448 return ret;
405449
406− ret = vc4_allocate_bin_bo(drm);
407− if (ret) {
408− clk_disable_unprepare(v3d->clk);
409− return ret;
410− }
411−
412450 /* Reset the binner overflow address/size at setup, to be sure
413451 * we don't reuse an old one.
414452 */
drivers/gpu/drm/virtio/Makefile+1−1
@@ -6,6 +6,6 @@ · 5 unmodified lines
66 virtio-gpu-y := virtgpu_drv.o virtgpu_kms.o virtgpu_gem.o \
77 virtgpu_fb.o virtgpu_display.o virtgpu_vq.o virtgpu_ttm.o \
88 virtgpu_fence.o virtgpu_object.o virtgpu_debugfs.o virtgpu_plane.o \
9− virtgpu_ioctl.o virtgpu_prime.o
9+ virtgpu_ioctl.o virtgpu_prime.o virtgpu_trace_points.o
1010
1111 obj-$(CONFIG_DRM_VIRTIO_GPU) += virtio-gpu.o
drivers/gpu/drm/virtio/virtgpu_drv.h+1−2
@@ -102,7 +102,6 @@ struct virtio_gpu_fence { · 101 unmodified lines
102102 struct dma_fence f;
103103 struct virtio_gpu_fence_driver *drv;
104104 struct list_head node;
105− uint64_t seq;
106105 };
107106 #define to_virtio_fence(x) \
108107 container_of(x, struct virtio_gpu_fence, f)
@@ -356,7 +355,7 @@ int virtio_gpu_mmap(struct file *filp, struct vm_area_struct *vma); · 247 unmodified lines
356355 bool virtio_fence_signaled(struct dma_fence *f);
357356 struct virtio_gpu_fence *virtio_gpu_fence_alloc(
358357 struct virtio_gpu_device *vgdev);
359−int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
358+void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
360359 struct virtio_gpu_ctrl_hdr *cmd_hdr,
361360 struct virtio_gpu_fence *fence);
362361 void virtio_gpu_fence_event_process(struct virtio_gpu_device *vdev,
drivers/gpu/drm/virtio/virtgpu_fence.c+15−10
@@ -24,6 +24,7 @@ · 23 unmodified lines
2424 */
2525
2626 #include <drm/drmP.h>
27+#include <trace/events/dma_fence.h>
2728 #include "virtgpu_drv.h"
2829
2930 static const char *virtio_get_driver_name(struct dma_fence *f)
@@ -40,16 +41,14 @@ bool virtio_fence_signaled(struct dma_fence *f) · 10 unmodified lines
4041 {
4142 struct virtio_gpu_fence *fence = to_virtio_fence(f);
4243
43− if (atomic64_read(&fence->drv->last_seq) >= fence->seq)
44+ if (atomic64_read(&fence->drv->last_seq) >= fence->f.seqno)
4445 return true;
4546 return false;
4647 }
4748
4849 static void virtio_fence_value_str(struct dma_fence *f, char *str, int size)
4950 {
50− struct virtio_gpu_fence *fence = to_virtio_fence(f);
51−
52− snprintf(str, size, "%llu", fence->seq);
51+ snprintf(str, size, "%llu", f->seqno);
5352 }
5453
5554 static void virtio_timeline_value_str(struct dma_fence *f, char *str, int size)
@@ -71,17 +70,22 @@ struct virtio_gpu_fence *virtio_gpu_fence_alloc(struct virtio_gpu_device *vgdev) · 15 unmodified lines
7170 {
7271 struct virtio_gpu_fence_driver *drv = &vgdev->fence_drv;
7372 struct virtio_gpu_fence *fence = kzalloc(sizeof(struct virtio_gpu_fence),
74− GFP_ATOMIC);
73+ GFP_KERNEL);
7574 if (!fence)
7675 return fence;
7776
7877 fence->drv = drv;
78+
79+ /* This only partially initializes the fence because the seqno is
80+ * unknown yet. The fence must not be used outside of the driver
81+ * until virtio_gpu_fence_emit is called.
82+ */
7983 dma_fence_init(&fence->f, &virtio_fence_ops, &drv->lock, drv->context, 0);
8084
8185 return fence;
8286 }
8387
84−int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
88+void virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev,
8589 struct virtio_gpu_ctrl_hdr *cmd_hdr,
8690 struct virtio_gpu_fence *fence)
8791 {
@@ -89,14 +93,15 @@ int virtio_gpu_fence_emit(struct virtio_gpu_device *vgdev, · 1 unmodified line
8993 unsigned long irq_flags;
9094
9195 spin_lock_irqsave(&drv->lock, irq_flags);
92− fence->seq = ++drv->sync_seq;
96+ fence->f.seqno = ++drv->sync_seq;
9397 dma_fence_get(&fence->f);
9498 list_add_tail(&fence->node, &drv->fences);
9599 spin_unlock_irqrestore(&drv->lock, irq_flags);
96100
101+ trace_dma_fence_emit(&fence->f);
102+
97103 cmd_hdr->flags |= cpu_to_le32(VIRTIO_GPU_FLAG_FENCE);
98− cmd_hdr->fence_id = cpu_to_le64(fence->seq);
99− return 0;
104+ cmd_hdr->fence_id = cpu_to_le64(fence->f.seqno);
100105 }
101106
102107 void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev,
@@ -109,7 +114,7 @@ void virtio_gpu_fence_event_process(struct virtio_gpu_device *vgdev, · 6 unmodified lines
109114 spin_lock_irqsave(&drv->lock, irq_flags);
110115 atomic64_set(&vgdev->fence_drv.last_seq, last_seq);
111116 list_for_each_entry_safe(fence, tmp, &drv->fences, node) {
112− if (last_seq < fence->seq)
117+ if (last_seq < fence->f.seqno)
113118 continue;
114119 dma_fence_signal_locked(&fence->f);
115120 list_del(&fence->node);
drivers/gpu/drm/virtio/virtgpu_ioctl.c+9−9
@@ -553,34 +553,34 @@ copy_exit: · 552 unmodified lines
553553
554554 struct drm_ioctl_desc virtio_gpu_ioctls[DRM_VIRTIO_NUM_IOCTLS] = {
555555 DRM_IOCTL_DEF_DRV(VIRTGPU_MAP, virtio_gpu_map_ioctl,
556− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
556+ DRM_AUTH | DRM_RENDER_ALLOW),
557557
558558 DRM_IOCTL_DEF_DRV(VIRTGPU_EXECBUFFER, virtio_gpu_execbuffer_ioctl,
559− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
559+ DRM_AUTH | DRM_RENDER_ALLOW),
560560
561561 DRM_IOCTL_DEF_DRV(VIRTGPU_GETPARAM, virtio_gpu_getparam_ioctl,
562− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
562+ DRM_AUTH | DRM_RENDER_ALLOW),
563563
564564 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_CREATE,
565565 virtio_gpu_resource_create_ioctl,
566− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
566+ DRM_AUTH | DRM_RENDER_ALLOW),
567567
568568 DRM_IOCTL_DEF_DRV(VIRTGPU_RESOURCE_INFO, virtio_gpu_resource_info_ioctl,
569− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
569+ DRM_AUTH | DRM_RENDER_ALLOW),
570570
571571 /* make transfer async to the main ring? - no sure, can we
572572 * thread these in the underlying GL
573573 */
574574 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_FROM_HOST,
575575 virtio_gpu_transfer_from_host_ioctl,
576− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
576+ DRM_AUTH | DRM_RENDER_ALLOW),
577577 DRM_IOCTL_DEF_DRV(VIRTGPU_TRANSFER_TO_HOST,
578578 virtio_gpu_transfer_to_host_ioctl,
579− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
579+ DRM_AUTH | DRM_RENDER_ALLOW),
580580
581581 DRM_IOCTL_DEF_DRV(VIRTGPU_WAIT, virtio_gpu_wait_ioctl,
582− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
582+ DRM_AUTH | DRM_RENDER_ALLOW),
583583
584584 DRM_IOCTL_DEF_DRV(VIRTGPU_GET_CAPS, virtio_gpu_get_caps_ioctl,
585− DRM_AUTH | DRM_UNLOCKED | DRM_RENDER_ALLOW),
585+ DRM_AUTH | DRM_RENDER_ALLOW),
586586 };
drivers/gpu/drm/virtio/virtgpu_trace.h+52−0
@@ -0,0 +1,52 @@
1+/* SPDX-License-Identifier: GPL-2.0 */
2+#if !defined(_VIRTGPU_TRACE_H_) || defined(TRACE_HEADER_MULTI_READ)
3+#define _VIRTGPU_TRACE_H_
4+
5+#include <linux/tracepoint.h>
6+
7+#undef TRACE_SYSTEM
8+#define TRACE_SYSTEM virtio_gpu
9+#define TRACE_INCLUDE_FILE virtgpu_trace
10+
11+DECLARE_EVENT_CLASS(virtio_gpu_cmd,
12+ TP_PROTO(struct virtqueue *vq, struct virtio_gpu_ctrl_hdr *hdr),
13+ TP_ARGS(vq, hdr),
14+ TP_STRUCT__entry(
15+ __field(int, dev)
16+ __field(unsigned int, vq)
17+ __field(const char *, name)
18+ __field(u32, type)
19+ __field(u32, flags)
20+ __field(u64, fence_id)
21+ __field(u32, ctx_id)
22+ ),
23+ TP_fast_assign(
24+ __entry->dev = vq->vdev->index;
25+ __entry->vq = vq->index;
26+ __entry->name = vq->name;
27+ __entry->type = le32_to_cpu(hdr->type);
28+ __entry->flags = le32_to_cpu(hdr->flags);
29+ __entry->fence_id = le64_to_cpu(hdr->fence_id);
30+ __entry->ctx_id = le32_to_cpu(hdr->ctx_id);
31+ ),
32+ TP_printk("vdev=%d vq=%u name=%s type=0x%x flags=0x%x fence_id=%llu ctx_id=%u",
33+ __entry->dev, __entry->vq, __entry->name,
34+ __entry->type, __entry->flags, __entry->fence_id,
35+ __entry->ctx_id)
36+);
37+
38+DEFINE_EVENT(virtio_gpu_cmd, virtio_gpu_cmd_queue,
39+ TP_PROTO(struct virtqueue *vq, struct virtio_gpu_ctrl_hdr *hdr),
40+ TP_ARGS(vq, hdr)
41+);
42+
43+DEFINE_EVENT(virtio_gpu_cmd, virtio_gpu_cmd_response,
44+ TP_PROTO(struct virtqueue *vq, struct virtio_gpu_ctrl_hdr *hdr),
45+ TP_ARGS(vq, hdr)
46+);
47+
48+#endif
49+
50+#undef TRACE_INCLUDE_PATH
51+#define TRACE_INCLUDE_PATH ../../drivers/gpu/drm/virtio
52+#include <trace/define_trace.h>
drivers/gpu/drm/virtio/virtgpu_trace_points.c+5−0
@@ -0,0 +1,5 @@
1+// SPDX-License-Identifier: GPL-2.0
2+#include "virtgpu_drv.h"
3+
4+#define CREATE_TRACE_POINTS
5+#include "virtgpu_trace.h"
drivers/gpu/drm/virtio/virtgpu_vq.c+10−0
@@ -28,6 +28,7 @@ · 27 unmodified lines
2828
2929 #include <drm/drmP.h>
3030 #include "virtgpu_drv.h"
31+#include "virtgpu_trace.h"
3132 #include <linux/virtio.h>
3233 #include <linux/virtio_config.h>
3334 #include <linux/virtio_ring.h>
@@ -192,6 +193,9 @@ void virtio_gpu_dequeue_ctrl_func(struct work_struct *work) · 158 unmodified lines
192193
193194 list_for_each_entry_safe(entry, tmp, &reclaim_list, list) {
194195 resp = (struct virtio_gpu_ctrl_hdr *)entry->resp_buf;
196+
197+ trace_virtio_gpu_cmd_response(vgdev->ctrlq.vq, resp);
198+
195199 if (resp->type != cpu_to_le32(VIRTIO_GPU_RESP_OK_NODATA)) {
196200 if (resp->type >= cpu_to_le32(VIRTIO_GPU_RESP_ERR_UNSPEC)) {
197201 struct virtio_gpu_ctrl_hdr *cmd;
@@ -284,6 +288,9 @@ retry: · 86 unmodified lines
284288 spin_lock(&vgdev->ctrlq.qlock);
285289 goto retry;
286290 } else {
291+ trace_virtio_gpu_cmd_queue(vq,
292+ (struct virtio_gpu_ctrl_hdr *)vbuf->buf);
293+
287294 virtqueue_kick(vq);
288295 }
289296
@@ -359,6 +366,9 @@ retry: · 69 unmodified lines
359366 spin_lock(&vgdev->cursorq.qlock);
360367 goto retry;
361368 } else {
369+ trace_virtio_gpu_cmd_queue(vq,
370+ (struct virtio_gpu_ctrl_hdr *)vbuf->buf);
371+
362372 virtqueue_kick(vq);
363373 }
364374
drivers/gpu/drm/vkms/vkms_crtc.c+13−20
@@ -83,26 +83,6 @@ bool vkms_get_vblank_timestamp(struct drm_device *dev, unsigned int pipe, · 82 unmodified lines
8383 return true;
8484 }
8585
86−static void vkms_atomic_crtc_reset(struct drm_crtc *crtc)
87−{
88− struct vkms_crtc_state *vkms_state = NULL;
89−
90− if (crtc->state) {
91− vkms_state = to_vkms_crtc_state(crtc->state);
92− __drm_atomic_helper_crtc_destroy_state(crtc->state);
93− kfree(vkms_state);
94− crtc->state = NULL;
95− }
96−
97− vkms_state = kzalloc(sizeof(*vkms_state), GFP_KERNEL);
98− if (!vkms_state)
99− return;
100− INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle);
101−
102− crtc->state = &vkms_state->base;
103− crtc->state->crtc = crtc;
104−}
105−
10686 static struct drm_crtc_state *
10787 vkms_atomic_crtc_duplicate_state(struct drm_crtc *crtc)
10888 {
@@ -135,6 +115,19 @@ static void vkms_atomic_crtc_destroy_state(struct drm_crtc *crtc, · 26 unmodified lines
135115 }
136116 }
137117
118+static void vkms_atomic_crtc_reset(struct drm_crtc *crtc)
119+{
120+ struct vkms_crtc_state *vkms_state =
121+ kzalloc(sizeof(*vkms_state), GFP_KERNEL);
122+
123+ if (crtc->state)
124+ vkms_atomic_crtc_destroy_state(crtc, crtc->state);
125+
126+ __drm_atomic_helper_crtc_reset(crtc, &vkms_state->base);
127+ if (vkms_state)
128+ INIT_WORK(&vkms_state->crc_work, vkms_crc_work_handle);
129+}
130+
138131 static const struct drm_crtc_funcs vkms_crtc_funcs = {
139132 .set_config = drm_atomic_helper_set_config,
140133 .destroy = drm_crtc_cleanup,
drivers/gpu/drm/zte/zx_plane.c+2−4
@@ -199,7 +199,6 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane, · 198 unmodified lines
199199 u32 dst_x, dst_y, dst_w, dst_h;
200200 uint32_t format;
201201 int fmt;
202− int num_planes;
203202 int i;
204203
205204 if (!fb)
@@ -218,13 +217,12 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane, · 12 unmodified lines
218217 dst_h = drm_rect_height(dst);
219218
220219 /* Set up data address registers for Y, Cb and Cr planes */
221− num_planes = drm_format_num_planes(format);
222220 paddr_reg = layer + VL_Y;
223− for (i = 0; i < num_planes; i++) {
221+ for (i = 0; i < fb->format->num_planes; i++) {
224222 cma_obj = drm_fb_cma_get_gem_obj(fb, i);
225223 paddr = cma_obj->paddr + fb->offsets[i];
226224 paddr += src_y * fb->pitches[i];
227− paddr += src_x * drm_format_plane_cpp(format, i);
225+ paddr += src_x * fb->format->cpp[i];
228226 zx_writel(paddr_reg, paddr);
229227 paddr_reg += 4;
230228 }
drivers/video/hdmi.c+257−0
@@ -650,6 +650,150 @@ hdmi_vendor_any_infoframe_check_only(const union hdmi_vendor_any_infoframe *fram · 649 unmodified lines
650650 return 0;
651651 }
652652
653+/**
654+ * hdmi_drm_infoframe_init() - initialize an HDMI Dynaminc Range and
655+ * mastering infoframe
656+ * @frame: HDMI DRM infoframe
657+ *
658+ * Returns 0 on success or a negative error code on failure.
659+ */
660+int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame)
661+{
662+ memset(frame, 0, sizeof(*frame));
663+
664+ frame->type = HDMI_INFOFRAME_TYPE_DRM;
665+ frame->version = 1;
666+ frame->length = HDMI_DRM_INFOFRAME_SIZE;
667+
668+ return 0;
669+}
670+EXPORT_SYMBOL(hdmi_drm_infoframe_init);
671+
672+static int hdmi_drm_infoframe_check_only(const struct hdmi_drm_infoframe *frame)
673+{
674+ if (frame->type != HDMI_INFOFRAME_TYPE_DRM ||
675+ frame->version != 1)
676+ return -EINVAL;
677+
678+ if (frame->length != HDMI_DRM_INFOFRAME_SIZE)
679+ return -EINVAL;
680+
681+ return 0;
682+}
683+
684+/**
685+ * hdmi_drm_infoframe_check() - check a HDMI DRM infoframe
686+ * @frame: HDMI DRM infoframe
687+ *
688+ * Validates that the infoframe is consistent.
689+ * Returns 0 on success or a negative error code on failure.
690+ */
691+int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame)
692+{
693+ return hdmi_drm_infoframe_check_only(frame);
694+}
695+EXPORT_SYMBOL(hdmi_drm_infoframe_check);
696+
697+/**
698+ * hdmi_drm_infoframe_pack_only() - write HDMI DRM infoframe to binary buffer
699+ * @frame: HDMI DRM infoframe
700+ * @buffer: destination buffer
701+ * @size: size of buffer
702+ *
703+ * Packs the information contained in the @frame structure into a binary
704+ * representation that can be written into the corresponding controller
705+ * registers. Also computes the checksum as required by section 5.3.5 of
706+ * the HDMI 1.4 specification.
707+ *
708+ * Returns the number of bytes packed into the binary buffer or a negative
709+ * error code on failure.
710+ */
711+ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
712+ void *buffer, size_t size)
713+{
714+ u8 *ptr = buffer;
715+ size_t length;
716+ int i;
717+
718+ length = HDMI_INFOFRAME_HEADER_SIZE + frame->length;
719+
720+ if (size < length)
721+ return -ENOSPC;
722+
723+ memset(buffer, 0, size);
724+
725+ ptr[0] = frame->type;
726+ ptr[1] = frame->version;
727+ ptr[2] = frame->length;
728+ ptr[3] = 0; /* checksum */
729+
730+ /* start infoframe payload */
731+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
732+
733+ *ptr++ = frame->eotf;
734+ *ptr++ = frame->metadata_type;
735+
736+ for (i = 0; i < 3; i++) {
737+ *ptr++ = frame->display_primaries[i].x;
738+ *ptr++ = frame->display_primaries[i].x >> 8;
739+ *ptr++ = frame->display_primaries[i].y;
740+ *ptr++ = frame->display_primaries[i].y >> 8;
741+ }
742+
743+ *ptr++ = frame->white_point.x;
744+ *ptr++ = frame->white_point.x >> 8;
745+
746+ *ptr++ = frame->white_point.y;
747+ *ptr++ = frame->white_point.y >> 8;
748+
749+ *ptr++ = frame->max_display_mastering_luminance;
750+ *ptr++ = frame->max_display_mastering_luminance >> 8;
751+
752+ *ptr++ = frame->min_display_mastering_luminance;
753+ *ptr++ = frame->min_display_mastering_luminance >> 8;
754+
755+ *ptr++ = frame->max_cll;
756+ *ptr++ = frame->max_cll >> 8;
757+
758+ *ptr++ = frame->max_fall;
759+ *ptr++ = frame->max_fall >> 8;
760+
761+ hdmi_infoframe_set_checksum(buffer, length);
762+
763+ return length;
764+}
765+EXPORT_SYMBOL(hdmi_drm_infoframe_pack_only);
766+
767+/**
768+ * hdmi_drm_infoframe_pack() - check a HDMI DRM infoframe,
769+ * and write it to binary buffer
770+ * @frame: HDMI DRM infoframe
771+ * @buffer: destination buffer
772+ * @size: size of buffer
773+ *
774+ * Validates that the infoframe is consistent and updates derived fields
775+ * (eg. length) based on other fields, after which it packs the information
776+ * contained in the @frame structure into a binary representation that
777+ * can be written into the corresponding controller registers. This function
778+ * also computes the checksum as required by section 5.3.5 of the HDMI 1.4
779+ * specification.
780+ *
781+ * Returns the number of bytes packed into the binary buffer or a negative
782+ * error code on failure.
783+ */
784+ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame,
785+ void *buffer, size_t size)
786+{
787+ int ret;
788+
789+ ret = hdmi_drm_infoframe_check(frame);
790+ if (ret)
791+ return ret;
792+
793+ return hdmi_drm_infoframe_pack_only(frame, buffer, size);
794+}
795+EXPORT_SYMBOL(hdmi_drm_infoframe_pack);
796+
653797 /*
654798 * hdmi_vendor_any_infoframe_check() - check a vendor infoframe
655799 */
@@ -758,6 +902,10 @@ hdmi_infoframe_pack_only(const union hdmi_infoframe *frame, void *buffer, size_t · 102 unmodified lines
758902 length = hdmi_avi_infoframe_pack_only(&frame->avi,
759903 buffer, size);
760904 break;
905+ case HDMI_INFOFRAME_TYPE_DRM:
906+ length = hdmi_drm_infoframe_pack_only(&frame->drm,
907+ buffer, size);
908+ break;
761909 case HDMI_INFOFRAME_TYPE_SPD:
762910 length = hdmi_spd_infoframe_pack_only(&frame->spd,
763911 buffer, size);
@@ -806,6 +954,9 @@ hdmi_infoframe_pack(union hdmi_infoframe *frame, · 42 unmodified lines
806954 case HDMI_INFOFRAME_TYPE_AVI:
807955 length = hdmi_avi_infoframe_pack(&frame->avi, buffer, size);
808956 break;
957+ case HDMI_INFOFRAME_TYPE_DRM:
958+ length = hdmi_drm_infoframe_pack(&frame->drm, buffer, size);
959+ break;
809960 case HDMI_INFOFRAME_TYPE_SPD:
810961 length = hdmi_spd_infoframe_pack(&frame->spd, buffer, size);
811962 break;
@@ -838,6 +989,8 @@ static const char *hdmi_infoframe_type_get_name(enum hdmi_infoframe_type type) · 26 unmodified lines
838989 return "Source Product Description (SPD)";
839990 case HDMI_INFOFRAME_TYPE_AUDIO:
840991 return "Audio";
992+ case HDMI_INFOFRAME_TYPE_DRM:
993+ return "Dynamic Range and Mastering";
841994 }
842995 return "Reserved";
843996 }
@@ -1284,6 +1437,40 @@ static void hdmi_audio_infoframe_log(const char *level, · 440 unmodified lines
12841437 frame->downmix_inhibit ? "Yes" : "No");
12851438 }
12861439
1440+/**
1441+ * hdmi_drm_infoframe_log() - log info of HDMI DRM infoframe
1442+ * @level: logging level
1443+ * @dev: device
1444+ * @frame: HDMI DRM infoframe
1445+ */
1446+static void hdmi_drm_infoframe_log(const char *level,
1447+ struct device *dev,
1448+ const struct hdmi_drm_infoframe *frame)
1449+{
1450+ int i;
1451+
1452+ hdmi_infoframe_log_header(level, dev,
1453+ (struct hdmi_any_infoframe *)frame);
1454+ hdmi_log("length: %d\n", frame->length);
1455+ hdmi_log("metadata type: %d\n", frame->metadata_type);
1456+ hdmi_log("eotf: %d\n", frame->eotf);
1457+ for (i = 0; i < 3; i++) {
1458+ hdmi_log("x[%d]: %d\n", i, frame->display_primaries[i].x);
1459+ hdmi_log("y[%d]: %d\n", i, frame->display_primaries[i].y);
1460+ }
1461+
1462+ hdmi_log("white point x: %d\n", frame->white_point.x);
1463+ hdmi_log("white point y: %d\n", frame->white_point.y);
1464+
1465+ hdmi_log("max_display_mastering_luminance: %d\n",
1466+ frame->max_display_mastering_luminance);
1467+ hdmi_log("min_display_mastering_luminance: %d\n",
1468+ frame->min_display_mastering_luminance);
1469+
1470+ hdmi_log("max_cll: %d\n", frame->max_cll);
1471+ hdmi_log("max_fall: %d\n", frame->max_fall);
1472+}
1473+
12871474 static const char *
12881475 hdmi_3d_structure_get_name(enum hdmi_3d_structure s3d_struct)
12891476 {
@@ -1372,6 +1559,9 @@ void hdmi_infoframe_log(const char *level, · 82 unmodified lines
13721559 case HDMI_INFOFRAME_TYPE_VENDOR:
13731560 hdmi_vendor_any_infoframe_log(level, dev, &frame->vendor);
13741561 break;
1562+ case HDMI_INFOFRAME_TYPE_DRM:
1563+ hdmi_drm_infoframe_log(level, dev, &frame->drm);
1564+ break;
13751565 }
13761566 }
13771567 EXPORT_SYMBOL(hdmi_infoframe_log);
@@ -1614,6 +1804,70 @@ hdmi_vendor_any_infoframe_unpack(union hdmi_vendor_any_infoframe *frame, · 236 unmodified lines
16141804 return 0;
16151805 }
16161806
1807+/**
1808+ * hdmi_drm_infoframe_unpack() - unpack binary buffer to a HDMI DRM infoframe
1809+ * @frame: HDMI DRM infoframe
1810+ * @buffer: source buffer
1811+ * @size: size of buffer
1812+ *
1813+ * Unpacks the information contained in binary @buffer into a structured
1814+ * @frame of the HDMI Dynamic Range and Mastering (DRM) information frame.
1815+ * Also verifies the checksum as required by section 5.3.5 of the HDMI 1.4
1816+ * specification.
1817+ *
1818+ * Returns 0 on success or a negative error code on failure.
1819+ */
1820+static int hdmi_drm_infoframe_unpack(struct hdmi_drm_infoframe *frame,
1821+ const void *buffer, size_t size)
1822+{
1823+ const u8 *ptr = buffer;
1824+ const u8 *temp;
1825+ u8 x_lsb, x_msb;
1826+ u8 y_lsb, y_msb;
1827+ int ret;
1828+ int i;
1829+
1830+ if (size < HDMI_INFOFRAME_SIZE(DRM))
1831+ return -EINVAL;
1832+
1833+ if (ptr[0] != HDMI_INFOFRAME_TYPE_DRM ||
1834+ ptr[1] != 1 ||
1835+ ptr[2] != HDMI_DRM_INFOFRAME_SIZE)
1836+ return -EINVAL;
1837+
1838+ if (hdmi_infoframe_checksum(buffer, HDMI_INFOFRAME_SIZE(DRM)) != 0)
1839+ return -EINVAL;
1840+
1841+ ret = hdmi_drm_infoframe_init(frame);
1842+ if (ret)
1843+ return ret;
1844+
1845+ ptr += HDMI_INFOFRAME_HEADER_SIZE;
1846+
1847+ frame->eotf = ptr[0] & 0x7;
1848+ frame->metadata_type = ptr[1] & 0x7;
1849+
1850+ temp = ptr + 2;
1851+ for (i = 0; i < 3; i++) {
1852+ x_lsb = *temp++;
1853+ x_msb = *temp++;
1854+ frame->display_primaries[i].x = (x_msb << 8) | x_lsb;
1855+ y_lsb = *temp++;
1856+ y_msb = *temp++;
1857+ frame->display_primaries[i].y = (y_msb << 8) | y_lsb;
1858+ }
1859+
1860+ frame->white_point.x = (ptr[15] << 8) | ptr[14];
1861+ frame->white_point.y = (ptr[17] << 8) | ptr[16];
1862+
1863+ frame->max_display_mastering_luminance = (ptr[19] << 8) | ptr[18];
1864+ frame->min_display_mastering_luminance = (ptr[21] << 8) | ptr[20];
1865+ frame->max_cll = (ptr[23] << 8) | ptr[22];
1866+ frame->max_fall = (ptr[25] << 8) | ptr[24];
1867+
1868+ return 0;
1869+}
1870+
16171871 /**
16181872 * hdmi_infoframe_unpack() - unpack binary buffer to a HDMI infoframe
16191873 * @frame: HDMI infoframe
@@ -1640,6 +1894,9 @@ int hdmi_infoframe_unpack(union hdmi_infoframe *frame, · 20 unmodified lines
16401894 case HDMI_INFOFRAME_TYPE_AVI:
16411895 ret = hdmi_avi_infoframe_unpack(&frame->avi, buffer, size);
16421896 break;
1897+ case HDMI_INFOFRAME_TYPE_DRM:
1898+ ret = hdmi_drm_infoframe_unpack(&frame->drm, buffer, size);
1899+ break;
16431900 case HDMI_INFOFRAME_TYPE_SPD:
16441901 ret = hdmi_spd_infoframe_unpack(&frame->spd, buffer, size);
16451902 break;
include/drm/drm_atomic_state_helper.h+2−0
@@ -37,6 +37,8 @@ struct drm_private_state; · 36 unmodified lines
3737 struct drm_modeset_acquire_ctx;
3838 struct drm_device;
3939
40+void __drm_atomic_helper_crtc_reset(struct drm_crtc *crtc,
41+ struct drm_crtc_state *state);
4042 void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc);
4143 void __drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc,
4244 struct drm_crtc_state *state);
include/drm/drm_connector.h+14−0
@@ -517,6 +517,10 @@ struct drm_connector_state { · 516 unmodified lines
517517 * Used by the atomic helpers to select the encoder, through the
518518 * &drm_connector_helper_funcs.atomic_best_encoder or
519519 * &drm_connector_helper_funcs.best_encoder callbacks.
520+ *
521+ * NOTE: Atomic drivers must fill this out (either themselves or through
522+ * helpers), for otherwise the GETCONNECTOR and GETENCODER IOCTLs will
523+ * not return correct data to userspace.
520524 */
521525 struct drm_encoder *best_encoder;
522526
@@ -599,6 +603,12 @@ struct drm_connector_state { · 76 unmodified lines
599603 * and the connector bpc limitations obtained from edid.
600604 */
601605 u8 max_bpc;
606+
607+ /**
608+ * @hdr_output_metadata:
609+ * DRM blob property for HDR output metadata
610+ */
611+ struct drm_property_blob *hdr_output_metadata;
602612 };
603613
604614 /**
@@ -1239,6 +1249,10 @@ struct drm_connector { · 634 unmodified lines
12391249 * &drm_mode_config.connector_free_work.
12401250 */
12411251 struct llist_node free_node;
1252+
1253+ /* HDR metdata */
1254+ struct hdr_output_metadata hdr_output_metadata;
1255+ struct hdr_sink_metadata hdr_sink_metadata;
12421256 };
12431257
12441258 #define obj_to_connector(x) container_of(x, struct drm_connector, base)
include/drm/drm_device.h+4−0
@@ -17,6 +17,7 @@ struct drm_vblank_crtc; · 16 unmodified lines
1717 struct drm_sg_mem;
1818 struct drm_local_map;
1919 struct drm_vma_offset_manager;
20+struct drm_vram_mm;
2021 struct drm_fb_helper;
2122
2223 struct inode;
@@ -286,6 +287,9 @@ struct drm_device { · 263 unmodified lines
286287 /** @vma_offset_manager: GEM information */
287288 struct drm_vma_offset_manager *vma_offset_manager;
288289
290+ /** @vram_mm: VRAM MM memory manager */
291+ struct drm_vram_mm *vram_mm;
292+
289293 /**
290294 * @switch_power_state:
291295 *
include/drm/drm_edid.h+5−0
@@ -25,6 +25,7 @@ · 24 unmodified lines
2525
2626 #include <linux/types.h>
2727 #include <linux/hdmi.h>
28+#include <drm/drm_mode.h>
2829
2930 struct drm_device;
3031 struct i2c_adapter;
@@ -370,6 +371,10 @@ drm_hdmi_avi_infoframe_quant_range(struct hdmi_avi_infoframe *frame, · 339 unmodified lines
370371 const struct drm_display_mode *mode,
371372 enum hdmi_quantization_range rgb_quant_range);
372373
374+int
375+drm_hdmi_infoframe_set_hdr_metadata(struct hdmi_drm_infoframe *frame,
376+ const struct drm_connector_state *conn_state);
377+
373378 /**
374379 * drm_eld_mnl - Get ELD monitor name length in bytes.
375380 * @eld: pointer to an eld memory structure with mnl set
include/drm/drm_fb_helper.h+0−10
@@ -49,9 +49,6 @@ struct drm_fb_offset { · 48 unmodified lines
4949
5050 struct drm_fb_helper_crtc {
5151 struct drm_mode_set mode_set;
52− struct drm_display_mode *desired_mode;
53− int x, y;
54− int rotation;
5552 };
5653
5754 /**
@@ -151,13 +148,6 @@ struct drm_fb_helper { · 93 unmodified lines
151148 struct drm_fb_helper_crtc *crtc_info;
152149 int connector_count;
153150 int connector_info_alloc_count;
154− /**
155− * @sw_rotations:
156− * Bitmask of all rotations requested for panel-orientation which
157− * could not be handled in hardware. If only one bit is set
158− * fbdev->fbcon_rotate_hint gets set to the requested rotation.
159− */
160− int sw_rotations;
161151 /**
162152 * @connector_info:
163153 *
include/drm/drm_fourcc.h+44−6
@@ -260,6 +260,50 @@ drm_format_info_is_yuv_sampling_444(const struct drm_format_info *info) · 259 unmodified lines
260260 return info->is_yuv && info->hsub == 1 && info->vsub == 1;
261261 }
262262
263+/**
264+ * drm_format_info_plane_width - width of the plane given the first plane
265+ * @info: pixel format info
266+ * @width: width of the first plane
267+ * @plane: plane index
268+ *
269+ * Returns:
270+ * The width of @plane, given that the width of the first plane is @width.
271+ */
272+static inline
273+int drm_format_info_plane_width(const struct drm_format_info *info, int width,
274+ int plane)
275+{
276+ if (!info || plane >= info->num_planes)
277+ return 0;
278+
279+ if (plane == 0)
280+ return width;
281+
282+ return width / info->hsub;
283+}
284+
285+/**
286+ * drm_format_info_plane_height - height of the plane given the first plane
287+ * @info: pixel format info
288+ * @height: height of the first plane
289+ * @plane: plane index
290+ *
291+ * Returns:
292+ * The height of @plane, given that the height of the first plane is @height.
293+ */
294+static inline
295+int drm_format_info_plane_height(const struct drm_format_info *info, int height,
296+ int plane)
297+{
298+ if (!info || plane >= info->num_planes)
299+ return 0;
300+
301+ if (plane == 0)
302+ return height;
303+
304+ return height / info->vsub;
305+}
306+
263307 const struct drm_format_info *__drm_format_info(u32 format);
264308 const struct drm_format_info *drm_format_info(u32 format);
265309 const struct drm_format_info *
@@ -268,12 +312,6 @@ drm_get_format_info(struct drm_device *dev, · 2 unmodified lines
268312 uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
269313 uint32_t drm_driver_legacy_fb_format(struct drm_device *dev,
270314 uint32_t bpp, uint32_t depth);
271−int drm_format_num_planes(uint32_t format);
272−int drm_format_plane_cpp(uint32_t format, int plane);
273−int drm_format_horz_chroma_subsampling(uint32_t format);
274−int drm_format_vert_chroma_subsampling(uint32_t format);
275−int drm_format_plane_width(int width, uint32_t format, int plane);
276−int drm_format_plane_height(int height, uint32_t format, int plane);
277315 unsigned int drm_format_info_block_width(const struct drm_format_info *info,
278316 int plane);
279317 unsigned int drm_format_info_block_height(const struct drm_format_info *info,
include/drm/drm_gem_vram_helper.h+162−0
@@ -0,0 +1,162 @@
1+/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
3+#ifndef DRM_GEM_VRAM_HELPER_H
4+#define DRM_GEM_VRAM_HELPER_H
5+
6+#include <drm/drm_gem.h>
7+#include <drm/ttm/ttm_bo_api.h>
8+#include <drm/ttm/ttm_placement.h>
9+#include <linux/kernel.h> /* for container_of() */
10+
11+struct drm_mode_create_dumb;
12+struct drm_vram_mm_funcs;
13+struct filp;
14+struct vm_area_struct;
15+
16+#define DRM_GEM_VRAM_PL_FLAG_VRAM TTM_PL_FLAG_VRAM
17+#define DRM_GEM_VRAM_PL_FLAG_SYSTEM TTM_PL_FLAG_SYSTEM
18+
19+/*
20+ * Buffer-object helpers
21+ */
22+
23+/**
24+ * struct drm_gem_vram_object - GEM object backed by VRAM
25+ * @gem: GEM object
26+ * @bo: TTM buffer object
27+ * @kmap: Mapping information for @bo
28+ * @placement: TTM placement information. Supported placements are \
29+ %TTM_PL_VRAM and %TTM_PL_SYSTEM
30+ * @placements: TTM placement information.
31+ * @pin_count: Pin counter
32+ *
33+ * The type struct drm_gem_vram_object represents a GEM object that is
34+ * backed by VRAM. It can be used for simple framebuffer devices with
35+ * dedicated memory. The buffer object can be evicted to system memory if
36+ * video memory becomes scarce.
37+ */
38+struct drm_gem_vram_object {
39+ struct drm_gem_object gem;
40+ struct ttm_buffer_object bo;
41+ struct ttm_bo_kmap_obj kmap;
42+
43+ /* Supported placements are %TTM_PL_VRAM and %TTM_PL_SYSTEM */
44+ struct ttm_placement placement;
45+ struct ttm_place placements[2];
46+
47+ int pin_count;
48+};
49+
50+/**
51+ * Returns the container of type &struct drm_gem_vram_object
52+ * for field bo.
53+ * @bo: the VRAM buffer object
54+ * Returns: The containing GEM VRAM object
55+ */
56+static inline struct drm_gem_vram_object *drm_gem_vram_of_bo(
57+ struct ttm_buffer_object *bo)
58+{
59+ return container_of(bo, struct drm_gem_vram_object, bo);
60+}
61+
62+/**
63+ * Returns the container of type &struct drm_gem_vram_object
64+ * for field gem.
65+ * @gem: the GEM object
66+ * Returns: The containing GEM VRAM object
67+ */
68+static inline struct drm_gem_vram_object *drm_gem_vram_of_gem(
69+ struct drm_gem_object *gem)
70+{
71+ return container_of(gem, struct drm_gem_vram_object, gem);
72+}
73+
74+struct drm_gem_vram_object *drm_gem_vram_create(struct drm_device *dev,
75+ struct ttm_bo_device *bdev,
76+ size_t size,
77+ unsigned long pg_align,
78+ bool interruptible);
79+void drm_gem_vram_put(struct drm_gem_vram_object *gbo);
80+int drm_gem_vram_lock(struct drm_gem_vram_object *gbo, bool no_wait);
81+void drm_gem_vram_unlock(struct drm_gem_vram_object *gbo);
82+u64 drm_gem_vram_mmap_offset(struct drm_gem_vram_object *gbo);
83+s64 drm_gem_vram_offset(struct drm_gem_vram_object *gbo);
84+int drm_gem_vram_pin(struct drm_gem_vram_object *gbo, unsigned long pl_flag);
85+int drm_gem_vram_pin_locked(struct drm_gem_vram_object *gbo,
86+ unsigned long pl_flag);
87+int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo);
88+int drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo);
89+void *drm_gem_vram_kmap_at(struct drm_gem_vram_object *gbo, bool map,
90+ bool *is_iomem, struct ttm_bo_kmap_obj *kmap);
91+void *drm_gem_vram_kmap(struct drm_gem_vram_object *gbo, bool map,
92+ bool *is_iomem);
93+void drm_gem_vram_kunmap_at(struct drm_gem_vram_object *gbo,
94+ struct ttm_bo_kmap_obj *kmap);
95+void drm_gem_vram_kunmap(struct drm_gem_vram_object *gbo);
96+
97+int drm_gem_vram_fill_create_dumb(struct drm_file *file,
98+ struct drm_device *dev,
99+ struct ttm_bo_device *bdev,
100+ unsigned long pg_align,
101+ bool interruptible,
102+ struct drm_mode_create_dumb *args);
103+
104+/*
105+ * Helpers for struct ttm_bo_driver
106+ */
107+
108+void drm_gem_vram_bo_driver_evict_flags(struct ttm_buffer_object *bo,
109+ struct ttm_placement *pl);
110+
111+int drm_gem_vram_bo_driver_verify_access(struct ttm_buffer_object *bo,
112+ struct file *filp);
113+
114+extern const struct drm_vram_mm_funcs drm_gem_vram_mm_funcs;
115+
116+/*
117+ * Helpers for struct drm_driver
118+ */
119+
120+void drm_gem_vram_driver_gem_free_object_unlocked(struct drm_gem_object *gem);
121+int drm_gem_vram_driver_dumb_create(struct drm_file *file,
122+ struct drm_device *dev,
123+ struct drm_mode_create_dumb *args);
124+int drm_gem_vram_driver_dumb_mmap_offset(struct drm_file *file,
125+ struct drm_device *dev,
126+ uint32_t handle, uint64_t *offset);
127+
128+/**
129+ * define DRM_GEM_VRAM_DRIVER - default callback functions for \
130+ &struct drm_driver
131+ *
132+ * Drivers that use VRAM MM and GEM VRAM can use this macro to initialize
133+ * &struct drm_driver with default functions.
134+ */
135+#define DRM_GEM_VRAM_DRIVER \
136+ .gem_free_object_unlocked = \
137+ drm_gem_vram_driver_gem_free_object_unlocked, \
138+ .dumb_create = drm_gem_vram_driver_dumb_create, \
139+ .dumb_map_offset = drm_gem_vram_driver_dumb_mmap_offset
140+
141+/*
142+ * PRIME helpers for struct drm_driver
143+ */
144+
145+int drm_gem_vram_driver_gem_prime_pin(struct drm_gem_object *obj);
146+void drm_gem_vram_driver_gem_prime_unpin(struct drm_gem_object *obj);
147+void *drm_gem_vram_driver_gem_prime_vmap(struct drm_gem_object *obj);
148+void drm_gem_vram_driver_gem_prime_vunmap(struct drm_gem_object *obj,
149+ void *vaddr);
150+int drm_gem_vram_driver_gem_prime_mmap(struct drm_gem_object *obj,
151+ struct vm_area_struct *vma);
152+
153+#define DRM_GEM_VRAM_DRIVER_PRIME \
154+ .gem_prime_export = drm_gem_prime_export, \
155+ .gem_prime_import = drm_gem_prime_import, \
156+ .gem_prime_pin = drm_gem_vram_driver_gem_prime_pin, \
157+ .gem_prime_unpin = drm_gem_vram_driver_gem_prime_unpin, \
158+ .gem_prime_vmap = drm_gem_vram_driver_gem_prime_vmap, \
159+ .gem_prime_vunmap = drm_gem_vram_driver_gem_prime_vunmap, \
160+ .gem_prime_mmap = drm_gem_vram_driver_gem_prime_mmap
161+
162+#endif
include/drm/drm_mode_config.h+7−0
@@ -836,6 +836,13 @@ struct drm_mode_config { · 835 unmodified lines
836836 */
837837 struct drm_property *writeback_out_fence_ptr_property;
838838
839+ /**
840+ * hdr_output_metadata_property: Connector property containing hdr
841+ * metatda. This will be provided by userspace compositors based
842+ * on HDR content
843+ */
844+ struct drm_property *hdr_output_metadata_property;
845+
839846 /* dumb ioctl parameters */
840847 uint32_t preferred_depth, prefer_shadow;
841848
include/drm/drm_vram_mm_helper.h+102−0
@@ -0,0 +1,102 @@
1+/* SPDX-License-Identifier: GPL-2.0-or-later */
2+
3+#ifndef DRM_VRAM_MM_HELPER_H
4+#define DRM_VRAM_MM_HELPER_H
5+
6+#include <drm/ttm/ttm_bo_driver.h>
7+
8+struct drm_device;
9+
10+/**
11+ * struct drm_vram_mm_funcs - Callback functions for &struct drm_vram_mm
12+ * @evict_flags: Provides an implementation for struct \
13+ &ttm_bo_driver.evict_flags
14+ * @verify_access: Provides an implementation for \
15+ struct &ttm_bo_driver.verify_access
16+ *
17+ * These callback function integrate VRAM MM with TTM buffer objects. New
18+ * functions can be added if necessary.
19+ */
20+struct drm_vram_mm_funcs {
21+ void (*evict_flags)(struct ttm_buffer_object *bo,
22+ struct ttm_placement *placement);
23+ int (*verify_access)(struct ttm_buffer_object *bo, struct file *filp);
24+};
25+
26+/**
27+ * struct drm_vram_mm - An instance of VRAM MM
28+ * @vram_base: Base address of the managed video memory
29+ * @vram_size: Size of the managed video memory in bytes
30+ * @bdev: The TTM BO device.
31+ * @funcs: TTM BO functions
32+ *
33+ * The fields &struct drm_vram_mm.vram_base and
34+ * &struct drm_vram_mm.vrm_size are managed by VRAM MM, but are
35+ * available for public read access. Use the field
36+ * &struct drm_vram_mm.bdev to access the TTM BO device.
37+ */
38+struct drm_vram_mm {
39+ uint64_t vram_base;
40+ size_t vram_size;
41+
42+ struct ttm_bo_device bdev;
43+
44+ const struct drm_vram_mm_funcs *funcs;
45+};
46+
47+/**
48+ * drm_vram_mm_of_bdev() - \
49+ Returns the container of type &struct ttm_bo_device for field bdev.
50+ * @bdev: the TTM BO device
51+ *
52+ * Returns:
53+ * The containing instance of &struct drm_vram_mm
54+ */
55+static inline struct drm_vram_mm *drm_vram_mm_of_bdev(
56+ struct ttm_bo_device *bdev)
57+{
58+ return container_of(bdev, struct drm_vram_mm, bdev);
59+}
60+
61+int drm_vram_mm_init(struct drm_vram_mm *vmm, struct drm_device *dev,
62+ uint64_t vram_base, size_t vram_size,
63+ const struct drm_vram_mm_funcs *funcs);
64+void drm_vram_mm_cleanup(struct drm_vram_mm *vmm);
65+
66+int drm_vram_mm_mmap(struct file *filp, struct vm_area_struct *vma,
67+ struct drm_vram_mm *vmm);
68+
69+/*
70+ * Helpers for integration with struct drm_device
71+ */
72+
73+struct drm_vram_mm *drm_vram_helper_alloc_mm(
74+ struct drm_device *dev, uint64_t vram_base, size_t vram_size,
75+ const struct drm_vram_mm_funcs *funcs);
76+void drm_vram_helper_release_mm(struct drm_device *dev);
77+
78+/*
79+ * Helpers for &struct file_operations
80+ */
81+
82+int drm_vram_mm_file_operations_mmap(
83+ struct file *filp, struct vm_area_struct *vma);
84+
85+/**
86+ * define DRM_VRAM_MM_FILE_OPERATIONS - default callback functions for \
87+ &struct file_operations
88+ *
89+ * Drivers that use VRAM MM can use this macro to initialize
90+ * &struct file_operations with default functions.
91+ */
92+#define DRM_VRAM_MM_FILE_OPERATIONS \
93+ .llseek = no_llseek, \
94+ .read = drm_read, \
95+ .poll = drm_poll, \
96+ .unlocked_ioctl = drm_ioctl, \
97+ .compat_ioctl = drm_compat_ioctl, \
98+ .mmap = drm_vram_mm_file_operations_mmap, \
99+ .open = drm_open, \
100+ .release = drm_release \
101+
102+#endif
include/drm/gma_drm.h+0−25
@@ -1,25 +0,0 @@
1−/**************************************************************************
2− * Copyright (c) 2007-2011, Intel Corporation.
3− * All Rights Reserved.
4− * Copyright (c) 2008, Tungsten Graphics Inc. Cedar Park, TX., USA.
5− * All Rights Reserved.
6− *
7− * This program is free software; you can redistribute it and/or modify it
8− * under the terms and conditions of the GNU General Public License,
9− * version 2, as published by the Free Software Foundation.
10− *
11− * This program is distributed in the hope it will be useful, but WITHOUT
12− * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13− * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14− * more details.
15− *
16− * You should have received a copy of the GNU General Public License along with
17− * this program; if not, write to the Free Software Foundation, Inc.,
18− * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
19− *
20− **************************************************************************/
21−
22−#ifndef _GMA_DRM_H_
23−#define _GMA_DRM_H_
24−
25−#endif
include/drm/gpu_scheduler.h+3−5
@@ -167,9 +167,6 @@ struct drm_sched_fence *to_drm_sched_fence(struct dma_fence *f); · 166 unmodified lines
167167 * @sched: the scheduler instance on which this job is scheduled.
168168 * @s_fence: contains the fences for the scheduling of job.
169169 * @finish_cb: the callback for the finished fence.
170− * @finish_work: schedules the function @drm_sched_job_finish once the job has
171− * finished to remove the job from the
172− * @drm_gpu_scheduler.ring_mirror_list.
173170 * @node: used to append this struct to the @drm_gpu_scheduler.ring_mirror_list.
174171 * @id: a unique id assigned to each job scheduled on the scheduler.
175172 * @karma: increment on every hang caused by this job. If this exceeds the hang
@@ -188,7 +185,6 @@ struct drm_sched_job { · 12 unmodified lines
188185 struct drm_gpu_scheduler *sched;
189186 struct drm_sched_fence *s_fence;
190187 struct dma_fence_cb finish_cb;
191− struct work_struct finish_work;
192188 struct list_head node;
193189 uint64_t id;
194190 atomic_t karma;
@@ -263,6 +259,7 @@ struct drm_sched_backend_ops { · 68 unmodified lines
263259 * guilty and it will be considered for scheduling further.
264260 * @num_jobs: the number of jobs in queue in the scheduler
265261 * @ready: marks if the underlying HW is ready to work
262+ * @free_guilty: A hit to time out handler to free the guilty job.
266263 *
267264 * One scheduler is implemented for each hardware ring.
268265 */
@@ -283,6 +280,7 @@ struct drm_gpu_scheduler { · 14 unmodified lines
283280 int hang_limit;
284281 atomic_t num_jobs;
285282 bool ready;
283+ bool free_guilty;
286284 };
287285
288286 int drm_sched_init(struct drm_gpu_scheduler *sched,
@@ -296,7 +294,7 @@ int drm_sched_job_init(struct drm_sched_job *job, · 7 unmodified lines
296294 void *owner);
297295 void drm_sched_job_cleanup(struct drm_sched_job *job);
298296 void drm_sched_wakeup(struct drm_gpu_scheduler *sched);
299−void drm_sched_stop(struct drm_gpu_scheduler *sched);
297+void drm_sched_stop(struct drm_gpu_scheduler *sched, struct drm_sched_job *bad);
300298 void drm_sched_start(struct drm_gpu_scheduler *sched, bool full_recovery);
301299 void drm_sched_resubmit_jobs(struct drm_gpu_scheduler *sched);
302300 void drm_sched_increase_karma(struct drm_sched_job *bad);
include/linux/dma-buf.h+38−9
@@ -39,18 +39,20 @@ struct dma_buf_attachment; · 38 unmodified lines
3939
4040 /**
4141 * struct dma_buf_ops - operations possible on struct dma_buf
42− * @map_atomic: [optional] maps a page from the buffer into kernel address
43− * space, users may not block until the subsequent unmap call.
44− * This callback must not sleep.
45− * @unmap_atomic: [optional] unmaps a atomically mapped page from the buffer.
46− * This Callback must not sleep.
47− * @map: [optional] maps a page from the buffer into kernel address space.
48− * @unmap: [optional] unmaps a page from the buffer.
4942 * @vmap: [optional] creates a virtual mapping for the buffer into kernel
5043 * address space. Same restrictions as for vmap and friends apply.
5144 * @vunmap: [optional] unmaps a vmap from the buffer
5245 */
5346 struct dma_buf_ops {
47+ /**
48+ * @cache_sgt_mapping:
49+ *
50+ * If true the framework will cache the first mapping made for each
51+ * attachment. This avoids creating mappings for attachments multiple
52+ * times.
53+ */
54+ bool cache_sgt_mapping;
55+
5456 /**
5557 * @attach:
5658 *
@@ -205,8 +207,6 @@ struct dma_buf_ops { · 148 unmodified lines
205207 * to be restarted.
206208 */
207209 int (*end_cpu_access)(struct dma_buf *, enum dma_data_direction);
208− void *(*map)(struct dma_buf *, unsigned long);
209− void (*unmap)(struct dma_buf *, unsigned long, void *);
210210
211211 /**
212212 * @mmap:
@@ -245,6 +245,31 @@ struct dma_buf_ops { · 32 unmodified lines
245245 */
246246 int (*mmap)(struct dma_buf *, struct vm_area_struct *vma);
247247
248+ /**
249+ * @map:
250+ *
251+ * Maps a page from the buffer into kernel address space. The page is
252+ * specified by offset into the buffer in PAGE_SIZE units.
253+ *
254+ * This callback is optional.
255+ *
256+ * Returns:
257+ *
258+ * Virtual address pointer where requested page can be accessed. NULL
259+ * on error or when this function is unimplemented by the exporter.
260+ */
261+ void *(*map)(struct dma_buf *, unsigned long);
262+
263+ /**
264+ * @unmap:
265+ *
266+ * Unmaps a page from the buffer. Page offset and address pointer should
267+ * be the same as the one passed to and returned by matching call to map.
268+ *
269+ * This callback is optional.
270+ */
271+ void (*unmap)(struct dma_buf *, unsigned long, void *);
272+
248273 void *(*vmap)(struct dma_buf *);
249274 void (*vunmap)(struct dma_buf *, void *vaddr);
250275 };
@@ -307,6 +332,8 @@ struct dma_buf { · 56 unmodified lines
307332 * @dmabuf: buffer for this attachment.
308333 * @dev: device attached to the buffer.
309334 * @node: list of dma_buf_attachment.
335+ * @sgt: cached mapping.
336+ * @dir: direction of cached mapping.
310337 * @priv: exporter specific attachment data.
311338 *
312339 * This structure holds the attachment information between the dma_buf buffer
@@ -322,6 +349,8 @@ struct dma_buf_attachment { · 9 unmodified lines
322349 struct dma_buf *dmabuf;
323350 struct device *dev;
324351 struct list_head node;
352+ struct sg_table *sgt;
353+ enum dma_data_direction dir;
325354 void *priv;
326355 };
327356
include/linux/hdmi.h+55−0
@@ -47,6 +47,7 @@ enum hdmi_infoframe_type { · 46 unmodified lines
4747 HDMI_INFOFRAME_TYPE_AVI = 0x82,
4848 HDMI_INFOFRAME_TYPE_SPD = 0x83,
4949 HDMI_INFOFRAME_TYPE_AUDIO = 0x84,
50+ HDMI_INFOFRAME_TYPE_DRM = 0x87,
5051 };
5152
5253 #define HDMI_IEEE_OUI 0x000c03
@@ -55,6 +56,7 @@ enum hdmi_infoframe_type { · 2 unmodified lines
5556 #define HDMI_AVI_INFOFRAME_SIZE 13
5657 #define HDMI_SPD_INFOFRAME_SIZE 25
5758 #define HDMI_AUDIO_INFOFRAME_SIZE 10
59+#define HDMI_DRM_INFOFRAME_SIZE 26
5860
5961 #define HDMI_INFOFRAME_SIZE(type) \
6062 (HDMI_INFOFRAME_HEADER_SIZE + HDMI_ ## type ## _INFOFRAME_SIZE)
@@ -152,6 +154,17 @@ enum hdmi_content_type { · 91 unmodified lines
152154 HDMI_CONTENT_TYPE_GAME,
153155 };
154156
157+enum hdmi_metadata_type {
158+ HDMI_STATIC_METADATA_TYPE1 = 1,
159+};
160+
161+enum hdmi_eotf {
162+ HDMI_EOTF_TRADITIONAL_GAMMA_SDR,
163+ HDMI_EOTF_TRADITIONAL_GAMMA_HDR,
164+ HDMI_EOTF_SMPTE_ST2084,
165+ HDMI_EOTF_BT_2100_HLG,
166+};
167+
155168 struct hdmi_avi_infoframe {
156169 enum hdmi_infoframe_type type;
157170 unsigned char version;
@@ -175,12 +188,37 @@ struct hdmi_avi_infoframe { · 17 unmodified lines
175188 unsigned short right_bar;
176189 };
177190
191+/* DRM Infoframe as per CTA 861.G spec */
192+struct hdmi_drm_infoframe {
193+ enum hdmi_infoframe_type type;
194+ unsigned char version;
195+ unsigned char length;
196+ enum hdmi_eotf eotf;
197+ enum hdmi_metadata_type metadata_type;
198+ struct {
199+ u16 x, y;
200+ } display_primaries[3];
201+ struct {
202+ u16 x, y;
203+ } white_point;
204+ u16 max_display_mastering_luminance;
205+ u16 min_display_mastering_luminance;
206+ u16 max_cll;
207+ u16 max_fall;
208+};
209+
178210 int hdmi_avi_infoframe_init(struct hdmi_avi_infoframe *frame);
179211 ssize_t hdmi_avi_infoframe_pack(struct hdmi_avi_infoframe *frame, void *buffer,
180212 size_t size);
181213 ssize_t hdmi_avi_infoframe_pack_only(const struct hdmi_avi_infoframe *frame,
182214 void *buffer, size_t size);
183215 int hdmi_avi_infoframe_check(struct hdmi_avi_infoframe *frame);
216+int hdmi_drm_infoframe_init(struct hdmi_drm_infoframe *frame);
217+ssize_t hdmi_drm_infoframe_pack(struct hdmi_drm_infoframe *frame, void *buffer,
218+ size_t size);
219+ssize_t hdmi_drm_infoframe_pack_only(const struct hdmi_drm_infoframe *frame,
220+ void *buffer, size_t size);
221+int hdmi_drm_infoframe_check(struct hdmi_drm_infoframe *frame);
184222
185223 enum hdmi_spd_sdi {
186224 HDMI_SPD_SDI_UNKNOWN,
@@ -320,6 +358,22 @@ struct hdmi_vendor_infoframe { · 133 unmodified lines
320358 unsigned int s3d_ext_data;
321359 };
322360
361+/* HDR Metadata as per 861.G spec */
362+struct hdr_static_metadata {
363+ __u8 eotf;
364+ __u8 metadata_type;
365+ __u16 max_cll;
366+ __u16 max_fall;
367+ __u16 min_cll;
368+};
369+
370+struct hdr_sink_metadata {
371+ __u32 metadata_type;
372+ union {
373+ struct hdr_static_metadata hdmi_type1;
374+ };
375+};
376+
323377 int hdmi_vendor_infoframe_init(struct hdmi_vendor_infoframe *frame);
324378 ssize_t hdmi_vendor_infoframe_pack(struct hdmi_vendor_infoframe *frame,
325379 void *buffer, size_t size);
@@ -355,6 +409,7 @@ union hdmi_infoframe { · 29 unmodified lines
355409 struct hdmi_spd_infoframe spd;
356410 union hdmi_vendor_any_infoframe vendor;
357411 struct hdmi_audio_infoframe audio;
412+ struct hdmi_drm_infoframe drm;
358413 };
359414
360415 ssize_t hdmi_infoframe_pack(union hdmi_infoframe *frame, void *buffer,
include/uapi/drm/drm.h+1−0
@@ -50,6 +50,7 @@ typedef unsigned int drm_handle_t; · 49 unmodified lines
5050
5151 #else /* One of the BSDs */
5252
53+#include <stdint.h>
5354 #include <sys/ioccom.h>
5455 #include <sys/types.h>
5556 typedef int8_t __s8;
include/uapi/drm/drm_mode.h+23−0
@@ -630,6 +630,29 @@ struct drm_color_lut { · 629 unmodified lines
630630 __u16 reserved;
631631 };
632632
633+/* HDR Metadata Infoframe as per 861.G spec */
634+struct hdr_metadata_infoframe {
635+ __u8 eotf;
636+ __u8 metadata_type;
637+ struct {
638+ __u16 x, y;
639+ } display_primaries[3];
640+ struct {
641+ __u16 x, y;
642+ } white_point;
643+ __u16 max_display_mastering_luminance;
644+ __u16 min_display_mastering_luminance;
645+ __u16 max_cll;
646+ __u16 max_fall;
647+};
648+
649+struct hdr_output_metadata {
650+ __u32 metadata_type;
651+ union {
652+ struct hdr_metadata_infoframe hdmi_metadata_type1;
653+ };
654+};
655+
633656 #define DRM_MODE_PAGE_FLIP_EVENT 0x01
634657 #define DRM_MODE_PAGE_FLIP_ASYNC 0x02
635658 #define DRM_MODE_PAGE_FLIP_TARGET_ABSOLUTE 0x4
include/uapi/drm/v3d_drm.h+28−0
@@ -37,6 +37,7 @@ extern "C" { · 36 unmodified lines
3737 #define DRM_V3D_GET_PARAM 0x04
3838 #define DRM_V3D_GET_BO_OFFSET 0x05
3939 #define DRM_V3D_SUBMIT_TFU 0x06
40+#define DRM_V3D_SUBMIT_CSD 0x07
4041
4142 #define DRM_IOCTL_V3D_SUBMIT_CL DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CL, struct drm_v3d_submit_cl)
4243 #define DRM_IOCTL_V3D_WAIT_BO DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_WAIT_BO, struct drm_v3d_wait_bo)
@@ -45,6 +46,7 @@ extern "C" { · 2 unmodified lines
4546 #define DRM_IOCTL_V3D_GET_PARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_PARAM, struct drm_v3d_get_param)
4647 #define DRM_IOCTL_V3D_GET_BO_OFFSET DRM_IOWR(DRM_COMMAND_BASE + DRM_V3D_GET_BO_OFFSET, struct drm_v3d_get_bo_offset)
4748 #define DRM_IOCTL_V3D_SUBMIT_TFU DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_TFU, struct drm_v3d_submit_tfu)
49+#define DRM_IOCTL_V3D_SUBMIT_CSD DRM_IOW(DRM_COMMAND_BASE + DRM_V3D_SUBMIT_CSD, struct drm_v3d_submit_csd)
4850
4951 /**
5052 * struct drm_v3d_submit_cl - ioctl argument for submitting commands to the 3D
@@ -190,6 +192,7 @@ enum drm_v3d_param { · 139 unmodified lines
190192 DRM_V3D_PARAM_V3D_CORE0_IDENT1,
191193 DRM_V3D_PARAM_V3D_CORE0_IDENT2,
192194 DRM_V3D_PARAM_SUPPORTS_TFU,
195+ DRM_V3D_PARAM_SUPPORTS_CSD,
193196 };
194197
195198 struct drm_v3d_get_param {
@@ -230,6 +233,31 @@ struct drm_v3d_submit_tfu { · 34 unmodified lines
230233 __u32 out_sync;
231234 };
232235
236+/* Submits a compute shader for dispatch. This job will block on any
237+ * previous compute shaders submitted on this fd, and any other
238+ * synchronization must be performed with in_sync/out_sync.
239+ */
240+struct drm_v3d_submit_csd {
241+ __u32 cfg[7];
242+ __u32 coef[4];
243+
244+ /* Pointer to a u32 array of the BOs that are referenced by the job.
245+ */
246+ __u64 bo_handles;
247+
248+ /* Number of BO handles passed in (size is that times 4). */
249+ __u32 bo_handle_count;
250+
251+ /* sync object to block on before running the CSD job. Each
252+ * CSD job will execute in the order submitted to its FD.
253+ * Synchronization against rendering/TFU jobs or CSD from
254+ * other fds requires using sync objects.
255+ */
256+ __u32 in_sync;
257+ /* Sync object to signal when the CSD job is done. */
258+ __u32 out_sync;
259+};
260+
233261 #if defined(__cplusplus)
234262 }
235263 #endif