History

Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux

Pull drm updates from Dave Airlie: "Highlights: - AMD KFD driver merge This is the AMD HSA interface for exposing a lowlevel interface for GPGPU use. They have an open source userspace built on top of this interface, and the code looks as good as it was going to get out of tree. - Initial atomic modesetting work The need for an atomic modesetting interface to allow userspace to try and send a complete set of modesetting state to the driver has arisen, and been suffering from neglect this past year. No more, the start of the common code and changes for msm driver to use it are in this tree. Ongoing work to get the userspace ioctl finished and the code clean will probably wait until next kernel. - DisplayID 1.3 and tiled monitor exposed to userspace. Tiled monitor property is now exposed for userspace to make use of. - Rockchip drm driver merged. - imx gpu driver moved out of staging Other stuff: - core: panel - MIPI DSI + new panels. expose suggested x/y properties for virtual GPUs - i915: Initial Skylake (SKL) support gen3/4 reset work start of dri1/ums removal infoframe tracking fixes for lots of things. - nouveau: tegra k1 voltage support GM204 modesetting support GT21x memory reclocking work - radeon: CI dpm fixes GPUVM improvements Initial DPM fan control - rcar-du: HDMI support added removed some support for old boards slave encoder driver for Analog Devices adv7511 - exynos: Exynos4415 SoC support - msm: a4xx gpu support atomic helper conversion - tegra: iommu support universal plane support ganged-mode DSI support - sti: HDMI i2c improvements - vmwgfx: some late fixes. - qxl: use suggested x/y properties" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (969 commits) drm: sti: fix module compilation issue drm/i915: save/restore GMBUS freq across suspend/resume on gen4 drm: sti: correctly cleanup CRTC and planes drm: sti: add HQVDP plane drm: sti: add cursor plane drm: sti: enable auxiliary CRTC drm: sti: fix delay in VTG programming drm: sti: prepare sti_tvout to support auxiliary crtc drm: sti: use drm_crtc_vblank_{on/off} instead of drm_vblank_{on/off} drm: sti: fix hdmi avi infoframe drm: sti: remove event lock while disabling vblank drm: sti: simplify gdp code drm: sti: clear all mixer control drm: sti: remove gpio for HDMI hot plug detection drm: sti: allow to change hdmi ddc i2c adapter drm/doc: Document drm_add_modes_noedid() usage drm/i915: Remove '& 0xffff' from the mask given to WA_REG() drm/i915: Invert the mask and val arguments in wa_add() and WA_REG() drm: Zero out DRM object memory upon cleanup drm/i915/bdw: Fix the write setting up the WIZ hashing mode ...

Linus Torvalds committed 11 years ago

Commit 988adfd2 parents 26178ec 4e0cd68549 files · +55591 −16726Browse files

Unified · Split

549 files
  1. CREDITS +7 −0
  2. Documentation/DocBook/drm.tmpl +292 −142
  3. Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txt +0 −0
  4. Documentation/devicetree/bindings/drm/imx/hdmi.txt +0 −0
  5. Documentation/devicetree/bindings/drm/imx/ldb.txt +0 −0
  6. Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt +2 −0
  7. Documentation/devicetree/bindings/gpu/st,stih4xx.txt +27 −2
  8. Documentation/devicetree/bindings/panel/auo,b116xw03.txt +7 −0
  9. Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt +7 −0
  10. Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt +7 −0
  11. Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt +7 −0
  12. Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt +49 −0
  13. Documentation/devicetree/bindings/vendor-prefixes.txt +2 −0
  14. Documentation/devicetree/bindings/video/adi,adv7511.txt +88 −0
  15. Documentation/devicetree/bindings/video/exynos_dsim.txt +1 −0
  16. Documentation/devicetree/bindings/video/rockchip-drm.txt +19 −0
  17. Documentation/devicetree/bindings/video/rockchip-vop.txt +58 −0
  18. Documentation/devicetree/bindings/video/samsung-fimd.txt +1 −0
  19. MAINTAINERS +17 −0
  20. arch/arm/mach-shmobile/board-lager.c +0 −58
  21. arch/arm/mach-shmobile/board-marzen.c +0 −58
  22. arch/x86/kernel/early-quirks.c +23 −0
  23. drivers/char/agp/intel-gtt.c +0 −4
  24. drivers/gpu/drm/Kconfig +6 −0
  25. drivers/gpu/drm/Makefile +5 −2
  26. drivers/gpu/drm/README.drm +0 −43
  27. drivers/gpu/drm/amd/amdkfd/Kconfig +9 −0
  28. drivers/gpu/drm/amd/amdkfd/Makefile +14 −0
  29. drivers/gpu/drm/amd/amdkfd/cik_regs.h +221 −0
  30. drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +595 −0
  31. drivers/gpu/drm/amd/amdkfd/kfd_crat.h +294 −0
  32. drivers/gpu/drm/amd/amdkfd/kfd_device.c +308 −0
  33. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +1062 −0
  34. drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h +146 −0
  35. drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c +256 −0
  36. drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c +356 −0
  37. drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c +176 −0
  38. drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c +353 −0
  39. drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h +69 −0
  40. drivers/gpu/drm/amd/amdkfd/kfd_module.c +159 −0
  41. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +346 −0
  42. drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h +91 −0
  43. drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c +565 −0
  44. drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +96 −0
  45. drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h +405 −0
  46. drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h +107 −0
  47. drivers/gpu/drm/amd/amdkfd/kfd_priv.h +600 −0
  48. drivers/gpu/drm/amd/amdkfd/kfd_process.c +410 −0
  49. drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c +343 −0
  50. drivers/gpu/drm/amd/amdkfd/kfd_queue.c +85 −0
  51. drivers/gpu/drm/amd/amdkfd/kfd_topology.c +1235 −0
  52. drivers/gpu/drm/amd/amdkfd/kfd_topology.h +168 −0
  53. drivers/gpu/drm/amd/include/kgd_kfd_interface.h +185 −0
  54. drivers/gpu/drm/armada/armada_crtc.c +1 −0
  55. drivers/gpu/drm/ast/ast_mode.c +1 −0
  56. drivers/gpu/drm/bochs/bochs_fbdev.c +14 −4
  57. drivers/gpu/drm/bochs/bochs_hw.c +20 −3
  58. drivers/gpu/drm/bochs/bochs_kms.c +22 −0
  59. drivers/gpu/drm/cirrus/cirrus_drv.h +3 −0
  60. drivers/gpu/drm/cirrus/cirrus_fbdev.c +4 −1
  61. drivers/gpu/drm/cirrus/cirrus_main.c +32 −8
  62. drivers/gpu/drm/cirrus/cirrus_mode.c +1 −0
  63. drivers/gpu/drm/drm_atomic.c +657 −0
  64. drivers/gpu/drm/drm_atomic_helper.c +1966 −0
  65. drivers/gpu/drm/drm_crtc.c +400 −181
  66. drivers/gpu/drm/drm_crtc_helper.c +132 −0
  67. drivers/gpu/drm/drm_dp_helper.c +6 −195
  68. drivers/gpu/drm/drm_dp_mst_topology.c +52 −16
  69. drivers/gpu/drm/drm_drv.c +5 −2
  70. drivers/gpu/drm/drm_edid.c +201 −30
  71. drivers/gpu/drm/drm_edid_load.c +1 −2
  72. drivers/gpu/drm/drm_fb_helper.c +110 −25
  73. drivers/gpu/drm/drm_flip_work.c +74 −31
  74. drivers/gpu/drm/drm_fops.c +8 −5
  75. drivers/gpu/drm/drm_gem.c +6 −7
  76. drivers/gpu/drm/drm_gem_cma_helper.c +215 −44
  77. drivers/gpu/drm/drm_irq.c +5 −4
  78. drivers/gpu/drm/drm_mipi_dsi.c +630 −30
  79. drivers/gpu/drm/drm_modes.c +1 −1
  80. drivers/gpu/drm/drm_modeset_lock.c +33 −10
  81. drivers/gpu/drm/drm_plane_helper.c +202 −1
  82. drivers/gpu/drm/drm_prime.c +3 −3
  83. drivers/gpu/drm/drm_probe_helper.c +2 −1
  84. drivers/gpu/drm/exynos/exynos_dp_core.c +45 −87
  85. drivers/gpu/drm/exynos/exynos_dp_core.h +3 −2
  86. drivers/gpu/drm/exynos/exynos_drm_crtc.h +1 −4
  87. drivers/gpu/drm/exynos/exynos_drm_dpi.c +22 −20
  88. drivers/gpu/drm/exynos/exynos_drm_drv.c +95 −157
  89. drivers/gpu/drm/exynos/exynos_drm_drv.h +26 −57
  90. drivers/gpu/drm/exynos/exynos_drm_dsi.c +66 −63
  91. drivers/gpu/drm/exynos/exynos_drm_encoder.h +0 −2
  92. drivers/gpu/drm/exynos/exynos_drm_fimd.c +148 −118
  93. drivers/gpu/drm/exynos/exynos_drm_iommu.h +0 −1
  94. drivers/gpu/drm/exynos/exynos_drm_ipp.c +3 −0
  95. drivers/gpu/drm/exynos/exynos_drm_vidi.c +92 −58
  96. drivers/gpu/drm/exynos/exynos_hdmi.c +30 −35
  97. drivers/gpu/drm/exynos/exynos_mixer.c +66 −60
  98. drivers/gpu/drm/gma500/Makefile +1 −0
  99. drivers/gpu/drm/gma500/cdv_intel_dp.c +195 −0
  100. drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c +31 −44
  101. drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h +0 −12
  102. drivers/gpu/drm/gma500/oaktrail_lvds.c +19 −12
  103. drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c +170 −0
  104. drivers/gpu/drm/gma500/psb_drv.c +20 −0
  105. drivers/gpu/drm/gma500/psb_drv.h +3 −0
  106. drivers/gpu/drm/gma500/psb_intel_display.c +1 −0
  107. drivers/gpu/drm/gma500/psb_intel_drv.h +1 −0
  108. drivers/gpu/drm/gma500/psb_intel_sdvo.c +0 −49
  109. drivers/gpu/drm/i2c/Kconfig +6 −0
  110. drivers/gpu/drm/i2c/Makefile +2 −0
  111. drivers/gpu/drm/i2c/adv7511.c +1010 −0
  112. drivers/gpu/drm/i2c/adv7511.h +289 −0
  113. drivers/gpu/drm/i915/Makefile +10 −3
  114. drivers/gpu/drm/i915/i915_cmd_parser.c +28 −11
  115. drivers/gpu/drm/i915/i915_debugfs.c +203 −67
  116. drivers/gpu/drm/i915/i915_dma.c +38 −1032
  117. drivers/gpu/drm/i915/i915_drv.c +149 −210
  118. drivers/gpu/drm/i915/i915_drv.h +205 −106
  119. drivers/gpu/drm/i915/i915_gem.c +336 −309
  120. drivers/gpu/drm/i915/i915_gem_context.c +12 −6
  121. drivers/gpu/drm/i915/i915_gem_execbuffer.c +62 −25
  122. drivers/gpu/drm/i915/i915_gem_gtt.c +66 −30
  123. drivers/gpu/drm/i915/i915_gem_gtt.h +6 −4
  124. drivers/gpu/drm/i915/i915_gem_render_state.c +2 −0
  125. drivers/gpu/drm/i915/i915_gem_stolen.c +6 −2
  126. drivers/gpu/drm/i915/i915_gem_tiling.c +45 −15
  127. drivers/gpu/drm/i915/i915_gpu_error.c +24 −19
  128. drivers/gpu/drm/i915/i915_ioc32.c +0 −2
  129. drivers/gpu/drm/i915/i915_irq.c +367 −633
  130. drivers/gpu/drm/i915/i915_reg.h +533 −110
  131. drivers/gpu/drm/i915/i915_suspend.c +21 −36
  132. drivers/gpu/drm/i915/i915_sysfs.c +19 −3
  133. drivers/gpu/drm/i915/i915_trace.h +104 −0
  134. drivers/gpu/drm/i915/i915_ums.c +14 −0
  135. drivers/gpu/drm/i915/intel_audio.c +463 −0
  136. drivers/gpu/drm/i915/intel_bios.h +5 −5
  137. drivers/gpu/drm/i915/intel_crt.c +2 −2
  138. drivers/gpu/drm/i915/intel_ddi.c +658 −61
  139. drivers/gpu/drm/i915/intel_display.c +1512 −1373
  140. drivers/gpu/drm/i915/intel_dp.c +455 −530
  141. drivers/gpu/drm/i915/intel_dp_mst.c +5 −11
  142. drivers/gpu/drm/i915/intel_drv.h +145 −67
  143. drivers/gpu/drm/i915/intel_dsi.c +1 −1
  144. drivers/gpu/drm/i915/intel_fbdev.c +31 −13
  145. drivers/gpu/drm/i915/intel_fifo_underrun.c +381 −0
  146. drivers/gpu/drm/i915/intel_frontbuffer.c +279 −0
  147. drivers/gpu/drm/i915/intel_hdmi.c +111 −9
  148. drivers/gpu/drm/i915/intel_lrc.c +257 −81
  149. drivers/gpu/drm/i915/intel_lrc.h +5 −1
  150. drivers/gpu/drm/i915/intel_lvds.c +2 −2
  151. drivers/gpu/drm/i915/intel_panel.c +86 −50
  152. drivers/gpu/drm/i915/intel_pm.c +3371 −3540
  153. drivers/gpu/drm/i915/intel_psr.c +481 −0
  154. drivers/gpu/drm/i915/intel_renderstate.h +1 −0
  155. drivers/gpu/drm/i915/intel_renderstate_gen8.c +640 −162
  156. drivers/gpu/drm/i915/intel_renderstate_gen9.c +974 −0
  157. drivers/gpu/drm/i915/intel_ringbuffer.c +188 −231
  158. drivers/gpu/drm/i915/intel_ringbuffer.h +8 −4
  159. drivers/gpu/drm/i915/intel_runtime_pm.c +1406 −0
  160. drivers/gpu/drm/i915/intel_sdvo.c +0 −47
  161. drivers/gpu/drm/i915/intel_sprite.c +474 −131
  162. drivers/gpu/drm/i915/intel_tv.c +4 −5
  163. drivers/gpu/drm/i915/intel_uncore.c +393 −102
  164. drivers/gpu/drm/imx/Kconfig +0 −0
  165. drivers/gpu/drm/imx/Makefile +0 −0
  166. drivers/gpu/drm/imx/imx-drm-core.c +1 −0
  167. drivers/gpu/drm/imx/imx-drm.h +0 −0
  168. drivers/gpu/drm/imx/imx-hdmi.c +0 −0
  169. drivers/gpu/drm/imx/imx-hdmi.h +0 −0
  170. drivers/gpu/drm/imx/imx-ldb.c +0 −0
  171. drivers/gpu/drm/imx/imx-tve.c +0 −0
  172. drivers/gpu/drm/imx/ipuv3-crtc.c +0 −0
  173. drivers/gpu/drm/imx/ipuv3-plane.c +0 −0
  174. drivers/gpu/drm/imx/ipuv3-plane.h +0 −0
  175. drivers/gpu/drm/imx/parallel-display.c +0 −0
  176. drivers/gpu/drm/mgag200/mgag200_mode.c +1 −0
  177. drivers/gpu/drm/msm/Kconfig +1 −0
  178. drivers/gpu/drm/msm/Makefile +4 −0
  179. drivers/gpu/drm/msm/adreno/a2xx.xml.h +13 −13
  180. drivers/gpu/drm/msm/adreno/a3xx.xml.h +221 −26
  181. drivers/gpu/drm/msm/adreno/a3xx_gpu.c +91 −0
  182. drivers/gpu/drm/msm/adreno/a4xx.xml.h +2144 −0
  183. drivers/gpu/drm/msm/adreno/a4xx_gpu.c +604 −0
  184. drivers/gpu/drm/msm/adreno/a4xx_gpu.h +34 −0
  185. drivers/gpu/drm/msm/adreno/adreno_common.xml.h +13 −4
  186. drivers/gpu/drm/msm/adreno/adreno_device.c +13 −0
  187. drivers/gpu/drm/msm/adreno/adreno_gpu.c +18 −13
  188. drivers/gpu/drm/msm/adreno/adreno_gpu.h +126 −0
  189. drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h +39 −36
  190. drivers/gpu/drm/msm/dsi/dsi.xml.h +4 −4
  191. drivers/gpu/drm/msm/dsi/mmss_cc.xml.h +4 −4
  192. drivers/gpu/drm/msm/dsi/sfpb.xml.h +4 −4
  193. drivers/gpu/drm/msm/hdmi/hdmi.c +81 −63
  194. drivers/gpu/drm/msm/hdmi/hdmi.h +0 −17
  195. drivers/gpu/drm/msm/hdmi/hdmi.xml.h +4 −4
  196. drivers/gpu/drm/msm/hdmi/hdmi_bridge.c +1 −2
  197. drivers/gpu/drm/msm/hdmi/hdmi_connector.c +4 −3
  198. drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c +1 −1
  199. drivers/gpu/drm/msm/hdmi/qfprom.xml.h +4 −4
  200. drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h +4 −4
  201. drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c +104 −244
  202. drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c +11 −6
  203. drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h +0 −17
  204. drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c +3 −0
  205. drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c +80 −41
  206. drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h +5 −5
  207. drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c +207 −0
  208. drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h +91 −0
  209. drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c +218 −248
  210. drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c +322 −0
  211. drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h +122 −0
  212. drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c +24 −0
  213. drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c +90 −3
  214. drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c +105 −168
  215. drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h +45 −86
  216. drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c +205 −123
  217. drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c +203 −38
  218. drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h +14 −9
  219. drivers/gpu/drm/msm/msm_atomic.c +163 −0
  220. drivers/gpu/drm/msm/msm_drv.c +25 −0
  221. drivers/gpu/drm/msm/msm_drv.h +23 −12
  222. drivers/gpu/drm/msm/msm_fb.c +44 −1
  223. drivers/gpu/drm/msm/msm_fbdev.c +0 −3
  224. drivers/gpu/drm/msm/msm_gem.c +16 −24
  225. drivers/gpu/drm/msm/msm_gem.h +13 −0
  226. drivers/gpu/drm/msm/msm_gem_prime.c +13 −0
  227. drivers/gpu/drm/nouveau/Makefile +18 −0
  228. drivers/gpu/drm/nouveau/core/core/handle.c +0 −113
  229. drivers/gpu/drm/nouveau/core/engine/device/base.c +12 −2
  230. drivers/gpu/drm/nouveau/core/engine/device/gm100.c +43 −0
  231. drivers/gpu/drm/nouveau/core/engine/device/nve0.c +1 −0
  232. drivers/gpu/drm/nouveau/core/engine/disp/dport.c +6 −3
  233. drivers/gpu/drm/nouveau/core/engine/disp/gm107.c +8 −8
  234. drivers/gpu/drm/nouveau/core/engine/disp/gm204.c +114 −0
  235. drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +48 −46
  236. drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +34 −29
  237. drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +20 −20
  238. drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +15 −15
  239. drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +8 −8
  240. drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +8 −8
  241. drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +56 −43
  242. drivers/gpu/drm/nouveau/core/engine/disp/nve0.c +15 −15
  243. drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c +8 −8
  244. drivers/gpu/drm/nouveau/core/engine/disp/outp.c +4 −1
  245. drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c +144 −0
  246. drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +1 −1
  247. drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c +1 −0
  248. drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +42 −6
  249. drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +1 −1
  250. drivers/gpu/drm/nouveau/core/include/core/device.h +8 −1
  251. drivers/gpu/drm/nouveau/core/include/core/handle.h +0 −5
  252. drivers/gpu/drm/nouveau/core/include/core/object.h +0 −17
  253. drivers/gpu/drm/nouveau/core/include/engine/disp.h +1 −0
  254. drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h +31 −0
  255. drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h +9 −5
  256. drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h +13 −0
  257. drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h +12 −0
  258. drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h +18 −0
  259. drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h +37 −0
  260. drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h +22 −1
  261. drivers/gpu/drm/nouveau/core/include/subdev/devinit.h +1 −0
  262. drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +3 −0
  263. drivers/gpu/drm/nouveau/core/include/subdev/pwr.h +2 −0
  264. drivers/gpu/drm/nouveau/core/include/subdev/volt.h +1 −0
  265. drivers/gpu/drm/nouveau/core/os.h +1 −0
  266. drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c +129 −0
  267. drivers/gpu/drm/nouveau/core/subdev/bios/base.c +15 −354
  268. drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c +15 −12
  269. drivers/gpu/drm/nouveau/core/subdev/bios/disp.c +1 −0
  270. drivers/gpu/drm/nouveau/core/subdev/bios/dp.c +9 −1
  271. drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c +1 −1
  272. drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c +36 −9
  273. drivers/gpu/drm/nouveau/core/subdev/bios/image.c +78 −0
  274. drivers/gpu/drm/nouveau/core/subdev/bios/init.c +49 −7
  275. drivers/gpu/drm/nouveau/core/subdev/bios/npde.c +59 −0
  276. drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c +69 −0
  277. drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c +135 −0
  278. drivers/gpu/drm/nouveau/core/subdev/bios/priv.h +25 −0
  279. drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c +12 −1
  280. drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c +2 −1
  281. drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c +270 −0
  282. drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c +111 −0
  283. drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c +71 −0
  284. drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c +108 −0
  285. drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c +112 −0
  286. drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c +69 −0
  287. drivers/gpu/drm/nouveau/core/subdev/bios/timing.c +38 −4
  288. drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c +16 −1
  289. drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +1 −1
  290. drivers/gpu/drm/nouveau/core/subdev/devinit/base.c +1 −3
  291. drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c +2 −1
  292. drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c +173 −0
  293. drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c +1 −0
  294. drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c +1 −0
  295. drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c +1 −0
  296. drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c +1 −0
  297. drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c +1 −0
  298. drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c +10 −0
  299. drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h +2 −0
  300. drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c +1 −0
  301. drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c +1 −0
  302. drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c +1 −0
  303. drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c +1 −0
  304. drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c +1 −0
  305. drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h +2 −0
  306. drivers/gpu/drm/nouveau/core/subdev/fb/base.c +15 −22
  307. drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c +117 −0
  308. drivers/gpu/drm/nouveau/core/subdev/fb/priv.h +1 −0
  309. drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +16 −0
  310. drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c +697 −116
  311. drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c +1 −1
  312. drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c +1 −1
  313. drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c +1 −1
  314. drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +66 −31
  315. drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c +221 −0
  316. drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h +4 −2
  317. drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c +2 −11
  318. drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c +1 −5
  319. drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c +2 −2
  320. drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c +86 −0
  321. drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h +4 −0
  322. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc +111 −0
  323. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h +404 −334
  324. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h +500 −363
  325. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h +481 −347
  326. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h +412 −342
  327. drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h +5 −0
  328. drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c +35 −2
  329. drivers/gpu/drm/nouveau/core/subdev/volt/base.c +38 −29
  330. drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c +199 −0
  331. drivers/gpu/drm/nouveau/dispnv04/crtc.c +3 −2
  332. drivers/gpu/drm/nouveau/dispnv04/overlay.c +2 −2
  333. drivers/gpu/drm/nouveau/nouveau_abi16.c +1 −1
  334. drivers/gpu/drm/nouveau/nouveau_bios.c +15 −11
  335. drivers/gpu/drm/nouveau/nouveau_bo.c +169 −27
  336. drivers/gpu/drm/nouveau/nouveau_bo.h +4 −1
  337. drivers/gpu/drm/nouveau/nouveau_chan.c +3 −8
  338. drivers/gpu/drm/nouveau/nouveau_display.c +22 −8
  339. drivers/gpu/drm/nouveau/nouveau_drm.c +127 −121
  340. drivers/gpu/drm/nouveau/nouveau_fbcon.c +18 −18
  341. drivers/gpu/drm/nouveau/nouveau_gem.c +15 −0
  342. drivers/gpu/drm/nouveau/nouveau_platform.c +2 −0
  343. drivers/gpu/drm/nouveau/nouveau_platform.h +2 −0
  344. drivers/gpu/drm/nouveau/nouveau_prime.c +1 −1
  345. drivers/gpu/drm/nouveau/nv17_fence.c +1 −1
  346. drivers/gpu/drm/nouveau/nv50_display.c +64 −70
  347. drivers/gpu/drm/nouveau/nv50_fence.c +1 −1
  348. drivers/gpu/drm/nouveau/nv84_fence.c +4 −4
  349. drivers/gpu/drm/nouveau/nvif/class.h +3 −0
  350. drivers/gpu/drm/nouveau/nvif/client.c +1 −0
  351. drivers/gpu/drm/nouveau/nvif/driver.h +1 −0
  352. drivers/gpu/drm/omapdrm/omap_crtc.c +1 −0
  353. drivers/gpu/drm/omapdrm/omap_gem.c +1 −2
  354. drivers/gpu/drm/omapdrm/omap_plane.c +2 −13
  355. drivers/gpu/drm/panel/Kconfig +13 −0
  356. drivers/gpu/drm/panel/Makefile +1 −0
  357. drivers/gpu/drm/panel/panel-ld9040.c +4 −9
  358. drivers/gpu/drm/panel/panel-s6e8aa0.c +6 −24
  359. drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c +464 −0
  360. drivers/gpu/drm/panel/panel-simple.c +117 −16
  361. drivers/gpu/drm/qxl/qxl_display.c +29 −7
  362. drivers/gpu/drm/qxl/qxl_release.c +2 −1
  363. drivers/gpu/drm/r128/r128_state.c +2 −2
  364. drivers/gpu/drm/radeon/Makefile +3 −1
  365. drivers/gpu/drm/radeon/atombios_crtc.c +1 −0
  366. drivers/gpu/drm/radeon/ci_dpm.c +670 −82
  367. drivers/gpu/drm/radeon/ci_dpm.h +8 −0
  368. drivers/gpu/drm/radeon/ci_smc.c +1 −1
  369. drivers/gpu/drm/radeon/cik.c +92 −122
  370. drivers/gpu/drm/radeon/cik_reg.h +136 −0
  371. drivers/gpu/drm/radeon/cik_sdma.c +17 −25
  372. drivers/gpu/drm/radeon/cikd.h +90 −3
  373. drivers/gpu/drm/radeon/evergreen_cs.c +7 −7
  374. drivers/gpu/drm/radeon/evergreen_dma.c +7 −11
  375. drivers/gpu/drm/radeon/ni.c +8 −12
  376. drivers/gpu/drm/radeon/ni_dma.c +7 −10
  377. drivers/gpu/drm/radeon/ppsmc.h +17 −1
  378. drivers/gpu/drm/radeon/pptable.h +8 −0
  379. drivers/gpu/drm/radeon/r100.c +5 −5
  380. drivers/gpu/drm/radeon/r200.c +1 −1
  381. drivers/gpu/drm/radeon/r300.c +3 −3
  382. drivers/gpu/drm/radeon/r600.c +7 −11
  383. drivers/gpu/drm/radeon/r600_cs.c +13 −13
  384. drivers/gpu/drm/radeon/r600_dma.c +7 −11
  385. drivers/gpu/drm/radeon/r600_dpm.c +9 −0
  386. drivers/gpu/drm/radeon/r600_dpm.h +3 −0
  387. drivers/gpu/drm/radeon/radeon.h +98 −64
  388. drivers/gpu/drm/radeon/radeon_asic.h +12 −6
  389. drivers/gpu/drm/radeon/radeon_atombios.c +15 −6
  390. drivers/gpu/drm/radeon/radeon_cs.c +49 −72
  391. drivers/gpu/drm/radeon/radeon_cursor.c +167 −101
  392. drivers/gpu/drm/radeon/radeon_device.c +32 −0
  393. drivers/gpu/drm/radeon/radeon_display.c +2 −1
  394. drivers/gpu/drm/radeon/radeon_drv.c +5 −0
  395. drivers/gpu/drm/radeon/radeon_fb.c +31 −1
  396. drivers/gpu/drm/radeon/radeon_fence.c +1 −0
  397. drivers/gpu/drm/radeon/radeon_gem.c +87 −5
  398. drivers/gpu/drm/radeon/radeon_ib.c +7 −9
  399. drivers/gpu/drm/radeon/radeon_kfd.c +563 −0
  400. drivers/gpu/drm/radeon/radeon_kfd.h +47 −0
  401. drivers/gpu/drm/radeon/radeon_kms.c +7 −2
  402. drivers/gpu/drm/radeon/radeon_legacy_crtc.c +1 −0
  403. drivers/gpu/drm/radeon/radeon_mode.h +15 −5
  404. drivers/gpu/drm/radeon/radeon_object.c +69 −14
  405. drivers/gpu/drm/radeon/radeon_object.h +2 −0
  406. drivers/gpu/drm/radeon/radeon_semaphore.c +4 −150
  407. drivers/gpu/drm/radeon/radeon_sync.c +220 −0
  408. drivers/gpu/drm/radeon/radeon_trace.h +1 −1
  409. drivers/gpu/drm/radeon/radeon_ttm.c +25 −2
  410. drivers/gpu/drm/radeon/radeon_uvd.c +7 −7
  411. drivers/gpu/drm/radeon/radeon_vce.c +4 −4
  412. drivers/gpu/drm/radeon/radeon_vm.c +149 −87
  413. drivers/gpu/drm/radeon/rv770_dma.c +7 −11
  414. drivers/gpu/drm/radeon/si.c +10 −14
  415. drivers/gpu/drm/radeon/si_dma.c +15 −22
  416. drivers/gpu/drm/radeon/si_dpm.c +365 −16
  417. drivers/gpu/drm/radeon/si_dpm.h +5 −0
  418. drivers/gpu/drm/radeon/si_smc.c +1 −1
  419. drivers/gpu/drm/radeon/sid.h +39 −1
  420. drivers/gpu/drm/radeon/sislands_smc.h +25 −0
  421. drivers/gpu/drm/radeon/smu7_discrete.h +29 −1
  422. drivers/gpu/drm/rcar-du/Kconfig +9 −2
  423. drivers/gpu/drm/rcar-du/Makefile +2 −0
  424. drivers/gpu/drm/rcar-du/rcar_du_crtc.c +2 −1
  425. drivers/gpu/drm/rcar-du/rcar_du_crtc.h +9 −1
  426. drivers/gpu/drm/rcar-du/rcar_du_drv.c +1 −3
  427. drivers/gpu/drm/rcar-du/rcar_du_drv.h +0 −2
  428. drivers/gpu/drm/rcar-du/rcar_du_encoder.c +32 −13
  429. drivers/gpu/drm/rcar-du/rcar_du_encoder.h +17 −6
  430. drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c +121 −0
  431. drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h +31 −0
  432. drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c +151 −0
  433. drivers/gpu/drm/rcar-du/rcar_du_hdmienc.h +35 −0
  434. drivers/gpu/drm/rcar-du/rcar_du_kms.c +10 −47
  435. drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c +15 −16
  436. drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h +0 −2
  437. drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h +0 −1
  438. drivers/gpu/drm/rcar-du/rcar_du_vgacon.c +3 −2
  439. drivers/gpu/drm/rockchip/Kconfig +17 −0
  440. drivers/gpu/drm/rockchip/Makefile +8 −0
  441. drivers/gpu/drm/rockchip/rockchip_drm_drv.c +551 −0
  442. drivers/gpu/drm/rockchip/rockchip_drm_drv.h +68 −0
  443. drivers/gpu/drm/rockchip/rockchip_drm_fb.c +201 −0
  444. drivers/gpu/drm/rockchip/rockchip_drm_fb.h +28 −0
  445. drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c +210 −0
  446. drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h +21 −0
  447. drivers/gpu/drm/rockchip/rockchip_drm_gem.c +294 −0
  448. drivers/gpu/drm/rockchip/rockchip_drm_gem.h +54 −0
  449. drivers/gpu/drm/rockchip/rockchip_drm_vop.c +1455 −0
  450. drivers/gpu/drm/rockchip/rockchip_drm_vop.h +201 −0
  451. drivers/gpu/drm/shmobile/shmob_drm_crtc.c +1 −0
  452. drivers/gpu/drm/sti/Kconfig +1 −0
  453. drivers/gpu/drm/sti/Makefile +3 −1
  454. drivers/gpu/drm/sti/sti_compositor.c +12 −8
  455. drivers/gpu/drm/sti/sti_compositor.h +0 −2
  456. drivers/gpu/drm/sti/sti_cursor.c +242 −0
  457. drivers/gpu/drm/sti/sti_cursor.h +12 −0
  458. drivers/gpu/drm/sti/sti_drm_crtc.c +14 −10
  459. drivers/gpu/drm/sti/sti_drm_drv.c +5 −1
  460. drivers/gpu/drm/sti/sti_drm_plane.c +3 −1
  461. drivers/gpu/drm/sti/sti_gdp.c +43 −19
  462. drivers/gpu/drm/sti/sti_hdmi.c +46 −38
  463. drivers/gpu/drm/sti/sti_hdmi.h +4 −2
  464. drivers/gpu/drm/sti/sti_hqvdp.c +1073 −0
  465. drivers/gpu/drm/sti/sti_hqvdp.h +12 −0
  466. drivers/gpu/drm/sti/sti_hqvdp_lut.h +373 −0
  467. drivers/gpu/drm/sti/sti_layer.c +17 −1
  468. drivers/gpu/drm/sti/sti_layer.h +10 −2
  469. drivers/gpu/drm/sti/sti_mixer.c +17 −0
  470. drivers/gpu/drm/sti/sti_mixer.h +3 −0
  471. drivers/gpu/drm/sti/sti_tvout.c +59 −45
  472. drivers/gpu/drm/sti/sti_vtg.c +28 −3
  473. drivers/gpu/drm/tegra/Kconfig +1 −0
  474. drivers/gpu/drm/tegra/dc.c +416 −180
  475. drivers/gpu/drm/tegra/drm.c +42 −4
  476. drivers/gpu/drm/tegra/drm.h +12 −6
  477. drivers/gpu/drm/tegra/dsi.c +688 −123
  478. drivers/gpu/drm/tegra/dsi.h +13 −1
  479. drivers/gpu/drm/tegra/fb.c +42 −10
  480. drivers/gpu/drm/tegra/gem.c +287 −79
  481. drivers/gpu/drm/tegra/gem.h +10 −4
  482. drivers/gpu/drm/tegra/output.c +28 −7
  483. drivers/gpu/drm/tilcdc/tilcdc_crtc.c +2 −5
  484. drivers/gpu/drm/tilcdc/tilcdc_drv.c +1 −2
  485. drivers/gpu/drm/ttm/ttm_bo_manager.c +5 −3
  486. drivers/gpu/drm/ttm/ttm_execbuf_util.c +9 −1
  487. drivers/gpu/drm/ttm/ttm_page_alloc.c +15 −11
  488. drivers/gpu/drm/ttm/ttm_page_alloc_dma.c +15 −10
  489. drivers/gpu/drm/udl/Makefile +1 −1
  490. drivers/gpu/drm/udl/udl_dmabuf.c +276 −0
  491. drivers/gpu/drm/udl/udl_drv.c +2 −0
  492. drivers/gpu/drm/udl/udl_drv.h +8 −0
  493. drivers/gpu/drm/udl/udl_gem.c +23 −74
  494. drivers/gpu/drm/udl/udl_modeset.c +1 −0
  495. drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +7 −4
  496. drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +4 −2
  497. drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +8 −31
  498. drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +2 −2
  499. drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +1 −0
  500. drivers/gpu/drm/vmwgfx/vmwgfx_resource.c +1 −1
  501. drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +1 −0
  502. drivers/gpu/drm/vmwgfx/vmwgfx_shader.c +1 −1
  503. drivers/gpu/host1x/cdma.c +1 −1
  504. drivers/gpu/host1x/cdma.h +1 −1
  505. drivers/gpu/host1x/hw/cdma_hw.c +5 −5
  506. drivers/gpu/host1x/hw/channel_hw.c +8 −4
  507. drivers/gpu/host1x/hw/debug_hw.c +2 −2
  508. drivers/gpu/host1x/job.h +1 −1
  509. drivers/gpu/host1x/mipi.c +107 −41
  510. drivers/iommu/amd_iommu_v2.c +9 −52
  511. drivers/soc/tegra/fuse/fuse-tegra.c +1 −0
  512. drivers/staging/Kconfig +0 −2
  513. drivers/staging/Makefile +0 −1
  514. drivers/staging/imx-drm/TODO +0 −17
  515. include/drm/drmP.h +21 −6
  516. include/drm/drm_atomic.h +69 −0
  517. include/drm/drm_atomic_helper.h +126 −0
  518. include/drm/drm_crtc.h +289 −38
  519. include/drm/drm_crtc_helper.h +13 −0
  520. include/drm/drm_displayid.h +76 −0
  521. include/drm/drm_dp_helper.h +4 −22
  522. include/drm/drm_dp_mst_helper.h +5 −3
  523. include/drm/drm_edid.h +109 −0
  524. include/drm/drm_fb_helper.h +6 −0
  525. include/drm/drm_flip_work.h +24 −9
  526. include/drm/drm_gem.h +7 −0
  527. include/drm/drm_gem_cma_helper.h +22 −8
  528. include/drm/drm_mipi_dsi.h +88 −6
  529. include/drm/drm_modeset_lock.h +4 −1
  530. include/drm/drm_plane_helper.h +44 −0
  531. include/drm/i915_pciids.h +17 −0
  532. include/drm/ttm/ttm_execbuf_util.h +8 −1
  533. include/linux/hdmi.h +18 −3
  534. include/linux/mmu_notifier.h +83 −5
  535. include/linux/platform_data/rcar-du.h +0 −74
  536. include/trace/events/host1x.h +15 −12
  537. include/uapi/drm/drm_mode.h +2 −0
  538. include/uapi/drm/i915_drm.h +7 −0
  539. include/uapi/linux/kfd_ioctl.h +154 −0
  540. kernel/events/uprobes.c +1 −1
  541. kernel/time/time.c +1 −0
  542. mm/fremap.c +1 −1
  543. mm/huge_memory.c +5 −4
  544. mm/hugetlb.c +6 −1
  545. mm/ksm.c +2 −2
  546. mm/memory.c +2 −1
  547. mm/migrate.c +2 −1
  548. mm/mmu_notifier.c +25 −0
  549. mm/rmap.c +1 −1
CREDITS+7−0
@@ -1197,6 +1197,13 @@ S: R. Tocantins, 89 - Cristo Rei · 1196 unmodified lines
11971197 S: 80050-430 - Curitiba - Paraná
11981198 S: Brazil
11991199
1200+N: Oded Gabbay
1201+E: oded.gabbay@gmail.com
1202+D: AMD KFD maintainer
1203+S: 12 Shraga Raphaeli
1204+S: Petah-Tikva, 4906418
1205+S: Israel
1206+
12001207 N: Kumar Gala
12011208 E: galak@kernel.crashing.org
12021209 D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support
Documentation/DocBook/drm.tmpl+292−142
@@ -492,10 +492,10 @@ char *date;</synopsis> · 491 unmodified lines
492492 <sect2>
493493 <title>The Translation Table Manager (TTM)</title>
494494 <para>
495− TTM design background and information belongs here.
495+ TTM design background and information belongs here.
496496 </para>
497497 <sect3>
498− <title>TTM initialization</title>
498+ <title>TTM initialization</title>
499499 <warning><para>This section is outdated.</para></warning>
500500 <para>
501501 Drivers wishing to support TTM must fill out a drm_bo_driver
@@ -503,42 +503,42 @@ char *date;</synopsis> · 1 unmodified line
503503 pointers for initializing the TTM, allocating and freeing memory,
504504 waiting for command completion and fence synchronization, and memory
505505 migration. See the radeon_ttm.c file for an example of usage.
506− </para>
507− <para>
508− The ttm_global_reference structure is made up of several fields:
509− </para>
510− <programlisting>
511− struct ttm_global_reference {
512− enum ttm_global_types global_type;
513− size_t size;
514− void *object;
515− int (*init) (struct ttm_global_reference *);
516− void (*release) (struct ttm_global_reference *);
517− };
518− </programlisting>
519− <para>
520− There should be one global reference structure for your memory
521− manager as a whole, and there will be others for each object
522− created by the memory manager at runtime. Your global TTM should
523− have a type of TTM_GLOBAL_TTM_MEM. The size field for the global
524− object should be sizeof(struct ttm_mem_global), and the init and
525− release hooks should point at your driver-specific init and
526− release routines, which probably eventually call
527− ttm_mem_global_init and ttm_mem_global_release, respectively.
528− </para>
529− <para>
530− Once your global TTM accounting structure is set up and initialized
531− by calling ttm_global_item_ref() on it,
532− you need to create a buffer object TTM to
533− provide a pool for buffer object allocation by clients and the
534− kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO,
535− and its size should be sizeof(struct ttm_bo_global). Again,
536− driver-specific init and release functions may be provided,
537− likely eventually calling ttm_bo_global_init() and
538− ttm_bo_global_release(), respectively. Also, like the previous
539− object, ttm_global_item_ref() is used to create an initial reference
540− count for the TTM, which will call your initialization function.
541− </para>
506+ </para>
507+ <para>
508+ The ttm_global_reference structure is made up of several fields:
509+ </para>
510+ <programlisting>
511+ struct ttm_global_reference {
512+ enum ttm_global_types global_type;
513+ size_t size;
514+ void *object;
515+ int (*init) (struct ttm_global_reference *);
516+ void (*release) (struct ttm_global_reference *);
517+ };
518+ </programlisting>
519+ <para>
520+ There should be one global reference structure for your memory
521+ manager as a whole, and there will be others for each object
522+ created by the memory manager at runtime. Your global TTM should
523+ have a type of TTM_GLOBAL_TTM_MEM. The size field for the global
524+ object should be sizeof(struct ttm_mem_global), and the init and
525+ release hooks should point at your driver-specific init and
526+ release routines, which probably eventually call
527+ ttm_mem_global_init and ttm_mem_global_release, respectively.
528+ </para>
529+ <para>
530+ Once your global TTM accounting structure is set up and initialized
531+ by calling ttm_global_item_ref() on it,
532+ you need to create a buffer object TTM to
533+ provide a pool for buffer object allocation by clients and the
534+ kernel itself. The type of this object should be TTM_GLOBAL_TTM_BO,
535+ and its size should be sizeof(struct ttm_bo_global). Again,
536+ driver-specific init and release functions may be provided,
537+ likely eventually calling ttm_bo_global_init() and
538+ ttm_bo_global_release(), respectively. Also, like the previous
539+ object, ttm_global_item_ref() is used to create an initial reference
540+ count for the TTM, which will call your initialization function.
541+ </para>
542542 </sect3>
543543 </sect2>
544544 <sect2 id="drm-gem">
@@ -566,19 +566,19 @@ char *date;</synopsis> · 21 unmodified lines
566566 using driver-specific ioctls.
567567 </para>
568568 <para>
569− On a fundamental level, GEM involves several operations:
570− <itemizedlist>
571− <listitem>Memory allocation and freeing</listitem>
572− <listitem>Command execution</listitem>
573− <listitem>Aperture management at command execution time</listitem>
574− </itemizedlist>
575− Buffer object allocation is relatively straightforward and largely
569+ On a fundamental level, GEM involves several operations:
570+ <itemizedlist>
571+ <listitem>Memory allocation and freeing</listitem>
572+ <listitem>Command execution</listitem>
573+ <listitem>Aperture management at command execution time</listitem>
574+ </itemizedlist>
575+ Buffer object allocation is relatively straightforward and largely
576576 provided by Linux's shmem layer, which provides memory to back each
577577 object.
578578 </para>
579579 <para>
580580 Device-specific operations, such as command execution, pinning, buffer
581− read &amp; write, mapping, and domain ownership transfers are left to
581+ read &amp; write, mapping, and domain ownership transfers are left to
582582 driver-specific ioctls.
583583 </para>
584584 <sect3>
@@ -738,16 +738,16 @@ char *date;</synopsis> · 153 unmodified lines
738738 respectively. The conversion is handled by the DRM core without any
739739 driver-specific support.
740740 </para>
741− <para>
742− GEM also supports buffer sharing with dma-buf file descriptors through
743− PRIME. GEM-based drivers must use the provided helpers functions to
744− implement the exporting and importing correctly. See <xref linkend="drm-prime-support" />.
745− Since sharing file descriptors is inherently more secure than the
746− easily guessable and global GEM names it is the preferred buffer
747− sharing mechanism. Sharing buffers through GEM names is only supported
748− for legacy userspace. Furthermore PRIME also allows cross-device
749− buffer sharing since it is based on dma-bufs.
750− </para>
741+ <para>
742+ GEM also supports buffer sharing with dma-buf file descriptors through
743+ PRIME. GEM-based drivers must use the provided helpers functions to
744+ implement the exporting and importing correctly. See <xref linkend="drm-prime-support" />.
745+ Since sharing file descriptors is inherently more secure than the
746+ easily guessable and global GEM names it is the preferred buffer
747+ sharing mechanism. Sharing buffers through GEM names is only supported
748+ for legacy userspace. Furthermore PRIME also allows cross-device
749+ buffer sharing since it is based on dma-bufs.
750+ </para>
751751 </sect3>
752752 <sect3 id="drm-gem-objects-mapping">
753753 <title>GEM Objects Mapping</title>
@@ -852,7 +852,7 @@ char *date;</synopsis> · 98 unmodified lines
852852 <sect3>
853853 <title>Command Execution</title>
854854 <para>
855− Perhaps the most important GEM function for GPU devices is providing a
855+ Perhaps the most important GEM function for GPU devices is providing a
856856 command execution interface to clients. Client programs construct
857857 command buffers containing references to previously allocated memory
858858 objects, and then submit them to GEM. At that point, GEM takes care to
@@ -874,95 +874,101 @@ char *date;</synopsis> · 15 unmodified lines
874874 <title>GEM Function Reference</title>
875875 !Edrivers/gpu/drm/drm_gem.c
876876 </sect3>
877− </sect2>
878− <sect2>
879− <title>VMA Offset Manager</title>
877+ </sect2>
878+ <sect2>
879+ <title>VMA Offset Manager</title>
880880 !Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager
881881 !Edrivers/gpu/drm/drm_vma_manager.c
882882 !Iinclude/drm/drm_vma_manager.h
883− </sect2>
884− <sect2 id="drm-prime-support">
885− <title>PRIME Buffer Sharing</title>
886− <para>
887− PRIME is the cross device buffer sharing framework in drm, originally
888− created for the OPTIMUS range of multi-gpu platforms. To userspace
889− PRIME buffers are dma-buf based file descriptors.
890− </para>
891− <sect3>
892− <title>Overview and Driver Interface</title>
893− <para>
894− Similar to GEM global names, PRIME file descriptors are
895− also used to share buffer objects across processes. They offer
896− additional security: as file descriptors must be explicitly sent over
897− UNIX domain sockets to be shared between applications, they can't be
898− guessed like the globally unique GEM names.
899− </para>
900− <para>
901− Drivers that support the PRIME
902− API must set the DRIVER_PRIME bit in the struct
903− <structname>drm_driver</structname>
904− <structfield>driver_features</structfield> field, and implement the
905− <methodname>prime_handle_to_fd</methodname> and
906− <methodname>prime_fd_to_handle</methodname> operations.
907− </para>
908− <para>
909− <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
910− struct drm_file *file_priv, uint32_t handle,
911− uint32_t flags, int *prime_fd);
883+ </sect2>
884+ <sect2 id="drm-prime-support">
885+ <title>PRIME Buffer Sharing</title>
886+ <para>
887+ PRIME is the cross device buffer sharing framework in drm, originally
888+ created for the OPTIMUS range of multi-gpu platforms. To userspace
889+ PRIME buffers are dma-buf based file descriptors.
890+ </para>
891+ <sect3>
892+ <title>Overview and Driver Interface</title>
893+ <para>
894+ Similar to GEM global names, PRIME file descriptors are
895+ also used to share buffer objects across processes. They offer
896+ additional security: as file descriptors must be explicitly sent over
897+ UNIX domain sockets to be shared between applications, they can't be
898+ guessed like the globally unique GEM names.
899+ </para>
900+ <para>
901+ Drivers that support the PRIME
902+ API must set the DRIVER_PRIME bit in the struct
903+ <structname>drm_driver</structname>
904+ <structfield>driver_features</structfield> field, and implement the
905+ <methodname>prime_handle_to_fd</methodname> and
906+ <methodname>prime_fd_to_handle</methodname> operations.
907+ </para>
908+ <para>
909+ <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
910+ struct drm_file *file_priv, uint32_t handle,
911+ uint32_t flags, int *prime_fd);
912912 int (*prime_fd_to_handle)(struct drm_device *dev,
913− struct drm_file *file_priv, int prime_fd,
914− uint32_t *handle);</synopsis>
915− Those two operations convert a handle to a PRIME file descriptor and
916− vice versa. Drivers must use the kernel dma-buf buffer sharing framework
917− to manage the PRIME file descriptors. Similar to the mode setting
918− API PRIME is agnostic to the underlying buffer object manager, as
919− long as handles are 32bit unsigned integers.
920− </para>
921− <para>
922− While non-GEM drivers must implement the operations themselves, GEM
923− drivers must use the <function>drm_gem_prime_handle_to_fd</function>
924− and <function>drm_gem_prime_fd_to_handle</function> helper functions.
925− Those helpers rely on the driver
926− <methodname>gem_prime_export</methodname> and
927− <methodname>gem_prime_import</methodname> operations to create a dma-buf
928− instance from a GEM object (dma-buf exporter role) and to create a GEM
929− object from a dma-buf instance (dma-buf importer role).
930− </para>
931− <para>
932− <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
933− struct drm_gem_object *obj,
934− int flags);
913+ struct drm_file *file_priv, int prime_fd,
914+ uint32_t *handle);</synopsis>
915+ Those two operations convert a handle to a PRIME file descriptor and
916+ vice versa. Drivers must use the kernel dma-buf buffer sharing framework
917+ to manage the PRIME file descriptors. Similar to the mode setting
918+ API PRIME is agnostic to the underlying buffer object manager, as
919+ long as handles are 32bit unsigned integers.
920+ </para>
921+ <para>
922+ While non-GEM drivers must implement the operations themselves, GEM
923+ drivers must use the <function>drm_gem_prime_handle_to_fd</function>
924+ and <function>drm_gem_prime_fd_to_handle</function> helper functions.
925+ Those helpers rely on the driver
926+ <methodname>gem_prime_export</methodname> and
927+ <methodname>gem_prime_import</methodname> operations to create a dma-buf
928+ instance from a GEM object (dma-buf exporter role) and to create a GEM
929+ object from a dma-buf instance (dma-buf importer role).
930+ </para>
931+ <para>
932+ <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
933+ struct drm_gem_object *obj,
934+ int flags);
935935 struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
936− struct dma_buf *dma_buf);</synopsis>
937− These two operations are mandatory for GEM drivers that support
938− PRIME.
939− </para>
940− </sect3>
941− <sect3>
942− <title>PRIME Helper Functions</title>
943−!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
936+ struct dma_buf *dma_buf);</synopsis>
937+ These two operations are mandatory for GEM drivers that support
938+ PRIME.
939+ </para>
944940 </sect3>
945− </sect2>
946− <sect2>
947− <title>PRIME Function References</title>
941+ <sect3>
942+ <title>PRIME Helper Functions</title>
943+!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
944+ </sect3>
945+ </sect2>
946+ <sect2>
947+ <title>PRIME Function References</title>
948948 !Edrivers/gpu/drm/drm_prime.c
949− </sect2>
950− <sect2>
951− <title>DRM MM Range Allocator</title>
952− <sect3>
953− <title>Overview</title>
949+ </sect2>
950+ <sect2>
951+ <title>DRM MM Range Allocator</title>
952+ <sect3>
953+ <title>Overview</title>
954954 !Pdrivers/gpu/drm/drm_mm.c Overview
955− </sect3>
956− <sect3>
957− <title>LRU Scan/Eviction Support</title>
955+ </sect3>
956+ <sect3>
957+ <title>LRU Scan/Eviction Support</title>
958958 !Pdrivers/gpu/drm/drm_mm.c lru scan roaster
959− </sect3>
959+ </sect3>
960960 </sect2>
961− <sect2>
962− <title>DRM MM Range Allocator Function References</title>
961+ <sect2>
962+ <title>DRM MM Range Allocator Function References</title>
963963 !Edrivers/gpu/drm/drm_mm.c
964964 !Iinclude/drm/drm_mm.h
965− </sect2>
965+ </sect2>
966+ <sect2>
967+ <title>CMA Helper Functions Reference</title>
968+!Pdrivers/gpu/drm/drm_gem_cma_helper.c cma helpers
969+!Edrivers/gpu/drm/drm_gem_cma_helper.c
970+!Iinclude/drm/drm_gem_cma_helper.h
971+ </sect2>
966972 </sect1>
967973
968974 <!-- Internals: mode setting -->
@@ -994,6 +1000,10 @@ int max_width, max_height;</synopsis> · 25 unmodified lines
9941000 <title>Display Modes Function Reference</title>
9951001 !Iinclude/drm/drm_modes.h
9961002 !Edrivers/gpu/drm/drm_modes.c
1003+ </sect2>
1004+ <sect2>
1005+ <title>Atomic Mode Setting Function Reference</title>
1006+!Edrivers/gpu/drm/drm_atomic.c
9971007 </sect2>
9981008 <sect2>
9991009 <title>Frame Buffer Creation</title>
@@ -1825,6 +1835,10 @@ void intel_crt_init(struct drm_device *dev) · 825 unmodified lines
18251835 <sect2>
18261836 <title>KMS API Functions</title>
18271837 !Edrivers/gpu/drm/drm_crtc.c
1838+ </sect2>
1839+ <sect2>
1840+ <title>KMS Data Structures</title>
1841+!Iinclude/drm/drm_crtc.h
18281842 </sect2>
18291843 <sect2>
18301844 <title>KMS Locking</title>
@@ -1933,10 +1947,16 @@ void intel_crt_init(struct drm_device *dev) · 102 unmodified lines
19331947 and then retrieves a list of modes by calling the connector
19341948 <methodname>get_modes</methodname> helper operation.
19351949 </para>
1950+ <para>
1951+ If the helper operation returns no mode, and if the connector status
1952+ is connector_status_connected, standard VESA DMT modes up to
1953+ 1024x768 are automatically added to the modes list by a call to
1954+ <function>drm_add_modes_noedid</function>.
1955+ </para>
19361956 <para>
1937− The function filters out modes larger than
1957+ The function then filters out modes larger than
19381958 <parameter>max_width</parameter> and <parameter>max_height</parameter>
1939− if specified. It then calls the optional connector
1959+ if specified. It finally calls the optional connector
19401960 <methodname>mode_valid</methodname> helper operation for each mode in
19411961 the probed list to check whether the mode is valid for the connector.
19421962 </para>
@@ -2076,11 +2096,19 @@ void intel_crt_init(struct drm_device *dev) · 133 unmodified lines
20762096 <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis>
20772097 <para>
20782098 Fill the connector's <structfield>probed_modes</structfield> list
2079− by parsing EDID data with <function>drm_add_edid_modes</function> or
2080− calling <function>drm_mode_probed_add</function> directly for every
2099+ by parsing EDID data with <function>drm_add_edid_modes</function>,
2100+ adding standard VESA DMT modes with <function>drm_add_modes_noedid</function>,
2101+ or calling <function>drm_mode_probed_add</function> directly for every
20812102 supported mode and return the number of modes it has detected. This
20822103 operation is mandatory.
20832104 </para>
2105+ <para>
2106+ Note that the caller function will automatically add standard VESA
2107+ DMT modes up to 1024x768 if the <methodname>get_modes</methodname>
2108+ helper operation returns no mode and if the connector status is
2109+ connector_status_connected. There is no need to call
2110+ <function>drm_add_edid_modes</function> manually in that case.
2111+ </para>
20842112 <para>
20852113 When adding modes manually the driver creates each mode with a call to
20862114 <function>drm_mode_create</function> and must fill the following fields.
@@ -2278,7 +2306,7 @@ void intel_crt_init(struct drm_device *dev) · 191 unmodified lines
22782306 <function>drm_helper_probe_single_connector_modes</function>.
22792307 </para>
22802308 <para>
2281− When parsing EDID data, <function>drm_add_edid_modes</function> fill the
2309+ When parsing EDID data, <function>drm_add_edid_modes</function> fills the
22822310 connector <structfield>display_info</structfield>
22832311 <structfield>width_mm</structfield> and
22842312 <structfield>height_mm</structfield> fields. When creating modes
@@ -2315,9 +2343,27 @@ void intel_crt_init(struct drm_device *dev) · 30 unmodified lines
23152343 </listitem>
23162344 </itemizedlist>
23172345 </sect2>
2346+ <sect2>
2347+ <title>Atomic Modeset Helper Functions Reference</title>
2348+ <sect3>
2349+ <title>Overview</title>
2350+!Pdrivers/gpu/drm/drm_atomic_helper.c overview
2351+ </sect3>
2352+ <sect3>
2353+ <title>Implementing Asynchronous Atomic Commit</title>
2354+!Pdrivers/gpu/drm/drm_atomic_helper.c implementing async commit
2355+ </sect3>
2356+ <sect3>
2357+ <title>Atomic State Reset and Initialization</title>
2358+!Pdrivers/gpu/drm/drm_atomic_helper.c atomic state reset and initialization
2359+ </sect3>
2360+!Iinclude/drm/drm_atomic_helper.h
2361+!Edrivers/gpu/drm/drm_atomic_helper.c
2362+ </sect2>
23182363 <sect2>
23192364 <title>Modeset Helper Functions Reference</title>
23202365 !Edrivers/gpu/drm/drm_crtc_helper.c
2366+!Pdrivers/gpu/drm/drm_crtc_helper.c overview
23212367 </sect2>
23222368 <sect2>
23232369 <title>Output Probing Helper Functions Reference</title>
@@ -2341,6 +2387,12 @@ void intel_crt_init(struct drm_device *dev) · 17 unmodified lines
23412387 !Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper
23422388 !Iinclude/drm/drm_dp_mst_helper.h
23432389 !Edrivers/gpu/drm/drm_dp_mst_topology.c
2390+ </sect2>
2391+ <sect2>
2392+ <title>MIPI DSI Helper Functions Reference</title>
2393+!Pdrivers/gpu/drm/drm_mipi_dsi.c dsi helpers
2394+!Iinclude/drm/drm_mipi_dsi.h
2395+!Edrivers/gpu/drm/drm_mipi_dsi.c
23442396 </sect2>
23452397 <sect2>
23462398 <title>EDID Helper Functions Reference</title>
@@ -2371,7 +2423,12 @@ void intel_crt_init(struct drm_device *dev) · 24 unmodified lines
23712423 </sect2>
23722424 <sect2>
23732425 <title id="drm-kms-planehelpers">Plane Helper Reference</title>
2374−!Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers
2426+!Edrivers/gpu/drm/drm_plane_helper.c
2427+!Pdrivers/gpu/drm/drm_plane_helper.c overview
2428+ </sect2>
2429+ <sect2>
2430+ <title>Tile group</title>
2431+!Pdrivers/gpu/drm/drm_crtc.c Tile group
23752432 </sect2>
23762433 </sect1>
23772434
@@ -2507,8 +2564,8 @@ void intel_crt_init(struct drm_device *dev) · 129 unmodified lines
25072564 <td valign="top" >Description/Restrictions</td>
25082565 </tr>
25092566 <tr>
2510− <td rowspan="21" valign="top" >DRM</td>
2511− <td rowspan="2" valign="top" >Generic</td>
2567+ <td rowspan="25" valign="top" >DRM</td>
2568+ <td rowspan="4" valign="top" >Generic</td>
25122569 <td valign="top" >“EDID”</td>
25132570 <td valign="top" >BLOB | IMMUTABLE</td>
25142571 <td valign="top" >0</td>
@@ -2523,6 +2580,20 @@ void intel_crt_init(struct drm_device *dev) · 8 unmodified lines
25232580 <td valign="top" >Contains DPMS operation mode value.</td>
25242581 </tr>
25252582 <tr>
2583+ <td valign="top" >“PATH”</td>
2584+ <td valign="top" >BLOB | IMMUTABLE</td>
2585+ <td valign="top" >0</td>
2586+ <td valign="top" >Connector</td>
2587+ <td valign="top" >Contains topology path to a connector.</td>
2588+ </tr>
2589+ <tr>
2590+ <td valign="top" >“TILE”</td>
2591+ <td valign="top" >BLOB | IMMUTABLE</td>
2592+ <td valign="top" >0</td>
2593+ <td valign="top" >Connector</td>
2594+ <td valign="top" >Contains tiling information for a connector.</td>
2595+ </tr>
2596+ <tr>
25262597 <td rowspan="1" valign="top" >Plane</td>
25272598 <td valign="top" >“type”</td>
25282599 <td valign="top" >ENUM | IMMUTABLE</td>
@@ -2638,6 +2709,21 @@ void intel_crt_init(struct drm_device *dev) · 109 unmodified lines
26382709 <td valign="top" >TBD</td>
26392710 </tr>
26402711 <tr>
2712+ <td rowspan="2" valign="top" >Virtual GPU</td>
2713+ <td valign="top" >“suggested X”</td>
2714+ <td valign="top" >RANGE</td>
2715+ <td valign="top" >Min=0, Max=0xffffffff</td>
2716+ <td valign="top" >Connector</td>
2717+ <td valign="top" >property to suggest an X offset for a connector</td>
2718+ </tr>
2719+ <tr>
2720+ <td valign="top" >“suggested Y”</td>
2721+ <td valign="top" >RANGE</td>
2722+ <td valign="top" >Min=0, Max=0xffffffff</td>
2723+ <td valign="top" >Connector</td>
2724+ <td valign="top" >property to suggest an Y offset for a connector</td>
2725+ </tr>
2726+ <tr>
26412727 <td rowspan="3" valign="top" >Optional</td>
26422728 <td valign="top" >“scaling mode”</td>
26432729 <td valign="top" >ENUM</td>
@@ -3787,6 +3873,26 @@ int num_ioctls;</synopsis> · 1143 unmodified lines
37873873 blocks. This excludes a set of SoC platforms with an SGX rendering unit,
37883874 those have basic support through the gma500 drm driver.
37893875 </para>
3876+ <sect1>
3877+ <title>Core Driver Infrastructure</title>
3878+ <para>
3879+ This section covers core driver infrastructure used by both the display
3880+ and the GEM parts of the driver.
3881+ </para>
3882+ <sect2>
3883+ <title>Runtime Power Management</title>
3884+!Pdrivers/gpu/drm/i915/intel_runtime_pm.c runtime pm
3885+!Idrivers/gpu/drm/i915/intel_runtime_pm.c
3886+ </sect2>
3887+ <sect2>
3888+ <title>Interrupt Handling</title>
3889+!Pdrivers/gpu/drm/i915/i915_irq.c interrupt handling
3890+!Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_init intel_irq_init_hw intel_hpd_init
3891+!Fdrivers/gpu/drm/i915/i915_irq.c intel_irq_fini
3892+!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_disable_interrupts
3893+!Fdrivers/gpu/drm/i915/i915_irq.c intel_runtime_pm_enable_interrupts
3894+ </sect2>
3895+ </sect1>
37903896 <sect1>
37913897 <title>Display Hardware Handling</title>
37923898 <para>
@@ -3803,6 +3909,18 @@ int num_ioctls;</synopsis> · 10 unmodified lines
38033909 configuration change.
38043910 </para>
38053911 </sect2>
3912+ <sect2>
3913+ <title>Frontbuffer Tracking</title>
3914+!Pdrivers/gpu/drm/i915/intel_frontbuffer.c frontbuffer tracking
3915+!Idrivers/gpu/drm/i915/intel_frontbuffer.c
3916+!Fdrivers/gpu/drm/i915/intel_drv.h intel_frontbuffer_flip
3917+!Fdrivers/gpu/drm/i915/i915_gem.c i915_gem_track_fb
3918+ </sect2>
3919+ <sect2>
3920+ <title>Display FIFO Underrun Reporting</title>
3921+!Pdrivers/gpu/drm/i915/intel_fifo_underrun.c fifo underrun handling
3922+!Idrivers/gpu/drm/i915/intel_fifo_underrun.c
3923+ </sect2>
38063924 <sect2>
38073925 <title>Plane Configuration</title>
38083926 <para>
@@ -3822,6 +3940,16 @@ int num_ioctls;</synopsis> · 13 unmodified lines
38223940 probing, so those sections fully apply.
38233941 </para>
38243942 </sect2>
3943+ <sect2>
3944+ <title>High Definition Audio</title>
3945+!Pdrivers/gpu/drm/i915/intel_audio.c High Definition Audio over HDMI and Display Port
3946+!Idrivers/gpu/drm/i915/intel_audio.c
3947+ </sect2>
3948+ <sect2>
3949+ <title>Panel Self Refresh PSR (PSR/SRD)</title>
3950+!Pdrivers/gpu/drm/i915/intel_psr.c Panel Self Refresh (PSR/SRD)
3951+!Idrivers/gpu/drm/i915/intel_psr.c
3952+ </sect2>
38253953 <sect2>
38263954 <title>DPIO</title>
38273955 !Pdrivers/gpu/drm/i915/i915_reg.h DPIO
@@ -3931,6 +4059,28 @@ int num_ioctls;</synopsis> · 103 unmodified lines
39314059 !Idrivers/gpu/drm/i915/intel_lrc.c
39324060 </sect2>
39334061 </sect1>
4062+
4063+ <sect1>
4064+ <title> Tracing </title>
4065+ <para>
4066+ This sections covers all things related to the tracepoints implemented in
4067+ the i915 driver.
4068+ </para>
4069+ <sect2>
4070+ <title> i915_ppgtt_create and i915_ppgtt_release </title>
4071+!Pdrivers/gpu/drm/i915/i915_trace.h i915_ppgtt_create and i915_ppgtt_release tracepoints
4072+ </sect2>
4073+ <sect2>
4074+ <title> i915_context_create and i915_context_free </title>
4075+!Pdrivers/gpu/drm/i915/i915_trace.h i915_context_create and i915_context_free tracepoints
4076+ </sect2>
4077+ <sect2>
4078+ <title> switch_mm </title>
4079+!Pdrivers/gpu/drm/i915/i915_trace.h switch_mm tracepoint
4080+ </sect2>
4081+ </sect1>
4082+
39344083 </chapter>
4084+!Cdrivers/gpu/drm/i915/i915_irq.c
39354085 </part>
39364086 </book>
Documentation/devicetree/bindings/drm/imx/fsl-imx-drm.txtrenamed from Documentation/devicetree/bindings/staging/imx-drm/fsl-imx-drm.txt+0−0

File renamed without changes.

Documentation/devicetree/bindings/drm/imx/hdmi.txtrenamed from Documentation/devicetree/bindings/staging/imx-drm/hdmi.txt+0−0

File renamed without changes.

Documentation/devicetree/bindings/drm/imx/ldb.txtrenamed from Documentation/devicetree/bindings/staging/imx-drm/ldb.txt+0−0

File renamed without changes.

Documentation/devicetree/bindings/gpu/nvidia,tegra20-host1x.txt+2−0
@@ -191,6 +191,8 @@ of the following host1x client modules: · 190 unmodified lines
191191 - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
192192 - nvidia,edid: supplies a binary EDID blob
193193 - nvidia,panel: phandle of a display panel
194+ - nvidia,ganged-mode: contains a phandle to a second DSI controller to gang
195+ up with in order to support up to 8 data lanes
194196
195197 - sor: serial output resource
196198
Documentation/devicetree/bindings/gpu/st,stih4xx.txt+27−2
@@ -68,7 +68,7 @@ STMicroelectronics stih4xx platforms · 67 unmodified lines
6868 number of clocks may depend of the SoC type.
6969 - clock-names: names of the clocks listed in clocks property in the same
7070 order.
71− - hdmi,hpd-gpio: gpio id to detect if an hdmi cable is plugged or not.
71+ - ddc: phandle of an I2C controller used for DDC EDID probing
7272
7373 sti-hda:
7474 Required properties:
@@ -83,6 +83,22 @@ sti-hda: · 8 unmodified lines
8383 - clock-names: names of the clocks listed in clocks property in the same
8484 order.
8585
86+sti-hqvdp:
87+ must be a child of sti-display-subsystem
88+ Required properties:
89+ - compatible: "st,stih<chip>-hqvdp"
90+ - reg: Physical base address of the IP registers and length of memory mapped region.
91+ - clocks: from common clock binding: handle hardware IP needed clocks, the
92+ number of clocks may depend of the SoC type.
93+ See ../clocks/clock-bindings.txt for details.
94+ - clock-names: names of the clocks listed in clocks property in the same
95+ order.
96+ - resets: resets to be used by the device
97+ See ../reset/reset.txt for details.
98+ - reset-names: names of the resets listed in resets property in the same
99+ order.
100+ - st,vtg: phandle on vtg main device node.
101+
86102 Example:
87103
88104 / {
@@ -173,7 +189,6 @@ Example: · 84 unmodified lines
173189 interrupt-names = "irq";
174190 clock-names = "pix", "tmds", "phy", "audio";
175191 clocks = <&clockgen_c_vcc CLK_S_PIX_HDMI>, <&clockgen_c_vcc CLK_S_TMDS_HDMI>, <&clockgen_c_vcc CLK_S_HDMI_REJECT_PLL>, <&clockgen_b1 CLK_S_PCM_0>;
176− hdmi,hpd-gpio = <&PIO2 5>;
177192 };
178193
179194 sti-hda@fe85a000 {
@@ -184,6 +199,16 @@ Example: · 4 unmodified lines
184199 clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>;
185200 };
186201 };
202+
203+ sti-hqvdp@9c000000 {
204+ compatible = "st,stih407-hqvdp";
205+ reg = <0x9C00000 0x100000>;
206+ clock-names = "hqvdp", "pix_main";
207+ clocks = <&clk_s_c0_flexgen CLK_MAIN_DISP>, <&clk_s_d2_flexgen CLK_PIX_MAIN_DISP>;
208+ reset-names = "hqvdp";
209+ resets = <&softreset STIH407_HDQVDP_SOFTRESET>;
210+ st,vtg = <&vtg_main>;
211+ };
187212 };
188213 ...
189214 };
Documentation/devicetree/bindings/panel/auo,b116xw03.txt+7−0
@@ -0,0 +1,7 @@
1+AU Optronics Corporation 11.6" HD (1366x768) color TFT-LCD panel
2+
3+Required properties:
4+- compatible: should be "auo,b116xw03"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt+7−0
@@ -0,0 +1,7 @@
1+HannStar Display Corp. HSD070PWW1 7.0" WXGA TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "hannstar,hsd070pww1"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt+7−0
@@ -0,0 +1,7 @@
1+Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "hit,tx23d38vm0caa"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt+7−0
@@ -0,0 +1,7 @@
1+Innolux Corporation 12.1" WXGA (1280x800) TFT LCD panel
2+
3+Required properties:
4+- compatible: should be "innolux,g121i1-l01"
5+
6+This binding is compatible with the simple-panel binding, which is specified
7+in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt+49−0
@@ -0,0 +1,49 @@
1+Sharp Microelectronics 10.1" WQXGA TFT LCD panel
2+
3+This panel requires a dual-channel DSI host to operate. It supports two modes:
4+- left-right: each channel drives the left or right half of the screen
5+- even-odd: each channel drives the even or odd lines of the screen
6+
7+Each of the DSI channels controls a separate DSI peripheral. The peripheral
8+driven by the first link (DSI-LINK1), left or even, is considered the primary
9+peripheral and controls the device. The 'link2' property contains a phandle
10+to the peripheral driven by the second link (DSI-LINK2, right or odd).
11+
12+Note that in video mode the DSI-LINK1 interface always provides the left/even
13+pixels and DSI-LINK2 always provides the right/odd pixels. In command mode it
14+is possible to program either link to drive the left/even or right/odd pixels
15+but for the sake of consistency this binding assumes that the same assignment
16+is chosen as for video mode.
17+
18+Required properties:
19+- compatible: should be "sharp,lq101r1sx01"
20+- reg: DSI virtual channel of the peripheral
21+
22+Required properties (for DSI-LINK1 only):
23+- link2: phandle to the DSI peripheral on the secondary link. Note that the
24+ presence of this property marks the containing node as DSI-LINK1.
25+- power-supply: phandle of the regulator that provides the supply voltage
26+
27+Optional properties (for DSI-LINK1 only):
28+- backlight: phandle of the backlight device attached to the panel
29+
30+Example:
31+
32+ dsi@54300000 {
33+ panel: panel@0 {
34+ compatible = "sharp,lq101r1sx01";
35+ reg = <0>;
36+
37+ link2 = <&secondary>;
38+
39+ power-supply = <...>;
40+ backlight = <...>;
41+ };
42+ };
43+
44+ dsi@54400000 {
45+ secondary: panel@0 {
46+ compatible = "sharp,lq101r1sx01";
47+ reg = <0>;
48+ };
49+ };
Documentation/devicetree/bindings/vendor-prefixes.txt+2−0
@@ -66,8 +66,10 @@ gmt Global Mixed-mode Technology, Inc. · 65 unmodified lines
6666 google Google, Inc.
6767 gumstix Gumstix, Inc.
6868 gw Gateworks Corporation
69+hannstar HannStar Display Corporation
6970 haoyu Haoyu Microelectronic Co. Ltd.
7071 hisilicon Hisilicon Limited.
72+hit Hitachi Ltd.
7173 honeywell Honeywell
7274 hp Hewlett Packard
7375 i2se I2SE GmbH
Documentation/devicetree/bindings/video/adi,adv7511.txt+88−0
@@ -0,0 +1,88 @@
1+Analog Device ADV7511(W)/13 HDMI Encoders
2+-----------------------------------------
3+
4+The ADV7511, ADV7511W and ADV7513 are HDMI audio and video transmitters
5+compatible with HDMI 1.4 and DVI 1.0. They support color space conversion,
6+S/PDIF, CEC and HDCP.
7+
8+Required properties:
9+
10+- compatible: Should be one of "adi,adv7511", "adi,adv7511w" or "adi,adv7513"
11+- reg: I2C slave address
12+
13+The ADV7511 supports a large number of input data formats that differ by their
14+color depth, color format, clock mode, bit justification and random
15+arrangement of components on the data bus. The combination of the following
16+properties describe the input and map directly to the video input tables of the
17+ADV7511 datasheet that document all the supported combinations.
18+
19+- adi,input-depth: Number of bits per color component at the input (8, 10 or
20+ 12).
21+- adi,input-colorspace: The input color space, one of "rgb", "yuv422" or
22+ "yuv444".
23+- adi,input-clock: The input clock type, one of "1x" (one clock cycle per
24+ pixel), "2x" (two clock cycles per pixel), "ddr" (one clock cycle per pixel,
25+ data driven on both edges).
26+
27+The following input format properties are required except in "rgb 1x" and
28+"yuv444 1x" modes, in which case they must not be specified.
29+
30+- adi,input-style: The input components arrangement variant (1, 2 or 3), as
31+ listed in the input format tables in the datasheet.
32+- adi,input-justification: The input bit justification ("left", "evenly",
33+ "right").
34+
35+Optional properties:
36+
37+- interrupts: Specifier for the ADV7511 interrupt
38+- pd-gpios: Specifier for the GPIO connected to the power down signal
39+
40+- adi,clock-delay: Video data clock delay relative to the pixel clock, in ps
41+ (-1200 ps .. 1600 ps). Defaults to no delay.
42+- adi,embedded-sync: The input uses synchronization signals embedded in the
43+ data stream (similar to BT.656). Defaults to separate H/V synchronization
44+ signals.
45+
46+Required nodes:
47+
48+The ADV7511 has two video ports. Their connections are modelled using the OF
49+graph bindings specified in Documentation/devicetree/bindings/graph.txt.
50+
51+- Video port 0 for the RGB or YUV input
52+- Video port 1 for the HDMI output
53+
54+
55+Example
56+-------
57+
58+ adv7511w: hdmi@39 {
59+ compatible = "adi,adv7511w";
60+ reg = <39>;
61+ interrupt-parent = <&gpio3>;
62+ interrupts = <29 IRQ_TYPE_EDGE_FALLING>;
63+
64+ adi,input-depth = <8>;
65+ adi,input-colorspace = "rgb";
66+ adi,input-clock = "1x";
67+ adi,input-style = <1>;
68+ adi,input-justification = "evenly";
69+
70+ ports {
71+ #address-cells = <1>;
72+ #size-cells = <0>;
73+
74+ port@0 {
75+ reg = <0>;
76+ adv7511w_in: endpoint {
77+ remote-endpoint = <&dpi_out>;
78+ };
79+ };
80+
81+ port@1 {
82+ reg = <1>;
83+ adv7511_out: endpoint {
84+ remote-endpoint = <&hdmi_connector_in>;
85+ };
86+ };
87+ };
88+ };
Documentation/devicetree/bindings/video/exynos_dsim.txt+1−0
@@ -4,6 +4,7 @@ Required properties: · 3 unmodified lines
44 - compatible: value should be one of the following
55 "samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
66 "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
7+ "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
78 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
89 - reg: physical base address and length of the registers set for the device
910 - interrupts: should contain DSI interrupt
Documentation/devicetree/bindings/video/rockchip-drm.txt+19−0
@@ -0,0 +1,19 @@
1+Rockchip DRM master device
2+================================
3+
4+The Rockchip DRM master device is a virtual device needed to list all
5+vop devices or other display interface nodes that comprise the
6+graphics subsystem.
7+
8+Required properties:
9+- compatible: Should be "rockchip,display-subsystem"
10+- ports: Should contain a list of phandles pointing to display interface port
11+ of vop devices. vop definitions as defined in
12+ Documentation/devicetree/bindings/video/rockchip-vop.txt
13+
14+example:
15+
16+display-subsystem {
17+ compatible = "rockchip,display-subsystem";
18+ ports = <&vopl_out>, <&vopb_out>;
19+};
Documentation/devicetree/bindings/video/rockchip-vop.txt+58−0
@@ -0,0 +1,58 @@
1+device-tree bindings for rockchip soc display controller (vop)
2+
3+VOP (Visual Output Processor) is the Display Controller for the Rockchip
4+series of SoCs which transfers the image data from a video memory
5+buffer to an external LCD interface.
6+
7+Required properties:
8+- compatible: value should be one of the following
9+ "rockchip,rk3288-vop";
10+
11+- interrupts: should contain a list of all VOP IP block interrupts in the
12+ order: VSYNC, LCD_SYSTEM. The interrupt specifier
13+ format depends on the interrupt controller used.
14+
15+- clocks: must include clock specifiers corresponding to entries in the
16+ clock-names property.
17+
18+- clock-names: Must contain
19+ aclk_vop: for ddr buffer transfer.
20+ hclk_vop: for ahb bus to R/W the phy regs.
21+ dclk_vop: pixel clock.
22+
23+- resets: Must contain an entry for each entry in reset-names.
24+ See ../reset/reset.txt for details.
25+- reset-names: Must include the following entries:
26+ - axi
27+ - ahb
28+ - dclk
29+
30+- iommus: required a iommu node
31+
32+- port: A port node with endpoint definitions as defined in
33+ Documentation/devicetree/bindings/media/video-interfaces.txt.
34+
35+Example:
36+SoC specific DT entry:
37+ vopb: vopb@ff930000 {
38+ compatible = "rockchip,rk3288-vop";
39+ reg = <0xff930000 0x19c>;
40+ interrupts = <GIC_SPI 15 IRQ_TYPE_LEVEL_HIGH>;
41+ clocks = <&cru ACLK_VOP0>, <&cru DCLK_VOP0>, <&cru HCLK_VOP0>;
42+ clock-names = "aclk_vop", "dclk_vop", "hclk_vop";
43+ resets = <&cru SRST_LCDC1_AXI>, <&cru SRST_LCDC1_AHB>, <&cru SRST_LCDC1_DCLK>;
44+ reset-names = "axi", "ahb", "dclk";
45+ iommus = <&vopb_mmu>;
46+ vopb_out: port {
47+ #address-cells = <1>;
48+ #size-cells = <0>;
49+ vopb_out_edp: endpoint@0 {
50+ reg = <0>;
51+ remote-endpoint=<&edp_in_vopb>;
52+ };
53+ vopb_out_hdmi: endpoint@1 {
54+ reg = <1>;
55+ remote-endpoint=<&hdmi_in_vopb>;
56+ };
57+ };
58+ };
Documentation/devicetree/bindings/video/samsung-fimd.txt+1−0
@@ -11,6 +11,7 @@ Required properties: · 10 unmodified lines
1111 "samsung,s5pv210-fimd"; /* for S5PV210 SoC */
1212 "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
1313 "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
14+ "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
1415 "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */
1516
1617 - reg: physical base address and length of the FIMD registers set.
MAINTAINERS+17−0
@@ -618,6 +618,16 @@ S: Maintained · 617 unmodified lines
618618 F: drivers/iommu/amd_iommu*.[ch]
619619 F: include/linux/amd-iommu.h
620620
621+AMD KFD
622+M: Oded Gabbay <oded.gabbay@amd.com>
623+L: dri-devel@lists.freedesktop.org
624+T: git git://people.freedesktop.org/~gabbayo/linux.git
625+S: Supported
626+F: drivers/gpu/drm/amd/amdkfd/
627+F: drivers/gpu/drm/radeon/radeon_kfd.c
628+F: drivers/gpu/drm/radeon/radeon_kfd.h
629+F: include/uapi/linux/kfd_ioctl.h
630+
621631 AMD MICROCODE UPDATE SUPPORT
622632 M: Andreas Herrmann <herrmann.der.user@googlemail.com>
623633 L: amd64-microcode@amd64.org
@@ -3297,6 +3307,13 @@ F: drivers/gpu/drm/exynos/ · 2673 unmodified lines
32973307 F: include/drm/exynos*
32983308 F: include/uapi/drm/exynos*
32993309
3310+DRM DRIVERS FOR FREESCALE IMX
3311+M: Philipp Zabel <p.zabel@pengutronix.de>
3312+L: dri-devel@lists.freedesktop.org
3313+S: Maintained
3314+F: drivers/gpu/drm/imx/
3315+F: Documentation/devicetree/bindings/drm/imx/
3316+
33003317 DRM DRIVERS FOR NVIDIA TEGRA
33013318 M: Thierry Reding <thierry.reding@gmail.com>
33023319 M: Terje Bergström <tbergstrom@nvidia.com>
arch/arm/mach-shmobile/board-lager.c+0−58
@@ -32,7 +32,6 @@ · 31 unmodified lines
3232 #include <linux/pinctrl/machine.h>
3333 #include <linux/platform_data/camera-rcar.h>
3434 #include <linux/platform_data/gpio-rcar.h>
35−#include <linux/platform_data/rcar-du.h>
3635 #include <linux/platform_data/usb-rcar-gen2-phy.h>
3736 #include <linux/platform_device.h>
3837 #include <linux/phy.h>
@@ -83,61 +82,6 @@ · 44 unmodified lines
8382 *
8483 */
8584
86−/* DU */
87−static struct rcar_du_encoder_data lager_du_encoders[] = {
88− {
89− .type = RCAR_DU_ENCODER_VGA,
90− .output = RCAR_DU_OUTPUT_DPAD0,
91− }, {
92− .type = RCAR_DU_ENCODER_NONE,
93− .output = RCAR_DU_OUTPUT_LVDS1,
94− .connector.lvds.panel = {
95− .width_mm = 210,
96− .height_mm = 158,
97− .mode = {
98− .pixelclock = 65000000,
99− .hactive = 1024,
100− .hfront_porch = 20,
101− .hback_porch = 160,
102− .hsync_len = 136,
103− .vactive = 768,
104− .vfront_porch = 3,
105− .vback_porch = 29,
106− .vsync_len = 6,
107− },
108− },
109− },
110−};
111−
112−static const struct rcar_du_platform_data lager_du_pdata __initconst = {
113− .encoders = lager_du_encoders,
114− .num_encoders = ARRAY_SIZE(lager_du_encoders),
115−};
116−
117−static const struct resource du_resources[] __initconst = {
118− DEFINE_RES_MEM(0xfeb00000, 0x70000),
119− DEFINE_RES_MEM_NAMED(0xfeb90000, 0x1c, "lvds.0"),
120− DEFINE_RES_MEM_NAMED(0xfeb94000, 0x1c, "lvds.1"),
121− DEFINE_RES_IRQ(gic_spi(256)),
122− DEFINE_RES_IRQ(gic_spi(268)),
123− DEFINE_RES_IRQ(gic_spi(269)),
124−};
125−
126−static void __init lager_add_du_device(void)
127−{
128− struct platform_device_info info = {
129− .name = "rcar-du-r8a7790",
130− .id = -1,
131− .res = du_resources,
132− .num_res = ARRAY_SIZE(du_resources),
133− .data = &lager_du_pdata,
134− .size_data = sizeof(lager_du_pdata),
135− .dma_mask = DMA_BIT_MASK(32),
136− };
137−
138− platform_device_register_full(&info);
139−}
140−
14185 /* LEDS */
14286 static struct gpio_led lager_leds[] = {
14387 {
@@ -800,8 +744,6 @@ static void __init lager_add_standard_devices(void) · 656 unmodified lines
800744
801745 platform_device_register_full(&ether_info);
802746
803− lager_add_du_device();
804−
805747 platform_device_register_resndata(NULL, "qspi", 0,
806748 qspi_resources,
807749 ARRAY_SIZE(qspi_resources),
arch/arm/mach-shmobile/board-marzen.c+0−58
@@ -27,7 +27,6 @@ · 26 unmodified lines
2727 #include <linux/pinctrl/machine.h>
2828 #include <linux/platform_data/camera-rcar.h>
2929 #include <linux/platform_data/gpio-rcar.h>
30−#include <linux/platform_data/rcar-du.h>
3130 #include <linux/platform_data/usb-rcar-phy.h>
3231 #include <linux/regulator/fixed.h>
3332 #include <linux/regulator/machine.h>
@@ -171,62 +170,6 @@ static struct platform_device hspi_device = { · 137 unmodified lines
171170 .num_resources = ARRAY_SIZE(hspi_resources),
172171 };
173172
174−/*
175− * DU
176− *
177− * The panel only specifies the [hv]display and [hv]total values. The position
178− * and width of the sync pulses don't matter, they're copied from VESA timings.
179− */
180−static struct rcar_du_encoder_data du_encoders[] = {
181− {
182− .type = RCAR_DU_ENCODER_VGA,
183− .output = RCAR_DU_OUTPUT_DPAD0,
184− }, {
185− .type = RCAR_DU_ENCODER_LVDS,
186− .output = RCAR_DU_OUTPUT_DPAD1,
187− .connector.lvds.panel = {
188− .width_mm = 210,
189− .height_mm = 158,
190− .mode = {
191− .pixelclock = 65000000,
192− .hactive = 1024,
193− .hfront_porch = 20,
194− .hback_porch = 160,
195− .hsync_len = 136,
196− .vactive = 768,
197− .vfront_porch = 3,
198− .vback_porch = 29,
199− .vsync_len = 6,
200− },
201− },
202− },
203−};
204−
205−static const struct rcar_du_platform_data du_pdata __initconst = {
206− .encoders = du_encoders,
207− .num_encoders = ARRAY_SIZE(du_encoders),
208−};
209−
210−static const struct resource du_resources[] __initconst = {
211− DEFINE_RES_MEM(0xfff80000, 0x40000),
212− DEFINE_RES_IRQ(gic_iid(0x3f)),
213−};
214−
215−static void __init marzen_add_du_device(void)
216−{
217− struct platform_device_info info = {
218− .name = "rcar-du-r8a7779",
219− .id = -1,
220− .res = du_resources,
221− .num_res = ARRAY_SIZE(du_resources),
222− .data = &du_pdata,
223− .size_data = sizeof(du_pdata),
224− .dma_mask = DMA_BIT_MASK(32),
225− };
226−
227− platform_device_register_full(&info);
228−}
229−
230173 /* LEDS */
231174 static struct gpio_led marzen_leds[] = {
232175 {
@@ -385,7 +328,6 @@ static void __init marzen_init(void) · 152 unmodified lines
385328 platform_device_register_full(&vin1_info);
386329 platform_device_register_full(&vin3_info);
387330 platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
388− marzen_add_du_device();
389331 }
390332
391333 static const char *marzen_boards_compat_dt[] __initdata = {
arch/x86/kernel/early-quirks.c+23−0
@@ -455,6 +455,23 @@ struct intel_stolen_funcs { · 454 unmodified lines
455455 u32 (*base)(int num, int slot, int func, size_t size);
456456 };
457457
458+static size_t __init gen9_stolen_size(int num, int slot, int func)
459+{
460+ u16 gmch_ctrl;
461+
462+ gmch_ctrl = read_pci_config_16(num, slot, func, SNB_GMCH_CTRL);
463+ gmch_ctrl >>= BDW_GMCH_GMS_SHIFT;
464+ gmch_ctrl &= BDW_GMCH_GMS_MASK;
465+
466+ if (gmch_ctrl < 0xf0)
467+ return gmch_ctrl << 25; /* 32 MB units */
468+ else
469+ /* 4MB increments starting at 0xf0 for 4MB */
470+ return (gmch_ctrl - 0xf0 + 1) << 22;
471+}
472+
473+typedef size_t (*stolen_size_fn)(int num, int slot, int func);
474+
458475 static const struct intel_stolen_funcs i830_stolen_funcs __initconst = {
459476 .base = i830_stolen_base,
460477 .size = i830_stolen_size,
@@ -490,6 +507,11 @@ static const struct intel_stolen_funcs gen8_stolen_funcs __initconst = { · 29 unmodified lines
490507 .size = gen8_stolen_size,
491508 };
492509
510+static const struct intel_stolen_funcs gen9_stolen_funcs __initconst = {
511+ .base = intel_stolen_base,
512+ .size = gen9_stolen_size,
513+};
514+
493515 static const struct intel_stolen_funcs chv_stolen_funcs __initconst = {
494516 .base = intel_stolen_base,
495517 .size = chv_stolen_size,
@@ -523,6 +545,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = { · 27 unmodified lines
523545 INTEL_BDW_M_IDS(&gen8_stolen_funcs),
524546 INTEL_BDW_D_IDS(&gen8_stolen_funcs),
525547 INTEL_CHV_IDS(&chv_stolen_funcs),
548+ INTEL_SKL_IDS(&gen9_stolen_funcs),
526549 };
527550
528551 static void __init intel_graphics_stolen(int num, int slot, int func)
drivers/char/agp/intel-gtt.c+0−4
@@ -153,7 +153,6 @@ static struct page *i8xx_alloc_pages(void) · 152 unmodified lines
153153 __free_pages(page, 2);
154154 return NULL;
155155 }
156− get_page(page);
157156 atomic_inc(&agp_bridge->current_memory_agp);
158157 return page;
159158 }
@@ -164,7 +163,6 @@ static void i8xx_destroy_pages(struct page *page) · 4 unmodified lines
164163 return;
165164
166165 set_pages_wb(page, 4);
167− put_page(page);
168166 __free_pages(page, 2);
169167 atomic_dec(&agp_bridge->current_memory_agp);
170168 }
@@ -300,7 +298,6 @@ static int intel_gtt_setup_scratch_page(void) · 129 unmodified lines
300298 page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
301299 if (page == NULL)
302300 return -ENOMEM;
303− get_page(page);
304301 set_pages_uc(page, 1);
305302
306303 if (intel_private.needs_dmar) {
@@ -560,7 +557,6 @@ static void intel_gtt_teardown_scratch_page(void) · 253 unmodified lines
560557 set_pages_wb(intel_private.scratch_page, 1);
561558 pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,
562559 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
563− put_page(intel_private.scratch_page);
564560 __free_page(intel_private.scratch_page);
565561 }
566562
drivers/gpu/drm/Kconfig+6−0
@@ -167,6 +167,8 @@ config DRM_SAVAGE · 166 unmodified lines
167167
168168 source "drivers/gpu/drm/exynos/Kconfig"
169169
170+source "drivers/gpu/drm/rockchip/Kconfig"
171+
170172 source "drivers/gpu/drm/vmwgfx/Kconfig"
171173
172174 source "drivers/gpu/drm/gma500/Kconfig"
@@ -200,3 +202,7 @@ source "drivers/gpu/drm/tegra/Kconfig" · 27 unmodified lines
200202 source "drivers/gpu/drm/panel/Kconfig"
201203
202204 source "drivers/gpu/drm/sti/Kconfig"
205+
206+source "drivers/gpu/drm/amd/amdkfd/Kconfig"
207+
208+source "drivers/gpu/drm/imx/Kconfig"
drivers/gpu/drm/Makefile+5−2
@@ -14,7 +14,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ · 13 unmodified lines
1414 drm_info.o drm_debugfs.o drm_encoder_slave.o \
1515 drm_trace_points.o drm_global.o drm_prime.o \
1616 drm_rect.o drm_vma_manager.o drm_flip_work.o \
17− drm_modeset_lock.o
17+ drm_modeset_lock.o drm_atomic.o
1818
1919 drm-$(CONFIG_COMPAT) += drm_ioc32.o
2020 drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
@@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o · 2 unmodified lines
2323 drm-$(CONFIG_OF) += drm_of.o
2424
2525 drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
26− drm_plane_helper.o drm_dp_mst_topology.o
26+ drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
2727 drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
2828 drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
2929 drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
@@ -49,6 +49,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ · 19 unmodified lines
4949 obj-$(CONFIG_DRM_VIA) +=via/
5050 obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
5151 obj-$(CONFIG_DRM_EXYNOS) +=exynos/
52+obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
5253 obj-$(CONFIG_DRM_GMA500) += gma500/
5354 obj-$(CONFIG_DRM_UDL) += udl/
5455 obj-$(CONFIG_DRM_AST) += ast/
@@ -62,6 +63,8 @@ obj-$(CONFIG_DRM_BOCHS) += bochs/ · 7 unmodified lines
6263 obj-$(CONFIG_DRM_MSM) += msm/
6364 obj-$(CONFIG_DRM_TEGRA) += tegra/
6465 obj-$(CONFIG_DRM_STI) += sti/
66+obj-$(CONFIG_DRM_IMX) += imx/
6567 obj-y += i2c/
6668 obj-y += panel/
6769 obj-y += bridge/
70+obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
drivers/gpu/drm/README.drm+0−43
@@ -1,43 +0,0 @@
1−************************************************************
2−* For the very latest on DRI development, please see: *
3−* http://dri.freedesktop.org/ *
4−************************************************************
5−
6−The Direct Rendering Manager (drm) is a device-independent kernel-level
7−device driver that provides support for the XFree86 Direct Rendering
8−Infrastructure (DRI).
9−
10−The DRM supports the Direct Rendering Infrastructure (DRI) in four major
11−ways:
12−
13− 1. The DRM provides synchronized access to the graphics hardware via
14− the use of an optimized two-tiered lock.
15−
16− 2. The DRM enforces the DRI security policy for access to the graphics
17− hardware by only allowing authenticated X11 clients access to
18− restricted regions of memory.
19−
20− 3. The DRM provides a generic DMA engine, complete with multiple
21− queues and the ability to detect the need for an OpenGL context
22− switch.
23−
24− 4. The DRM is extensible via the use of small device-specific modules
25− that rely extensively on the API exported by the DRM module.
26−
27−
28−Documentation on the DRI is available from:
29− http://dri.freedesktop.org/wiki/Documentation
30− http://sourceforge.net/project/showfiles.php?group_id=387
31− http://dri.sourceforge.net/doc/
32−
33−For specific information about kernel-level support, see:
34−
35− The Direct Rendering Manager, Kernel Support for the Direct Rendering
36− Infrastructure
37− http://dri.sourceforge.net/doc/drm_low_level.html
38−
39− Hardware Locking for the Direct Rendering Infrastructure
40− http://dri.sourceforge.net/doc/hardware_locking_low_level.html
41−
42− A Security Analysis of the Direct Rendering Infrastructure
43− http://dri.sourceforge.net/doc/security_low_level.html
drivers/gpu/drm/amd/amdkfd/Kconfig+9−0
@@ -0,0 +1,9 @@
1+#
2+# Heterogenous system architecture configuration
3+#
4+
5+config HSA_AMD
6+ tristate "HSA kernel driver for AMD GPU devices"
7+ depends on DRM_RADEON && AMD_IOMMU_V2 && X86_64
8+ help
9+ Enable this if you want to use HSA features on AMD GPU devices.
drivers/gpu/drm/amd/amdkfd/Makefile+14−0
@@ -0,0 +1,14 @@
1+#
2+# Makefile for Heterogenous System Architecture support for AMD GPU devices
3+#
4+
5+ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/
6+
7+amdkfd-y := kfd_module.o kfd_device.o kfd_chardev.o kfd_topology.o \
8+ kfd_pasid.o kfd_doorbell.o kfd_flat_memory.o \
9+ kfd_process.o kfd_queue.o kfd_mqd_manager.o \
10+ kfd_kernel_queue.o kfd_packet_manager.o \
11+ kfd_process_queue_manager.o kfd_device_queue_manager.o \
12+ kfd_interrupt.o
13+
14+obj-$(CONFIG_HSA_AMD) += amdkfd.o
drivers/gpu/drm/amd/amdkfd/cik_regs.h+221−0
@@ -0,0 +1,221 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#ifndef CIK_REGS_H
24+#define CIK_REGS_H
25+
26+#define IH_VMID_0_LUT 0x3D40u
27+
28+#define BIF_DOORBELL_CNTL 0x530Cu
29+
30+#define SRBM_GFX_CNTL 0xE44
31+#define PIPEID(x) ((x) << 0)
32+#define MEID(x) ((x) << 2)
33+#define VMID(x) ((x) << 4)
34+#define QUEUEID(x) ((x) << 8)
35+
36+#define SQ_CONFIG 0x8C00
37+
38+#define SH_MEM_BASES 0x8C28
39+/* if PTR32, these are the bases for scratch and lds */
40+#define PRIVATE_BASE(x) ((x) << 0) /* scratch */
41+#define SHARED_BASE(x) ((x) << 16) /* LDS */
42+#define SH_MEM_APE1_BASE 0x8C2C
43+/* if PTR32, this is the base location of GPUVM */
44+#define SH_MEM_APE1_LIMIT 0x8C30
45+/* if PTR32, this is the upper limit of GPUVM */
46+#define SH_MEM_CONFIG 0x8C34
47+#define PTR32 (1 << 0)
48+#define PRIVATE_ATC (1 << 1)
49+#define ALIGNMENT_MODE(x) ((x) << 2)
50+#define SH_MEM_ALIGNMENT_MODE_DWORD 0
51+#define SH_MEM_ALIGNMENT_MODE_DWORD_STRICT 1
52+#define SH_MEM_ALIGNMENT_MODE_STRICT 2
53+#define SH_MEM_ALIGNMENT_MODE_UNALIGNED 3
54+#define DEFAULT_MTYPE(x) ((x) << 4)
55+#define APE1_MTYPE(x) ((x) << 7)
56+
57+/* valid for both DEFAULT_MTYPE and APE1_MTYPE */
58+#define MTYPE_CACHED 0
59+#define MTYPE_NONCACHED 3
60+
61+
62+#define SH_STATIC_MEM_CONFIG 0x9604u
63+
64+#define TC_CFG_L1_LOAD_POLICY0 0xAC68
65+#define TC_CFG_L1_LOAD_POLICY1 0xAC6C
66+#define TC_CFG_L1_STORE_POLICY 0xAC70
67+#define TC_CFG_L2_LOAD_POLICY0 0xAC74
68+#define TC_CFG_L2_LOAD_POLICY1 0xAC78
69+#define TC_CFG_L2_STORE_POLICY0 0xAC7C
70+#define TC_CFG_L2_STORE_POLICY1 0xAC80
71+#define TC_CFG_L2_ATOMIC_POLICY 0xAC84
72+#define TC_CFG_L1_VOLATILE 0xAC88
73+#define TC_CFG_L2_VOLATILE 0xAC8C
74+
75+#define CP_PQ_WPTR_POLL_CNTL 0xC20C
76+#define WPTR_POLL_EN (1 << 31)
77+
78+#define CPC_INT_CNTL 0xC2D0
79+#define CP_ME1_PIPE0_INT_CNTL 0xC214
80+#define CP_ME1_PIPE1_INT_CNTL 0xC218
81+#define CP_ME1_PIPE2_INT_CNTL 0xC21C
82+#define CP_ME1_PIPE3_INT_CNTL 0xC220
83+#define CP_ME2_PIPE0_INT_CNTL 0xC224
84+#define CP_ME2_PIPE1_INT_CNTL 0xC228
85+#define CP_ME2_PIPE2_INT_CNTL 0xC22C
86+#define CP_ME2_PIPE3_INT_CNTL 0xC230
87+#define DEQUEUE_REQUEST_INT_ENABLE (1 << 13)
88+#define WRM_POLL_TIMEOUT_INT_ENABLE (1 << 17)
89+#define PRIV_REG_INT_ENABLE (1 << 23)
90+#define TIME_STAMP_INT_ENABLE (1 << 26)
91+#define GENERIC2_INT_ENABLE (1 << 29)
92+#define GENERIC1_INT_ENABLE (1 << 30)
93+#define GENERIC0_INT_ENABLE (1 << 31)
94+#define CP_ME1_PIPE0_INT_STATUS 0xC214
95+#define CP_ME1_PIPE1_INT_STATUS 0xC218
96+#define CP_ME1_PIPE2_INT_STATUS 0xC21C
97+#define CP_ME1_PIPE3_INT_STATUS 0xC220
98+#define CP_ME2_PIPE0_INT_STATUS 0xC224
99+#define CP_ME2_PIPE1_INT_STATUS 0xC228
100+#define CP_ME2_PIPE2_INT_STATUS 0xC22C
101+#define CP_ME2_PIPE3_INT_STATUS 0xC230
102+#define DEQUEUE_REQUEST_INT_STATUS (1 << 13)
103+#define WRM_POLL_TIMEOUT_INT_STATUS (1 << 17)
104+#define PRIV_REG_INT_STATUS (1 << 23)
105+#define TIME_STAMP_INT_STATUS (1 << 26)
106+#define GENERIC2_INT_STATUS (1 << 29)
107+#define GENERIC1_INT_STATUS (1 << 30)
108+#define GENERIC0_INT_STATUS (1 << 31)
109+
110+#define CP_HPD_EOP_BASE_ADDR 0xC904
111+#define CP_HPD_EOP_BASE_ADDR_HI 0xC908
112+#define CP_HPD_EOP_VMID 0xC90C
113+#define CP_HPD_EOP_CONTROL 0xC910
114+#define EOP_SIZE(x) ((x) << 0)
115+#define EOP_SIZE_MASK (0x3f << 0)
116+#define CP_MQD_BASE_ADDR 0xC914
117+#define CP_MQD_BASE_ADDR_HI 0xC918
118+#define CP_HQD_ACTIVE 0xC91C
119+#define CP_HQD_VMID 0xC920
120+
121+#define CP_HQD_PERSISTENT_STATE 0xC924u
122+#define DEFAULT_CP_HQD_PERSISTENT_STATE (0x33U << 8)
123+#define PRELOAD_REQ (1 << 0)
124+
125+#define CP_HQD_PIPE_PRIORITY 0xC928u
126+#define CP_HQD_QUEUE_PRIORITY 0xC92Cu
127+#define CP_HQD_QUANTUM 0xC930u
128+#define QUANTUM_EN 1U
129+#define QUANTUM_SCALE_1MS (1U << 4)
130+#define QUANTUM_DURATION(x) ((x) << 8)
131+
132+#define CP_HQD_PQ_BASE 0xC934
133+#define CP_HQD_PQ_BASE_HI 0xC938
134+#define CP_HQD_PQ_RPTR 0xC93C
135+#define CP_HQD_PQ_RPTR_REPORT_ADDR 0xC940
136+#define CP_HQD_PQ_RPTR_REPORT_ADDR_HI 0xC944
137+#define CP_HQD_PQ_WPTR_POLL_ADDR 0xC948
138+#define CP_HQD_PQ_WPTR_POLL_ADDR_HI 0xC94C
139+#define CP_HQD_PQ_DOORBELL_CONTROL 0xC950
140+#define DOORBELL_OFFSET(x) ((x) << 2)
141+#define DOORBELL_OFFSET_MASK (0x1fffff << 2)
142+#define DOORBELL_SOURCE (1 << 28)
143+#define DOORBELL_SCHD_HIT (1 << 29)
144+#define DOORBELL_EN (1 << 30)
145+#define DOORBELL_HIT (1 << 31)
146+#define CP_HQD_PQ_WPTR 0xC954
147+#define CP_HQD_PQ_CONTROL 0xC958
148+#define QUEUE_SIZE(x) ((x) << 0)
149+#define QUEUE_SIZE_MASK (0x3f << 0)
150+#define RPTR_BLOCK_SIZE(x) ((x) << 8)
151+#define RPTR_BLOCK_SIZE_MASK (0x3f << 8)
152+#define MIN_AVAIL_SIZE(x) ((x) << 20)
153+#define PQ_ATC_EN (1 << 23)
154+#define PQ_VOLATILE (1 << 26)
155+#define NO_UPDATE_RPTR (1 << 27)
156+#define UNORD_DISPATCH (1 << 28)
157+#define ROQ_PQ_IB_FLIP (1 << 29)
158+#define PRIV_STATE (1 << 30)
159+#define KMD_QUEUE (1 << 31)
160+
161+#define DEFAULT_RPTR_BLOCK_SIZE RPTR_BLOCK_SIZE(5)
162+#define DEFAULT_MIN_AVAIL_SIZE MIN_AVAIL_SIZE(3)
163+
164+#define CP_HQD_IB_BASE_ADDR 0xC95Cu
165+#define CP_HQD_IB_BASE_ADDR_HI 0xC960u
166+#define CP_HQD_IB_RPTR 0xC964u
167+#define CP_HQD_IB_CONTROL 0xC968u
168+#define IB_ATC_EN (1U << 23)
169+#define DEFAULT_MIN_IB_AVAIL_SIZE (3U << 20)
170+
171+#define CP_HQD_DEQUEUE_REQUEST 0xC974
172+#define DEQUEUE_REQUEST_DRAIN 1
173+#define DEQUEUE_REQUEST_RESET 2
174+#define DEQUEUE_INT (1U << 8)
175+
176+#define CP_HQD_SEMA_CMD 0xC97Cu
177+#define CP_HQD_MSG_TYPE 0xC980u
178+#define CP_HQD_ATOMIC0_PREOP_LO 0xC984u
179+#define CP_HQD_ATOMIC0_PREOP_HI 0xC988u
180+#define CP_HQD_ATOMIC1_PREOP_LO 0xC98Cu
181+#define CP_HQD_ATOMIC1_PREOP_HI 0xC990u
182+#define CP_HQD_HQ_SCHEDULER0 0xC994u
183+#define CP_HQD_HQ_SCHEDULER1 0xC998u
184+
185+
186+#define CP_MQD_CONTROL 0xC99C
187+#define MQD_VMID(x) ((x) << 0)
188+#define MQD_VMID_MASK (0xf << 0)
189+#define MQD_CONTROL_PRIV_STATE_EN (1U << 8)
190+
191+#define GRBM_GFX_INDEX 0x30800
192+#define INSTANCE_INDEX(x) ((x) << 0)
193+#define SH_INDEX(x) ((x) << 8)
194+#define SE_INDEX(x) ((x) << 16)
195+#define SH_BROADCAST_WRITES (1 << 29)
196+#define INSTANCE_BROADCAST_WRITES (1 << 30)
197+#define SE_BROADCAST_WRITES (1 << 31)
198+
199+#define SQC_CACHES 0x30d20
200+#define SQC_POLICY 0x8C38u
201+#define SQC_VOLATILE 0x8C3Cu
202+
203+#define CP_PERFMON_CNTL 0x36020
204+
205+#define ATC_VMID0_PASID_MAPPING 0x339Cu
206+#define ATC_VMID_PASID_MAPPING_UPDATE_STATUS 0x3398u
207+#define ATC_VMID_PASID_MAPPING_VALID (1U << 31)
208+
209+#define ATC_VM_APERTURE0_CNTL 0x3310u
210+#define ATS_ACCESS_MODE_NEVER 0
211+#define ATS_ACCESS_MODE_ALWAYS 1
212+
213+#define ATC_VM_APERTURE0_CNTL2 0x3318u
214+#define ATC_VM_APERTURE0_HIGH_ADDR 0x3308u
215+#define ATC_VM_APERTURE0_LOW_ADDR 0x3300u
216+#define ATC_VM_APERTURE1_CNTL 0x3314u
217+#define ATC_VM_APERTURE1_CNTL2 0x331Cu
218+#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu
219+#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u
220+
221+#endif
drivers/gpu/drm/amd/amdkfd/kfd_chardev.c+595−0
@@ -0,0 +1,595 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/device.h>
24+#include <linux/export.h>
25+#include <linux/err.h>
26+#include <linux/fs.h>
27+#include <linux/sched.h>
28+#include <linux/slab.h>
29+#include <linux/uaccess.h>
30+#include <linux/compat.h>
31+#include <uapi/linux/kfd_ioctl.h>
32+#include <linux/time.h>
33+#include <linux/mm.h>
34+#include <linux/uaccess.h>
35+#include <uapi/asm-generic/mman-common.h>
36+#include <asm/processor.h>
37+#include "kfd_priv.h"
38+#include "kfd_device_queue_manager.h"
39+
40+static long kfd_ioctl(struct file *, unsigned int, unsigned long);
41+static int kfd_open(struct inode *, struct file *);
42+static int kfd_mmap(struct file *, struct vm_area_struct *);
43+
44+static const char kfd_dev_name[] = "kfd";
45+
46+static const struct file_operations kfd_fops = {
47+ .owner = THIS_MODULE,
48+ .unlocked_ioctl = kfd_ioctl,
49+ .compat_ioctl = kfd_ioctl,
50+ .open = kfd_open,
51+ .mmap = kfd_mmap,
52+};
53+
54+static int kfd_char_dev_major = -1;
55+static struct class *kfd_class;
56+struct device *kfd_device;
57+
58+int kfd_chardev_init(void)
59+{
60+ int err = 0;
61+
62+ kfd_char_dev_major = register_chrdev(0, kfd_dev_name, &kfd_fops);
63+ err = kfd_char_dev_major;
64+ if (err < 0)
65+ goto err_register_chrdev;
66+
67+ kfd_class = class_create(THIS_MODULE, kfd_dev_name);
68+ err = PTR_ERR(kfd_class);
69+ if (IS_ERR(kfd_class))
70+ goto err_class_create;
71+
72+ kfd_device = device_create(kfd_class, NULL,
73+ MKDEV(kfd_char_dev_major, 0),
74+ NULL, kfd_dev_name);
75+ err = PTR_ERR(kfd_device);
76+ if (IS_ERR(kfd_device))
77+ goto err_device_create;
78+
79+ return 0;
80+
81+err_device_create:
82+ class_destroy(kfd_class);
83+err_class_create:
84+ unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
85+err_register_chrdev:
86+ return err;
87+}
88+
89+void kfd_chardev_exit(void)
90+{
91+ device_destroy(kfd_class, MKDEV(kfd_char_dev_major, 0));
92+ class_destroy(kfd_class);
93+ unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
94+}
95+
96+struct device *kfd_chardev(void)
97+{
98+ return kfd_device;
99+}
100+
101+
102+static int kfd_open(struct inode *inode, struct file *filep)
103+{
104+ struct kfd_process *process;
105+ bool is_32bit_user_mode;
106+
107+ if (iminor(inode) != 0)
108+ return -ENODEV;
109+
110+ is_32bit_user_mode = is_compat_task();
111+
112+ if (is_32bit_user_mode == true) {
113+ dev_warn(kfd_device,
114+ "Process %d (32-bit) failed to open /dev/kfd\n"
115+ "32-bit processes are not supported by amdkfd\n",
116+ current->pid);
117+ return -EPERM;
118+ }
119+
120+ process = kfd_create_process(current);
121+ if (IS_ERR(process))
122+ return PTR_ERR(process);
123+
124+ process->is_32bit_user_mode = is_32bit_user_mode;
125+
126+ dev_dbg(kfd_device, "process %d opened, compat mode (32 bit) - %d\n",
127+ process->pasid, process->is_32bit_user_mode);
128+
129+ kfd_init_apertures(process);
130+
131+ return 0;
132+}
133+
134+static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
135+ void __user *arg)
136+{
137+ struct kfd_ioctl_get_version_args args;
138+ int err = 0;
139+
140+ args.major_version = KFD_IOCTL_MAJOR_VERSION;
141+ args.minor_version = KFD_IOCTL_MINOR_VERSION;
142+
143+ if (copy_to_user(arg, &args, sizeof(args)))
144+ err = -EFAULT;
145+
146+ return err;
147+}
148+
149+static int set_queue_properties_from_user(struct queue_properties *q_properties,
150+ struct kfd_ioctl_create_queue_args *args)
151+{
152+ if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
153+ pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
154+ return -EINVAL;
155+ }
156+
157+ if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
158+ pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
159+ return -EINVAL;
160+ }
161+
162+ if ((args->ring_base_address) &&
163+ (!access_ok(VERIFY_WRITE,
164+ (const void __user *) args->ring_base_address,
165+ sizeof(uint64_t)))) {
166+ pr_err("kfd: can't access ring base address\n");
167+ return -EFAULT;
168+ }
169+
170+ if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
171+ pr_err("kfd: ring size must be a power of 2 or 0\n");
172+ return -EINVAL;
173+ }
174+
175+ if (!access_ok(VERIFY_WRITE,
176+ (const void __user *) args->read_pointer_address,
177+ sizeof(uint32_t))) {
178+ pr_err("kfd: can't access read pointer\n");
179+ return -EFAULT;
180+ }
181+
182+ if (!access_ok(VERIFY_WRITE,
183+ (const void __user *) args->write_pointer_address,
184+ sizeof(uint32_t))) {
185+ pr_err("kfd: can't access write pointer\n");
186+ return -EFAULT;
187+ }
188+
189+ q_properties->is_interop = false;
190+ q_properties->queue_percent = args->queue_percentage;
191+ q_properties->priority = args->queue_priority;
192+ q_properties->queue_address = args->ring_base_address;
193+ q_properties->queue_size = args->ring_size;
194+ q_properties->read_ptr = (uint32_t *) args->read_pointer_address;
195+ q_properties->write_ptr = (uint32_t *) args->write_pointer_address;
196+ if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE ||
197+ args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
198+ q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
199+ else
200+ return -ENOTSUPP;
201+
202+ if (args->queue_type == KFD_IOC_QUEUE_TYPE_COMPUTE_AQL)
203+ q_properties->format = KFD_QUEUE_FORMAT_AQL;
204+ else
205+ q_properties->format = KFD_QUEUE_FORMAT_PM4;
206+
207+ pr_debug("Queue Percentage (%d, %d)\n",
208+ q_properties->queue_percent, args->queue_percentage);
209+
210+ pr_debug("Queue Priority (%d, %d)\n",
211+ q_properties->priority, args->queue_priority);
212+
213+ pr_debug("Queue Address (0x%llX, 0x%llX)\n",
214+ q_properties->queue_address, args->ring_base_address);
215+
216+ pr_debug("Queue Size (0x%llX, %u)\n",
217+ q_properties->queue_size, args->ring_size);
218+
219+ pr_debug("Queue r/w Pointers (0x%llX, 0x%llX)\n",
220+ (uint64_t) q_properties->read_ptr,
221+ (uint64_t) q_properties->write_ptr);
222+
223+ pr_debug("Queue Format (%d)\n", q_properties->format);
224+
225+ return 0;
226+}
227+
228+static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
229+ void __user *arg)
230+{
231+ struct kfd_ioctl_create_queue_args args;
232+ struct kfd_dev *dev;
233+ int err = 0;
234+ unsigned int queue_id;
235+ struct kfd_process_device *pdd;
236+ struct queue_properties q_properties;
237+
238+ memset(&q_properties, 0, sizeof(struct queue_properties));
239+
240+ if (copy_from_user(&args, arg, sizeof(args)))
241+ return -EFAULT;
242+
243+ pr_debug("kfd: creating queue ioctl\n");
244+
245+ err = set_queue_properties_from_user(&q_properties, &args);
246+ if (err)
247+ return err;
248+
249+ dev = kfd_device_by_id(args.gpu_id);
250+ if (dev == NULL)
251+ return -EINVAL;
252+
253+ mutex_lock(&p->mutex);
254+
255+ pdd = kfd_bind_process_to_device(dev, p);
256+ if (IS_ERR(pdd)) {
257+ err = PTR_ERR(pdd);
258+ goto err_bind_process;
259+ }
260+
261+ pr_debug("kfd: creating queue for PASID %d on GPU 0x%x\n",
262+ p->pasid,
263+ dev->id);
264+
265+ err = pqm_create_queue(&p->pqm, dev, filep, &q_properties, 0,
266+ KFD_QUEUE_TYPE_COMPUTE, &queue_id);
267+ if (err != 0)
268+ goto err_create_queue;
269+
270+ args.queue_id = queue_id;
271+
272+ /* Return gpu_id as doorbell offset for mmap usage */
273+ args.doorbell_offset = args.gpu_id << PAGE_SHIFT;
274+
275+ if (copy_to_user(arg, &args, sizeof(args))) {
276+ err = -EFAULT;
277+ goto err_copy_args_out;
278+ }
279+
280+ mutex_unlock(&p->mutex);
281+
282+ pr_debug("kfd: queue id %d was created successfully\n", args.queue_id);
283+
284+ pr_debug("ring buffer address == 0x%016llX\n",
285+ args.ring_base_address);
286+
287+ pr_debug("read ptr address == 0x%016llX\n",
288+ args.read_pointer_address);
289+
290+ pr_debug("write ptr address == 0x%016llX\n",
291+ args.write_pointer_address);
292+
293+ return 0;
294+
295+err_copy_args_out:
296+ pqm_destroy_queue(&p->pqm, queue_id);
297+err_create_queue:
298+err_bind_process:
299+ mutex_unlock(&p->mutex);
300+ return err;
301+}
302+
303+static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
304+ void __user *arg)
305+{
306+ int retval;
307+ struct kfd_ioctl_destroy_queue_args args;
308+
309+ if (copy_from_user(&args, arg, sizeof(args)))
310+ return -EFAULT;
311+
312+ pr_debug("kfd: destroying queue id %d for PASID %d\n",
313+ args.queue_id,
314+ p->pasid);
315+
316+ mutex_lock(&p->mutex);
317+
318+ retval = pqm_destroy_queue(&p->pqm, args.queue_id);
319+
320+ mutex_unlock(&p->mutex);
321+ return retval;
322+}
323+
324+static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
325+ void __user *arg)
326+{
327+ int retval;
328+ struct kfd_ioctl_update_queue_args args;
329+ struct queue_properties properties;
330+
331+ if (copy_from_user(&args, arg, sizeof(args)))
332+ return -EFAULT;
333+
334+ if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
335+ pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
336+ return -EINVAL;
337+ }
338+
339+ if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) {
340+ pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
341+ return -EINVAL;
342+ }
343+
344+ if ((args.ring_base_address) &&
345+ (!access_ok(VERIFY_WRITE,
346+ (const void __user *) args.ring_base_address,
347+ sizeof(uint64_t)))) {
348+ pr_err("kfd: can't access ring base address\n");
349+ return -EFAULT;
350+ }
351+
352+ if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) {
353+ pr_err("kfd: ring size must be a power of 2 or 0\n");
354+ return -EINVAL;
355+ }
356+
357+ properties.queue_address = args.ring_base_address;
358+ properties.queue_size = args.ring_size;
359+ properties.queue_percent = args.queue_percentage;
360+ properties.priority = args.queue_priority;
361+
362+ pr_debug("kfd: updating queue id %d for PASID %d\n",
363+ args.queue_id, p->pasid);
364+
365+ mutex_lock(&p->mutex);
366+
367+ retval = pqm_update_queue(&p->pqm, args.queue_id, &properties);
368+
369+ mutex_unlock(&p->mutex);
370+
371+ return retval;
372+}
373+
374+static long kfd_ioctl_set_memory_policy(struct file *filep,
375+ struct kfd_process *p, void __user *arg)
376+{
377+ struct kfd_ioctl_set_memory_policy_args args;
378+ struct kfd_dev *dev;
379+ int err = 0;
380+ struct kfd_process_device *pdd;
381+ enum cache_policy default_policy, alternate_policy;
382+
383+ if (copy_from_user(&args, arg, sizeof(args)))
384+ return -EFAULT;
385+
386+ if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
387+ && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
388+ return -EINVAL;
389+ }
390+
391+ if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
392+ && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
393+ return -EINVAL;
394+ }
395+
396+ dev = kfd_device_by_id(args.gpu_id);
397+ if (dev == NULL)
398+ return -EINVAL;
399+
400+ mutex_lock(&p->mutex);
401+
402+ pdd = kfd_bind_process_to_device(dev, p);
403+ if (IS_ERR(pdd)) {
404+ err = PTR_ERR(pdd);
405+ goto out;
406+ }
407+
408+ default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
409+ ? cache_policy_coherent : cache_policy_noncoherent;
410+
411+ alternate_policy =
412+ (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
413+ ? cache_policy_coherent : cache_policy_noncoherent;
414+
415+ if (!dev->dqm->set_cache_memory_policy(dev->dqm,
416+ &pdd->qpd,
417+ default_policy,
418+ alternate_policy,
419+ (void __user *)args.alternate_aperture_base,
420+ args.alternate_aperture_size))
421+ err = -EINVAL;
422+
423+out:
424+ mutex_unlock(&p->mutex);
425+
426+ return err;
427+}
428+
429+static long kfd_ioctl_get_clock_counters(struct file *filep,
430+ struct kfd_process *p, void __user *arg)
431+{
432+ struct kfd_ioctl_get_clock_counters_args args;
433+ struct kfd_dev *dev;
434+ struct timespec time;
435+
436+ if (copy_from_user(&args, arg, sizeof(args)))
437+ return -EFAULT;
438+
439+ dev = kfd_device_by_id(args.gpu_id);
440+ if (dev == NULL)
441+ return -EINVAL;
442+
443+ /* Reading GPU clock counter from KGD */
444+ args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
445+
446+ /* No access to rdtsc. Using raw monotonic time */
447+ getrawmonotonic(&time);
448+ args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
449+
450+ get_monotonic_boottime(&time);
451+ args.system_clock_counter = (uint64_t)timespec_to_ns(&time);
452+
453+ /* Since the counter is in nano-seconds we use 1GHz frequency */
454+ args.system_clock_freq = 1000000000;
455+
456+ if (copy_to_user(arg, &args, sizeof(args)))
457+ return -EFAULT;
458+
459+ return 0;
460+}
461+
462+
463+static int kfd_ioctl_get_process_apertures(struct file *filp,
464+ struct kfd_process *p, void __user *arg)
465+{
466+ struct kfd_ioctl_get_process_apertures_args args;
467+ struct kfd_process_device_apertures *pAperture;
468+ struct kfd_process_device *pdd;
469+
470+ dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
471+
472+ if (copy_from_user(&args, arg, sizeof(args)))
473+ return -EFAULT;
474+
475+ args.num_of_nodes = 0;
476+
477+ mutex_lock(&p->mutex);
478+
479+ /*if the process-device list isn't empty*/
480+ if (kfd_has_process_device_data(p)) {
481+ /* Run over all pdd of the process */
482+ pdd = kfd_get_first_process_device_data(p);
483+ do {
484+ pAperture = &args.process_apertures[args.num_of_nodes];
485+ pAperture->gpu_id = pdd->dev->id;
486+ pAperture->lds_base = pdd->lds_base;
487+ pAperture->lds_limit = pdd->lds_limit;
488+ pAperture->gpuvm_base = pdd->gpuvm_base;
489+ pAperture->gpuvm_limit = pdd->gpuvm_limit;
490+ pAperture->scratch_base = pdd->scratch_base;
491+ pAperture->scratch_limit = pdd->scratch_limit;
492+
493+ dev_dbg(kfd_device,
494+ "node id %u\n", args.num_of_nodes);
495+ dev_dbg(kfd_device,
496+ "gpu id %u\n", pdd->dev->id);
497+ dev_dbg(kfd_device,
498+ "lds_base %llX\n", pdd->lds_base);
499+ dev_dbg(kfd_device,
500+ "lds_limit %llX\n", pdd->lds_limit);
501+ dev_dbg(kfd_device,
502+ "gpuvm_base %llX\n", pdd->gpuvm_base);
503+ dev_dbg(kfd_device,
504+ "gpuvm_limit %llX\n", pdd->gpuvm_limit);
505+ dev_dbg(kfd_device,
506+ "scratch_base %llX\n", pdd->scratch_base);
507+ dev_dbg(kfd_device,
508+ "scratch_limit %llX\n", pdd->scratch_limit);
509+
510+ args.num_of_nodes++;
511+ } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
512+ (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS));
513+ }
514+
515+ mutex_unlock(&p->mutex);
516+
517+ if (copy_to_user(arg, &args, sizeof(args)))
518+ return -EFAULT;
519+
520+ return 0;
521+}
522+
523+static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
524+{
525+ struct kfd_process *process;
526+ long err = -EINVAL;
527+
528+ dev_dbg(kfd_device,
529+ "ioctl cmd 0x%x (#%d), arg 0x%lx\n",
530+ cmd, _IOC_NR(cmd), arg);
531+
532+ process = kfd_get_process(current);
533+ if (IS_ERR(process))
534+ return PTR_ERR(process);
535+
536+ switch (cmd) {
537+ case KFD_IOC_GET_VERSION:
538+ err = kfd_ioctl_get_version(filep, process, (void __user *)arg);
539+ break;
540+ case KFD_IOC_CREATE_QUEUE:
541+ err = kfd_ioctl_create_queue(filep, process,
542+ (void __user *)arg);
543+ break;
544+
545+ case KFD_IOC_DESTROY_QUEUE:
546+ err = kfd_ioctl_destroy_queue(filep, process,
547+ (void __user *)arg);
548+ break;
549+
550+ case KFD_IOC_SET_MEMORY_POLICY:
551+ err = kfd_ioctl_set_memory_policy(filep, process,
552+ (void __user *)arg);
553+ break;
554+
555+ case KFD_IOC_GET_CLOCK_COUNTERS:
556+ err = kfd_ioctl_get_clock_counters(filep, process,
557+ (void __user *)arg);
558+ break;
559+
560+ case KFD_IOC_GET_PROCESS_APERTURES:
561+ err = kfd_ioctl_get_process_apertures(filep, process,
562+ (void __user *)arg);
563+ break;
564+
565+ case KFD_IOC_UPDATE_QUEUE:
566+ err = kfd_ioctl_update_queue(filep, process,
567+ (void __user *)arg);
568+ break;
569+
570+ default:
571+ dev_err(kfd_device,
572+ "unknown ioctl cmd 0x%x, arg 0x%lx)\n",
573+ cmd, arg);
574+ err = -EINVAL;
575+ break;
576+ }
577+
578+ if (err < 0)
579+ dev_err(kfd_device,
580+ "ioctl error %ld for ioctl cmd 0x%x (#%d)\n",
581+ err, cmd, _IOC_NR(cmd));
582+
583+ return err;
584+}
585+
586+static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
587+{
588+ struct kfd_process *process;
589+
590+ process = kfd_get_process(current);
591+ if (IS_ERR(process))
592+ return PTR_ERR(process);
593+
594+ return kfd_doorbell_mmap(process, vma);
595+}
drivers/gpu/drm/amd/amdkfd/kfd_crat.h+294−0
@@ -0,0 +1,294 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#ifndef KFD_CRAT_H_INCLUDED
24+#define KFD_CRAT_H_INCLUDED
25+
26+#include <linux/types.h>
27+
28+#pragma pack(1)
29+
30+/*
31+ * 4CC signature values for the CRAT and CDIT ACPI tables
32+ */
33+
34+#define CRAT_SIGNATURE "CRAT"
35+#define CDIT_SIGNATURE "CDIT"
36+
37+/*
38+ * Component Resource Association Table (CRAT)
39+ */
40+
41+#define CRAT_OEMID_LENGTH 6
42+#define CRAT_OEMTABLEID_LENGTH 8
43+#define CRAT_RESERVED_LENGTH 6
44+
45+#define CRAT_OEMID_64BIT_MASK ((1ULL << (CRAT_OEMID_LENGTH * 8)) - 1)
46+
47+struct crat_header {
48+ uint32_t signature;
49+ uint32_t length;
50+ uint8_t revision;
51+ uint8_t checksum;
52+ uint8_t oem_id[CRAT_OEMID_LENGTH];
53+ uint8_t oem_table_id[CRAT_OEMTABLEID_LENGTH];
54+ uint32_t oem_revision;
55+ uint32_t creator_id;
56+ uint32_t creator_revision;
57+ uint32_t total_entries;
58+ uint16_t num_domains;
59+ uint8_t reserved[CRAT_RESERVED_LENGTH];
60+};
61+
62+/*
63+ * The header structure is immediately followed by total_entries of the
64+ * data definitions
65+ */
66+
67+/*
68+ * The currently defined subtype entries in the CRAT
69+ */
70+#define CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY 0
71+#define CRAT_SUBTYPE_MEMORY_AFFINITY 1
72+#define CRAT_SUBTYPE_CACHE_AFFINITY 2
73+#define CRAT_SUBTYPE_TLB_AFFINITY 3
74+#define CRAT_SUBTYPE_CCOMPUTE_AFFINITY 4
75+#define CRAT_SUBTYPE_IOLINK_AFFINITY 5
76+#define CRAT_SUBTYPE_MAX 6
77+
78+#define CRAT_SIBLINGMAP_SIZE 32
79+
80+/*
81+ * ComputeUnit Affinity structure and definitions
82+ */
83+#define CRAT_CU_FLAGS_ENABLED 0x00000001
84+#define CRAT_CU_FLAGS_HOT_PLUGGABLE 0x00000002
85+#define CRAT_CU_FLAGS_CPU_PRESENT 0x00000004
86+#define CRAT_CU_FLAGS_GPU_PRESENT 0x00000008
87+#define CRAT_CU_FLAGS_IOMMU_PRESENT 0x00000010
88+#define CRAT_CU_FLAGS_RESERVED 0xffffffe0
89+
90+#define CRAT_COMPUTEUNIT_RESERVED_LENGTH 4
91+
92+struct crat_subtype_computeunit {
93+ uint8_t type;
94+ uint8_t length;
95+ uint16_t reserved;
96+ uint32_t flags;
97+ uint32_t proximity_domain;
98+ uint32_t processor_id_low;
99+ uint16_t num_cpu_cores;
100+ uint16_t num_simd_cores;
101+ uint16_t max_waves_simd;
102+ uint16_t io_count;
103+ uint16_t hsa_capability;
104+ uint16_t lds_size_in_kb;
105+ uint8_t wave_front_size;
106+ uint8_t num_banks;
107+ uint16_t micro_engine_id;
108+ uint8_t num_arrays;
109+ uint8_t num_cu_per_array;
110+ uint8_t num_simd_per_cu;
111+ uint8_t max_slots_scatch_cu;
112+ uint8_t reserved2[CRAT_COMPUTEUNIT_RESERVED_LENGTH];
113+};
114+
115+/*
116+ * HSA Memory Affinity structure and definitions
117+ */
118+#define CRAT_MEM_FLAGS_ENABLED 0x00000001
119+#define CRAT_MEM_FLAGS_HOT_PLUGGABLE 0x00000002
120+#define CRAT_MEM_FLAGS_NON_VOLATILE 0x00000004
121+#define CRAT_MEM_FLAGS_RESERVED 0xfffffff8
122+
123+#define CRAT_MEMORY_RESERVED_LENGTH 8
124+
125+struct crat_subtype_memory {
126+ uint8_t type;
127+ uint8_t length;
128+ uint16_t reserved;
129+ uint32_t flags;
130+ uint32_t promixity_domain;
131+ uint32_t base_addr_low;
132+ uint32_t base_addr_high;
133+ uint32_t length_low;
134+ uint32_t length_high;
135+ uint32_t width;
136+ uint8_t reserved2[CRAT_MEMORY_RESERVED_LENGTH];
137+};
138+
139+/*
140+ * HSA Cache Affinity structure and definitions
141+ */
142+#define CRAT_CACHE_FLAGS_ENABLED 0x00000001
143+#define CRAT_CACHE_FLAGS_DATA_CACHE 0x00000002
144+#define CRAT_CACHE_FLAGS_INST_CACHE 0x00000004
145+#define CRAT_CACHE_FLAGS_CPU_CACHE 0x00000008
146+#define CRAT_CACHE_FLAGS_SIMD_CACHE 0x00000010
147+#define CRAT_CACHE_FLAGS_RESERVED 0xffffffe0
148+
149+#define CRAT_CACHE_RESERVED_LENGTH 8
150+
151+struct crat_subtype_cache {
152+ uint8_t type;
153+ uint8_t length;
154+ uint16_t reserved;
155+ uint32_t flags;
156+ uint32_t processor_id_low;
157+ uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];
158+ uint32_t cache_size;
159+ uint8_t cache_level;
160+ uint8_t lines_per_tag;
161+ uint16_t cache_line_size;
162+ uint8_t associativity;
163+ uint8_t cache_properties;
164+ uint16_t cache_latency;
165+ uint8_t reserved2[CRAT_CACHE_RESERVED_LENGTH];
166+};
167+
168+/*
169+ * HSA TLB Affinity structure and definitions
170+ */
171+#define CRAT_TLB_FLAGS_ENABLED 0x00000001
172+#define CRAT_TLB_FLAGS_DATA_TLB 0x00000002
173+#define CRAT_TLB_FLAGS_INST_TLB 0x00000004
174+#define CRAT_TLB_FLAGS_CPU_TLB 0x00000008
175+#define CRAT_TLB_FLAGS_SIMD_TLB 0x00000010
176+#define CRAT_TLB_FLAGS_RESERVED 0xffffffe0
177+
178+#define CRAT_TLB_RESERVED_LENGTH 4
179+
180+struct crat_subtype_tlb {
181+ uint8_t type;
182+ uint8_t length;
183+ uint16_t reserved;
184+ uint32_t flags;
185+ uint32_t processor_id_low;
186+ uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];
187+ uint32_t tlb_level;
188+ uint8_t data_tlb_associativity_2mb;
189+ uint8_t data_tlb_size_2mb;
190+ uint8_t instruction_tlb_associativity_2mb;
191+ uint8_t instruction_tlb_size_2mb;
192+ uint8_t data_tlb_associativity_4k;
193+ uint8_t data_tlb_size_4k;
194+ uint8_t instruction_tlb_associativity_4k;
195+ uint8_t instruction_tlb_size_4k;
196+ uint8_t data_tlb_associativity_1gb;
197+ uint8_t data_tlb_size_1gb;
198+ uint8_t instruction_tlb_associativity_1gb;
199+ uint8_t instruction_tlb_size_1gb;
200+ uint8_t reserved2[CRAT_TLB_RESERVED_LENGTH];
201+};
202+
203+/*
204+ * HSA CCompute/APU Affinity structure and definitions
205+ */
206+#define CRAT_CCOMPUTE_FLAGS_ENABLED 0x00000001
207+#define CRAT_CCOMPUTE_FLAGS_RESERVED 0xfffffffe
208+
209+#define CRAT_CCOMPUTE_RESERVED_LENGTH 16
210+
211+struct crat_subtype_ccompute {
212+ uint8_t type;
213+ uint8_t length;
214+ uint16_t reserved;
215+ uint32_t flags;
216+ uint32_t processor_id_low;
217+ uint8_t sibling_map[CRAT_SIBLINGMAP_SIZE];
218+ uint32_t apu_size;
219+ uint8_t reserved2[CRAT_CCOMPUTE_RESERVED_LENGTH];
220+};
221+
222+/*
223+ * HSA IO Link Affinity structure and definitions
224+ */
225+#define CRAT_IOLINK_FLAGS_ENABLED 0x00000001
226+#define CRAT_IOLINK_FLAGS_COHERENCY 0x00000002
227+#define CRAT_IOLINK_FLAGS_RESERVED 0xfffffffc
228+
229+/*
230+ * IO interface types
231+ */
232+#define CRAT_IOLINK_TYPE_UNDEFINED 0
233+#define CRAT_IOLINK_TYPE_HYPERTRANSPORT 1
234+#define CRAT_IOLINK_TYPE_PCIEXPRESS 2
235+#define CRAT_IOLINK_TYPE_OTHER 3
236+#define CRAT_IOLINK_TYPE_MAX 255
237+
238+#define CRAT_IOLINK_RESERVED_LENGTH 24
239+
240+struct crat_subtype_iolink {
241+ uint8_t type;
242+ uint8_t length;
243+ uint16_t reserved;
244+ uint32_t flags;
245+ uint32_t proximity_domain_from;
246+ uint32_t proximity_domain_to;
247+ uint8_t io_interface_type;
248+ uint8_t version_major;
249+ uint16_t version_minor;
250+ uint32_t minimum_latency;
251+ uint32_t maximum_latency;
252+ uint32_t minimum_bandwidth_mbs;
253+ uint32_t maximum_bandwidth_mbs;
254+ uint32_t recommended_transfer_size;
255+ uint8_t reserved2[CRAT_IOLINK_RESERVED_LENGTH];
256+};
257+
258+/*
259+ * HSA generic sub-type header
260+ */
261+
262+#define CRAT_SUBTYPE_FLAGS_ENABLED 0x00000001
263+
264+struct crat_subtype_generic {
265+ uint8_t type;
266+ uint8_t length;
267+ uint16_t reserved;
268+ uint32_t flags;
269+};
270+
271+/*
272+ * Component Locality Distance Information Table (CDIT)
273+ */
274+#define CDIT_OEMID_LENGTH 6
275+#define CDIT_OEMTABLEID_LENGTH 8
276+
277+struct cdit_header {
278+ uint32_t signature;
279+ uint32_t length;
280+ uint8_t revision;
281+ uint8_t checksum;
282+ uint8_t oem_id[CDIT_OEMID_LENGTH];
283+ uint8_t oem_table_id[CDIT_OEMTABLEID_LENGTH];
284+ uint32_t oem_revision;
285+ uint32_t creator_id;
286+ uint32_t creator_revision;
287+ uint32_t total_entries;
288+ uint16_t num_domains;
289+ uint8_t entry[1];
290+};
291+
292+#pragma pack()
293+
294+#endif /* KFD_CRAT_H_INCLUDED */
drivers/gpu/drm/amd/amdkfd/kfd_device.c+308−0
@@ -0,0 +1,308 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/amd-iommu.h>
24+#include <linux/bsearch.h>
25+#include <linux/pci.h>
26+#include <linux/slab.h>
27+#include "kfd_priv.h"
28+#include "kfd_device_queue_manager.h"
29+
30+#define MQD_SIZE_ALIGNED 768
31+
32+static const struct kfd_device_info kaveri_device_info = {
33+ .max_pasid_bits = 16,
34+ .ih_ring_entry_size = 4 * sizeof(uint32_t),
35+ .mqd_size_aligned = MQD_SIZE_ALIGNED
36+};
37+
38+struct kfd_deviceid {
39+ unsigned short did;
40+ const struct kfd_device_info *device_info;
41+};
42+
43+/* Please keep this sorted by increasing device id. */
44+static const struct kfd_deviceid supported_devices[] = {
45+ { 0x1304, &kaveri_device_info }, /* Kaveri */
46+ { 0x1305, &kaveri_device_info }, /* Kaveri */
47+ { 0x1306, &kaveri_device_info }, /* Kaveri */
48+ { 0x1307, &kaveri_device_info }, /* Kaveri */
49+ { 0x1309, &kaveri_device_info }, /* Kaveri */
50+ { 0x130A, &kaveri_device_info }, /* Kaveri */
51+ { 0x130B, &kaveri_device_info }, /* Kaveri */
52+ { 0x130C, &kaveri_device_info }, /* Kaveri */
53+ { 0x130D, &kaveri_device_info }, /* Kaveri */
54+ { 0x130E, &kaveri_device_info }, /* Kaveri */
55+ { 0x130F, &kaveri_device_info }, /* Kaveri */
56+ { 0x1310, &kaveri_device_info }, /* Kaveri */
57+ { 0x1311, &kaveri_device_info }, /* Kaveri */
58+ { 0x1312, &kaveri_device_info }, /* Kaveri */
59+ { 0x1313, &kaveri_device_info }, /* Kaveri */
60+ { 0x1315, &kaveri_device_info }, /* Kaveri */
61+ { 0x1316, &kaveri_device_info }, /* Kaveri */
62+ { 0x1317, &kaveri_device_info }, /* Kaveri */
63+ { 0x1318, &kaveri_device_info }, /* Kaveri */
64+ { 0x131B, &kaveri_device_info }, /* Kaveri */
65+ { 0x131C, &kaveri_device_info }, /* Kaveri */
66+ { 0x131D, &kaveri_device_info }, /* Kaveri */
67+};
68+
69+static const struct kfd_device_info *lookup_device_info(unsigned short did)
70+{
71+ size_t i;
72+
73+ for (i = 0; i < ARRAY_SIZE(supported_devices); i++) {
74+ if (supported_devices[i].did == did) {
75+ BUG_ON(supported_devices[i].device_info == NULL);
76+ return supported_devices[i].device_info;
77+ }
78+ }
79+
80+ return NULL;
81+}
82+
83+struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev)
84+{
85+ struct kfd_dev *kfd;
86+
87+ const struct kfd_device_info *device_info =
88+ lookup_device_info(pdev->device);
89+
90+ if (!device_info)
91+ return NULL;
92+
93+ kfd = kzalloc(sizeof(*kfd), GFP_KERNEL);
94+ if (!kfd)
95+ return NULL;
96+
97+ kfd->kgd = kgd;
98+ kfd->device_info = device_info;
99+ kfd->pdev = pdev;
100+ kfd->init_complete = false;
101+
102+ return kfd;
103+}
104+
105+static bool device_iommu_pasid_init(struct kfd_dev *kfd)
106+{
107+ const u32 required_iommu_flags = AMD_IOMMU_DEVICE_FLAG_ATS_SUP |
108+ AMD_IOMMU_DEVICE_FLAG_PRI_SUP |
109+ AMD_IOMMU_DEVICE_FLAG_PASID_SUP;
110+
111+ struct amd_iommu_device_info iommu_info;
112+ unsigned int pasid_limit;
113+ int err;
114+
115+ err = amd_iommu_device_info(kfd->pdev, &iommu_info);
116+ if (err < 0) {
117+ dev_err(kfd_device,
118+ "error getting iommu info. is the iommu enabled?\n");
119+ return false;
120+ }
121+
122+ if ((iommu_info.flags & required_iommu_flags) != required_iommu_flags) {
123+ dev_err(kfd_device, "error required iommu flags ats(%i), pri(%i), pasid(%i)\n",
124+ (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_ATS_SUP) != 0,
125+ (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PRI_SUP) != 0,
126+ (iommu_info.flags & AMD_IOMMU_DEVICE_FLAG_PASID_SUP) != 0);
127+ return false;
128+ }
129+
130+ pasid_limit = min_t(unsigned int,
131+ (unsigned int)1 << kfd->device_info->max_pasid_bits,
132+ iommu_info.max_pasids);
133+ /*
134+ * last pasid is used for kernel queues doorbells
135+ * in the future the last pasid might be used for a kernel thread.
136+ */
137+ pasid_limit = min_t(unsigned int,
138+ pasid_limit,
139+ kfd->doorbell_process_limit - 1);
140+
141+ err = amd_iommu_init_device(kfd->pdev, pasid_limit);
142+ if (err < 0) {
143+ dev_err(kfd_device, "error initializing iommu device\n");
144+ return false;
145+ }
146+
147+ if (!kfd_set_pasid_limit(pasid_limit)) {
148+ dev_err(kfd_device, "error setting pasid limit\n");
149+ amd_iommu_free_device(kfd->pdev);
150+ return false;
151+ }
152+
153+ return true;
154+}
155+
156+static void iommu_pasid_shutdown_callback(struct pci_dev *pdev, int pasid)
157+{
158+ struct kfd_dev *dev = kfd_device_by_pci_dev(pdev);
159+
160+ if (dev)
161+ kfd_unbind_process_from_device(dev, pasid);
162+}
163+
164+bool kgd2kfd_device_init(struct kfd_dev *kfd,
165+ const struct kgd2kfd_shared_resources *gpu_resources)
166+{
167+ unsigned int size;
168+
169+ kfd->shared_resources = *gpu_resources;
170+
171+ /* calculate max size of mqds needed for queues */
172+ size = max_num_of_processes *
173+ max_num_of_queues_per_process *
174+ kfd->device_info->mqd_size_aligned;
175+
176+ /* add another 512KB for all other allocations on gart */
177+ size += 512 * 1024;
178+
179+ if (kfd2kgd->init_sa_manager(kfd->kgd, size)) {
180+ dev_err(kfd_device,
181+ "Error initializing sa manager for device (%x:%x)\n",
182+ kfd->pdev->vendor, kfd->pdev->device);
183+ goto out;
184+ }
185+
186+ kfd_doorbell_init(kfd);
187+
188+ if (kfd_topology_add_device(kfd) != 0) {
189+ dev_err(kfd_device,
190+ "Error adding device (%x:%x) to topology\n",
191+ kfd->pdev->vendor, kfd->pdev->device);
192+ goto kfd_topology_add_device_error;
193+ }
194+
195+ if (kfd_interrupt_init(kfd)) {
196+ dev_err(kfd_device,
197+ "Error initializing interrupts for device (%x:%x)\n",
198+ kfd->pdev->vendor, kfd->pdev->device);
199+ goto kfd_interrupt_error;
200+ }
201+
202+ if (!device_iommu_pasid_init(kfd)) {
203+ dev_err(kfd_device,
204+ "Error initializing iommuv2 for device (%x:%x)\n",
205+ kfd->pdev->vendor, kfd->pdev->device);
206+ goto device_iommu_pasid_error;
207+ }
208+ amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
209+ iommu_pasid_shutdown_callback);
210+
211+ kfd->dqm = device_queue_manager_init(kfd);
212+ if (!kfd->dqm) {
213+ dev_err(kfd_device,
214+ "Error initializing queue manager for device (%x:%x)\n",
215+ kfd->pdev->vendor, kfd->pdev->device);
216+ goto device_queue_manager_error;
217+ }
218+
219+ if (kfd->dqm->start(kfd->dqm) != 0) {
220+ dev_err(kfd_device,
221+ "Error starting queuen manager for device (%x:%x)\n",
222+ kfd->pdev->vendor, kfd->pdev->device);
223+ goto dqm_start_error;
224+ }
225+
226+ kfd->init_complete = true;
227+ dev_info(kfd_device, "added device (%x:%x)\n", kfd->pdev->vendor,
228+ kfd->pdev->device);
229+
230+ pr_debug("kfd: Starting kfd with the following scheduling policy %d\n",
231+ sched_policy);
232+
233+ goto out;
234+
235+dqm_start_error:
236+ device_queue_manager_uninit(kfd->dqm);
237+device_queue_manager_error:
238+ amd_iommu_free_device(kfd->pdev);
239+device_iommu_pasid_error:
240+ kfd_interrupt_exit(kfd);
241+kfd_interrupt_error:
242+ kfd_topology_remove_device(kfd);
243+kfd_topology_add_device_error:
244+ kfd2kgd->fini_sa_manager(kfd->kgd);
245+ dev_err(kfd_device,
246+ "device (%x:%x) NOT added due to errors\n",
247+ kfd->pdev->vendor, kfd->pdev->device);
248+out:
249+ return kfd->init_complete;
250+}
251+
252+void kgd2kfd_device_exit(struct kfd_dev *kfd)
253+{
254+ if (kfd->init_complete) {
255+ device_queue_manager_uninit(kfd->dqm);
256+ amd_iommu_free_device(kfd->pdev);
257+ kfd_interrupt_exit(kfd);
258+ kfd_topology_remove_device(kfd);
259+ }
260+
261+ kfree(kfd);
262+}
263+
264+void kgd2kfd_suspend(struct kfd_dev *kfd)
265+{
266+ BUG_ON(kfd == NULL);
267+
268+ if (kfd->init_complete) {
269+ kfd->dqm->stop(kfd->dqm);
270+ amd_iommu_set_invalidate_ctx_cb(kfd->pdev, NULL);
271+ amd_iommu_free_device(kfd->pdev);
272+ }
273+}
274+
275+int kgd2kfd_resume(struct kfd_dev *kfd)
276+{
277+ unsigned int pasid_limit;
278+ int err;
279+
280+ BUG_ON(kfd == NULL);
281+
282+ pasid_limit = kfd_get_pasid_limit();
283+
284+ if (kfd->init_complete) {
285+ err = amd_iommu_init_device(kfd->pdev, pasid_limit);
286+ if (err < 0)
287+ return -ENXIO;
288+ amd_iommu_set_invalidate_ctx_cb(kfd->pdev,
289+ iommu_pasid_shutdown_callback);
290+ kfd->dqm->start(kfd->dqm);
291+ }
292+
293+ return 0;
294+}
295+
296+/* This is called directly from KGD at ISR. */
297+void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry)
298+{
299+ if (kfd->init_complete) {
300+ spin_lock(&kfd->interrupt_lock);
301+
302+ if (kfd->interrupts_active
303+ && enqueue_ih_ring_entry(kfd, ih_ring_entry))
304+ schedule_work(&kfd->interrupt_work);
305+
306+ spin_unlock(&kfd->interrupt_lock);
307+ }
308+}
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c+1062−0
@@ -0,0 +1,1062 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/slab.h>
25+#include <linux/list.h>
26+#include <linux/types.h>
27+#include <linux/printk.h>
28+#include <linux/bitops.h>
29+#include "kfd_priv.h"
30+#include "kfd_device_queue_manager.h"
31+#include "kfd_mqd_manager.h"
32+#include "cik_regs.h"
33+#include "kfd_kernel_queue.h"
34+#include "../../radeon/cik_reg.h"
35+
36+/* Size of the per-pipe EOP queue */
37+#define CIK_HPD_EOP_BYTES_LOG2 11
38+#define CIK_HPD_EOP_BYTES (1U << CIK_HPD_EOP_BYTES_LOG2)
39+
40+static bool is_mem_initialized;
41+
42+static int init_memory(struct device_queue_manager *dqm);
43+static int set_pasid_vmid_mapping(struct device_queue_manager *dqm,
44+ unsigned int pasid, unsigned int vmid);
45+
46+static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
47+ struct queue *q,
48+ struct qcm_process_device *qpd);
49+static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock);
50+static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock);
51+
52+
53+static inline unsigned int get_pipes_num(struct device_queue_manager *dqm)
54+{
55+ BUG_ON(!dqm || !dqm->dev);
56+ return dqm->dev->shared_resources.compute_pipe_count;
57+}
58+
59+static inline unsigned int get_first_pipe(struct device_queue_manager *dqm)
60+{
61+ BUG_ON(!dqm);
62+ return dqm->dev->shared_resources.first_compute_pipe;
63+}
64+
65+static inline unsigned int get_pipes_num_cpsch(void)
66+{
67+ return PIPE_PER_ME_CP_SCHEDULING;
68+}
69+
70+static inline unsigned int
71+get_sh_mem_bases_nybble_64(struct kfd_process_device *pdd)
72+{
73+ uint32_t nybble;
74+
75+ nybble = (pdd->lds_base >> 60) & 0x0E;
76+
77+ return nybble;
78+
79+}
80+
81+static inline unsigned int get_sh_mem_bases_32(struct kfd_process_device *pdd)
82+{
83+ unsigned int shared_base;
84+
85+ shared_base = (pdd->lds_base >> 16) & 0xFF;
86+
87+ return shared_base;
88+}
89+
90+static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
91+static void init_process_memory(struct device_queue_manager *dqm,
92+ struct qcm_process_device *qpd)
93+{
94+ struct kfd_process_device *pdd;
95+ unsigned int temp;
96+
97+ BUG_ON(!dqm || !qpd);
98+
99+ pdd = qpd_to_pdd(qpd);
100+
101+ /* check if sh_mem_config register already configured */
102+ if (qpd->sh_mem_config == 0) {
103+ qpd->sh_mem_config =
104+ ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED) |
105+ DEFAULT_MTYPE(MTYPE_NONCACHED) |
106+ APE1_MTYPE(MTYPE_NONCACHED);
107+ qpd->sh_mem_ape1_limit = 0;
108+ qpd->sh_mem_ape1_base = 0;
109+ }
110+
111+ if (qpd->pqm->process->is_32bit_user_mode) {
112+ temp = get_sh_mem_bases_32(pdd);
113+ qpd->sh_mem_bases = SHARED_BASE(temp);
114+ qpd->sh_mem_config |= PTR32;
115+ } else {
116+ temp = get_sh_mem_bases_nybble_64(pdd);
117+ qpd->sh_mem_bases = compute_sh_mem_bases_64bit(temp);
118+ }
119+
120+ pr_debug("kfd: is32bit process: %d sh_mem_bases nybble: 0x%X and register 0x%X\n",
121+ qpd->pqm->process->is_32bit_user_mode, temp, qpd->sh_mem_bases);
122+}
123+
124+static void program_sh_mem_settings(struct device_queue_manager *dqm,
125+ struct qcm_process_device *qpd)
126+{
127+ return kfd2kgd->program_sh_mem_settings(dqm->dev->kgd, qpd->vmid,
128+ qpd->sh_mem_config,
129+ qpd->sh_mem_ape1_base,
130+ qpd->sh_mem_ape1_limit,
131+ qpd->sh_mem_bases);
132+}
133+
134+static int allocate_vmid(struct device_queue_manager *dqm,
135+ struct qcm_process_device *qpd,
136+ struct queue *q)
137+{
138+ int bit, allocated_vmid;
139+
140+ if (dqm->vmid_bitmap == 0)
141+ return -ENOMEM;
142+
143+ bit = find_first_bit((unsigned long *)&dqm->vmid_bitmap, CIK_VMID_NUM);
144+ clear_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
145+
146+ /* Kaveri kfd vmid's starts from vmid 8 */
147+ allocated_vmid = bit + KFD_VMID_START_OFFSET;
148+ pr_debug("kfd: vmid allocation %d\n", allocated_vmid);
149+ qpd->vmid = allocated_vmid;
150+ q->properties.vmid = allocated_vmid;
151+
152+ set_pasid_vmid_mapping(dqm, q->process->pasid, q->properties.vmid);
153+ program_sh_mem_settings(dqm, qpd);
154+
155+ return 0;
156+}
157+
158+static void deallocate_vmid(struct device_queue_manager *dqm,
159+ struct qcm_process_device *qpd,
160+ struct queue *q)
161+{
162+ int bit = qpd->vmid - KFD_VMID_START_OFFSET;
163+
164+ set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
165+ qpd->vmid = 0;
166+ q->properties.vmid = 0;
167+}
168+
169+static int create_queue_nocpsch(struct device_queue_manager *dqm,
170+ struct queue *q,
171+ struct qcm_process_device *qpd,
172+ int *allocated_vmid)
173+{
174+ int retval;
175+
176+ BUG_ON(!dqm || !q || !qpd || !allocated_vmid);
177+
178+ pr_debug("kfd: In func %s\n", __func__);
179+ print_queue(q);
180+
181+ mutex_lock(&dqm->lock);
182+
183+ if (list_empty(&qpd->queues_list)) {
184+ retval = allocate_vmid(dqm, qpd, q);
185+ if (retval != 0) {
186+ mutex_unlock(&dqm->lock);
187+ return retval;
188+ }
189+ }
190+ *allocated_vmid = qpd->vmid;
191+ q->properties.vmid = qpd->vmid;
192+
193+ retval = create_compute_queue_nocpsch(dqm, q, qpd);
194+
195+ if (retval != 0) {
196+ if (list_empty(&qpd->queues_list)) {
197+ deallocate_vmid(dqm, qpd, q);
198+ *allocated_vmid = 0;
199+ }
200+ mutex_unlock(&dqm->lock);
201+ return retval;
202+ }
203+
204+ list_add(&q->list, &qpd->queues_list);
205+ dqm->queue_count++;
206+
207+ mutex_unlock(&dqm->lock);
208+ return 0;
209+}
210+
211+static int allocate_hqd(struct device_queue_manager *dqm, struct queue *q)
212+{
213+ bool set;
214+ int pipe, bit;
215+
216+ set = false;
217+
218+ for (pipe = dqm->next_pipe_to_allocate; pipe < get_pipes_num(dqm);
219+ pipe = (pipe + 1) % get_pipes_num(dqm)) {
220+ if (dqm->allocated_queues[pipe] != 0) {
221+ bit = find_first_bit(
222+ (unsigned long *)&dqm->allocated_queues[pipe],
223+ QUEUES_PER_PIPE);
224+
225+ clear_bit(bit,
226+ (unsigned long *)&dqm->allocated_queues[pipe]);
227+ q->pipe = pipe;
228+ q->queue = bit;
229+ set = true;
230+ break;
231+ }
232+ }
233+
234+ if (set == false)
235+ return -EBUSY;
236+
237+ pr_debug("kfd: DQM %s hqd slot - pipe (%d) queue(%d)\n",
238+ __func__, q->pipe, q->queue);
239+ /* horizontal hqd allocation */
240+ dqm->next_pipe_to_allocate = (pipe + 1) % get_pipes_num(dqm);
241+
242+ return 0;
243+}
244+
245+static inline void deallocate_hqd(struct device_queue_manager *dqm,
246+ struct queue *q)
247+{
248+ set_bit(q->queue, (unsigned long *)&dqm->allocated_queues[q->pipe]);
249+}
250+
251+static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
252+ struct queue *q,
253+ struct qcm_process_device *qpd)
254+{
255+ int retval;
256+ struct mqd_manager *mqd;
257+
258+ BUG_ON(!dqm || !q || !qpd);
259+
260+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
261+ if (mqd == NULL)
262+ return -ENOMEM;
263+
264+ retval = allocate_hqd(dqm, q);
265+ if (retval != 0)
266+ return retval;
267+
268+ retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
269+ &q->gart_mqd_addr, &q->properties);
270+ if (retval != 0) {
271+ deallocate_hqd(dqm, q);
272+ return retval;
273+ }
274+
275+ return 0;
276+}
277+
278+static int destroy_queue_nocpsch(struct device_queue_manager *dqm,
279+ struct qcm_process_device *qpd,
280+ struct queue *q)
281+{
282+ int retval;
283+ struct mqd_manager *mqd;
284+
285+ BUG_ON(!dqm || !q || !q->mqd || !qpd);
286+
287+ retval = 0;
288+
289+ pr_debug("kfd: In Func %s\n", __func__);
290+
291+ mutex_lock(&dqm->lock);
292+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
293+ if (mqd == NULL) {
294+ retval = -ENOMEM;
295+ goto out;
296+ }
297+
298+ retval = mqd->destroy_mqd(mqd, q->mqd,
299+ KFD_PREEMPT_TYPE_WAVEFRONT,
300+ QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
301+ q->pipe, q->queue);
302+
303+ if (retval != 0)
304+ goto out;
305+
306+ deallocate_hqd(dqm, q);
307+
308+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
309+
310+ list_del(&q->list);
311+ if (list_empty(&qpd->queues_list))
312+ deallocate_vmid(dqm, qpd, q);
313+ dqm->queue_count--;
314+out:
315+ mutex_unlock(&dqm->lock);
316+ return retval;
317+}
318+
319+static int update_queue(struct device_queue_manager *dqm, struct queue *q)
320+{
321+ int retval;
322+ struct mqd_manager *mqd;
323+
324+ BUG_ON(!dqm || !q || !q->mqd);
325+
326+ mutex_lock(&dqm->lock);
327+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
328+ if (mqd == NULL) {
329+ mutex_unlock(&dqm->lock);
330+ return -ENOMEM;
331+ }
332+
333+ retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
334+ if (q->properties.is_active == true)
335+ dqm->queue_count++;
336+ else
337+ dqm->queue_count--;
338+
339+ if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
340+ retval = execute_queues_cpsch(dqm, false);
341+
342+ mutex_unlock(&dqm->lock);
343+ return retval;
344+}
345+
346+static struct mqd_manager *get_mqd_manager_nocpsch(
347+ struct device_queue_manager *dqm, enum KFD_MQD_TYPE type)
348+{
349+ struct mqd_manager *mqd;
350+
351+ BUG_ON(!dqm || type >= KFD_MQD_TYPE_MAX);
352+
353+ pr_debug("kfd: In func %s mqd type %d\n", __func__, type);
354+
355+ mqd = dqm->mqds[type];
356+ if (!mqd) {
357+ mqd = mqd_manager_init(type, dqm->dev);
358+ if (mqd == NULL)
359+ pr_err("kfd: mqd manager is NULL");
360+ dqm->mqds[type] = mqd;
361+ }
362+
363+ return mqd;
364+}
365+
366+static int register_process_nocpsch(struct device_queue_manager *dqm,
367+ struct qcm_process_device *qpd)
368+{
369+ struct device_process_node *n;
370+
371+ BUG_ON(!dqm || !qpd);
372+
373+ pr_debug("kfd: In func %s\n", __func__);
374+
375+ n = kzalloc(sizeof(struct device_process_node), GFP_KERNEL);
376+ if (!n)
377+ return -ENOMEM;
378+
379+ n->qpd = qpd;
380+
381+ mutex_lock(&dqm->lock);
382+ list_add(&n->list, &dqm->queues);
383+
384+ init_process_memory(dqm, qpd);
385+ dqm->processes_count++;
386+
387+ mutex_unlock(&dqm->lock);
388+
389+ return 0;
390+}
391+
392+static int unregister_process_nocpsch(struct device_queue_manager *dqm,
393+ struct qcm_process_device *qpd)
394+{
395+ int retval;
396+ struct device_process_node *cur, *next;
397+
398+ BUG_ON(!dqm || !qpd);
399+
400+ BUG_ON(!list_empty(&qpd->queues_list));
401+
402+ pr_debug("kfd: In func %s\n", __func__);
403+
404+ retval = 0;
405+ mutex_lock(&dqm->lock);
406+
407+ list_for_each_entry_safe(cur, next, &dqm->queues, list) {
408+ if (qpd == cur->qpd) {
409+ list_del(&cur->list);
410+ kfree(cur);
411+ dqm->processes_count--;
412+ goto out;
413+ }
414+ }
415+ /* qpd not found in dqm list */
416+ retval = 1;
417+out:
418+ mutex_unlock(&dqm->lock);
419+ return retval;
420+}
421+
422+static int
423+set_pasid_vmid_mapping(struct device_queue_manager *dqm, unsigned int pasid,
424+ unsigned int vmid)
425+{
426+ uint32_t pasid_mapping;
427+
428+ pasid_mapping = (pasid == 0) ? 0 : (uint32_t)pasid |
429+ ATC_VMID_PASID_MAPPING_VALID;
430+ return kfd2kgd->set_pasid_vmid_mapping(dqm->dev->kgd, pasid_mapping,
431+ vmid);
432+}
433+
434+static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble)
435+{
436+ /* In 64-bit mode, we can only control the top 3 bits of the LDS,
437+ * scratch and GPUVM apertures.
438+ * The hardware fills in the remaining 59 bits according to the
439+ * following pattern:
440+ * LDS: X0000000'00000000 - X0000001'00000000 (4GB)
441+ * Scratch: X0000001'00000000 - X0000002'00000000 (4GB)
442+ * GPUVM: Y0010000'00000000 - Y0020000'00000000 (1TB)
443+ *
444+ * (where X/Y is the configurable nybble with the low-bit 0)
445+ *
446+ * LDS and scratch will have the same top nybble programmed in the
447+ * top 3 bits of SH_MEM_BASES.PRIVATE_BASE.
448+ * GPUVM can have a different top nybble programmed in the
449+ * top 3 bits of SH_MEM_BASES.SHARED_BASE.
450+ * We don't bother to support different top nybbles
451+ * for LDS/Scratch and GPUVM.
452+ */
453+
454+ BUG_ON((top_address_nybble & 1) || top_address_nybble > 0xE ||
455+ top_address_nybble == 0);
456+
457+ return PRIVATE_BASE(top_address_nybble << 12) |
458+ SHARED_BASE(top_address_nybble << 12);
459+}
460+
461+static int init_memory(struct device_queue_manager *dqm)
462+{
463+ int i, retval;
464+
465+ for (i = 8; i < 16; i++)
466+ set_pasid_vmid_mapping(dqm, 0, i);
467+
468+ retval = kfd2kgd->init_memory(dqm->dev->kgd);
469+ if (retval == 0)
470+ is_mem_initialized = true;
471+ return retval;
472+}
473+
474+
475+static int init_pipelines(struct device_queue_manager *dqm,
476+ unsigned int pipes_num, unsigned int first_pipe)
477+{
478+ void *hpdptr;
479+ struct mqd_manager *mqd;
480+ unsigned int i, err, inx;
481+ uint64_t pipe_hpd_addr;
482+
483+ BUG_ON(!dqm || !dqm->dev);
484+
485+ pr_debug("kfd: In func %s\n", __func__);
486+
487+ /*
488+ * Allocate memory for the HPDs. This is hardware-owned per-pipe data.
489+ * The driver never accesses this memory after zeroing it.
490+ * It doesn't even have to be saved/restored on suspend/resume
491+ * because it contains no data when there are no active queues.
492+ */
493+
494+ err = kfd2kgd->allocate_mem(dqm->dev->kgd,
495+ CIK_HPD_EOP_BYTES * pipes_num,
496+ PAGE_SIZE,
497+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
498+ (struct kgd_mem **) &dqm->pipeline_mem);
499+
500+ if (err) {
501+ pr_err("kfd: error allocate vidmem num pipes: %d\n",
502+ pipes_num);
503+ return -ENOMEM;
504+ }
505+
506+ hpdptr = dqm->pipeline_mem->cpu_ptr;
507+ dqm->pipelines_addr = dqm->pipeline_mem->gpu_addr;
508+
509+ memset(hpdptr, 0, CIK_HPD_EOP_BYTES * pipes_num);
510+
511+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_COMPUTE);
512+ if (mqd == NULL) {
513+ kfd2kgd->free_mem(dqm->dev->kgd,
514+ (struct kgd_mem *) dqm->pipeline_mem);
515+ return -ENOMEM;
516+ }
517+
518+ for (i = 0; i < pipes_num; i++) {
519+ inx = i + first_pipe;
520+ pipe_hpd_addr = dqm->pipelines_addr + i * CIK_HPD_EOP_BYTES;
521+ pr_debug("kfd: pipeline address %llX\n", pipe_hpd_addr);
522+ /* = log2(bytes/4)-1 */
523+ kfd2kgd->init_pipeline(dqm->dev->kgd, i,
524+ CIK_HPD_EOP_BYTES_LOG2 - 3, pipe_hpd_addr);
525+ }
526+
527+ return 0;
528+}
529+
530+
531+static int init_scheduler(struct device_queue_manager *dqm)
532+{
533+ int retval;
534+
535+ BUG_ON(!dqm);
536+
537+ pr_debug("kfd: In %s\n", __func__);
538+
539+ retval = init_pipelines(dqm, get_pipes_num(dqm), KFD_DQM_FIRST_PIPE);
540+ if (retval != 0)
541+ return retval;
542+
543+ retval = init_memory(dqm);
544+
545+ return retval;
546+}
547+
548+static int initialize_nocpsch(struct device_queue_manager *dqm)
549+{
550+ int i;
551+
552+ BUG_ON(!dqm);
553+
554+ pr_debug("kfd: In func %s num of pipes: %d\n",
555+ __func__, get_pipes_num(dqm));
556+
557+ mutex_init(&dqm->lock);
558+ INIT_LIST_HEAD(&dqm->queues);
559+ dqm->queue_count = dqm->next_pipe_to_allocate = 0;
560+ dqm->allocated_queues = kcalloc(get_pipes_num(dqm),
561+ sizeof(unsigned int), GFP_KERNEL);
562+ if (!dqm->allocated_queues) {
563+ mutex_destroy(&dqm->lock);
564+ return -ENOMEM;
565+ }
566+
567+ for (i = 0; i < get_pipes_num(dqm); i++)
568+ dqm->allocated_queues[i] = (1 << QUEUES_PER_PIPE) - 1;
569+
570+ dqm->vmid_bitmap = (1 << VMID_PER_DEVICE) - 1;
571+
572+ init_scheduler(dqm);
573+ return 0;
574+}
575+
576+static void uninitialize_nocpsch(struct device_queue_manager *dqm)
577+{
578+ int i;
579+
580+ BUG_ON(!dqm);
581+
582+ BUG_ON(dqm->queue_count > 0 || dqm->processes_count > 0);
583+
584+ kfree(dqm->allocated_queues);
585+ for (i = 0 ; i < KFD_MQD_TYPE_MAX ; i++)
586+ kfree(dqm->mqds[i]);
587+ mutex_destroy(&dqm->lock);
588+ kfd2kgd->free_mem(dqm->dev->kgd,
589+ (struct kgd_mem *) dqm->pipeline_mem);
590+}
591+
592+static int start_nocpsch(struct device_queue_manager *dqm)
593+{
594+ return 0;
595+}
596+
597+static int stop_nocpsch(struct device_queue_manager *dqm)
598+{
599+ return 0;
600+}
601+
602+/*
603+ * Device Queue Manager implementation for cp scheduler
604+ */
605+
606+static int set_sched_resources(struct device_queue_manager *dqm)
607+{
608+ struct scheduling_resources res;
609+ unsigned int queue_num, queue_mask;
610+
611+ BUG_ON(!dqm);
612+
613+ pr_debug("kfd: In func %s\n", __func__);
614+
615+ queue_num = get_pipes_num_cpsch() * QUEUES_PER_PIPE;
616+ queue_mask = (1 << queue_num) - 1;
617+ res.vmid_mask = (1 << VMID_PER_DEVICE) - 1;
618+ res.vmid_mask <<= KFD_VMID_START_OFFSET;
619+ res.queue_mask = queue_mask << (get_first_pipe(dqm) * QUEUES_PER_PIPE);
620+ res.gws_mask = res.oac_mask = res.gds_heap_base =
621+ res.gds_heap_size = 0;
622+
623+ pr_debug("kfd: scheduling resources:\n"
624+ " vmid mask: 0x%8X\n"
625+ " queue mask: 0x%8llX\n",
626+ res.vmid_mask, res.queue_mask);
627+
628+ return pm_send_set_resources(&dqm->packets, &res);
629+}
630+
631+static int initialize_cpsch(struct device_queue_manager *dqm)
632+{
633+ int retval;
634+
635+ BUG_ON(!dqm);
636+
637+ pr_debug("kfd: In func %s num of pipes: %d\n",
638+ __func__, get_pipes_num_cpsch());
639+
640+ mutex_init(&dqm->lock);
641+ INIT_LIST_HEAD(&dqm->queues);
642+ dqm->queue_count = dqm->processes_count = 0;
643+ dqm->active_runlist = false;
644+ retval = init_pipelines(dqm, get_pipes_num(dqm), 0);
645+ if (retval != 0)
646+ goto fail_init_pipelines;
647+
648+ return 0;
649+
650+fail_init_pipelines:
651+ mutex_destroy(&dqm->lock);
652+ return retval;
653+}
654+
655+static int start_cpsch(struct device_queue_manager *dqm)
656+{
657+ struct device_process_node *node;
658+ int retval;
659+
660+ BUG_ON(!dqm);
661+
662+ retval = 0;
663+
664+ retval = pm_init(&dqm->packets, dqm);
665+ if (retval != 0)
666+ goto fail_packet_manager_init;
667+
668+ retval = set_sched_resources(dqm);
669+ if (retval != 0)
670+ goto fail_set_sched_resources;
671+
672+ pr_debug("kfd: allocating fence memory\n");
673+
674+ /* allocate fence memory on the gart */
675+ retval = kfd2kgd->allocate_mem(dqm->dev->kgd,
676+ sizeof(*dqm->fence_addr),
677+ 32,
678+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
679+ (struct kgd_mem **) &dqm->fence_mem);
680+
681+ if (retval != 0)
682+ goto fail_allocate_vidmem;
683+
684+ dqm->fence_addr = dqm->fence_mem->cpu_ptr;
685+ dqm->fence_gpu_addr = dqm->fence_mem->gpu_addr;
686+
687+ list_for_each_entry(node, &dqm->queues, list)
688+ if (node->qpd->pqm->process && dqm->dev)
689+ kfd_bind_process_to_device(dqm->dev,
690+ node->qpd->pqm->process);
691+
692+ execute_queues_cpsch(dqm, true);
693+
694+ return 0;
695+fail_allocate_vidmem:
696+fail_set_sched_resources:
697+ pm_uninit(&dqm->packets);
698+fail_packet_manager_init:
699+ return retval;
700+}
701+
702+static int stop_cpsch(struct device_queue_manager *dqm)
703+{
704+ struct device_process_node *node;
705+ struct kfd_process_device *pdd;
706+
707+ BUG_ON(!dqm);
708+
709+ destroy_queues_cpsch(dqm, true);
710+
711+ list_for_each_entry(node, &dqm->queues, list) {
712+ pdd = qpd_to_pdd(node->qpd);
713+ pdd->bound = false;
714+ }
715+ kfd2kgd->free_mem(dqm->dev->kgd,
716+ (struct kgd_mem *) dqm->fence_mem);
717+ pm_uninit(&dqm->packets);
718+
719+ return 0;
720+}
721+
722+static int create_kernel_queue_cpsch(struct device_queue_manager *dqm,
723+ struct kernel_queue *kq,
724+ struct qcm_process_device *qpd)
725+{
726+ BUG_ON(!dqm || !kq || !qpd);
727+
728+ pr_debug("kfd: In func %s\n", __func__);
729+
730+ mutex_lock(&dqm->lock);
731+ list_add(&kq->list, &qpd->priv_queue_list);
732+ dqm->queue_count++;
733+ qpd->is_debug = true;
734+ execute_queues_cpsch(dqm, false);
735+ mutex_unlock(&dqm->lock);
736+
737+ return 0;
738+}
739+
740+static void destroy_kernel_queue_cpsch(struct device_queue_manager *dqm,
741+ struct kernel_queue *kq,
742+ struct qcm_process_device *qpd)
743+{
744+ BUG_ON(!dqm || !kq);
745+
746+ pr_debug("kfd: In %s\n", __func__);
747+
748+ mutex_lock(&dqm->lock);
749+ destroy_queues_cpsch(dqm, false);
750+ list_del(&kq->list);
751+ dqm->queue_count--;
752+ qpd->is_debug = false;
753+ execute_queues_cpsch(dqm, false);
754+ mutex_unlock(&dqm->lock);
755+}
756+
757+static int create_queue_cpsch(struct device_queue_manager *dqm, struct queue *q,
758+ struct qcm_process_device *qpd, int *allocate_vmid)
759+{
760+ int retval;
761+ struct mqd_manager *mqd;
762+
763+ BUG_ON(!dqm || !q || !qpd);
764+
765+ retval = 0;
766+
767+ if (allocate_vmid)
768+ *allocate_vmid = 0;
769+
770+ mutex_lock(&dqm->lock);
771+
772+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP);
773+ if (mqd == NULL) {
774+ mutex_unlock(&dqm->lock);
775+ return -ENOMEM;
776+ }
777+
778+ retval = mqd->init_mqd(mqd, &q->mqd, &q->mqd_mem_obj,
779+ &q->gart_mqd_addr, &q->properties);
780+ if (retval != 0)
781+ goto out;
782+
783+ list_add(&q->list, &qpd->queues_list);
784+ if (q->properties.is_active) {
785+ dqm->queue_count++;
786+ retval = execute_queues_cpsch(dqm, false);
787+ }
788+
789+out:
790+ mutex_unlock(&dqm->lock);
791+ return retval;
792+}
793+
794+static int fence_wait_timeout(unsigned int *fence_addr,
795+ unsigned int fence_value,
796+ unsigned long timeout)
797+{
798+ BUG_ON(!fence_addr);
799+ timeout += jiffies;
800+
801+ while (*fence_addr != fence_value) {
802+ if (time_after(jiffies, timeout)) {
803+ pr_err("kfd: qcm fence wait loop timeout expired\n");
804+ return -ETIME;
805+ }
806+ cpu_relax();
807+ }
808+
809+ return 0;
810+}
811+
812+static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock)
813+{
814+ int retval;
815+
816+ BUG_ON(!dqm);
817+
818+ retval = 0;
819+
820+ if (lock)
821+ mutex_lock(&dqm->lock);
822+ if (dqm->active_runlist == false)
823+ goto out;
824+ retval = pm_send_unmap_queue(&dqm->packets, KFD_QUEUE_TYPE_COMPUTE,
825+ KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES, 0, false, 0);
826+ if (retval != 0)
827+ goto out;
828+
829+ *dqm->fence_addr = KFD_FENCE_INIT;
830+ pm_send_query_status(&dqm->packets, dqm->fence_gpu_addr,
831+ KFD_FENCE_COMPLETED);
832+ /* should be timed out */
833+ fence_wait_timeout(dqm->fence_addr, KFD_FENCE_COMPLETED,
834+ QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS);
835+ pm_release_ib(&dqm->packets);
836+ dqm->active_runlist = false;
837+
838+out:
839+ if (lock)
840+ mutex_unlock(&dqm->lock);
841+ return retval;
842+}
843+
844+static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock)
845+{
846+ int retval;
847+
848+ BUG_ON(!dqm);
849+
850+ if (lock)
851+ mutex_lock(&dqm->lock);
852+
853+ retval = destroy_queues_cpsch(dqm, false);
854+ if (retval != 0) {
855+ pr_err("kfd: the cp might be in an unrecoverable state due to an unsuccessful queues preemption");
856+ goto out;
857+ }
858+
859+ if (dqm->queue_count <= 0 || dqm->processes_count <= 0) {
860+ retval = 0;
861+ goto out;
862+ }
863+
864+ if (dqm->active_runlist) {
865+ retval = 0;
866+ goto out;
867+ }
868+
869+ retval = pm_send_runlist(&dqm->packets, &dqm->queues);
870+ if (retval != 0) {
871+ pr_err("kfd: failed to execute runlist");
872+ goto out;
873+ }
874+ dqm->active_runlist = true;
875+
876+out:
877+ if (lock)
878+ mutex_unlock(&dqm->lock);
879+ return retval;
880+}
881+
882+static int destroy_queue_cpsch(struct device_queue_manager *dqm,
883+ struct qcm_process_device *qpd,
884+ struct queue *q)
885+{
886+ int retval;
887+ struct mqd_manager *mqd;
888+
889+ BUG_ON(!dqm || !qpd || !q);
890+
891+ retval = 0;
892+
893+ /* remove queue from list to prevent rescheduling after preemption */
894+ mutex_lock(&dqm->lock);
895+
896+ mqd = dqm->get_mqd_manager(dqm, KFD_MQD_TYPE_CIK_CP);
897+ if (!mqd) {
898+ retval = -ENOMEM;
899+ goto failed;
900+ }
901+
902+ list_del(&q->list);
903+ dqm->queue_count--;
904+
905+ execute_queues_cpsch(dqm, false);
906+
907+ mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
908+
909+ mutex_unlock(&dqm->lock);
910+
911+ return 0;
912+
913+failed:
914+ mutex_unlock(&dqm->lock);
915+ return retval;
916+}
917+
918+/*
919+ * Low bits must be 0000/FFFF as required by HW, high bits must be 0 to
920+ * stay in user mode.
921+ */
922+#define APE1_FIXED_BITS_MASK 0xFFFF80000000FFFFULL
923+/* APE1 limit is inclusive and 64K aligned. */
924+#define APE1_LIMIT_ALIGNMENT 0xFFFF
925+
926+static bool set_cache_memory_policy(struct device_queue_manager *dqm,
927+ struct qcm_process_device *qpd,
928+ enum cache_policy default_policy,
929+ enum cache_policy alternate_policy,
930+ void __user *alternate_aperture_base,
931+ uint64_t alternate_aperture_size)
932+{
933+ uint32_t default_mtype;
934+ uint32_t ape1_mtype;
935+
936+ pr_debug("kfd: In func %s\n", __func__);
937+
938+ mutex_lock(&dqm->lock);
939+
940+ if (alternate_aperture_size == 0) {
941+ /* base > limit disables APE1 */
942+ qpd->sh_mem_ape1_base = 1;
943+ qpd->sh_mem_ape1_limit = 0;
944+ } else {
945+ /*
946+ * In FSA64, APE1_Base[63:0] = { 16{SH_MEM_APE1_BASE[31]},
947+ * SH_MEM_APE1_BASE[31:0], 0x0000 }
948+ * APE1_Limit[63:0] = { 16{SH_MEM_APE1_LIMIT[31]},
949+ * SH_MEM_APE1_LIMIT[31:0], 0xFFFF }
950+ * Verify that the base and size parameters can be
951+ * represented in this format and convert them.
952+ * Additionally restrict APE1 to user-mode addresses.
953+ */
954+
955+ uint64_t base = (uintptr_t)alternate_aperture_base;
956+ uint64_t limit = base + alternate_aperture_size - 1;
957+
958+ if (limit <= base)
959+ goto out;
960+
961+ if ((base & APE1_FIXED_BITS_MASK) != 0)
962+ goto out;
963+
964+ if ((limit & APE1_FIXED_BITS_MASK) != APE1_LIMIT_ALIGNMENT)
965+ goto out;
966+
967+ qpd->sh_mem_ape1_base = base >> 16;
968+ qpd->sh_mem_ape1_limit = limit >> 16;
969+ }
970+
971+ default_mtype = (default_policy == cache_policy_coherent) ?
972+ MTYPE_NONCACHED :
973+ MTYPE_CACHED;
974+
975+ ape1_mtype = (alternate_policy == cache_policy_coherent) ?
976+ MTYPE_NONCACHED :
977+ MTYPE_CACHED;
978+
979+ qpd->sh_mem_config = (qpd->sh_mem_config & PTR32)
980+ | ALIGNMENT_MODE(SH_MEM_ALIGNMENT_MODE_UNALIGNED)
981+ | DEFAULT_MTYPE(default_mtype)
982+ | APE1_MTYPE(ape1_mtype);
983+
984+ if ((sched_policy == KFD_SCHED_POLICY_NO_HWS) && (qpd->vmid != 0))
985+ program_sh_mem_settings(dqm, qpd);
986+
987+ pr_debug("kfd: sh_mem_config: 0x%x, ape1_base: 0x%x, ape1_limit: 0x%x\n",
988+ qpd->sh_mem_config, qpd->sh_mem_ape1_base,
989+ qpd->sh_mem_ape1_limit);
990+
991+ mutex_unlock(&dqm->lock);
992+ return true;
993+
994+out:
995+ mutex_unlock(&dqm->lock);
996+ return false;
997+}
998+
999+struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev)
1000+{
1001+ struct device_queue_manager *dqm;
1002+
1003+ BUG_ON(!dev);
1004+
1005+ dqm = kzalloc(sizeof(struct device_queue_manager), GFP_KERNEL);
1006+ if (!dqm)
1007+ return NULL;
1008+
1009+ dqm->dev = dev;
1010+ switch (sched_policy) {
1011+ case KFD_SCHED_POLICY_HWS:
1012+ case KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION:
1013+ /* initialize dqm for cp scheduling */
1014+ dqm->create_queue = create_queue_cpsch;
1015+ dqm->initialize = initialize_cpsch;
1016+ dqm->start = start_cpsch;
1017+ dqm->stop = stop_cpsch;
1018+ dqm->destroy_queue = destroy_queue_cpsch;
1019+ dqm->update_queue = update_queue;
1020+ dqm->get_mqd_manager = get_mqd_manager_nocpsch;
1021+ dqm->register_process = register_process_nocpsch;
1022+ dqm->unregister_process = unregister_process_nocpsch;
1023+ dqm->uninitialize = uninitialize_nocpsch;
1024+ dqm->create_kernel_queue = create_kernel_queue_cpsch;
1025+ dqm->destroy_kernel_queue = destroy_kernel_queue_cpsch;
1026+ dqm->set_cache_memory_policy = set_cache_memory_policy;
1027+ break;
1028+ case KFD_SCHED_POLICY_NO_HWS:
1029+ /* initialize dqm for no cp scheduling */
1030+ dqm->start = start_nocpsch;
1031+ dqm->stop = stop_nocpsch;
1032+ dqm->create_queue = create_queue_nocpsch;
1033+ dqm->destroy_queue = destroy_queue_nocpsch;
1034+ dqm->update_queue = update_queue;
1035+ dqm->get_mqd_manager = get_mqd_manager_nocpsch;
1036+ dqm->register_process = register_process_nocpsch;
1037+ dqm->unregister_process = unregister_process_nocpsch;
1038+ dqm->initialize = initialize_nocpsch;
1039+ dqm->uninitialize = uninitialize_nocpsch;
1040+ dqm->set_cache_memory_policy = set_cache_memory_policy;
1041+ break;
1042+ default:
1043+ BUG();
1044+ break;
1045+ }
1046+
1047+ if (dqm->initialize(dqm) != 0) {
1048+ kfree(dqm);
1049+ return NULL;
1050+ }
1051+
1052+ return dqm;
1053+}
1054+
1055+void device_queue_manager_uninit(struct device_queue_manager *dqm)
1056+{
1057+ BUG_ON(!dqm);
1058+
1059+ dqm->uninitialize(dqm);
1060+ kfree(dqm);
1061+}
1062+
drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.h+146−0
@@ -0,0 +1,146 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#ifndef KFD_DEVICE_QUEUE_MANAGER_H_
25+#define KFD_DEVICE_QUEUE_MANAGER_H_
26+
27+#include <linux/rwsem.h>
28+#include <linux/list.h>
29+#include "kfd_priv.h"
30+#include "kfd_mqd_manager.h"
31+
32+#define QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS (500)
33+#define QUEUES_PER_PIPE (8)
34+#define PIPE_PER_ME_CP_SCHEDULING (3)
35+#define CIK_VMID_NUM (8)
36+#define KFD_VMID_START_OFFSET (8)
37+#define VMID_PER_DEVICE CIK_VMID_NUM
38+#define KFD_DQM_FIRST_PIPE (0)
39+
40+struct device_process_node {
41+ struct qcm_process_device *qpd;
42+ struct list_head list;
43+};
44+
45+/**
46+ * struct device_queue_manager
47+ *
48+ * @create_queue: Queue creation routine.
49+ *
50+ * @destroy_queue: Queue destruction routine.
51+ *
52+ * @update_queue: Queue update routine.
53+ *
54+ * @get_mqd_manager: Returns the mqd manager according to the mqd type.
55+ *
56+ * @exeute_queues: Dispatches the queues list to the H/W.
57+ *
58+ * @register_process: This routine associates a specific process with device.
59+ *
60+ * @unregister_process: destroys the associations between process to device.
61+ *
62+ * @initialize: Initializes the pipelines and memory module for that device.
63+ *
64+ * @start: Initializes the resources/modules the the device needs for queues
65+ * execution. This function is called on device initialization and after the
66+ * system woke up after suspension.
67+ *
68+ * @stop: This routine stops execution of all the active queue running on the
69+ * H/W and basically this function called on system suspend.
70+ *
71+ * @uninitialize: Destroys all the device queue manager resources allocated in
72+ * initialize routine.
73+ *
74+ * @create_kernel_queue: Creates kernel queue. Used for debug queue.
75+ *
76+ * @destroy_kernel_queue: Destroys kernel queue. Used for debug queue.
77+ *
78+ * @set_cache_memory_policy: Sets memory policy (cached/ non cached) for the
79+ * memory apertures.
80+ *
81+ * This struct is a base class for the kfd queues scheduler in the
82+ * device level. The device base class should expose the basic operations
83+ * for queue creation and queue destruction. This base class hides the
84+ * scheduling mode of the driver and the specific implementation of the
85+ * concrete device. This class is the only class in the queues scheduler
86+ * that configures the H/W.
87+ */
88+
89+struct device_queue_manager {
90+ int (*create_queue)(struct device_queue_manager *dqm,
91+ struct queue *q,
92+ struct qcm_process_device *qpd,
93+ int *allocate_vmid);
94+ int (*destroy_queue)(struct device_queue_manager *dqm,
95+ struct qcm_process_device *qpd,
96+ struct queue *q);
97+ int (*update_queue)(struct device_queue_manager *dqm,
98+ struct queue *q);
99+
100+ struct mqd_manager * (*get_mqd_manager)
101+ (struct device_queue_manager *dqm,
102+ enum KFD_MQD_TYPE type);
103+
104+ int (*register_process)(struct device_queue_manager *dqm,
105+ struct qcm_process_device *qpd);
106+ int (*unregister_process)(struct device_queue_manager *dqm,
107+ struct qcm_process_device *qpd);
108+ int (*initialize)(struct device_queue_manager *dqm);
109+ int (*start)(struct device_queue_manager *dqm);
110+ int (*stop)(struct device_queue_manager *dqm);
111+ void (*uninitialize)(struct device_queue_manager *dqm);
112+ int (*create_kernel_queue)(struct device_queue_manager *dqm,
113+ struct kernel_queue *kq,
114+ struct qcm_process_device *qpd);
115+ void (*destroy_kernel_queue)(struct device_queue_manager *dqm,
116+ struct kernel_queue *kq,
117+ struct qcm_process_device *qpd);
118+ bool (*set_cache_memory_policy)(struct device_queue_manager *dqm,
119+ struct qcm_process_device *qpd,
120+ enum cache_policy default_policy,
121+ enum cache_policy alternate_policy,
122+ void __user *alternate_aperture_base,
123+ uint64_t alternate_aperture_size);
124+
125+
126+ struct mqd_manager *mqds[KFD_MQD_TYPE_MAX];
127+ struct packet_manager packets;
128+ struct kfd_dev *dev;
129+ struct mutex lock;
130+ struct list_head queues;
131+ unsigned int processes_count;
132+ unsigned int queue_count;
133+ unsigned int next_pipe_to_allocate;
134+ unsigned int *allocated_queues;
135+ unsigned int vmid_bitmap;
136+ uint64_t pipelines_addr;
137+ struct kfd_mem_obj *pipeline_mem;
138+ uint64_t fence_gpu_addr;
139+ unsigned int *fence_addr;
140+ struct kfd_mem_obj *fence_mem;
141+ bool active_runlist;
142+};
143+
144+
145+
146+#endif /* KFD_DEVICE_QUEUE_MANAGER_H_ */
drivers/gpu/drm/amd/amdkfd/kfd_doorbell.c+256−0
@@ -0,0 +1,256 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+#include "kfd_priv.h"
23+#include <linux/mm.h>
24+#include <linux/mman.h>
25+#include <linux/slab.h>
26+#include <linux/io.h>
27+
28+/*
29+ * This extension supports a kernel level doorbells management for
30+ * the kernel queues.
31+ * Basically the last doorbells page is devoted to kernel queues
32+ * and that's assures that any user process won't get access to the
33+ * kernel doorbells page
34+ */
35+static DEFINE_MUTEX(doorbell_mutex);
36+static unsigned long doorbell_available_index[
37+ DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)] = { 0 };
38+
39+#define KERNEL_DOORBELL_PASID 1
40+#define KFD_SIZE_OF_DOORBELL_IN_BYTES 4
41+
42+/*
43+ * Each device exposes a doorbell aperture, a PCI MMIO aperture that
44+ * receives 32-bit writes that are passed to queues as wptr values.
45+ * The doorbells are intended to be written by applications as part
46+ * of queueing work on user-mode queues.
47+ * We assign doorbells to applications in PAGE_SIZE-sized and aligned chunks.
48+ * We map the doorbell address space into user-mode when a process creates
49+ * its first queue on each device.
50+ * Although the mapping is done by KFD, it is equivalent to an mmap of
51+ * the /dev/kfd with the particular device encoded in the mmap offset.
52+ * There will be other uses for mmap of /dev/kfd, so only a range of
53+ * offsets (KFD_MMAP_DOORBELL_START-END) is used for doorbells.
54+ */
55+
56+/* # of doorbell bytes allocated for each process. */
57+static inline size_t doorbell_process_allocation(void)
58+{
59+ return roundup(KFD_SIZE_OF_DOORBELL_IN_BYTES *
60+ KFD_MAX_NUM_OF_QUEUES_PER_PROCESS,
61+ PAGE_SIZE);
62+}
63+
64+/* Doorbell calculations for device init. */
65+void kfd_doorbell_init(struct kfd_dev *kfd)
66+{
67+ size_t doorbell_start_offset;
68+ size_t doorbell_aperture_size;
69+ size_t doorbell_process_limit;
70+
71+ /*
72+ * We start with calculations in bytes because the input data might
73+ * only be byte-aligned.
74+ * Only after we have done the rounding can we assume any alignment.
75+ */
76+
77+ doorbell_start_offset =
78+ roundup(kfd->shared_resources.doorbell_start_offset,
79+ doorbell_process_allocation());
80+
81+ doorbell_aperture_size =
82+ rounddown(kfd->shared_resources.doorbell_aperture_size,
83+ doorbell_process_allocation());
84+
85+ if (doorbell_aperture_size > doorbell_start_offset)
86+ doorbell_process_limit =
87+ (doorbell_aperture_size - doorbell_start_offset) /
88+ doorbell_process_allocation();
89+ else
90+ doorbell_process_limit = 0;
91+
92+ kfd->doorbell_base = kfd->shared_resources.doorbell_physical_address +
93+ doorbell_start_offset;
94+
95+ kfd->doorbell_id_offset = doorbell_start_offset / sizeof(u32);
96+ kfd->doorbell_process_limit = doorbell_process_limit - 1;
97+
98+ kfd->doorbell_kernel_ptr = ioremap(kfd->doorbell_base,
99+ doorbell_process_allocation());
100+
101+ BUG_ON(!kfd->doorbell_kernel_ptr);
102+
103+ pr_debug("kfd: doorbell initialization:\n");
104+ pr_debug("kfd: doorbell base == 0x%08lX\n",
105+ (uintptr_t)kfd->doorbell_base);
106+
107+ pr_debug("kfd: doorbell_id_offset == 0x%08lX\n",
108+ kfd->doorbell_id_offset);
109+
110+ pr_debug("kfd: doorbell_process_limit == 0x%08lX\n",
111+ doorbell_process_limit);
112+
113+ pr_debug("kfd: doorbell_kernel_offset == 0x%08lX\n",
114+ (uintptr_t)kfd->doorbell_base);
115+
116+ pr_debug("kfd: doorbell aperture size == 0x%08lX\n",
117+ kfd->shared_resources.doorbell_aperture_size);
118+
119+ pr_debug("kfd: doorbell kernel address == 0x%08lX\n",
120+ (uintptr_t)kfd->doorbell_kernel_ptr);
121+}
122+
123+int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma)
124+{
125+ phys_addr_t address;
126+ struct kfd_dev *dev;
127+
128+ /*
129+ * For simplicitly we only allow mapping of the entire doorbell
130+ * allocation of a single device & process.
131+ */
132+ if (vma->vm_end - vma->vm_start != doorbell_process_allocation())
133+ return -EINVAL;
134+
135+ /* Find kfd device according to gpu id */
136+ dev = kfd_device_by_id(vma->vm_pgoff);
137+ if (dev == NULL)
138+ return -EINVAL;
139+
140+ /* Find if pdd exists for combination of process and gpu id */
141+ if (!kfd_get_process_device_data(dev, process, 0))
142+ return -EINVAL;
143+
144+ /* Calculate physical address of doorbell */
145+ address = kfd_get_process_doorbells(dev, process);
146+
147+ vma->vm_flags |= VM_IO | VM_DONTCOPY | VM_DONTEXPAND | VM_NORESERVE |
148+ VM_DONTDUMP | VM_PFNMAP;
149+
150+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
151+
152+ pr_debug("kfd: mapping doorbell page in kfd_doorbell_mmap\n"
153+ " target user address == 0x%08llX\n"
154+ " physical address == 0x%08llX\n"
155+ " vm_flags == 0x%04lX\n"
156+ " size == 0x%04lX\n",
157+ (unsigned long long) vma->vm_start, address, vma->vm_flags,
158+ doorbell_process_allocation());
159+
160+
161+ return io_remap_pfn_range(vma,
162+ vma->vm_start,
163+ address >> PAGE_SHIFT,
164+ doorbell_process_allocation(),
165+ vma->vm_page_prot);
166+}
167+
168+
169+/* get kernel iomem pointer for a doorbell */
170+u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
171+ unsigned int *doorbell_off)
172+{
173+ u32 inx;
174+
175+ BUG_ON(!kfd || !doorbell_off);
176+
177+ mutex_lock(&doorbell_mutex);
178+ inx = find_first_zero_bit(doorbell_available_index,
179+ KFD_MAX_NUM_OF_QUEUES_PER_PROCESS);
180+
181+ __set_bit(inx, doorbell_available_index);
182+ mutex_unlock(&doorbell_mutex);
183+
184+ if (inx >= KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)
185+ return NULL;
186+
187+ /*
188+ * Calculating the kernel doorbell offset using "faked" kernel
189+ * pasid that allocated for kernel queues only
190+ */
191+ *doorbell_off = KERNEL_DOORBELL_PASID * (doorbell_process_allocation() /
192+ sizeof(u32)) + inx;
193+
194+ pr_debug("kfd: get kernel queue doorbell\n"
195+ " doorbell offset == 0x%08d\n"
196+ " kernel address == 0x%08lX\n",
197+ *doorbell_off, (uintptr_t)(kfd->doorbell_kernel_ptr + inx));
198+
199+ return kfd->doorbell_kernel_ptr + inx;
200+}
201+
202+void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr)
203+{
204+ unsigned int inx;
205+
206+ BUG_ON(!kfd || !db_addr);
207+
208+ inx = (unsigned int)(db_addr - kfd->doorbell_kernel_ptr);
209+
210+ mutex_lock(&doorbell_mutex);
211+ __clear_bit(inx, doorbell_available_index);
212+ mutex_unlock(&doorbell_mutex);
213+}
214+
215+inline void write_kernel_doorbell(u32 __iomem *db, u32 value)
216+{
217+ if (db) {
218+ writel(value, db);
219+ pr_debug("writing %d to doorbell address 0x%p\n", value, db);
220+ }
221+}
222+
223+/*
224+ * queue_ids are in the range [0,MAX_PROCESS_QUEUES) and are mapped 1:1
225+ * to doorbells with the process's doorbell page
226+ */
227+unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd,
228+ struct kfd_process *process,
229+ unsigned int queue_id)
230+{
231+ /*
232+ * doorbell_id_offset accounts for doorbells taken by KGD.
233+ * pasid * doorbell_process_allocation/sizeof(u32) adjusts
234+ * to the process's doorbells
235+ */
236+ return kfd->doorbell_id_offset +
237+ process->pasid * (doorbell_process_allocation()/sizeof(u32)) +
238+ queue_id;
239+}
240+
241+uint64_t kfd_get_number_elems(struct kfd_dev *kfd)
242+{
243+ uint64_t num_of_elems = (kfd->shared_resources.doorbell_aperture_size -
244+ kfd->shared_resources.doorbell_start_offset) /
245+ doorbell_process_allocation() + 1;
246+
247+ return num_of_elems;
248+
249+}
250+
251+phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev,
252+ struct kfd_process *process)
253+{
254+ return dev->doorbell_base +
255+ process->pasid * doorbell_process_allocation();
256+}
drivers/gpu/drm/amd/amdkfd/kfd_flat_memory.c+356−0
@@ -0,0 +1,356 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/device.h>
25+#include <linux/export.h>
26+#include <linux/err.h>
27+#include <linux/fs.h>
28+#include <linux/sched.h>
29+#include <linux/slab.h>
30+#include <linux/uaccess.h>
31+#include <linux/compat.h>
32+#include <uapi/linux/kfd_ioctl.h>
33+#include <linux/time.h>
34+#include "kfd_priv.h"
35+#include <linux/mm.h>
36+#include <uapi/asm-generic/mman-common.h>
37+#include <asm/processor.h>
38+
39+/*
40+ * The primary memory I/O features being added for revisions of gfxip
41+ * beyond 7.0 (Kaveri) are:
42+ *
43+ * Access to ATC/IOMMU mapped memory w/ associated extension of VA to 48b
44+ *
45+ * “Flat” shader memory access – These are new shader vector memory
46+ * operations that do not reference a T#/V# so a “pointer” is what is
47+ * sourced from the vector gprs for direct access to memory.
48+ * This pointer space has the Shared(LDS) and Private(Scratch) memory
49+ * mapped into this pointer space as apertures.
50+ * The hardware then determines how to direct the memory request
51+ * based on what apertures the request falls in.
52+ *
53+ * Unaligned support and alignment check
54+ *
55+ *
56+ * System Unified Address - SUA
57+ *
58+ * The standard usage for GPU virtual addresses are that they are mapped by
59+ * a set of page tables we call GPUVM and these page tables are managed by
60+ * a combination of vidMM/driver software components. The current virtual
61+ * address (VA) range for GPUVM is 40b.
62+ *
63+ * As of gfxip7.1 and beyond we’re adding the ability for compute memory
64+ * clients (CP/RLC, DMA, SHADER(ifetch, scalar, and vector ops)) to access
65+ * the same page tables used by host x86 processors and that are managed by
66+ * the operating system. This is via a technique and hardware called ATC/IOMMU.
67+ * The GPU has the capability of accessing both the GPUVM and ATC address
68+ * spaces for a given VMID (process) simultaneously and we call this feature
69+ * system unified address (SUA).
70+ *
71+ * There are three fundamental address modes of operation for a given VMID
72+ * (process) on the GPU:
73+ *
74+ * HSA64 – 64b pointers and the default address space is ATC
75+ * HSA32 – 32b pointers and the default address space is ATC
76+ * GPUVM – 64b pointers and the default address space is GPUVM (driver
77+ * model mode)
78+ *
79+ *
80+ * HSA64 - ATC/IOMMU 64b
81+ *
82+ * A 64b pointer in the AMD64/IA64 CPU architecture is not fully utilized
83+ * by the CPU so an AMD CPU can only access the high area
84+ * (VA[63:47] == 0x1FFFF) and low area (VA[63:47 == 0) of the address space
85+ * so the actual VA carried to translation is 48b. There is a “hole” in
86+ * the middle of the 64b VA space.
87+ *
88+ * The GPU not only has access to all of the CPU accessible address space via
89+ * ATC/IOMMU, but it also has access to the GPUVM address space. The “system
90+ * unified address” feature (SUA) is the mapping of GPUVM and ATC address
91+ * spaces into a unified pointer space. The method we take for 64b mode is
92+ * to map the full 40b GPUVM address space into the hole of the 64b address
93+ * space.
94+
95+ * The GPUVM_Base/GPUVM_Limit defines the aperture in the 64b space where we
96+ * direct requests to be translated via GPUVM page tables instead of the
97+ * IOMMU path.
98+ *
99+ *
100+ * 64b to 49b Address conversion
101+ *
102+ * Note that there are still significant portions of unused regions (holes)
103+ * in the 64b address space even for the GPU. There are several places in
104+ * the pipeline (sw and hw), we wish to compress the 64b virtual address
105+ * to a 49b address. This 49b address is constituted of an “ATC” bit
106+ * plus a 48b virtual address. This 49b address is what is passed to the
107+ * translation hardware. ATC==0 means the 48b address is a GPUVM address
108+ * (max of 2^40 – 1) intended to be translated via GPUVM page tables.
109+ * ATC==1 means the 48b address is intended to be translated via IOMMU
110+ * page tables.
111+ *
112+ * A 64b pointer is compared to the apertures that are defined (Base/Limit), in
113+ * this case the GPUVM aperture (red) is defined and if a pointer falls in this
114+ * aperture, we subtract the GPUVM_Base address and set the ATC bit to zero
115+ * as part of the 64b to 49b conversion.
116+ *
117+ * Where this 64b to 49b conversion is done is a function of the usage.
118+ * Most GPU memory access is via memory objects where the driver builds
119+ * a descriptor which consists of a base address and a memory access by
120+ * the GPU usually consists of some kind of an offset or Cartesian coordinate
121+ * that references this memory descriptor. This is the case for shader
122+ * instructions that reference the T# or V# constants, or for specified
123+ * locations of assets (ex. the shader program location). In these cases
124+ * the driver is what handles the 64b to 49b conversion and the base
125+ * address in the descriptor (ex. V# or T# or shader program location)
126+ * is defined as a 48b address w/ an ATC bit. For this usage a given
127+ * memory object cannot straddle multiple apertures in the 64b address
128+ * space. For example a shader program cannot jump in/out between ATC
129+ * and GPUVM space.
130+ *
131+ * In some cases we wish to pass a 64b pointer to the GPU hardware and
132+ * the GPU hw does the 64b to 49b conversion before passing memory
133+ * requests to the cache/memory system. This is the case for the
134+ * S_LOAD and FLAT_* shader memory instructions where we have 64b pointers
135+ * in scalar and vector GPRs respectively.
136+ *
137+ * In all cases (no matter where the 64b -> 49b conversion is done), the gfxip
138+ * hardware sends a 48b address along w/ an ATC bit, to the memory controller
139+ * on the memory request interfaces.
140+ *
141+ * <client>_MC_rdreq_atc // read request ATC bit
142+ *
143+ * 0 : <client>_MC_rdreq_addr is a GPUVM VA
144+ *
145+ * 1 : <client>_MC_rdreq_addr is a ATC VA
146+ *
147+ *
148+ * “Spare” aperture (APE1)
149+ *
150+ * We use the GPUVM aperture to differentiate ATC vs. GPUVM, but we also use
151+ * apertures to set the Mtype field for S_LOAD/FLAT_* ops which is input to the
152+ * config tables for setting cache policies. The “spare” (APE1) aperture is
153+ * motivated by getting a different Mtype from the default.
154+ * The default aperture isn’t an actual base/limit aperture; it is just the
155+ * address space that doesn’t hit any defined base/limit apertures.
156+ * The following diagram is a complete picture of the gfxip7.x SUA apertures.
157+ * The APE1 can be placed either below or above
158+ * the hole (cannot be in the hole).
159+ *
160+ *
161+ * General Aperture definitions and rules
162+ *
163+ * An aperture register definition consists of a Base, Limit, Mtype, and
164+ * usually an ATC bit indicating which translation tables that aperture uses.
165+ * In all cases (for SUA and DUA apertures discussed later), aperture base
166+ * and limit definitions are 64KB aligned.
167+ *
168+ * <ape>_Base[63:0] = { <ape>_Base_register[63:16], 0x0000 }
169+ *
170+ * <ape>_Limit[63:0] = { <ape>_Limit_register[63:16], 0xFFFF }
171+ *
172+ * The base and limit are considered inclusive to an aperture so being
173+ * inside an aperture means (address >= Base) AND (address <= Limit).
174+ *
175+ * In no case is a payload that straddles multiple apertures expected to work.
176+ * For example a load_dword_x4 that starts in one aperture and ends in another,
177+ * does not work. For the vector FLAT_* ops we have detection capability in
178+ * the shader for reporting a “memory violation” back to the
179+ * SQ block for use in traps.
180+ * A memory violation results when an op falls into the hole,
181+ * or a payload straddles multiple apertures. The S_LOAD instruction
182+ * does not have this detection.
183+ *
184+ * Apertures cannot overlap.
185+ *
186+ *
187+ *
188+ * HSA32 - ATC/IOMMU 32b
189+ *
190+ * For HSA32 mode, the pointers are interpreted as 32 bits and use a single GPR
191+ * instead of two for the S_LOAD and FLAT_* ops. The entire GPUVM space of 40b
192+ * will not fit so there is only partial visibility to the GPUVM
193+ * space (defined by the aperture) for S_LOAD and FLAT_* ops.
194+ * There is no spare (APE1) aperture for HSA32 mode.
195+ *
196+ *
197+ * GPUVM 64b mode (driver model)
198+ *
199+ * This mode is related to HSA64 in that the difference really is that
200+ * the default aperture is GPUVM (ATC==0) and not ATC space.
201+ * We have gfxip7.x hardware that has FLAT_* and S_LOAD support for
202+ * SUA GPUVM mode, but does not support HSA32/HSA64.
203+ *
204+ *
205+ * Device Unified Address - DUA
206+ *
207+ * Device unified address (DUA) is the name of the feature that maps the
208+ * Shared(LDS) memory and Private(Scratch) memory into the overall address
209+ * space for use by the new FLAT_* vector memory ops. The Shared and
210+ * Private memories are mapped as apertures into the address space,
211+ * and the hardware detects when a FLAT_* memory request is to be redirected
212+ * to the LDS or Scratch memory when it falls into one of these apertures.
213+ * Like the SUA apertures, the Shared/Private apertures are 64KB aligned and
214+ * the base/limit is “in” the aperture. For both HSA64 and GPUVM SUA modes,
215+ * the Shared/Private apertures are always placed in a limited selection of
216+ * options in the hole of the 64b address space. For HSA32 mode, the
217+ * Shared/Private apertures can be placed anywhere in the 32b space
218+ * except at 0.
219+ *
220+ *
221+ * HSA64 Apertures for FLAT_* vector ops
222+ *
223+ * For HSA64 SUA mode, the Shared and Private apertures are always placed
224+ * in the hole w/ a limited selection of possible locations. The requests
225+ * that fall in the private aperture are expanded as a function of the
226+ * work-item id (tid) and redirected to the location of the
227+ * “hidden private memory”. The hidden private can be placed in either GPUVM
228+ * or ATC space. The addresses that fall in the shared aperture are
229+ * re-directed to the on-chip LDS memory hardware.
230+ *
231+ *
232+ * HSA32 Apertures for FLAT_* vector ops
233+ *
234+ * In HSA32 mode, the Private and Shared apertures can be placed anywhere
235+ * in the 32b space except at 0 (Private or Shared Base at zero disables
236+ * the apertures). If the base address of the apertures are non-zero
237+ * (ie apertures exists), the size is always 64KB.
238+ *
239+ *
240+ * GPUVM Apertures for FLAT_* vector ops
241+ *
242+ * In GPUVM mode, the Shared/Private apertures are specified identically
243+ * to HSA64 mode where they are always in the hole at a limited selection
244+ * of locations.
245+ *
246+ *
247+ * Aperture Definitions for SUA and DUA
248+ *
249+ * The interpretation of the aperture register definitions for a given
250+ * VMID is a function of the “SUA Mode” which is one of HSA64, HSA32, or
251+ * GPUVM64 discussed in previous sections. The mode is first decoded, and
252+ * then the remaining register decode is a function of the mode.
253+ *
254+ *
255+ * SUA Mode Decode
256+ *
257+ * For the S_LOAD and FLAT_* shader operations, the SUA mode is decoded from
258+ * the COMPUTE_DISPATCH_INITIATOR:DATA_ATC bit and
259+ * the SH_MEM_CONFIG:PTR32 bits.
260+ *
261+ * COMPUTE_DISPATCH_INITIATOR:DATA_ATC SH_MEM_CONFIG:PTR32 Mode
262+ *
263+ * 1 0 HSA64
264+ *
265+ * 1 1 HSA32
266+ *
267+ * 0 X GPUVM64
268+ *
269+ * In general the hardware will ignore the PTR32 bit and treat
270+ * as “0” whenever DATA_ATC = “0”, but sw should set PTR32=0
271+ * when DATA_ATC=0.
272+ *
273+ * The DATA_ATC bit is only set for compute dispatches.
274+ * All “Draw” dispatches are hardcoded to GPUVM64 mode
275+ * for FLAT_* / S_LOAD operations.
276+ */
277+
278+#define MAKE_GPUVM_APP_BASE(gpu_num) \
279+ (((uint64_t)(gpu_num) << 61) + 0x1000000000000L)
280+
281+#define MAKE_GPUVM_APP_LIMIT(base) \
282+ (((uint64_t)(base) & \
283+ 0xFFFFFF0000000000UL) | 0xFFFFFFFFFFL)
284+
285+#define MAKE_SCRATCH_APP_BASE(gpu_num) \
286+ (((uint64_t)(gpu_num) << 61) + 0x100000000L)
287+
288+#define MAKE_SCRATCH_APP_LIMIT(base) \
289+ (((uint64_t)base & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
290+
291+#define MAKE_LDS_APP_BASE(gpu_num) \
292+ (((uint64_t)(gpu_num) << 61) + 0x0)
293+#define MAKE_LDS_APP_LIMIT(base) \
294+ (((uint64_t)(base) & 0xFFFFFFFF00000000UL) | 0xFFFFFFFF)
295+
296+int kfd_init_apertures(struct kfd_process *process)
297+{
298+ uint8_t id = 0;
299+ struct kfd_dev *dev;
300+ struct kfd_process_device *pdd;
301+
302+ mutex_lock(&process->mutex);
303+
304+ /*Iterating over all devices*/
305+ while ((dev = kfd_topology_enum_kfd_devices(id)) != NULL &&
306+ id < NUM_OF_SUPPORTED_GPUS) {
307+
308+ pdd = kfd_get_process_device_data(dev, process, 1);
309+
310+ /*
311+ * For 64 bit process aperture will be statically reserved in
312+ * the x86_64 non canonical process address space
313+ * amdkfd doesn't currently support apertures for 32 bit process
314+ */
315+ if (process->is_32bit_user_mode) {
316+ pdd->lds_base = pdd->lds_limit = 0;
317+ pdd->gpuvm_base = pdd->gpuvm_limit = 0;
318+ pdd->scratch_base = pdd->scratch_limit = 0;
319+ } else {
320+ /*
321+ * node id couldn't be 0 - the three MSB bits of
322+ * aperture shoudn't be 0
323+ */
324+ pdd->lds_base = MAKE_LDS_APP_BASE(id + 1);
325+
326+ pdd->lds_limit = MAKE_LDS_APP_LIMIT(pdd->lds_base);
327+
328+ pdd->gpuvm_base = MAKE_GPUVM_APP_BASE(id + 1);
329+
330+ pdd->gpuvm_limit =
331+ MAKE_GPUVM_APP_LIMIT(pdd->gpuvm_base);
332+
333+ pdd->scratch_base = MAKE_SCRATCH_APP_BASE(id + 1);
334+
335+ pdd->scratch_limit =
336+ MAKE_SCRATCH_APP_LIMIT(pdd->scratch_base);
337+ }
338+
339+ dev_dbg(kfd_device, "node id %u\n", id);
340+ dev_dbg(kfd_device, "gpu id %u\n", pdd->dev->id);
341+ dev_dbg(kfd_device, "lds_base %llX\n", pdd->lds_base);
342+ dev_dbg(kfd_device, "lds_limit %llX\n", pdd->lds_limit);
343+ dev_dbg(kfd_device, "gpuvm_base %llX\n", pdd->gpuvm_base);
344+ dev_dbg(kfd_device, "gpuvm_limit %llX\n", pdd->gpuvm_limit);
345+ dev_dbg(kfd_device, "scratch_base %llX\n", pdd->scratch_base);
346+ dev_dbg(kfd_device, "scratch_limit %llX\n", pdd->scratch_limit);
347+
348+ id++;
349+ }
350+
351+ mutex_unlock(&process->mutex);
352+
353+ return 0;
354+}
355+
356+
drivers/gpu/drm/amd/amdkfd/kfd_interrupt.c+176−0
@@ -0,0 +1,176 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+/*
24+ * KFD Interrupts.
25+ *
26+ * AMD GPUs deliver interrupts by pushing an interrupt description onto the
27+ * interrupt ring and then sending an interrupt. KGD receives the interrupt
28+ * in ISR and sends us a pointer to each new entry on the interrupt ring.
29+ *
30+ * We generally can't process interrupt-signaled events from ISR, so we call
31+ * out to each interrupt client module (currently only the scheduler) to ask if
32+ * each interrupt is interesting. If they return true, then it requires further
33+ * processing so we copy it to an internal interrupt ring and call each
34+ * interrupt client again from a work-queue.
35+ *
36+ * There's no acknowledgment for the interrupts we use. The hardware simply
37+ * queues a new interrupt each time without waiting.
38+ *
39+ * The fixed-size internal queue means that it's possible for us to lose
40+ * interrupts because we have no back-pressure to the hardware.
41+ */
42+
43+#include <linux/slab.h>
44+#include <linux/device.h>
45+#include "kfd_priv.h"
46+
47+#define KFD_INTERRUPT_RING_SIZE 256
48+
49+static void interrupt_wq(struct work_struct *);
50+
51+int kfd_interrupt_init(struct kfd_dev *kfd)
52+{
53+ void *interrupt_ring = kmalloc_array(KFD_INTERRUPT_RING_SIZE,
54+ kfd->device_info->ih_ring_entry_size,
55+ GFP_KERNEL);
56+ if (!interrupt_ring)
57+ return -ENOMEM;
58+
59+ kfd->interrupt_ring = interrupt_ring;
60+ kfd->interrupt_ring_size =
61+ KFD_INTERRUPT_RING_SIZE * kfd->device_info->ih_ring_entry_size;
62+ atomic_set(&kfd->interrupt_ring_wptr, 0);
63+ atomic_set(&kfd->interrupt_ring_rptr, 0);
64+
65+ spin_lock_init(&kfd->interrupt_lock);
66+
67+ INIT_WORK(&kfd->interrupt_work, interrupt_wq);
68+
69+ kfd->interrupts_active = true;
70+
71+ /*
72+ * After this function returns, the interrupt will be enabled. This
73+ * barrier ensures that the interrupt running on a different processor
74+ * sees all the above writes.
75+ */
76+ smp_wmb();
77+
78+ return 0;
79+}
80+
81+void kfd_interrupt_exit(struct kfd_dev *kfd)
82+{
83+ /*
84+ * Stop the interrupt handler from writing to the ring and scheduling
85+ * workqueue items. The spinlock ensures that any interrupt running
86+ * after we have unlocked sees interrupts_active = false.
87+ */
88+ unsigned long flags;
89+
90+ spin_lock_irqsave(&kfd->interrupt_lock, flags);
91+ kfd->interrupts_active = false;
92+ spin_unlock_irqrestore(&kfd->interrupt_lock, flags);
93+
94+ /*
95+ * Flush_scheduled_work ensures that there are no outstanding
96+ * work-queue items that will access interrupt_ring. New work items
97+ * can't be created because we stopped interrupt handling above.
98+ */
99+ flush_scheduled_work();
100+
101+ kfree(kfd->interrupt_ring);
102+}
103+
104+/*
105+ * This assumes that it can't be called concurrently with itself
106+ * but only with dequeue_ih_ring_entry.
107+ */
108+bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry)
109+{
110+ unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr);
111+ unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr);
112+
113+ if ((rptr - wptr) % kfd->interrupt_ring_size ==
114+ kfd->device_info->ih_ring_entry_size) {
115+ /* This is very bad, the system is likely to hang. */
116+ dev_err_ratelimited(kfd_chardev(),
117+ "Interrupt ring overflow, dropping interrupt.\n");
118+ return false;
119+ }
120+
121+ memcpy(kfd->interrupt_ring + wptr, ih_ring_entry,
122+ kfd->device_info->ih_ring_entry_size);
123+
124+ wptr = (wptr + kfd->device_info->ih_ring_entry_size) %
125+ kfd->interrupt_ring_size;
126+ smp_wmb(); /* Ensure memcpy'd data is visible before wptr update. */
127+ atomic_set(&kfd->interrupt_ring_wptr, wptr);
128+
129+ return true;
130+}
131+
132+/*
133+ * This assumes that it can't be called concurrently with itself
134+ * but only with enqueue_ih_ring_entry.
135+ */
136+static bool dequeue_ih_ring_entry(struct kfd_dev *kfd, void *ih_ring_entry)
137+{
138+ /*
139+ * Assume that wait queues have an implicit barrier, i.e. anything that
140+ * happened in the ISR before it queued work is visible.
141+ */
142+
143+ unsigned int wptr = atomic_read(&kfd->interrupt_ring_wptr);
144+ unsigned int rptr = atomic_read(&kfd->interrupt_ring_rptr);
145+
146+ if (rptr == wptr)
147+ return false;
148+
149+ memcpy(ih_ring_entry, kfd->interrupt_ring + rptr,
150+ kfd->device_info->ih_ring_entry_size);
151+
152+ rptr = (rptr + kfd->device_info->ih_ring_entry_size) %
153+ kfd->interrupt_ring_size;
154+
155+ /*
156+ * Ensure the rptr write update is not visible until
157+ * memcpy has finished reading.
158+ */
159+ smp_mb();
160+ atomic_set(&kfd->interrupt_ring_rptr, rptr);
161+
162+ return true;
163+}
164+
165+static void interrupt_wq(struct work_struct *work)
166+{
167+ struct kfd_dev *dev = container_of(work, struct kfd_dev,
168+ interrupt_work);
169+
170+ uint32_t ih_ring_entry[DIV_ROUND_UP(
171+ dev->device_info->ih_ring_entry_size,
172+ sizeof(uint32_t))];
173+
174+ while (dequeue_ih_ring_entry(dev, ih_ring_entry))
175+ ;
176+}
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.c+353−0
@@ -0,0 +1,353 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/types.h>
25+#include <linux/mutex.h>
26+#include <linux/slab.h>
27+#include <linux/printk.h>
28+#include <linux/sched.h>
29+#include "kfd_kernel_queue.h"
30+#include "kfd_priv.h"
31+#include "kfd_device_queue_manager.h"
32+#include "kfd_pm4_headers.h"
33+#include "kfd_pm4_opcodes.h"
34+
35+#define PM4_COUNT_ZERO (((1 << 15) - 1) << 16)
36+
37+static bool initialize(struct kernel_queue *kq, struct kfd_dev *dev,
38+ enum kfd_queue_type type, unsigned int queue_size)
39+{
40+ struct queue_properties prop;
41+ int retval;
42+ union PM4_MES_TYPE_3_HEADER nop;
43+
44+ BUG_ON(!kq || !dev);
45+ BUG_ON(type != KFD_QUEUE_TYPE_DIQ && type != KFD_QUEUE_TYPE_HIQ);
46+
47+ pr_debug("kfd: In func %s initializing queue type %d size %d\n",
48+ __func__, KFD_QUEUE_TYPE_HIQ, queue_size);
49+
50+ nop.opcode = IT_NOP;
51+ nop.type = PM4_TYPE_3;
52+ nop.u32all |= PM4_COUNT_ZERO;
53+
54+ kq->dev = dev;
55+ kq->nop_packet = nop.u32all;
56+ switch (type) {
57+ case KFD_QUEUE_TYPE_DIQ:
58+ case KFD_QUEUE_TYPE_HIQ:
59+ kq->mqd = dev->dqm->get_mqd_manager(dev->dqm,
60+ KFD_MQD_TYPE_CIK_HIQ);
61+ break;
62+ default:
63+ BUG();
64+ break;
65+ }
66+
67+ if (kq->mqd == NULL)
68+ return false;
69+
70+ prop.doorbell_ptr = kfd_get_kernel_doorbell(dev, &prop.doorbell_off);
71+
72+ if (prop.doorbell_ptr == NULL)
73+ goto err_get_kernel_doorbell;
74+
75+ retval = kfd2kgd->allocate_mem(dev->kgd,
76+ queue_size,
77+ PAGE_SIZE,
78+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
79+ (struct kgd_mem **) &kq->pq);
80+
81+ if (retval != 0)
82+ goto err_pq_allocate_vidmem;
83+
84+ kq->pq_kernel_addr = kq->pq->cpu_ptr;
85+ kq->pq_gpu_addr = kq->pq->gpu_addr;
86+
87+ retval = kfd2kgd->allocate_mem(dev->kgd,
88+ sizeof(*kq->rptr_kernel),
89+ 32,
90+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
91+ (struct kgd_mem **) &kq->rptr_mem);
92+
93+ if (retval != 0)
94+ goto err_rptr_allocate_vidmem;
95+
96+ kq->rptr_kernel = kq->rptr_mem->cpu_ptr;
97+ kq->rptr_gpu_addr = kq->rptr_mem->gpu_addr;
98+
99+ retval = kfd2kgd->allocate_mem(dev->kgd,
100+ sizeof(*kq->wptr_kernel),
101+ 32,
102+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
103+ (struct kgd_mem **) &kq->wptr_mem);
104+
105+ if (retval != 0)
106+ goto err_wptr_allocate_vidmem;
107+
108+ kq->wptr_kernel = kq->wptr_mem->cpu_ptr;
109+ kq->wptr_gpu_addr = kq->wptr_mem->gpu_addr;
110+
111+ memset(kq->pq_kernel_addr, 0, queue_size);
112+ memset(kq->rptr_kernel, 0, sizeof(*kq->rptr_kernel));
113+ memset(kq->wptr_kernel, 0, sizeof(*kq->wptr_kernel));
114+
115+ prop.queue_size = queue_size;
116+ prop.is_interop = false;
117+ prop.priority = 1;
118+ prop.queue_percent = 100;
119+ prop.type = type;
120+ prop.vmid = 0;
121+ prop.queue_address = kq->pq_gpu_addr;
122+ prop.read_ptr = (uint32_t *) kq->rptr_gpu_addr;
123+ prop.write_ptr = (uint32_t *) kq->wptr_gpu_addr;
124+
125+ if (init_queue(&kq->queue, prop) != 0)
126+ goto err_init_queue;
127+
128+ kq->queue->device = dev;
129+ kq->queue->process = kfd_get_process(current);
130+
131+ retval = kq->mqd->init_mqd(kq->mqd, &kq->queue->mqd,
132+ &kq->queue->mqd_mem_obj,
133+ &kq->queue->gart_mqd_addr,
134+ &kq->queue->properties);
135+ if (retval != 0)
136+ goto err_init_mqd;
137+
138+ /* assign HIQ to HQD */
139+ if (type == KFD_QUEUE_TYPE_HIQ) {
140+ pr_debug("assigning hiq to hqd\n");
141+ kq->queue->pipe = KFD_CIK_HIQ_PIPE;
142+ kq->queue->queue = KFD_CIK_HIQ_QUEUE;
143+ kq->mqd->load_mqd(kq->mqd, kq->queue->mqd, kq->queue->pipe,
144+ kq->queue->queue, NULL);
145+ } else {
146+ /* allocate fence for DIQ */
147+
148+ retval = kfd2kgd->allocate_mem(dev->kgd,
149+ sizeof(uint32_t),
150+ 32,
151+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
152+ (struct kgd_mem **) &kq->fence_mem_obj);
153+
154+ if (retval != 0)
155+ goto err_alloc_fence;
156+
157+ kq->fence_kernel_address = kq->fence_mem_obj->cpu_ptr;
158+ kq->fence_gpu_addr = kq->fence_mem_obj->gpu_addr;
159+ }
160+
161+ print_queue(kq->queue);
162+
163+ return true;
164+err_alloc_fence:
165+err_init_mqd:
166+ uninit_queue(kq->queue);
167+err_init_queue:
168+ kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->wptr_mem);
169+err_wptr_allocate_vidmem:
170+ kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->rptr_mem);
171+err_rptr_allocate_vidmem:
172+ kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq);
173+err_pq_allocate_vidmem:
174+ pr_err("kfd: error init pq\n");
175+ kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
176+err_get_kernel_doorbell:
177+ pr_err("kfd: error init doorbell");
178+ return false;
179+
180+}
181+
182+static void uninitialize(struct kernel_queue *kq)
183+{
184+ BUG_ON(!kq);
185+
186+ if (kq->queue->properties.type == KFD_QUEUE_TYPE_HIQ)
187+ kq->mqd->destroy_mqd(kq->mqd,
188+ NULL,
189+ false,
190+ QUEUE_PREEMPT_DEFAULT_TIMEOUT_MS,
191+ kq->queue->pipe,
192+ kq->queue->queue);
193+
194+ kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->rptr_mem);
195+ kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->wptr_mem);
196+ kfd2kgd->free_mem(kq->dev->kgd, (struct kgd_mem *) kq->pq);
197+ kfd_release_kernel_doorbell(kq->dev,
198+ kq->queue->properties.doorbell_ptr);
199+ uninit_queue(kq->queue);
200+}
201+
202+static int acquire_packet_buffer(struct kernel_queue *kq,
203+ size_t packet_size_in_dwords, unsigned int **buffer_ptr)
204+{
205+ size_t available_size;
206+ size_t queue_size_dwords;
207+ uint32_t wptr, rptr;
208+ unsigned int *queue_address;
209+
210+ BUG_ON(!kq || !buffer_ptr);
211+
212+ rptr = *kq->rptr_kernel;
213+ wptr = *kq->wptr_kernel;
214+ queue_address = (unsigned int *)kq->pq_kernel_addr;
215+ queue_size_dwords = kq->queue->properties.queue_size / sizeof(uint32_t);
216+
217+ pr_debug("kfd: In func %s\nrptr: %d\nwptr: %d\nqueue_address 0x%p\n",
218+ __func__, rptr, wptr, queue_address);
219+
220+ available_size = (rptr - 1 - wptr + queue_size_dwords) %
221+ queue_size_dwords;
222+
223+ if (packet_size_in_dwords >= queue_size_dwords ||
224+ packet_size_in_dwords >= available_size) {
225+ /*
226+ * make sure calling functions know
227+ * acquire_packet_buffer() failed
228+ */
229+ *buffer_ptr = NULL;
230+ return -ENOMEM;
231+ }
232+
233+ if (wptr + packet_size_in_dwords >= queue_size_dwords) {
234+ while (wptr > 0) {
235+ queue_address[wptr] = kq->nop_packet;
236+ wptr = (wptr + 1) % queue_size_dwords;
237+ }
238+ }
239+
240+ *buffer_ptr = &queue_address[wptr];
241+ kq->pending_wptr = wptr + packet_size_in_dwords;
242+
243+ return 0;
244+}
245+
246+static void submit_packet(struct kernel_queue *kq)
247+{
248+#ifdef DEBUG
249+ int i;
250+#endif
251+
252+ BUG_ON(!kq);
253+
254+#ifdef DEBUG
255+ for (i = *kq->wptr_kernel; i < kq->pending_wptr; i++) {
256+ pr_debug("0x%2X ", kq->pq_kernel_addr[i]);
257+ if (i % 15 == 0)
258+ pr_debug("\n");
259+ }
260+ pr_debug("\n");
261+#endif
262+
263+ *kq->wptr_kernel = kq->pending_wptr;
264+ write_kernel_doorbell(kq->queue->properties.doorbell_ptr,
265+ kq->pending_wptr);
266+}
267+
268+static int sync_with_hw(struct kernel_queue *kq, unsigned long timeout_ms)
269+{
270+ unsigned long org_timeout_ms;
271+
272+ BUG_ON(!kq);
273+
274+ org_timeout_ms = timeout_ms;
275+ timeout_ms += jiffies * 1000 / HZ;
276+ while (*kq->wptr_kernel != *kq->rptr_kernel) {
277+ if (time_after(jiffies * 1000 / HZ, timeout_ms)) {
278+ pr_err("kfd: kernel_queue %s timeout expired %lu\n",
279+ __func__, org_timeout_ms);
280+ pr_err("kfd: wptr: %d rptr: %d\n",
281+ *kq->wptr_kernel, *kq->rptr_kernel);
282+ return -ETIME;
283+ }
284+ schedule();
285+ }
286+
287+ return 0;
288+}
289+
290+static void rollback_packet(struct kernel_queue *kq)
291+{
292+ BUG_ON(!kq);
293+ kq->pending_wptr = *kq->queue->properties.write_ptr;
294+}
295+
296+struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
297+ enum kfd_queue_type type)
298+{
299+ struct kernel_queue *kq;
300+
301+ BUG_ON(!dev);
302+
303+ kq = kzalloc(sizeof(struct kernel_queue), GFP_KERNEL);
304+ if (!kq)
305+ return NULL;
306+
307+ kq->initialize = initialize;
308+ kq->uninitialize = uninitialize;
309+ kq->acquire_packet_buffer = acquire_packet_buffer;
310+ kq->submit_packet = submit_packet;
311+ kq->sync_with_hw = sync_with_hw;
312+ kq->rollback_packet = rollback_packet;
313+
314+ if (kq->initialize(kq, dev, type, KFD_KERNEL_QUEUE_SIZE) == false) {
315+ pr_err("kfd: failed to init kernel queue\n");
316+ kfree(kq);
317+ return NULL;
318+ }
319+ return kq;
320+}
321+
322+void kernel_queue_uninit(struct kernel_queue *kq)
323+{
324+ BUG_ON(!kq);
325+
326+ kq->uninitialize(kq);
327+ kfree(kq);
328+}
329+
330+static __attribute__((unused)) void test_kq(struct kfd_dev *dev)
331+{
332+ struct kernel_queue *kq;
333+ uint32_t *buffer, i;
334+ int retval;
335+
336+ BUG_ON(!dev);
337+
338+ pr_debug("kfd: starting kernel queue test\n");
339+
340+ kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_HIQ);
341+ BUG_ON(!kq);
342+
343+ retval = kq->acquire_packet_buffer(kq, 5, &buffer);
344+ BUG_ON(retval != 0);
345+ for (i = 0; i < 5; i++)
346+ buffer[i] = kq->nop_packet;
347+ kq->submit_packet(kq);
348+ kq->sync_with_hw(kq, 1000);
349+
350+ pr_debug("kfd: ending kernel queue test\n");
351+}
352+
353+
drivers/gpu/drm/amd/amdkfd/kfd_kernel_queue.h+69−0
@@ -0,0 +1,69 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#ifndef KFD_KERNEL_QUEUE_H_
25+#define KFD_KERNEL_QUEUE_H_
26+
27+#include <linux/list.h>
28+#include <linux/types.h>
29+#include "kfd_priv.h"
30+
31+struct kernel_queue {
32+ /* interface */
33+ bool (*initialize)(struct kernel_queue *kq, struct kfd_dev *dev,
34+ enum kfd_queue_type type, unsigned int queue_size);
35+ void (*uninitialize)(struct kernel_queue *kq);
36+ int (*acquire_packet_buffer)(struct kernel_queue *kq,
37+ size_t packet_size_in_dwords,
38+ unsigned int **buffer_ptr);
39+
40+ void (*submit_packet)(struct kernel_queue *kq);
41+ int (*sync_with_hw)(struct kernel_queue *kq,
42+ unsigned long timeout_ms);
43+ void (*rollback_packet)(struct kernel_queue *kq);
44+
45+ /* data */
46+ struct kfd_dev *dev;
47+ struct mqd_manager *mqd;
48+ struct queue *queue;
49+ uint32_t pending_wptr;
50+ unsigned int nop_packet;
51+
52+ struct kfd_mem_obj *rptr_mem;
53+ uint32_t *rptr_kernel;
54+ uint64_t rptr_gpu_addr;
55+ struct kfd_mem_obj *wptr_mem;
56+ uint32_t *wptr_kernel;
57+ uint64_t wptr_gpu_addr;
58+ struct kfd_mem_obj *pq;
59+ uint64_t pq_gpu_addr;
60+ uint32_t *pq_kernel_addr;
61+
62+ struct kfd_mem_obj *fence_mem_obj;
63+ uint64_t fence_gpu_addr;
64+ void *fence_kernel_address;
65+
66+ struct list_head list;
67+};
68+
69+#endif /* KFD_KERNEL_QUEUE_H_ */
drivers/gpu/drm/amd/amdkfd/kfd_module.c+159−0
@@ -0,0 +1,159 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/module.h>
24+#include <linux/sched.h>
25+#include <linux/moduleparam.h>
26+#include <linux/device.h>
27+#include "kfd_priv.h"
28+
29+#define KFD_DRIVER_AUTHOR "AMD Inc. and others"
30+
31+#define KFD_DRIVER_DESC "Standalone HSA driver for AMD's GPUs"
32+#define KFD_DRIVER_DATE "20141113"
33+#define KFD_DRIVER_MAJOR 0
34+#define KFD_DRIVER_MINOR 7
35+#define KFD_DRIVER_PATCHLEVEL 0
36+
37+const struct kfd2kgd_calls *kfd2kgd;
38+static const struct kgd2kfd_calls kgd2kfd = {
39+ .exit = kgd2kfd_exit,
40+ .probe = kgd2kfd_probe,
41+ .device_init = kgd2kfd_device_init,
42+ .device_exit = kgd2kfd_device_exit,
43+ .interrupt = kgd2kfd_interrupt,
44+ .suspend = kgd2kfd_suspend,
45+ .resume = kgd2kfd_resume,
46+};
47+
48+int sched_policy = KFD_SCHED_POLICY_HWS;
49+module_param(sched_policy, int, 0444);
50+MODULE_PARM_DESC(sched_policy,
51+ "Kernel cmdline parameter that defines the amdkfd scheduling policy");
52+
53+int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT;
54+module_param(max_num_of_processes, int, 0444);
55+MODULE_PARM_DESC(max_num_of_processes,
56+ "Kernel cmdline parameter that defines the amdkfd maximum number of supported processes");
57+
58+int max_num_of_queues_per_process = KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT;
59+module_param(max_num_of_queues_per_process, int, 0444);
60+MODULE_PARM_DESC(max_num_of_queues_per_process,
61+ "Kernel cmdline parameter that defines the amdkfd maximum number of supported queues per process");
62+
63+bool kgd2kfd_init(unsigned interface_version,
64+ const struct kfd2kgd_calls *f2g,
65+ const struct kgd2kfd_calls **g2f)
66+{
67+ /*
68+ * Only one interface version is supported,
69+ * no kfd/kgd version skew allowed.
70+ */
71+ if (interface_version != KFD_INTERFACE_VERSION)
72+ return false;
73+
74+ /* Protection against multiple amd kgd loads */
75+ if (kfd2kgd)
76+ return true;
77+
78+ kfd2kgd = f2g;
79+ *g2f = &kgd2kfd;
80+
81+ return true;
82+}
83+EXPORT_SYMBOL(kgd2kfd_init);
84+
85+void kgd2kfd_exit(void)
86+{
87+}
88+
89+static int __init kfd_module_init(void)
90+{
91+ int err;
92+
93+ kfd2kgd = NULL;
94+
95+ /* Verify module parameters */
96+ if ((sched_policy < KFD_SCHED_POLICY_HWS) ||
97+ (sched_policy > KFD_SCHED_POLICY_NO_HWS)) {
98+ pr_err("kfd: sched_policy has invalid value\n");
99+ return -1;
100+ }
101+
102+ /* Verify module parameters */
103+ if ((max_num_of_processes < 0) ||
104+ (max_num_of_processes > KFD_MAX_NUM_OF_PROCESSES)) {
105+ pr_err("kfd: max_num_of_processes must be between 0 to KFD_MAX_NUM_OF_PROCESSES\n");
106+ return -1;
107+ }
108+
109+ if ((max_num_of_queues_per_process < 0) ||
110+ (max_num_of_queues_per_process >
111+ KFD_MAX_NUM_OF_QUEUES_PER_PROCESS)) {
112+ pr_err("kfd: max_num_of_queues_per_process must be between 0 to KFD_MAX_NUM_OF_QUEUES_PER_PROCESS\n");
113+ return -1;
114+ }
115+
116+ err = kfd_pasid_init();
117+ if (err < 0)
118+ goto err_pasid;
119+
120+ err = kfd_chardev_init();
121+ if (err < 0)
122+ goto err_ioctl;
123+
124+ err = kfd_topology_init();
125+ if (err < 0)
126+ goto err_topology;
127+
128+ kfd_process_create_wq();
129+
130+ dev_info(kfd_device, "Initialized module\n");
131+
132+ return 0;
133+
134+err_topology:
135+ kfd_chardev_exit();
136+err_ioctl:
137+ kfd_pasid_exit();
138+err_pasid:
139+ return err;
140+}
141+
142+static void __exit kfd_module_exit(void)
143+{
144+ kfd_process_destroy_wq();
145+ kfd_topology_shutdown();
146+ kfd_chardev_exit();
147+ kfd_pasid_exit();
148+ dev_info(kfd_device, "Removed module\n");
149+}
150+
151+module_init(kfd_module_init);
152+module_exit(kfd_module_exit);
153+
154+MODULE_AUTHOR(KFD_DRIVER_AUTHOR);
155+MODULE_DESCRIPTION(KFD_DRIVER_DESC);
156+MODULE_LICENSE("GPL and additional rights");
157+MODULE_VERSION(__stringify(KFD_DRIVER_MAJOR) "."
158+ __stringify(KFD_DRIVER_MINOR) "."
159+ __stringify(KFD_DRIVER_PATCHLEVEL));
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c+346−0
@@ -0,0 +1,346 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/printk.h>
25+#include <linux/slab.h>
26+#include "kfd_priv.h"
27+#include "kfd_mqd_manager.h"
28+#include "cik_regs.h"
29+#include "../../radeon/cik_reg.h"
30+
31+inline void busy_wait(unsigned long ms)
32+{
33+ while (time_before(jiffies, ms))
34+ cpu_relax();
35+}
36+
37+static inline struct cik_mqd *get_mqd(void *mqd)
38+{
39+ return (struct cik_mqd *)mqd;
40+}
41+
42+static int init_mqd(struct mqd_manager *mm, void **mqd,
43+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
44+ struct queue_properties *q)
45+{
46+ uint64_t addr;
47+ struct cik_mqd *m;
48+ int retval;
49+
50+ BUG_ON(!mm || !q || !mqd);
51+
52+ pr_debug("kfd: In func %s\n", __func__);
53+
54+ retval = kfd2kgd->allocate_mem(mm->dev->kgd,
55+ sizeof(struct cik_mqd),
56+ 256,
57+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
58+ (struct kgd_mem **) mqd_mem_obj);
59+
60+ if (retval != 0)
61+ return -ENOMEM;
62+
63+ m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
64+ addr = (*mqd_mem_obj)->gpu_addr;
65+
66+ memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
67+
68+ m->header = 0xC0310800;
69+ m->compute_pipelinestat_enable = 1;
70+ m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
71+ m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
72+ m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
73+ m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
74+
75+ /*
76+ * Make sure to use the last queue state saved on mqd when the cp
77+ * reassigns the queue, so when queue is switched on/off (e.g over
78+ * subscription or quantum timeout) the context will be consistent
79+ */
80+ m->cp_hqd_persistent_state =
81+ DEFAULT_CP_HQD_PERSISTENT_STATE | PRELOAD_REQ;
82+
83+ m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
84+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
85+ m->cp_mqd_base_addr_hi = upper_32_bits(addr);
86+
87+ m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE | IB_ATC_EN;
88+ /* Although WinKFD writes this, I suspect it should not be necessary */
89+ m->cp_hqd_ib_control = IB_ATC_EN | DEFAULT_MIN_IB_AVAIL_SIZE;
90+
91+ m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
92+ QUANTUM_DURATION(10);
93+
94+ /*
95+ * Pipe Priority
96+ * Identifies the pipe relative priority when this queue is connected
97+ * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
98+ * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
99+ * 0 = CS_LOW (typically below GFX)
100+ * 1 = CS_MEDIUM (typically between HP3D and GFX
101+ * 2 = CS_HIGH (typically above HP3D)
102+ */
103+ m->cp_hqd_pipe_priority = 1;
104+ m->cp_hqd_queue_priority = 15;
105+
106+ *mqd = m;
107+ if (gart_addr != NULL)
108+ *gart_addr = addr;
109+ retval = mm->update_mqd(mm, m, q);
110+
111+ return retval;
112+}
113+
114+static void uninit_mqd(struct mqd_manager *mm, void *mqd,
115+ struct kfd_mem_obj *mqd_mem_obj)
116+{
117+ BUG_ON(!mm || !mqd);
118+ kfd2kgd->free_mem(mm->dev->kgd, (struct kgd_mem *) mqd_mem_obj);
119+}
120+
121+static int load_mqd(struct mqd_manager *mm, void *mqd, uint32_t pipe_id,
122+ uint32_t queue_id, uint32_t __user *wptr)
123+{
124+ return kfd2kgd->hqd_load(mm->dev->kgd, mqd, pipe_id, queue_id, wptr);
125+
126+}
127+
128+static int update_mqd(struct mqd_manager *mm, void *mqd,
129+ struct queue_properties *q)
130+{
131+ struct cik_mqd *m;
132+
133+ BUG_ON(!mm || !q || !mqd);
134+
135+ pr_debug("kfd: In func %s\n", __func__);
136+
137+ m = get_mqd(mqd);
138+ m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
139+ DEFAULT_MIN_AVAIL_SIZE | PQ_ATC_EN;
140+
141+ /*
142+ * Calculating queue size which is log base 2 of actual queue size -1
143+ * dwords and another -1 for ffs
144+ */
145+ m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
146+ - 1 - 1;
147+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
148+ m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
149+ m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
150+ m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
151+ m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
152+ DOORBELL_OFFSET(q->doorbell_off);
153+
154+ m->cp_hqd_vmid = q->vmid;
155+
156+ if (q->format == KFD_QUEUE_FORMAT_AQL) {
157+ m->cp_hqd_iq_rptr = AQL_ENABLE;
158+ m->cp_hqd_pq_control |= NO_UPDATE_RPTR;
159+ }
160+
161+ m->cp_hqd_active = 0;
162+ q->is_active = false;
163+ if (q->queue_size > 0 &&
164+ q->queue_address != 0 &&
165+ q->queue_percent > 0) {
166+ m->cp_hqd_active = 1;
167+ q->is_active = true;
168+ }
169+
170+ return 0;
171+}
172+
173+static int destroy_mqd(struct mqd_manager *mm, void *mqd,
174+ enum kfd_preempt_type type,
175+ unsigned int timeout, uint32_t pipe_id,
176+ uint32_t queue_id)
177+{
178+ return kfd2kgd->hqd_destroy(mm->dev->kgd, type, timeout,
179+ pipe_id, queue_id);
180+}
181+
182+static bool is_occupied(struct mqd_manager *mm, void *mqd,
183+ uint64_t queue_address, uint32_t pipe_id,
184+ uint32_t queue_id)
185+{
186+
187+ return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address,
188+ pipe_id, queue_id);
189+
190+}
191+
192+/*
193+ * HIQ MQD Implementation, concrete implementation for HIQ MQD implementation.
194+ * The HIQ queue in Kaveri is using the same MQD structure as all the user mode
195+ * queues but with different initial values.
196+ */
197+
198+static int init_mqd_hiq(struct mqd_manager *mm, void **mqd,
199+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
200+ struct queue_properties *q)
201+{
202+ uint64_t addr;
203+ struct cik_mqd *m;
204+ int retval;
205+
206+ BUG_ON(!mm || !q || !mqd || !mqd_mem_obj);
207+
208+ pr_debug("kfd: In func %s\n", __func__);
209+
210+ retval = kfd2kgd->allocate_mem(mm->dev->kgd,
211+ sizeof(struct cik_mqd),
212+ 256,
213+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
214+ (struct kgd_mem **) mqd_mem_obj);
215+
216+ if (retval != 0)
217+ return -ENOMEM;
218+
219+ m = (struct cik_mqd *) (*mqd_mem_obj)->cpu_ptr;
220+ addr = (*mqd_mem_obj)->gpu_addr;
221+
222+ memset(m, 0, ALIGN(sizeof(struct cik_mqd), 256));
223+
224+ m->header = 0xC0310800;
225+ m->compute_pipelinestat_enable = 1;
226+ m->compute_static_thread_mgmt_se0 = 0xFFFFFFFF;
227+ m->compute_static_thread_mgmt_se1 = 0xFFFFFFFF;
228+ m->compute_static_thread_mgmt_se2 = 0xFFFFFFFF;
229+ m->compute_static_thread_mgmt_se3 = 0xFFFFFFFF;
230+
231+ m->cp_hqd_persistent_state = DEFAULT_CP_HQD_PERSISTENT_STATE |
232+ PRELOAD_REQ;
233+ m->cp_hqd_quantum = QUANTUM_EN | QUANTUM_SCALE_1MS |
234+ QUANTUM_DURATION(10);
235+
236+ m->cp_mqd_control = MQD_CONTROL_PRIV_STATE_EN;
237+ m->cp_mqd_base_addr_lo = lower_32_bits(addr);
238+ m->cp_mqd_base_addr_hi = upper_32_bits(addr);
239+
240+ m->cp_hqd_ib_control = DEFAULT_MIN_IB_AVAIL_SIZE;
241+
242+ /*
243+ * Pipe Priority
244+ * Identifies the pipe relative priority when this queue is connected
245+ * to the pipeline. The pipe priority is against the GFX pipe and HP3D.
246+ * In KFD we are using a fixed pipe priority set to CS_MEDIUM.
247+ * 0 = CS_LOW (typically below GFX)
248+ * 1 = CS_MEDIUM (typically between HP3D and GFX
249+ * 2 = CS_HIGH (typically above HP3D)
250+ */
251+ m->cp_hqd_pipe_priority = 1;
252+ m->cp_hqd_queue_priority = 15;
253+
254+ *mqd = m;
255+ if (gart_addr)
256+ *gart_addr = addr;
257+ retval = mm->update_mqd(mm, m, q);
258+
259+ return retval;
260+}
261+
262+static int update_mqd_hiq(struct mqd_manager *mm, void *mqd,
263+ struct queue_properties *q)
264+{
265+ struct cik_mqd *m;
266+
267+ BUG_ON(!mm || !q || !mqd);
268+
269+ pr_debug("kfd: In func %s\n", __func__);
270+
271+ m = get_mqd(mqd);
272+ m->cp_hqd_pq_control = DEFAULT_RPTR_BLOCK_SIZE |
273+ DEFAULT_MIN_AVAIL_SIZE |
274+ PRIV_STATE |
275+ KMD_QUEUE;
276+
277+ /*
278+ * Calculating queue size which is log base 2 of actual queue
279+ * size -1 dwords
280+ */
281+ m->cp_hqd_pq_control |= ffs(q->queue_size / sizeof(unsigned int))
282+ - 1 - 1;
283+ m->cp_hqd_pq_base_lo = lower_32_bits((uint64_t)q->queue_address >> 8);
284+ m->cp_hqd_pq_base_hi = upper_32_bits((uint64_t)q->queue_address >> 8);
285+ m->cp_hqd_pq_rptr_report_addr_lo = lower_32_bits((uint64_t)q->read_ptr);
286+ m->cp_hqd_pq_rptr_report_addr_hi = upper_32_bits((uint64_t)q->read_ptr);
287+ m->cp_hqd_pq_doorbell_control = DOORBELL_EN |
288+ DOORBELL_OFFSET(q->doorbell_off);
289+
290+ m->cp_hqd_vmid = q->vmid;
291+
292+ m->cp_hqd_active = 0;
293+ q->is_active = false;
294+ if (q->queue_size > 0 &&
295+ q->queue_address != 0 &&
296+ q->queue_percent > 0) {
297+ m->cp_hqd_active = 1;
298+ q->is_active = true;
299+ }
300+
301+ return 0;
302+}
303+
304+struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
305+ struct kfd_dev *dev)
306+{
307+ struct mqd_manager *mqd;
308+
309+ BUG_ON(!dev);
310+ BUG_ON(type >= KFD_MQD_TYPE_MAX);
311+
312+ pr_debug("kfd: In func %s\n", __func__);
313+
314+ mqd = kzalloc(sizeof(struct mqd_manager), GFP_KERNEL);
315+ if (!mqd)
316+ return NULL;
317+
318+ mqd->dev = dev;
319+
320+ switch (type) {
321+ case KFD_MQD_TYPE_CIK_CP:
322+ case KFD_MQD_TYPE_CIK_COMPUTE:
323+ mqd->init_mqd = init_mqd;
324+ mqd->uninit_mqd = uninit_mqd;
325+ mqd->load_mqd = load_mqd;
326+ mqd->update_mqd = update_mqd;
327+ mqd->destroy_mqd = destroy_mqd;
328+ mqd->is_occupied = is_occupied;
329+ break;
330+ case KFD_MQD_TYPE_CIK_HIQ:
331+ mqd->init_mqd = init_mqd_hiq;
332+ mqd->uninit_mqd = uninit_mqd;
333+ mqd->load_mqd = load_mqd;
334+ mqd->update_mqd = update_mqd_hiq;
335+ mqd->destroy_mqd = destroy_mqd;
336+ mqd->is_occupied = is_occupied;
337+ break;
338+ default:
339+ kfree(mqd);
340+ return NULL;
341+ }
342+
343+ return mqd;
344+}
345+
346+/* SDMA queues should be implemented here when the cp will supports them */
drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.h+91−0
@@ -0,0 +1,91 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#ifndef KFD_MQD_MANAGER_H_
25+#define KFD_MQD_MANAGER_H_
26+
27+#include "kfd_priv.h"
28+
29+/**
30+ * struct mqd_manager
31+ *
32+ * @init_mqd: Allocates the mqd buffer on local gpu memory and initialize it.
33+ *
34+ * @load_mqd: Loads the mqd to a concrete hqd slot. Used only for no cp
35+ * scheduling mode.
36+ *
37+ * @update_mqd: Handles a update call for the MQD
38+ *
39+ * @destroy_mqd: Destroys the HQD slot and by that preempt the relevant queue.
40+ * Used only for no cp scheduling.
41+ *
42+ * @uninit_mqd: Releases the mqd buffer from local gpu memory.
43+ *
44+ * @is_occupied: Checks if the relevant HQD slot is occupied.
45+ *
46+ * @mqd_mutex: Mqd manager mutex.
47+ *
48+ * @dev: The kfd device structure coupled with this module.
49+ *
50+ * MQD stands for Memory Queue Descriptor which represents the current queue
51+ * state in the memory and initiate the HQD (Hardware Queue Descriptor) state.
52+ * This structure is actually a base class for the different types of MQDs
53+ * structures for the variant ASICs that should be supported in the future.
54+ * This base class is also contains all the MQD specific operations.
55+ * Another important thing to mention is that each queue has a MQD that keeps
56+ * his state (or context) after each preemption or reassignment.
57+ * Basically there are a instances of the mqd manager class per MQD type per
58+ * ASIC. Currently the kfd driver supports only Kaveri so there are instances
59+ * per KFD_MQD_TYPE for each device.
60+ *
61+ */
62+
63+struct mqd_manager {
64+ int (*init_mqd)(struct mqd_manager *mm, void **mqd,
65+ struct kfd_mem_obj **mqd_mem_obj, uint64_t *gart_addr,
66+ struct queue_properties *q);
67+
68+ int (*load_mqd)(struct mqd_manager *mm, void *mqd,
69+ uint32_t pipe_id, uint32_t queue_id,
70+ uint32_t __user *wptr);
71+
72+ int (*update_mqd)(struct mqd_manager *mm, void *mqd,
73+ struct queue_properties *q);
74+
75+ int (*destroy_mqd)(struct mqd_manager *mm, void *mqd,
76+ enum kfd_preempt_type type,
77+ unsigned int timeout, uint32_t pipe_id,
78+ uint32_t queue_id);
79+
80+ void (*uninit_mqd)(struct mqd_manager *mm, void *mqd,
81+ struct kfd_mem_obj *mqd_mem_obj);
82+
83+ bool (*is_occupied)(struct mqd_manager *mm, void *mqd,
84+ uint64_t queue_address, uint32_t pipe_id,
85+ uint32_t queue_id);
86+
87+ struct mutex mqd_mutex;
88+ struct kfd_dev *dev;
89+};
90+
91+#endif /* KFD_MQD_MANAGER_H_ */
drivers/gpu/drm/amd/amdkfd/kfd_packet_manager.c+565−0
@@ -0,0 +1,565 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/slab.h>
25+#include <linux/mutex.h>
26+#include "kfd_device_queue_manager.h"
27+#include "kfd_kernel_queue.h"
28+#include "kfd_priv.h"
29+#include "kfd_pm4_headers.h"
30+#include "kfd_pm4_opcodes.h"
31+
32+static inline void inc_wptr(unsigned int *wptr, unsigned int increment_bytes,
33+ unsigned int buffer_size_bytes)
34+{
35+ unsigned int temp = *wptr + increment_bytes / sizeof(uint32_t);
36+
37+ BUG_ON((temp * sizeof(uint32_t)) > buffer_size_bytes);
38+ *wptr = temp;
39+}
40+
41+static unsigned int build_pm4_header(unsigned int opcode, size_t packet_size)
42+{
43+ union PM4_MES_TYPE_3_HEADER header;
44+
45+ header.u32all = 0;
46+ header.opcode = opcode;
47+ header.count = packet_size/sizeof(uint32_t) - 2;
48+ header.type = PM4_TYPE_3;
49+
50+ return header.u32all;
51+}
52+
53+static void pm_calc_rlib_size(struct packet_manager *pm,
54+ unsigned int *rlib_size,
55+ bool *over_subscription)
56+{
57+ unsigned int process_count, queue_count;
58+
59+ BUG_ON(!pm || !rlib_size || !over_subscription);
60+
61+ process_count = pm->dqm->processes_count;
62+ queue_count = pm->dqm->queue_count;
63+
64+ /* check if there is over subscription*/
65+ *over_subscription = false;
66+ if ((process_count > 1) ||
67+ queue_count > PIPE_PER_ME_CP_SCHEDULING * QUEUES_PER_PIPE) {
68+ *over_subscription = true;
69+ pr_debug("kfd: over subscribed runlist\n");
70+ }
71+
72+ /* calculate run list ib allocation size */
73+ *rlib_size = process_count * sizeof(struct pm4_map_process) +
74+ queue_count * sizeof(struct pm4_map_queues);
75+
76+ /*
77+ * Increase the allocation size in case we need a chained run list
78+ * when over subscription
79+ */
80+ if (*over_subscription)
81+ *rlib_size += sizeof(struct pm4_runlist);
82+
83+ pr_debug("kfd: runlist ib size %d\n", *rlib_size);
84+}
85+
86+static int pm_allocate_runlist_ib(struct packet_manager *pm,
87+ unsigned int **rl_buffer,
88+ uint64_t *rl_gpu_buffer,
89+ unsigned int *rl_buffer_size,
90+ bool *is_over_subscription)
91+{
92+ int retval;
93+
94+ BUG_ON(!pm);
95+ BUG_ON(pm->allocated == true);
96+ BUG_ON(is_over_subscription == NULL);
97+
98+ pm_calc_rlib_size(pm, rl_buffer_size, is_over_subscription);
99+
100+ retval = kfd2kgd->allocate_mem(pm->dqm->dev->kgd,
101+ *rl_buffer_size,
102+ PAGE_SIZE,
103+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE,
104+ (struct kgd_mem **) &pm->ib_buffer_obj);
105+
106+ if (retval != 0) {
107+ pr_err("kfd: failed to allocate runlist IB\n");
108+ return retval;
109+ }
110+
111+ *(void **)rl_buffer = pm->ib_buffer_obj->cpu_ptr;
112+ *rl_gpu_buffer = pm->ib_buffer_obj->gpu_addr;
113+
114+ memset(*rl_buffer, 0, *rl_buffer_size);
115+ pm->allocated = true;
116+ return retval;
117+}
118+
119+static int pm_create_runlist(struct packet_manager *pm, uint32_t *buffer,
120+ uint64_t ib, size_t ib_size_in_dwords, bool chain)
121+{
122+ struct pm4_runlist *packet;
123+
124+ BUG_ON(!pm || !buffer || !ib);
125+
126+ packet = (struct pm4_runlist *)buffer;
127+
128+ memset(buffer, 0, sizeof(struct pm4_runlist));
129+ packet->header.u32all = build_pm4_header(IT_RUN_LIST,
130+ sizeof(struct pm4_runlist));
131+
132+ packet->bitfields4.ib_size = ib_size_in_dwords;
133+ packet->bitfields4.chain = chain ? 1 : 0;
134+ packet->bitfields4.offload_polling = 0;
135+ packet->bitfields4.valid = 1;
136+ packet->ordinal2 = lower_32_bits(ib);
137+ packet->bitfields3.ib_base_hi = upper_32_bits(ib);
138+
139+ return 0;
140+}
141+
142+static int pm_create_map_process(struct packet_manager *pm, uint32_t *buffer,
143+ struct qcm_process_device *qpd)
144+{
145+ struct pm4_map_process *packet;
146+ struct queue *cur;
147+ uint32_t num_queues;
148+
149+ BUG_ON(!pm || !buffer || !qpd);
150+
151+ packet = (struct pm4_map_process *)buffer;
152+
153+ pr_debug("kfd: In func %s\n", __func__);
154+
155+ memset(buffer, 0, sizeof(struct pm4_map_process));
156+
157+ packet->header.u32all = build_pm4_header(IT_MAP_PROCESS,
158+ sizeof(struct pm4_map_process));
159+ packet->bitfields2.diq_enable = (qpd->is_debug) ? 1 : 0;
160+ packet->bitfields2.process_quantum = 1;
161+ packet->bitfields2.pasid = qpd->pqm->process->pasid;
162+ packet->bitfields3.page_table_base = qpd->page_table_base;
163+ packet->bitfields10.gds_size = qpd->gds_size;
164+ packet->bitfields10.num_gws = qpd->num_gws;
165+ packet->bitfields10.num_oac = qpd->num_oac;
166+ num_queues = 0;
167+ list_for_each_entry(cur, &qpd->queues_list, list)
168+ num_queues++;
169+ packet->bitfields10.num_queues = num_queues;
170+
171+ packet->sh_mem_config = qpd->sh_mem_config;
172+ packet->sh_mem_bases = qpd->sh_mem_bases;
173+ packet->sh_mem_ape1_base = qpd->sh_mem_ape1_base;
174+ packet->sh_mem_ape1_limit = qpd->sh_mem_ape1_limit;
175+
176+ packet->gds_addr_lo = lower_32_bits(qpd->gds_context_area);
177+ packet->gds_addr_hi = upper_32_bits(qpd->gds_context_area);
178+
179+ return 0;
180+}
181+
182+static int pm_create_map_queue(struct packet_manager *pm, uint32_t *buffer,
183+ struct queue *q)
184+{
185+ struct pm4_map_queues *packet;
186+
187+ BUG_ON(!pm || !buffer || !q);
188+
189+ pr_debug("kfd: In func %s\n", __func__);
190+
191+ packet = (struct pm4_map_queues *)buffer;
192+ memset(buffer, 0, sizeof(struct pm4_map_queues));
193+
194+ packet->header.u32all = build_pm4_header(IT_MAP_QUEUES,
195+ sizeof(struct pm4_map_queues));
196+ packet->bitfields2.alloc_format =
197+ alloc_format__mes_map_queues__one_per_pipe;
198+ packet->bitfields2.num_queues = 1;
199+ packet->bitfields2.queue_sel =
200+ queue_sel__mes_map_queues__map_to_hws_determined_queue_slots;
201+
202+ packet->bitfields2.vidmem = (q->properties.is_interop) ?
203+ vidmem__mes_map_queues__uses_video_memory :
204+ vidmem__mes_map_queues__uses_no_video_memory;
205+
206+ switch (q->properties.type) {
207+ case KFD_QUEUE_TYPE_COMPUTE:
208+ case KFD_QUEUE_TYPE_DIQ:
209+ packet->bitfields2.engine_sel =
210+ engine_sel__mes_map_queues__compute;
211+ break;
212+ case KFD_QUEUE_TYPE_SDMA:
213+ packet->bitfields2.engine_sel =
214+ engine_sel__mes_map_queues__sdma0;
215+ break;
216+ default:
217+ BUG();
218+ break;
219+ }
220+
221+ packet->mes_map_queues_ordinals[0].bitfields3.doorbell_offset =
222+ q->properties.doorbell_off;
223+
224+ packet->mes_map_queues_ordinals[0].mqd_addr_lo =
225+ lower_32_bits(q->gart_mqd_addr);
226+
227+ packet->mes_map_queues_ordinals[0].mqd_addr_hi =
228+ upper_32_bits(q->gart_mqd_addr);
229+
230+ packet->mes_map_queues_ordinals[0].wptr_addr_lo =
231+ lower_32_bits((uint64_t)q->properties.write_ptr);
232+
233+ packet->mes_map_queues_ordinals[0].wptr_addr_hi =
234+ upper_32_bits((uint64_t)q->properties.write_ptr);
235+
236+ return 0;
237+}
238+
239+static int pm_create_runlist_ib(struct packet_manager *pm,
240+ struct list_head *queues,
241+ uint64_t *rl_gpu_addr,
242+ size_t *rl_size_bytes)
243+{
244+ unsigned int alloc_size_bytes;
245+ unsigned int *rl_buffer, rl_wptr, i;
246+ int retval, proccesses_mapped;
247+ struct device_process_node *cur;
248+ struct qcm_process_device *qpd;
249+ struct queue *q;
250+ struct kernel_queue *kq;
251+ bool is_over_subscription;
252+
253+ BUG_ON(!pm || !queues || !rl_size_bytes || !rl_gpu_addr);
254+
255+ rl_wptr = retval = proccesses_mapped = 0;
256+
257+ retval = pm_allocate_runlist_ib(pm, &rl_buffer, rl_gpu_addr,
258+ &alloc_size_bytes, &is_over_subscription);
259+ if (retval != 0)
260+ return retval;
261+
262+ *rl_size_bytes = alloc_size_bytes;
263+
264+ pr_debug("kfd: In func %s\n", __func__);
265+ pr_debug("kfd: building runlist ib process count: %d queues count %d\n",
266+ pm->dqm->processes_count, pm->dqm->queue_count);
267+
268+ /* build the run list ib packet */
269+ list_for_each_entry(cur, queues, list) {
270+ qpd = cur->qpd;
271+ /* build map process packet */
272+ if (proccesses_mapped >= pm->dqm->processes_count) {
273+ pr_debug("kfd: not enough space left in runlist IB\n");
274+ pm_release_ib(pm);
275+ return -ENOMEM;
276+ }
277+ retval = pm_create_map_process(pm, &rl_buffer[rl_wptr], qpd);
278+ if (retval != 0)
279+ return retval;
280+ proccesses_mapped++;
281+ inc_wptr(&rl_wptr, sizeof(struct pm4_map_process),
282+ alloc_size_bytes);
283+
284+ list_for_each_entry(kq, &qpd->priv_queue_list, list) {
285+ if (kq->queue->properties.is_active != true)
286+ continue;
287+ retval = pm_create_map_queue(pm, &rl_buffer[rl_wptr],
288+ kq->queue);
289+ if (retval != 0)
290+ return retval;
291+ inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues),
292+ alloc_size_bytes);
293+ }
294+
295+ list_for_each_entry(q, &qpd->queues_list, list) {
296+ if (q->properties.is_active != true)
297+ continue;
298+ retval = pm_create_map_queue(pm,
299+ &rl_buffer[rl_wptr], q);
300+ if (retval != 0)
301+ return retval;
302+ inc_wptr(&rl_wptr, sizeof(struct pm4_map_queues),
303+ alloc_size_bytes);
304+ }
305+ }
306+
307+ pr_debug("kfd: finished map process and queues to runlist\n");
308+
309+ if (is_over_subscription)
310+ pm_create_runlist(pm, &rl_buffer[rl_wptr], *rl_gpu_addr,
311+ alloc_size_bytes / sizeof(uint32_t), true);
312+
313+ for (i = 0; i < alloc_size_bytes / sizeof(uint32_t); i++)
314+ pr_debug("0x%2X ", rl_buffer[i]);
315+ pr_debug("\n");
316+
317+ return 0;
318+}
319+
320+int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm)
321+{
322+ BUG_ON(!dqm);
323+
324+ pm->dqm = dqm;
325+ mutex_init(&pm->lock);
326+ pm->priv_queue = kernel_queue_init(dqm->dev, KFD_QUEUE_TYPE_HIQ);
327+ if (pm->priv_queue == NULL) {
328+ mutex_destroy(&pm->lock);
329+ return -ENOMEM;
330+ }
331+ pm->allocated = false;
332+
333+ return 0;
334+}
335+
336+void pm_uninit(struct packet_manager *pm)
337+{
338+ BUG_ON(!pm);
339+
340+ mutex_destroy(&pm->lock);
341+ kernel_queue_uninit(pm->priv_queue);
342+}
343+
344+int pm_send_set_resources(struct packet_manager *pm,
345+ struct scheduling_resources *res)
346+{
347+ struct pm4_set_resources *packet;
348+
349+ BUG_ON(!pm || !res);
350+
351+ pr_debug("kfd: In func %s\n", __func__);
352+
353+ mutex_lock(&pm->lock);
354+ pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
355+ sizeof(*packet) / sizeof(uint32_t),
356+ (unsigned int **)&packet);
357+ if (packet == NULL) {
358+ mutex_unlock(&pm->lock);
359+ pr_err("kfd: failed to allocate buffer on kernel queue\n");
360+ return -ENOMEM;
361+ }
362+
363+ memset(packet, 0, sizeof(struct pm4_set_resources));
364+ packet->header.u32all = build_pm4_header(IT_SET_RESOURCES,
365+ sizeof(struct pm4_set_resources));
366+
367+ packet->bitfields2.queue_type =
368+ queue_type__mes_set_resources__hsa_interface_queue_hiq;
369+ packet->bitfields2.vmid_mask = res->vmid_mask;
370+ packet->bitfields2.unmap_latency = KFD_UNMAP_LATENCY;
371+ packet->bitfields7.oac_mask = res->oac_mask;
372+ packet->bitfields8.gds_heap_base = res->gds_heap_base;
373+ packet->bitfields8.gds_heap_size = res->gds_heap_size;
374+
375+ packet->gws_mask_lo = lower_32_bits(res->gws_mask);
376+ packet->gws_mask_hi = upper_32_bits(res->gws_mask);
377+
378+ packet->queue_mask_lo = lower_32_bits(res->queue_mask);
379+ packet->queue_mask_hi = upper_32_bits(res->queue_mask);
380+
381+ pm->priv_queue->submit_packet(pm->priv_queue);
382+ pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
383+
384+ mutex_unlock(&pm->lock);
385+
386+ return 0;
387+}
388+
389+int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues)
390+{
391+ uint64_t rl_gpu_ib_addr;
392+ uint32_t *rl_buffer;
393+ size_t rl_ib_size, packet_size_dwords;
394+ int retval;
395+
396+ BUG_ON(!pm || !dqm_queues);
397+
398+ retval = pm_create_runlist_ib(pm, dqm_queues, &rl_gpu_ib_addr,
399+ &rl_ib_size);
400+ if (retval != 0)
401+ goto fail_create_runlist_ib;
402+
403+ pr_debug("kfd: runlist IB address: 0x%llX\n", rl_gpu_ib_addr);
404+
405+ packet_size_dwords = sizeof(struct pm4_runlist) / sizeof(uint32_t);
406+ mutex_lock(&pm->lock);
407+
408+ retval = pm->priv_queue->acquire_packet_buffer(pm->priv_queue,
409+ packet_size_dwords, &rl_buffer);
410+ if (retval != 0)
411+ goto fail_acquire_packet_buffer;
412+
413+ retval = pm_create_runlist(pm, rl_buffer, rl_gpu_ib_addr,
414+ rl_ib_size / sizeof(uint32_t), false);
415+ if (retval != 0)
416+ goto fail_create_runlist;
417+
418+ pm->priv_queue->submit_packet(pm->priv_queue);
419+ pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
420+
421+ mutex_unlock(&pm->lock);
422+
423+ return retval;
424+
425+fail_create_runlist:
426+ pm->priv_queue->rollback_packet(pm->priv_queue);
427+fail_acquire_packet_buffer:
428+ mutex_unlock(&pm->lock);
429+fail_create_runlist_ib:
430+ if (pm->allocated == true)
431+ pm_release_ib(pm);
432+ return retval;
433+}
434+
435+int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
436+ uint32_t fence_value)
437+{
438+ int retval;
439+ struct pm4_query_status *packet;
440+
441+ BUG_ON(!pm || !fence_address);
442+
443+ mutex_lock(&pm->lock);
444+ retval = pm->priv_queue->acquire_packet_buffer(
445+ pm->priv_queue,
446+ sizeof(struct pm4_query_status) / sizeof(uint32_t),
447+ (unsigned int **)&packet);
448+ if (retval != 0)
449+ goto fail_acquire_packet_buffer;
450+
451+ packet->header.u32all = build_pm4_header(IT_QUERY_STATUS,
452+ sizeof(struct pm4_query_status));
453+
454+ packet->bitfields2.context_id = 0;
455+ packet->bitfields2.interrupt_sel =
456+ interrupt_sel__mes_query_status__completion_status;
457+ packet->bitfields2.command =
458+ command__mes_query_status__fence_only_after_write_ack;
459+
460+ packet->addr_hi = upper_32_bits((uint64_t)fence_address);
461+ packet->addr_lo = lower_32_bits((uint64_t)fence_address);
462+ packet->data_hi = upper_32_bits((uint64_t)fence_value);
463+ packet->data_lo = lower_32_bits((uint64_t)fence_value);
464+
465+ pm->priv_queue->submit_packet(pm->priv_queue);
466+ pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
467+ mutex_unlock(&pm->lock);
468+
469+ return 0;
470+
471+fail_acquire_packet_buffer:
472+ mutex_unlock(&pm->lock);
473+ return retval;
474+}
475+
476+int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
477+ enum kfd_preempt_type_filter mode,
478+ uint32_t filter_param, bool reset,
479+ unsigned int sdma_engine)
480+{
481+ int retval;
482+ uint32_t *buffer;
483+ struct pm4_unmap_queues *packet;
484+
485+ BUG_ON(!pm);
486+
487+ mutex_lock(&pm->lock);
488+ retval = pm->priv_queue->acquire_packet_buffer(
489+ pm->priv_queue,
490+ sizeof(struct pm4_unmap_queues) / sizeof(uint32_t),
491+ &buffer);
492+ if (retval != 0)
493+ goto err_acquire_packet_buffer;
494+
495+ packet = (struct pm4_unmap_queues *)buffer;
496+ memset(buffer, 0, sizeof(struct pm4_unmap_queues));
497+
498+ packet->header.u32all = build_pm4_header(IT_UNMAP_QUEUES,
499+ sizeof(struct pm4_unmap_queues));
500+ switch (type) {
501+ case KFD_QUEUE_TYPE_COMPUTE:
502+ case KFD_QUEUE_TYPE_DIQ:
503+ packet->bitfields2.engine_sel =
504+ engine_sel__mes_unmap_queues__compute;
505+ break;
506+ case KFD_QUEUE_TYPE_SDMA:
507+ packet->bitfields2.engine_sel =
508+ engine_sel__mes_unmap_queues__sdma0 + sdma_engine;
509+ break;
510+ default:
511+ BUG();
512+ break;
513+ }
514+
515+ if (reset)
516+ packet->bitfields2.action =
517+ action__mes_unmap_queues__reset_queues;
518+ else
519+ packet->bitfields2.action =
520+ action__mes_unmap_queues__preempt_queues;
521+
522+ switch (mode) {
523+ case KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE:
524+ packet->bitfields2.queue_sel =
525+ queue_sel__mes_unmap_queues__perform_request_on_specified_queues;
526+ packet->bitfields2.num_queues = 1;
527+ packet->bitfields3b.doorbell_offset0 = filter_param;
528+ break;
529+ case KFD_PREEMPT_TYPE_FILTER_BY_PASID:
530+ packet->bitfields2.queue_sel =
531+ queue_sel__mes_unmap_queues__perform_request_on_pasid_queues;
532+ packet->bitfields3a.pasid = filter_param;
533+ break;
534+ case KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES:
535+ packet->bitfields2.queue_sel =
536+ queue_sel__mes_unmap_queues__perform_request_on_all_active_queues;
537+ break;
538+ default:
539+ BUG();
540+ break;
541+ };
542+
543+ pm->priv_queue->submit_packet(pm->priv_queue);
544+ pm->priv_queue->sync_with_hw(pm->priv_queue, KFD_HIQ_TIMEOUT);
545+
546+ mutex_unlock(&pm->lock);
547+ return 0;
548+
549+err_acquire_packet_buffer:
550+ mutex_unlock(&pm->lock);
551+ return retval;
552+}
553+
554+void pm_release_ib(struct packet_manager *pm)
555+{
556+ BUG_ON(!pm);
557+
558+ mutex_lock(&pm->lock);
559+ if (pm->allocated) {
560+ kfd2kgd->free_mem(pm->dqm->dev->kgd,
561+ (struct kgd_mem *) pm->ib_buffer_obj);
562+ pm->allocated = false;
563+ }
564+ mutex_unlock(&pm->lock);
565+}
drivers/gpu/drm/amd/amdkfd/kfd_pasid.c+96−0
@@ -0,0 +1,96 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/slab.h>
24+#include <linux/types.h>
25+#include "kfd_priv.h"
26+
27+static unsigned long *pasid_bitmap;
28+static unsigned int pasid_limit;
29+static DEFINE_MUTEX(pasid_mutex);
30+
31+int kfd_pasid_init(void)
32+{
33+ pasid_limit = max_num_of_processes;
34+
35+ pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL);
36+ if (!pasid_bitmap)
37+ return -ENOMEM;
38+
39+ set_bit(0, pasid_bitmap); /* PASID 0 is reserved. */
40+
41+ return 0;
42+}
43+
44+void kfd_pasid_exit(void)
45+{
46+ kfree(pasid_bitmap);
47+}
48+
49+bool kfd_set_pasid_limit(unsigned int new_limit)
50+{
51+ if (new_limit < pasid_limit) {
52+ bool ok;
53+
54+ mutex_lock(&pasid_mutex);
55+
56+ /* ensure that no pasids >= new_limit are in-use */
57+ ok = (find_next_bit(pasid_bitmap, pasid_limit, new_limit) ==
58+ pasid_limit);
59+ if (ok)
60+ pasid_limit = new_limit;
61+
62+ mutex_unlock(&pasid_mutex);
63+
64+ return ok;
65+ }
66+
67+ return true;
68+}
69+
70+inline unsigned int kfd_get_pasid_limit(void)
71+{
72+ return pasid_limit;
73+}
74+
75+unsigned int kfd_pasid_alloc(void)
76+{
77+ unsigned int found;
78+
79+ mutex_lock(&pasid_mutex);
80+
81+ found = find_first_zero_bit(pasid_bitmap, pasid_limit);
82+ if (found == pasid_limit)
83+ found = 0;
84+ else
85+ set_bit(found, pasid_bitmap);
86+
87+ mutex_unlock(&pasid_mutex);
88+
89+ return found;
90+}
91+
92+void kfd_pasid_free(unsigned int pasid)
93+{
94+ BUG_ON(pasid == 0 || pasid >= pasid_limit);
95+ clear_bit(pasid, pasid_bitmap);
96+}
drivers/gpu/drm/amd/amdkfd/kfd_pm4_headers.h+405−0
@@ -0,0 +1,405 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#ifndef KFD_PM4_HEADERS_H_
25+#define KFD_PM4_HEADERS_H_
26+
27+#ifndef PM4_MES_HEADER_DEFINED
28+#define PM4_MES_HEADER_DEFINED
29+union PM4_MES_TYPE_3_HEADER {
30+ struct {
31+ uint32_t reserved1:8; /* < reserved */
32+ uint32_t opcode:8; /* < IT opcode */
33+ uint32_t count:14; /* < number of DWORDs - 1
34+ * in the information body.
35+ */
36+ uint32_t type:2; /* < packet identifier.
37+ * It should be 3 for type 3 packets
38+ */
39+ };
40+ uint32_t u32all;
41+};
42+#endif /* PM4_MES_HEADER_DEFINED */
43+
44+/* --------------------MES_SET_RESOURCES-------------------- */
45+
46+#ifndef PM4_MES_SET_RESOURCES_DEFINED
47+#define PM4_MES_SET_RESOURCES_DEFINED
48+enum set_resources_queue_type_enum {
49+ queue_type__mes_set_resources__kernel_interface_queue_kiq = 0,
50+ queue_type__mes_set_resources__hsa_interface_queue_hiq = 1,
51+ queue_type__mes_set_resources__hsa_debug_interface_queue = 4
52+};
53+
54+struct pm4_set_resources {
55+ union {
56+ union PM4_MES_TYPE_3_HEADER header; /* header */
57+ uint32_t ordinal1;
58+ };
59+
60+ union {
61+ struct {
62+ uint32_t vmid_mask:16;
63+ uint32_t unmap_latency:8;
64+ uint32_t reserved1:5;
65+ enum set_resources_queue_type_enum queue_type:3;
66+ } bitfields2;
67+ uint32_t ordinal2;
68+ };
69+
70+ uint32_t queue_mask_lo;
71+ uint32_t queue_mask_hi;
72+ uint32_t gws_mask_lo;
73+ uint32_t gws_mask_hi;
74+
75+ union {
76+ struct {
77+ uint32_t oac_mask:16;
78+ uint32_t reserved2:16;
79+ } bitfields7;
80+ uint32_t ordinal7;
81+ };
82+
83+ union {
84+ struct {
85+ uint32_t gds_heap_base:6;
86+ uint32_t reserved3:5;
87+ uint32_t gds_heap_size:6;
88+ uint32_t reserved4:15;
89+ } bitfields8;
90+ uint32_t ordinal8;
91+ };
92+
93+};
94+#endif
95+
96+/*--------------------MES_RUN_LIST-------------------- */
97+
98+#ifndef PM4_MES_RUN_LIST_DEFINED
99+#define PM4_MES_RUN_LIST_DEFINED
100+
101+struct pm4_runlist {
102+ union {
103+ union PM4_MES_TYPE_3_HEADER header; /* header */
104+ uint32_t ordinal1;
105+ };
106+
107+ union {
108+ struct {
109+ uint32_t reserved1:2;
110+ uint32_t ib_base_lo:30;
111+ } bitfields2;
112+ uint32_t ordinal2;
113+ };
114+
115+ union {
116+ struct {
117+ uint32_t ib_base_hi:16;
118+ uint32_t reserved2:16;
119+ } bitfields3;
120+ uint32_t ordinal3;
121+ };
122+
123+ union {
124+ struct {
125+ uint32_t ib_size:20;
126+ uint32_t chain:1;
127+ uint32_t offload_polling:1;
128+ uint32_t reserved3:1;
129+ uint32_t valid:1;
130+ uint32_t reserved4:8;
131+ } bitfields4;
132+ uint32_t ordinal4;
133+ };
134+
135+};
136+#endif
137+
138+/*--------------------MES_MAP_PROCESS-------------------- */
139+
140+#ifndef PM4_MES_MAP_PROCESS_DEFINED
141+#define PM4_MES_MAP_PROCESS_DEFINED
142+
143+struct pm4_map_process {
144+ union {
145+ union PM4_MES_TYPE_3_HEADER header; /* header */
146+ uint32_t ordinal1;
147+ };
148+
149+ union {
150+ struct {
151+ uint32_t pasid:16;
152+ uint32_t reserved1:8;
153+ uint32_t diq_enable:1;
154+ uint32_t process_quantum:7;
155+ } bitfields2;
156+ uint32_t ordinal2;
157+ };
158+
159+ union {
160+ struct {
161+ uint32_t page_table_base:28;
162+ uint32_t reserved3:4;
163+ } bitfields3;
164+ uint32_t ordinal3;
165+ };
166+
167+ uint32_t sh_mem_bases;
168+ uint32_t sh_mem_ape1_base;
169+ uint32_t sh_mem_ape1_limit;
170+ uint32_t sh_mem_config;
171+ uint32_t gds_addr_lo;
172+ uint32_t gds_addr_hi;
173+
174+ union {
175+ struct {
176+ uint32_t num_gws:6;
177+ uint32_t reserved4:2;
178+ uint32_t num_oac:4;
179+ uint32_t reserved5:4;
180+ uint32_t gds_size:6;
181+ uint32_t num_queues:10;
182+ } bitfields10;
183+ uint32_t ordinal10;
184+ };
185+
186+};
187+#endif
188+
189+/*--------------------MES_MAP_QUEUES--------------------*/
190+
191+#ifndef PM4_MES_MAP_QUEUES_DEFINED
192+#define PM4_MES_MAP_QUEUES_DEFINED
193+enum map_queues_queue_sel_enum {
194+ queue_sel__mes_map_queues__map_to_specified_queue_slots = 0,
195+ queue_sel__mes_map_queues__map_to_hws_determined_queue_slots = 1,
196+ queue_sel__mes_map_queues__enable_process_queues = 2
197+};
198+
199+enum map_queues_vidmem_enum {
200+ vidmem__mes_map_queues__uses_no_video_memory = 0,
201+ vidmem__mes_map_queues__uses_video_memory = 1
202+};
203+
204+enum map_queues_alloc_format_enum {
205+ alloc_format__mes_map_queues__one_per_pipe = 0,
206+ alloc_format__mes_map_queues__all_on_one_pipe = 1
207+};
208+
209+enum map_queues_engine_sel_enum {
210+ engine_sel__mes_map_queues__compute = 0,
211+ engine_sel__mes_map_queues__sdma0 = 2,
212+ engine_sel__mes_map_queues__sdma1 = 3
213+};
214+
215+struct pm4_map_queues {
216+ union {
217+ union PM4_MES_TYPE_3_HEADER header; /* header */
218+ uint32_t ordinal1;
219+ };
220+
221+ union {
222+ struct {
223+ uint32_t reserved1:4;
224+ enum map_queues_queue_sel_enum queue_sel:2;
225+ uint32_t reserved2:2;
226+ uint32_t vmid:4;
227+ uint32_t reserved3:4;
228+ enum map_queues_vidmem_enum vidmem:2;
229+ uint32_t reserved4:6;
230+ enum map_queues_alloc_format_enum alloc_format:2;
231+ enum map_queues_engine_sel_enum engine_sel:3;
232+ uint32_t num_queues:3;
233+ } bitfields2;
234+ uint32_t ordinal2;
235+ };
236+
237+ struct {
238+ union {
239+ struct {
240+ uint32_t reserved5:2;
241+ uint32_t doorbell_offset:21;
242+ uint32_t reserved6:3;
243+ uint32_t queue:6;
244+ } bitfields3;
245+ uint32_t ordinal3;
246+ };
247+
248+ uint32_t mqd_addr_lo;
249+ uint32_t mqd_addr_hi;
250+ uint32_t wptr_addr_lo;
251+ uint32_t wptr_addr_hi;
252+
253+ } mes_map_queues_ordinals[1]; /* 1..N of these ordinal groups */
254+
255+};
256+#endif
257+
258+/*--------------------MES_QUERY_STATUS--------------------*/
259+
260+#ifndef PM4_MES_QUERY_STATUS_DEFINED
261+#define PM4_MES_QUERY_STATUS_DEFINED
262+enum query_status_interrupt_sel_enum {
263+ interrupt_sel__mes_query_status__completion_status = 0,
264+ interrupt_sel__mes_query_status__process_status = 1,
265+ interrupt_sel__mes_query_status__queue_status = 2
266+};
267+
268+enum query_status_command_enum {
269+ command__mes_query_status__interrupt_only = 0,
270+ command__mes_query_status__fence_only_immediate = 1,
271+ command__mes_query_status__fence_only_after_write_ack = 2,
272+ command__mes_query_status__fence_wait_for_write_ack_send_interrupt = 3
273+};
274+
275+enum query_status_engine_sel_enum {
276+ engine_sel__mes_query_status__compute = 0,
277+ engine_sel__mes_query_status__sdma0_queue = 2,
278+ engine_sel__mes_query_status__sdma1_queue = 3
279+};
280+
281+struct pm4_query_status {
282+ union {
283+ union PM4_MES_TYPE_3_HEADER header; /* header */
284+ uint32_t ordinal1;
285+ };
286+
287+ union {
288+ struct {
289+ uint32_t context_id:28;
290+ enum query_status_interrupt_sel_enum interrupt_sel:2;
291+ enum query_status_command_enum command:2;
292+ } bitfields2;
293+ uint32_t ordinal2;
294+ };
295+
296+ union {
297+ struct {
298+ uint32_t pasid:16;
299+ uint32_t reserved1:16;
300+ } bitfields3a;
301+ struct {
302+ uint32_t reserved2:2;
303+ uint32_t doorbell_offset:21;
304+ uint32_t reserved3:3;
305+ enum query_status_engine_sel_enum engine_sel:3;
306+ uint32_t reserved4:3;
307+ } bitfields3b;
308+ uint32_t ordinal3;
309+ };
310+
311+ uint32_t addr_lo;
312+ uint32_t addr_hi;
313+ uint32_t data_lo;
314+ uint32_t data_hi;
315+};
316+#endif
317+
318+/*--------------------MES_UNMAP_QUEUES--------------------*/
319+
320+#ifndef PM4_MES_UNMAP_QUEUES_DEFINED
321+#define PM4_MES_UNMAP_QUEUES_DEFINED
322+enum unmap_queues_action_enum {
323+ action__mes_unmap_queues__preempt_queues = 0,
324+ action__mes_unmap_queues__reset_queues = 1,
325+ action__mes_unmap_queues__disable_process_queues = 2
326+};
327+
328+enum unmap_queues_queue_sel_enum {
329+ queue_sel__mes_unmap_queues__perform_request_on_specified_queues = 0,
330+ queue_sel__mes_unmap_queues__perform_request_on_pasid_queues = 1,
331+ queue_sel__mes_unmap_queues__perform_request_on_all_active_queues = 2
332+};
333+
334+enum unmap_queues_engine_sel_enum {
335+ engine_sel__mes_unmap_queues__compute = 0,
336+ engine_sel__mes_unmap_queues__sdma0 = 2,
337+ engine_sel__mes_unmap_queues__sdma1 = 3
338+};
339+
340+struct pm4_unmap_queues {
341+ union {
342+ union PM4_MES_TYPE_3_HEADER header; /* header */
343+ uint32_t ordinal1;
344+ };
345+
346+ union {
347+ struct {
348+ enum unmap_queues_action_enum action:2;
349+ uint32_t reserved1:2;
350+ enum unmap_queues_queue_sel_enum queue_sel:2;
351+ uint32_t reserved2:20;
352+ enum unmap_queues_engine_sel_enum engine_sel:3;
353+ uint32_t num_queues:3;
354+ } bitfields2;
355+ uint32_t ordinal2;
356+ };
357+
358+ union {
359+ struct {
360+ uint32_t pasid:16;
361+ uint32_t reserved3:16;
362+ } bitfields3a;
363+ struct {
364+ uint32_t reserved4:2;
365+ uint32_t doorbell_offset0:21;
366+ uint32_t reserved5:9;
367+ } bitfields3b;
368+ uint32_t ordinal3;
369+ };
370+
371+ union {
372+ struct {
373+ uint32_t reserved6:2;
374+ uint32_t doorbell_offset1:21;
375+ uint32_t reserved7:9;
376+ } bitfields4;
377+ uint32_t ordinal4;
378+ };
379+
380+ union {
381+ struct {
382+ uint32_t reserved8:2;
383+ uint32_t doorbell_offset2:21;
384+ uint32_t reserved9:9;
385+ } bitfields5;
386+ uint32_t ordinal5;
387+ };
388+
389+ union {
390+ struct {
391+ uint32_t reserved10:2;
392+ uint32_t doorbell_offset3:21;
393+ uint32_t reserved11:9;
394+ } bitfields6;
395+ uint32_t ordinal6;
396+ };
397+
398+};
399+#endif
400+
401+enum {
402+ CACHE_FLUSH_AND_INV_TS_EVENT = 0x00000014
403+};
404+
405+#endif /* KFD_PM4_HEADERS_H_ */
drivers/gpu/drm/amd/amdkfd/kfd_pm4_opcodes.h+107−0
@@ -0,0 +1,107 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+
25+#ifndef KFD_PM4_OPCODES_H
26+#define KFD_PM4_OPCODES_H
27+
28+enum it_opcode_type {
29+ IT_NOP = 0x10,
30+ IT_SET_BASE = 0x11,
31+ IT_CLEAR_STATE = 0x12,
32+ IT_INDEX_BUFFER_SIZE = 0x13,
33+ IT_DISPATCH_DIRECT = 0x15,
34+ IT_DISPATCH_INDIRECT = 0x16,
35+ IT_ATOMIC_GDS = 0x1D,
36+ IT_OCCLUSION_QUERY = 0x1F,
37+ IT_SET_PREDICATION = 0x20,
38+ IT_REG_RMW = 0x21,
39+ IT_COND_EXEC = 0x22,
40+ IT_PRED_EXEC = 0x23,
41+ IT_DRAW_INDIRECT = 0x24,
42+ IT_DRAW_INDEX_INDIRECT = 0x25,
43+ IT_INDEX_BASE = 0x26,
44+ IT_DRAW_INDEX_2 = 0x27,
45+ IT_CONTEXT_CONTROL = 0x28,
46+ IT_INDEX_TYPE = 0x2A,
47+ IT_DRAW_INDIRECT_MULTI = 0x2C,
48+ IT_DRAW_INDEX_AUTO = 0x2D,
49+ IT_NUM_INSTANCES = 0x2F,
50+ IT_DRAW_INDEX_MULTI_AUTO = 0x30,
51+ IT_INDIRECT_BUFFER_CNST = 0x33,
52+ IT_STRMOUT_BUFFER_UPDATE = 0x34,
53+ IT_DRAW_INDEX_OFFSET_2 = 0x35,
54+ IT_DRAW_PREAMBLE = 0x36,
55+ IT_WRITE_DATA = 0x37,
56+ IT_DRAW_INDEX_INDIRECT_MULTI = 0x38,
57+ IT_MEM_SEMAPHORE = 0x39,
58+ IT_COPY_DW = 0x3B,
59+ IT_WAIT_REG_MEM = 0x3C,
60+ IT_INDIRECT_BUFFER = 0x3F,
61+ IT_COPY_DATA = 0x40,
62+ IT_PFP_SYNC_ME = 0x42,
63+ IT_SURFACE_SYNC = 0x43,
64+ IT_COND_WRITE = 0x45,
65+ IT_EVENT_WRITE = 0x46,
66+ IT_EVENT_WRITE_EOP = 0x47,
67+ IT_EVENT_WRITE_EOS = 0x48,
68+ IT_RELEASE_MEM = 0x49,
69+ IT_PREAMBLE_CNTL = 0x4A,
70+ IT_DMA_DATA = 0x50,
71+ IT_ACQUIRE_MEM = 0x58,
72+ IT_REWIND = 0x59,
73+ IT_LOAD_UCONFIG_REG = 0x5E,
74+ IT_LOAD_SH_REG = 0x5F,
75+ IT_LOAD_CONFIG_REG = 0x60,
76+ IT_LOAD_CONTEXT_REG = 0x61,
77+ IT_SET_CONFIG_REG = 0x68,
78+ IT_SET_CONTEXT_REG = 0x69,
79+ IT_SET_CONTEXT_REG_INDIRECT = 0x73,
80+ IT_SET_SH_REG = 0x76,
81+ IT_SET_SH_REG_OFFSET = 0x77,
82+ IT_SET_QUEUE_REG = 0x78,
83+ IT_SET_UCONFIG_REG = 0x79,
84+ IT_SCRATCH_RAM_WRITE = 0x7D,
85+ IT_SCRATCH_RAM_READ = 0x7E,
86+ IT_LOAD_CONST_RAM = 0x80,
87+ IT_WRITE_CONST_RAM = 0x81,
88+ IT_DUMP_CONST_RAM = 0x83,
89+ IT_INCREMENT_CE_COUNTER = 0x84,
90+ IT_INCREMENT_DE_COUNTER = 0x85,
91+ IT_WAIT_ON_CE_COUNTER = 0x86,
92+ IT_WAIT_ON_DE_COUNTER_DIFF = 0x88,
93+ IT_SWITCH_BUFFER = 0x8B,
94+ IT_SET_RESOURCES = 0xA0,
95+ IT_MAP_PROCESS = 0xA1,
96+ IT_MAP_QUEUES = 0xA2,
97+ IT_UNMAP_QUEUES = 0xA3,
98+ IT_QUERY_STATUS = 0xA4,
99+ IT_RUN_LIST = 0xA5,
100+};
101+
102+#define PM4_TYPE_0 0
103+#define PM4_TYPE_2 2
104+#define PM4_TYPE_3 3
105+
106+#endif /* KFD_PM4_OPCODES_H */
107+
drivers/gpu/drm/amd/amdkfd/kfd_priv.h+600−0
@@ -0,0 +1,600 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#ifndef KFD_PRIV_H_INCLUDED
24+#define KFD_PRIV_H_INCLUDED
25+
26+#include <linux/hashtable.h>
27+#include <linux/mmu_notifier.h>
28+#include <linux/mutex.h>
29+#include <linux/types.h>
30+#include <linux/atomic.h>
31+#include <linux/workqueue.h>
32+#include <linux/spinlock.h>
33+#include <linux/kfd_ioctl.h>
34+#include <kgd_kfd_interface.h>
35+
36+#define KFD_SYSFS_FILE_MODE 0444
37+
38+/*
39+ * When working with cp scheduler we should assign the HIQ manually or via
40+ * the radeon driver to a fixed hqd slot, here are the fixed HIQ hqd slot
41+ * definitions for Kaveri. In Kaveri only the first ME queues participates
42+ * in the cp scheduling taking that in mind we set the HIQ slot in the
43+ * second ME.
44+ */
45+#define KFD_CIK_HIQ_PIPE 4
46+#define KFD_CIK_HIQ_QUEUE 0
47+
48+/* GPU ID hash width in bits */
49+#define KFD_GPU_ID_HASH_WIDTH 16
50+
51+/* Macro for allocating structures */
52+#define kfd_alloc_struct(ptr_to_struct) \
53+ ((typeof(ptr_to_struct)) kzalloc(sizeof(*ptr_to_struct), GFP_KERNEL))
54+
55+/* Kernel module parameter to specify maximum number of supported processes */
56+extern int max_num_of_processes;
57+
58+#define KFD_MAX_NUM_OF_PROCESSES_DEFAULT 32
59+#define KFD_MAX_NUM_OF_PROCESSES 512
60+
61+/*
62+ * Kernel module parameter to specify maximum number of supported queues
63+ * per process
64+ */
65+extern int max_num_of_queues_per_process;
66+
67+#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT 128
68+#define KFD_MAX_NUM_OF_QUEUES_PER_PROCESS 1024
69+
70+#define KFD_KERNEL_QUEUE_SIZE 2048
71+
72+/* Kernel module parameter to specify the scheduling policy */
73+extern int sched_policy;
74+
75+/**
76+ * enum kfd_sched_policy
77+ *
78+ * @KFD_SCHED_POLICY_HWS: H/W scheduling policy known as command processor (cp)
79+ * scheduling. In this scheduling mode we're using the firmware code to
80+ * schedule the user mode queues and kernel queues such as HIQ and DIQ.
81+ * the HIQ queue is used as a special queue that dispatches the configuration
82+ * to the cp and the user mode queues list that are currently running.
83+ * the DIQ queue is a debugging queue that dispatches debugging commands to the
84+ * firmware.
85+ * in this scheduling mode user mode queues over subscription feature is
86+ * enabled.
87+ *
88+ * @KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION: The same as above but the over
89+ * subscription feature disabled.
90+ *
91+ * @KFD_SCHED_POLICY_NO_HWS: no H/W scheduling policy is a mode which directly
92+ * set the command processor registers and sets the queues "manually". This
93+ * mode is used *ONLY* for debugging proposes.
94+ *
95+ */
96+enum kfd_sched_policy {
97+ KFD_SCHED_POLICY_HWS = 0,
98+ KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION,
99+ KFD_SCHED_POLICY_NO_HWS
100+};
101+
102+enum cache_policy {
103+ cache_policy_coherent,
104+ cache_policy_noncoherent
105+};
106+
107+struct kfd_device_info {
108+ unsigned int max_pasid_bits;
109+ size_t ih_ring_entry_size;
110+ uint16_t mqd_size_aligned;
111+};
112+
113+struct kfd_dev {
114+ struct kgd_dev *kgd;
115+
116+ const struct kfd_device_info *device_info;
117+ struct pci_dev *pdev;
118+
119+ unsigned int id; /* topology stub index */
120+
121+ phys_addr_t doorbell_base; /* Start of actual doorbells used by
122+ * KFD. It is aligned for mapping
123+ * into user mode
124+ */
125+ size_t doorbell_id_offset; /* Doorbell offset (from KFD doorbell
126+ * to HW doorbell, GFX reserved some
127+ * at the start)
128+ */
129+ size_t doorbell_process_limit; /* Number of processes we have doorbell
130+ * space for.
131+ */
132+ u32 __iomem *doorbell_kernel_ptr; /* This is a pointer for a doorbells
133+ * page used by kernel queue
134+ */
135+
136+ struct kgd2kfd_shared_resources shared_resources;
137+
138+ void *interrupt_ring;
139+ size_t interrupt_ring_size;
140+ atomic_t interrupt_ring_rptr;
141+ atomic_t interrupt_ring_wptr;
142+ struct work_struct interrupt_work;
143+ spinlock_t interrupt_lock;
144+
145+ /* QCM Device instance */
146+ struct device_queue_manager *dqm;
147+
148+ bool init_complete;
149+ /*
150+ * Interrupts of interest to KFD are copied
151+ * from the HW ring into a SW ring.
152+ */
153+ bool interrupts_active;
154+};
155+
156+/* KGD2KFD callbacks */
157+void kgd2kfd_exit(void);
158+struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev);
159+bool kgd2kfd_device_init(struct kfd_dev *kfd,
160+ const struct kgd2kfd_shared_resources *gpu_resources);
161+void kgd2kfd_device_exit(struct kfd_dev *kfd);
162+
163+extern const struct kfd2kgd_calls *kfd2kgd;
164+
165+struct kfd_mem_obj {
166+ void *bo;
167+ uint64_t gpu_addr;
168+ uint32_t *cpu_ptr;
169+};
170+
171+enum kfd_mempool {
172+ KFD_MEMPOOL_SYSTEM_CACHEABLE = 1,
173+ KFD_MEMPOOL_SYSTEM_WRITECOMBINE = 2,
174+ KFD_MEMPOOL_FRAMEBUFFER = 3,
175+};
176+
177+/* Character device interface */
178+int kfd_chardev_init(void);
179+void kfd_chardev_exit(void);
180+struct device *kfd_chardev(void);
181+
182+/**
183+ * enum kfd_preempt_type_filter
184+ *
185+ * @KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE: Preempts single queue.
186+ *
187+ * @KFD_PRERMPT_TYPE_FILTER_ALL_QUEUES: Preempts all queues in the
188+ * running queues list.
189+ *
190+ * @KFD_PRERMPT_TYPE_FILTER_BY_PASID: Preempts queues that belongs to
191+ * specific process.
192+ *
193+ */
194+enum kfd_preempt_type_filter {
195+ KFD_PREEMPT_TYPE_FILTER_SINGLE_QUEUE,
196+ KFD_PREEMPT_TYPE_FILTER_ALL_QUEUES,
197+ KFD_PREEMPT_TYPE_FILTER_BY_PASID
198+};
199+
200+enum kfd_preempt_type {
201+ KFD_PREEMPT_TYPE_WAVEFRONT,
202+ KFD_PREEMPT_TYPE_WAVEFRONT_RESET
203+};
204+
205+/**
206+ * enum kfd_queue_type
207+ *
208+ * @KFD_QUEUE_TYPE_COMPUTE: Regular user mode queue type.
209+ *
210+ * @KFD_QUEUE_TYPE_SDMA: Sdma user mode queue type.
211+ *
212+ * @KFD_QUEUE_TYPE_HIQ: HIQ queue type.
213+ *
214+ * @KFD_QUEUE_TYPE_DIQ: DIQ queue type.
215+ */
216+enum kfd_queue_type {
217+ KFD_QUEUE_TYPE_COMPUTE,
218+ KFD_QUEUE_TYPE_SDMA,
219+ KFD_QUEUE_TYPE_HIQ,
220+ KFD_QUEUE_TYPE_DIQ
221+};
222+
223+enum kfd_queue_format {
224+ KFD_QUEUE_FORMAT_PM4,
225+ KFD_QUEUE_FORMAT_AQL
226+};
227+
228+/**
229+ * struct queue_properties
230+ *
231+ * @type: The queue type.
232+ *
233+ * @queue_id: Queue identifier.
234+ *
235+ * @queue_address: Queue ring buffer address.
236+ *
237+ * @queue_size: Queue ring buffer size.
238+ *
239+ * @priority: Defines the queue priority relative to other queues in the
240+ * process.
241+ * This is just an indication and HW scheduling may override the priority as
242+ * necessary while keeping the relative prioritization.
243+ * the priority granularity is from 0 to f which f is the highest priority.
244+ * currently all queues are initialized with the highest priority.
245+ *
246+ * @queue_percent: This field is partially implemented and currently a zero in
247+ * this field defines that the queue is non active.
248+ *
249+ * @read_ptr: User space address which points to the number of dwords the
250+ * cp read from the ring buffer. This field updates automatically by the H/W.
251+ *
252+ * @write_ptr: Defines the number of dwords written to the ring buffer.
253+ *
254+ * @doorbell_ptr: This field aim is to notify the H/W of new packet written to
255+ * the queue ring buffer. This field should be similar to write_ptr and the user
256+ * should update this field after he updated the write_ptr.
257+ *
258+ * @doorbell_off: The doorbell offset in the doorbell pci-bar.
259+ *
260+ * @is_interop: Defines if this is a interop queue. Interop queue means that the
261+ * queue can access both graphics and compute resources.
262+ *
263+ * @is_active: Defines if the queue is active or not.
264+ *
265+ * @vmid: If the scheduling mode is no cp scheduling the field defines the vmid
266+ * of the queue.
267+ *
268+ * This structure represents the queue properties for each queue no matter if
269+ * it's user mode or kernel mode queue.
270+ *
271+ */
272+struct queue_properties {
273+ enum kfd_queue_type type;
274+ enum kfd_queue_format format;
275+ unsigned int queue_id;
276+ uint64_t queue_address;
277+ uint64_t queue_size;
278+ uint32_t priority;
279+ uint32_t queue_percent;
280+ uint32_t *read_ptr;
281+ uint32_t *write_ptr;
282+ uint32_t __iomem *doorbell_ptr;
283+ uint32_t doorbell_off;
284+ bool is_interop;
285+ bool is_active;
286+ /* Not relevant for user mode queues in cp scheduling */
287+ unsigned int vmid;
288+};
289+
290+/**
291+ * struct queue
292+ *
293+ * @list: Queue linked list.
294+ *
295+ * @mqd: The queue MQD.
296+ *
297+ * @mqd_mem_obj: The MQD local gpu memory object.
298+ *
299+ * @gart_mqd_addr: The MQD gart mc address.
300+ *
301+ * @properties: The queue properties.
302+ *
303+ * @mec: Used only in no cp scheduling mode and identifies to micro engine id
304+ * that the queue should be execute on.
305+ *
306+ * @pipe: Used only in no cp scheduling mode and identifies the queue's pipe id.
307+ *
308+ * @queue: Used only in no cp scheduliong mode and identifies the queue's slot.
309+ *
310+ * @process: The kfd process that created this queue.
311+ *
312+ * @device: The kfd device that created this queue.
313+ *
314+ * This structure represents user mode compute queues.
315+ * It contains all the necessary data to handle such queues.
316+ *
317+ */
318+
319+struct queue {
320+ struct list_head list;
321+ void *mqd;
322+ struct kfd_mem_obj *mqd_mem_obj;
323+ uint64_t gart_mqd_addr;
324+ struct queue_properties properties;
325+
326+ uint32_t mec;
327+ uint32_t pipe;
328+ uint32_t queue;
329+
330+ struct kfd_process *process;
331+ struct kfd_dev *device;
332+};
333+
334+/*
335+ * Please read the kfd_mqd_manager.h description.
336+ */
337+enum KFD_MQD_TYPE {
338+ KFD_MQD_TYPE_CIK_COMPUTE = 0, /* for no cp scheduling */
339+ KFD_MQD_TYPE_CIK_HIQ, /* for hiq */
340+ KFD_MQD_TYPE_CIK_CP, /* for cp queues and diq */
341+ KFD_MQD_TYPE_CIK_SDMA, /* for sdma queues */
342+ KFD_MQD_TYPE_MAX
343+};
344+
345+struct scheduling_resources {
346+ unsigned int vmid_mask;
347+ enum kfd_queue_type type;
348+ uint64_t queue_mask;
349+ uint64_t gws_mask;
350+ uint32_t oac_mask;
351+ uint32_t gds_heap_base;
352+ uint32_t gds_heap_size;
353+};
354+
355+struct process_queue_manager {
356+ /* data */
357+ struct kfd_process *process;
358+ unsigned int num_concurrent_processes;
359+ struct list_head queues;
360+ unsigned long *queue_slot_bitmap;
361+};
362+
363+struct qcm_process_device {
364+ /* The Device Queue Manager that owns this data */
365+ struct device_queue_manager *dqm;
366+ struct process_queue_manager *pqm;
367+ /* Device Queue Manager lock */
368+ struct mutex *lock;
369+ /* Queues list */
370+ struct list_head queues_list;
371+ struct list_head priv_queue_list;
372+
373+ unsigned int queue_count;
374+ unsigned int vmid;
375+ bool is_debug;
376+ /*
377+ * All the memory management data should be here too
378+ */
379+ uint64_t gds_context_area;
380+ uint32_t sh_mem_config;
381+ uint32_t sh_mem_bases;
382+ uint32_t sh_mem_ape1_base;
383+ uint32_t sh_mem_ape1_limit;
384+ uint32_t page_table_base;
385+ uint32_t gds_size;
386+ uint32_t num_gws;
387+ uint32_t num_oac;
388+};
389+
390+/* Data that is per-process-per device. */
391+struct kfd_process_device {
392+ /*
393+ * List of all per-device data for a process.
394+ * Starts from kfd_process.per_device_data.
395+ */
396+ struct list_head per_device_list;
397+
398+ /* The device that owns this data. */
399+ struct kfd_dev *dev;
400+
401+
402+ /* per-process-per device QCM data structure */
403+ struct qcm_process_device qpd;
404+
405+ /*Apertures*/
406+ uint64_t lds_base;
407+ uint64_t lds_limit;
408+ uint64_t gpuvm_base;
409+ uint64_t gpuvm_limit;
410+ uint64_t scratch_base;
411+ uint64_t scratch_limit;
412+
413+ /* Is this process/pasid bound to this device? (amd_iommu_bind_pasid) */
414+ bool bound;
415+};
416+
417+#define qpd_to_pdd(x) container_of(x, struct kfd_process_device, qpd)
418+
419+/* Process data */
420+struct kfd_process {
421+ /*
422+ * kfd_process are stored in an mm_struct*->kfd_process*
423+ * hash table (kfd_processes in kfd_process.c)
424+ */
425+ struct hlist_node kfd_processes;
426+
427+ struct mm_struct *mm;
428+
429+ struct mutex mutex;
430+
431+ /*
432+ * In any process, the thread that started main() is the lead
433+ * thread and outlives the rest.
434+ * It is here because amd_iommu_bind_pasid wants a task_struct.
435+ */
436+ struct task_struct *lead_thread;
437+
438+ /* We want to receive a notification when the mm_struct is destroyed */
439+ struct mmu_notifier mmu_notifier;
440+
441+ /* Use for delayed freeing of kfd_process structure */
442+ struct rcu_head rcu;
443+
444+ unsigned int pasid;
445+
446+ /*
447+ * List of kfd_process_device structures,
448+ * one for each device the process is using.
449+ */
450+ struct list_head per_device_data;
451+
452+ struct process_queue_manager pqm;
453+
454+ /* The process's queues. */
455+ size_t queue_array_size;
456+
457+ /* Size is queue_array_size, up to MAX_PROCESS_QUEUES. */
458+ struct kfd_queue **queues;
459+
460+ unsigned long allocated_queue_bitmap[DIV_ROUND_UP(KFD_MAX_NUM_OF_QUEUES_PER_PROCESS, BITS_PER_LONG)];
461+
462+ /*Is the user space process 32 bit?*/
463+ bool is_32bit_user_mode;
464+};
465+
466+void kfd_process_create_wq(void);
467+void kfd_process_destroy_wq(void);
468+struct kfd_process *kfd_create_process(const struct task_struct *);
469+struct kfd_process *kfd_get_process(const struct task_struct *);
470+
471+struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
472+ struct kfd_process *p);
473+void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid);
474+struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
475+ struct kfd_process *p,
476+ int create_pdd);
477+
478+/* Process device data iterator */
479+struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p);
480+struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
481+ struct kfd_process_device *pdd);
482+bool kfd_has_process_device_data(struct kfd_process *p);
483+
484+/* PASIDs */
485+int kfd_pasid_init(void);
486+void kfd_pasid_exit(void);
487+bool kfd_set_pasid_limit(unsigned int new_limit);
488+unsigned int kfd_get_pasid_limit(void);
489+unsigned int kfd_pasid_alloc(void);
490+void kfd_pasid_free(unsigned int pasid);
491+
492+/* Doorbells */
493+void kfd_doorbell_init(struct kfd_dev *kfd);
494+int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
495+u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
496+ unsigned int *doorbell_off);
497+void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr);
498+u32 read_kernel_doorbell(u32 __iomem *db);
499+void write_kernel_doorbell(u32 __iomem *db, u32 value);
500+unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd,
501+ struct kfd_process *process,
502+ unsigned int queue_id);
503+
504+extern struct device *kfd_device;
505+
506+/* Topology */
507+int kfd_topology_init(void);
508+void kfd_topology_shutdown(void);
509+int kfd_topology_add_device(struct kfd_dev *gpu);
510+int kfd_topology_remove_device(struct kfd_dev *gpu);
511+struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
512+struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
513+struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx);
514+
515+/* Interrupts */
516+int kfd_interrupt_init(struct kfd_dev *dev);
517+void kfd_interrupt_exit(struct kfd_dev *dev);
518+void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry);
519+bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry);
520+
521+/* Power Management */
522+void kgd2kfd_suspend(struct kfd_dev *kfd);
523+int kgd2kfd_resume(struct kfd_dev *kfd);
524+
525+/* amdkfd Apertures */
526+int kfd_init_apertures(struct kfd_process *process);
527+
528+/* Queue Context Management */
529+inline uint32_t lower_32(uint64_t x);
530+inline uint32_t upper_32(uint64_t x);
531+
532+int init_queue(struct queue **q, struct queue_properties properties);
533+void uninit_queue(struct queue *q);
534+void print_queue_properties(struct queue_properties *q);
535+void print_queue(struct queue *q);
536+
537+struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
538+ struct kfd_dev *dev);
539+struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev);
540+void device_queue_manager_uninit(struct device_queue_manager *dqm);
541+struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
542+ enum kfd_queue_type type);
543+void kernel_queue_uninit(struct kernel_queue *kq);
544+
545+/* Process Queue Manager */
546+struct process_queue_node {
547+ struct queue *q;
548+ struct kernel_queue *kq;
549+ struct list_head process_queue_list;
550+};
551+
552+int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p);
553+void pqm_uninit(struct process_queue_manager *pqm);
554+int pqm_create_queue(struct process_queue_manager *pqm,
555+ struct kfd_dev *dev,
556+ struct file *f,
557+ struct queue_properties *properties,
558+ unsigned int flags,
559+ enum kfd_queue_type type,
560+ unsigned int *qid);
561+int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid);
562+int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
563+ struct queue_properties *p);
564+
565+/* Packet Manager */
566+
567+#define KFD_HIQ_TIMEOUT (500)
568+
569+#define KFD_FENCE_COMPLETED (100)
570+#define KFD_FENCE_INIT (10)
571+#define KFD_UNMAP_LATENCY (150)
572+
573+struct packet_manager {
574+ struct device_queue_manager *dqm;
575+ struct kernel_queue *priv_queue;
576+ struct mutex lock;
577+ bool allocated;
578+ struct kfd_mem_obj *ib_buffer_obj;
579+};
580+
581+int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm);
582+void pm_uninit(struct packet_manager *pm);
583+int pm_send_set_resources(struct packet_manager *pm,
584+ struct scheduling_resources *res);
585+int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues);
586+int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
587+ uint32_t fence_value);
588+
589+int pm_send_unmap_queue(struct packet_manager *pm, enum kfd_queue_type type,
590+ enum kfd_preempt_type_filter mode,
591+ uint32_t filter_param, bool reset,
592+ unsigned int sdma_engine);
593+
594+void pm_release_ib(struct packet_manager *pm);
595+
596+uint64_t kfd_get_number_elems(struct kfd_dev *kfd);
597+phys_addr_t kfd_get_process_doorbells(struct kfd_dev *dev,
598+ struct kfd_process *process);
599+
600+#endif
drivers/gpu/drm/amd/amdkfd/kfd_process.c+410−0
@@ -0,0 +1,410 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/mutex.h>
24+#include <linux/log2.h>
25+#include <linux/sched.h>
26+#include <linux/slab.h>
27+#include <linux/amd-iommu.h>
28+#include <linux/notifier.h>
29+struct mm_struct;
30+
31+#include "kfd_priv.h"
32+
33+/*
34+ * Initial size for the array of queues.
35+ * The allocated size is doubled each time
36+ * it is exceeded up to MAX_PROCESS_QUEUES.
37+ */
38+#define INITIAL_QUEUE_ARRAY_SIZE 16
39+
40+/*
41+ * List of struct kfd_process (field kfd_process).
42+ * Unique/indexed by mm_struct*
43+ */
44+#define KFD_PROCESS_TABLE_SIZE 5 /* bits: 32 entries */
45+static DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE);
46+static DEFINE_MUTEX(kfd_processes_mutex);
47+
48+DEFINE_STATIC_SRCU(kfd_processes_srcu);
49+
50+static struct workqueue_struct *kfd_process_wq;
51+
52+struct kfd_process_release_work {
53+ struct work_struct kfd_work;
54+ struct kfd_process *p;
55+};
56+
57+static struct kfd_process *find_process(const struct task_struct *thread);
58+static struct kfd_process *create_process(const struct task_struct *thread);
59+
60+void kfd_process_create_wq(void)
61+{
62+ if (!kfd_process_wq)
63+ kfd_process_wq = create_workqueue("kfd_process_wq");
64+}
65+
66+void kfd_process_destroy_wq(void)
67+{
68+ if (kfd_process_wq) {
69+ flush_workqueue(kfd_process_wq);
70+ destroy_workqueue(kfd_process_wq);
71+ kfd_process_wq = NULL;
72+ }
73+}
74+
75+struct kfd_process *kfd_create_process(const struct task_struct *thread)
76+{
77+ struct kfd_process *process;
78+
79+ BUG_ON(!kfd_process_wq);
80+
81+ if (thread->mm == NULL)
82+ return ERR_PTR(-EINVAL);
83+
84+ /* Only the pthreads threading model is supported. */
85+ if (thread->group_leader->mm != thread->mm)
86+ return ERR_PTR(-EINVAL);
87+
88+ /* Take mmap_sem because we call __mmu_notifier_register inside */
89+ down_write(&thread->mm->mmap_sem);
90+
91+ /*
92+ * take kfd processes mutex before starting of process creation
93+ * so there won't be a case where two threads of the same process
94+ * create two kfd_process structures
95+ */
96+ mutex_lock(&kfd_processes_mutex);
97+
98+ /* A prior open of /dev/kfd could have already created the process. */
99+ process = find_process(thread);
100+ if (process)
101+ pr_debug("kfd: process already found\n");
102+
103+ if (!process)
104+ process = create_process(thread);
105+
106+ mutex_unlock(&kfd_processes_mutex);
107+
108+ up_write(&thread->mm->mmap_sem);
109+
110+ return process;
111+}
112+
113+struct kfd_process *kfd_get_process(const struct task_struct *thread)
114+{
115+ struct kfd_process *process;
116+
117+ if (thread->mm == NULL)
118+ return ERR_PTR(-EINVAL);
119+
120+ /* Only the pthreads threading model is supported. */
121+ if (thread->group_leader->mm != thread->mm)
122+ return ERR_PTR(-EINVAL);
123+
124+ process = find_process(thread);
125+
126+ return process;
127+}
128+
129+static struct kfd_process *find_process_by_mm(const struct mm_struct *mm)
130+{
131+ struct kfd_process *process;
132+
133+ hash_for_each_possible_rcu(kfd_processes_table, process,
134+ kfd_processes, (uintptr_t)mm)
135+ if (process->mm == mm)
136+ return process;
137+
138+ return NULL;
139+}
140+
141+static struct kfd_process *find_process(const struct task_struct *thread)
142+{
143+ struct kfd_process *p;
144+ int idx;
145+
146+ idx = srcu_read_lock(&kfd_processes_srcu);
147+ p = find_process_by_mm(thread->mm);
148+ srcu_read_unlock(&kfd_processes_srcu, idx);
149+
150+ return p;
151+}
152+
153+static void kfd_process_wq_release(struct work_struct *work)
154+{
155+ struct kfd_process_release_work *my_work;
156+ struct kfd_process_device *pdd, *temp;
157+ struct kfd_process *p;
158+
159+ my_work = (struct kfd_process_release_work *) work;
160+
161+ p = my_work->p;
162+
163+ mutex_lock(&p->mutex);
164+
165+ list_for_each_entry_safe(pdd, temp, &p->per_device_data,
166+ per_device_list) {
167+ amd_iommu_unbind_pasid(pdd->dev->pdev, p->pasid);
168+ list_del(&pdd->per_device_list);
169+
170+ kfree(pdd);
171+ }
172+
173+ kfd_pasid_free(p->pasid);
174+
175+ mutex_unlock(&p->mutex);
176+
177+ mutex_destroy(&p->mutex);
178+
179+ kfree(p->queues);
180+
181+ kfree(p);
182+
183+ kfree((void *)work);
184+}
185+
186+static void kfd_process_destroy_delayed(struct rcu_head *rcu)
187+{
188+ struct kfd_process_release_work *work;
189+ struct kfd_process *p;
190+
191+ BUG_ON(!kfd_process_wq);
192+
193+ p = container_of(rcu, struct kfd_process, rcu);
194+ BUG_ON(atomic_read(&p->mm->mm_count) <= 0);
195+
196+ mmdrop(p->mm);
197+
198+ work = (struct kfd_process_release_work *)
199+ kmalloc(sizeof(struct kfd_process_release_work), GFP_ATOMIC);
200+
201+ if (work) {
202+ INIT_WORK((struct work_struct *) work, kfd_process_wq_release);
203+ work->p = p;
204+ queue_work(kfd_process_wq, (struct work_struct *) work);
205+ }
206+}
207+
208+static void kfd_process_notifier_release(struct mmu_notifier *mn,
209+ struct mm_struct *mm)
210+{
211+ struct kfd_process *p;
212+
213+ /*
214+ * The kfd_process structure can not be free because the
215+ * mmu_notifier srcu is read locked
216+ */
217+ p = container_of(mn, struct kfd_process, mmu_notifier);
218+ BUG_ON(p->mm != mm);
219+
220+ mutex_lock(&kfd_processes_mutex);
221+ hash_del_rcu(&p->kfd_processes);
222+ mutex_unlock(&kfd_processes_mutex);
223+ synchronize_srcu(&kfd_processes_srcu);
224+
225+ mutex_lock(&p->mutex);
226+
227+ /* In case our notifier is called before IOMMU notifier */
228+ pqm_uninit(&p->pqm);
229+
230+ mutex_unlock(&p->mutex);
231+
232+ /*
233+ * Because we drop mm_count inside kfd_process_destroy_delayed
234+ * and because the mmu_notifier_unregister function also drop
235+ * mm_count we need to take an extra count here.
236+ */
237+ atomic_inc(&p->mm->mm_count);
238+ mmu_notifier_unregister_no_release(&p->mmu_notifier, p->mm);
239+ mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed);
240+}
241+
242+static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
243+ .release = kfd_process_notifier_release,
244+};
245+
246+static struct kfd_process *create_process(const struct task_struct *thread)
247+{
248+ struct kfd_process *process;
249+ int err = -ENOMEM;
250+
251+ process = kzalloc(sizeof(*process), GFP_KERNEL);
252+
253+ if (!process)
254+ goto err_alloc_process;
255+
256+ process->queues = kmalloc_array(INITIAL_QUEUE_ARRAY_SIZE,
257+ sizeof(process->queues[0]), GFP_KERNEL);
258+ if (!process->queues)
259+ goto err_alloc_queues;
260+
261+ process->pasid = kfd_pasid_alloc();
262+ if (process->pasid == 0)
263+ goto err_alloc_pasid;
264+
265+ mutex_init(&process->mutex);
266+
267+ process->mm = thread->mm;
268+
269+ /* register notifier */
270+ process->mmu_notifier.ops = &kfd_process_mmu_notifier_ops;
271+ err = __mmu_notifier_register(&process->mmu_notifier, process->mm);
272+ if (err)
273+ goto err_mmu_notifier;
274+
275+ hash_add_rcu(kfd_processes_table, &process->kfd_processes,
276+ (uintptr_t)process->mm);
277+
278+ process->lead_thread = thread->group_leader;
279+
280+ process->queue_array_size = INITIAL_QUEUE_ARRAY_SIZE;
281+
282+ INIT_LIST_HEAD(&process->per_device_data);
283+
284+ err = pqm_init(&process->pqm, process);
285+ if (err != 0)
286+ goto err_process_pqm_init;
287+
288+ return process;
289+
290+err_process_pqm_init:
291+ hash_del_rcu(&process->kfd_processes);
292+ synchronize_rcu();
293+ mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm);
294+err_mmu_notifier:
295+ kfd_pasid_free(process->pasid);
296+err_alloc_pasid:
297+ kfree(process->queues);
298+err_alloc_queues:
299+ kfree(process);
300+err_alloc_process:
301+ return ERR_PTR(err);
302+}
303+
304+struct kfd_process_device *kfd_get_process_device_data(struct kfd_dev *dev,
305+ struct kfd_process *p,
306+ int create_pdd)
307+{
308+ struct kfd_process_device *pdd = NULL;
309+
310+ list_for_each_entry(pdd, &p->per_device_data, per_device_list)
311+ if (pdd->dev == dev)
312+ return pdd;
313+
314+ if (create_pdd) {
315+ pdd = kzalloc(sizeof(*pdd), GFP_KERNEL);
316+ if (pdd != NULL) {
317+ pdd->dev = dev;
318+ INIT_LIST_HEAD(&pdd->qpd.queues_list);
319+ INIT_LIST_HEAD(&pdd->qpd.priv_queue_list);
320+ pdd->qpd.dqm = dev->dqm;
321+ list_add(&pdd->per_device_list, &p->per_device_data);
322+ }
323+ }
324+
325+ return pdd;
326+}
327+
328+/*
329+ * Direct the IOMMU to bind the process (specifically the pasid->mm)
330+ * to the device.
331+ * Unbinding occurs when the process dies or the device is removed.
332+ *
333+ * Assumes that the process lock is held.
334+ */
335+struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
336+ struct kfd_process *p)
337+{
338+ struct kfd_process_device *pdd = kfd_get_process_device_data(dev, p, 1);
339+ int err;
340+
341+ if (pdd == NULL)
342+ return ERR_PTR(-ENOMEM);
343+
344+ if (pdd->bound)
345+ return pdd;
346+
347+ err = amd_iommu_bind_pasid(dev->pdev, p->pasid, p->lead_thread);
348+ if (err < 0)
349+ return ERR_PTR(err);
350+
351+ pdd->bound = true;
352+
353+ return pdd;
354+}
355+
356+void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid)
357+{
358+ struct kfd_process *p;
359+ struct kfd_process_device *pdd;
360+ int idx, i;
361+
362+ BUG_ON(dev == NULL);
363+
364+ idx = srcu_read_lock(&kfd_processes_srcu);
365+
366+ hash_for_each_rcu(kfd_processes_table, i, p, kfd_processes)
367+ if (p->pasid == pasid)
368+ break;
369+
370+ srcu_read_unlock(&kfd_processes_srcu, idx);
371+
372+ BUG_ON(p->pasid != pasid);
373+
374+ mutex_lock(&p->mutex);
375+
376+ pqm_uninit(&p->pqm);
377+
378+ pdd = kfd_get_process_device_data(dev, p, 0);
379+
380+ /*
381+ * Just mark pdd as unbound, because we still need it to call
382+ * amd_iommu_unbind_pasid() in when the process exits.
383+ * We don't call amd_iommu_unbind_pasid() here
384+ * because the IOMMU called us.
385+ */
386+ if (pdd)
387+ pdd->bound = false;
388+
389+ mutex_unlock(&p->mutex);
390+}
391+
392+struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p)
393+{
394+ return list_first_entry(&p->per_device_data,
395+ struct kfd_process_device,
396+ per_device_list);
397+}
398+
399+struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
400+ struct kfd_process_device *pdd)
401+{
402+ if (list_is_last(&pdd->per_device_list, &p->per_device_data))
403+ return NULL;
404+ return list_next_entry(pdd, per_device_list);
405+}
406+
407+bool kfd_has_process_device_data(struct kfd_process *p)
408+{
409+ return !(list_empty(&p->per_device_data));
410+}
drivers/gpu/drm/amd/amdkfd/kfd_process_queue_manager.c+343−0
@@ -0,0 +1,343 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/slab.h>
25+#include <linux/list.h>
26+#include "kfd_device_queue_manager.h"
27+#include "kfd_priv.h"
28+#include "kfd_kernel_queue.h"
29+
30+static inline struct process_queue_node *get_queue_by_qid(
31+ struct process_queue_manager *pqm, unsigned int qid)
32+{
33+ struct process_queue_node *pqn;
34+
35+ BUG_ON(!pqm);
36+
37+ list_for_each_entry(pqn, &pqm->queues, process_queue_list) {
38+ if (pqn->q && pqn->q->properties.queue_id == qid)
39+ return pqn;
40+ if (pqn->kq && pqn->kq->queue->properties.queue_id == qid)
41+ return pqn;
42+ }
43+
44+ return NULL;
45+}
46+
47+static int find_available_queue_slot(struct process_queue_manager *pqm,
48+ unsigned int *qid)
49+{
50+ unsigned long found;
51+
52+ BUG_ON(!pqm || !qid);
53+
54+ pr_debug("kfd: in %s\n", __func__);
55+
56+ found = find_first_zero_bit(pqm->queue_slot_bitmap,
57+ max_num_of_queues_per_process);
58+
59+ pr_debug("kfd: the new slot id %lu\n", found);
60+
61+ if (found >= max_num_of_queues_per_process) {
62+ pr_info("amdkfd: Can not open more queues for process with pasid %d\n",
63+ pqm->process->pasid);
64+ return -ENOMEM;
65+ }
66+
67+ set_bit(found, pqm->queue_slot_bitmap);
68+ *qid = found;
69+
70+ return 0;
71+}
72+
73+int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p)
74+{
75+ BUG_ON(!pqm);
76+
77+ INIT_LIST_HEAD(&pqm->queues);
78+ pqm->queue_slot_bitmap =
79+ kzalloc(DIV_ROUND_UP(max_num_of_queues_per_process,
80+ BITS_PER_BYTE), GFP_KERNEL);
81+ if (pqm->queue_slot_bitmap == NULL)
82+ return -ENOMEM;
83+ pqm->process = p;
84+
85+ return 0;
86+}
87+
88+void pqm_uninit(struct process_queue_manager *pqm)
89+{
90+ int retval;
91+ struct process_queue_node *pqn, *next;
92+
93+ BUG_ON(!pqm);
94+
95+ pr_debug("In func %s\n", __func__);
96+
97+ list_for_each_entry_safe(pqn, next, &pqm->queues, process_queue_list) {
98+ retval = pqm_destroy_queue(
99+ pqm,
100+ (pqn->q != NULL) ?
101+ pqn->q->properties.queue_id :
102+ pqn->kq->queue->properties.queue_id);
103+
104+ if (retval != 0) {
105+ pr_err("kfd: failed to destroy queue\n");
106+ return;
107+ }
108+ }
109+ kfree(pqm->queue_slot_bitmap);
110+ pqm->queue_slot_bitmap = NULL;
111+}
112+
113+static int create_cp_queue(struct process_queue_manager *pqm,
114+ struct kfd_dev *dev, struct queue **q,
115+ struct queue_properties *q_properties,
116+ struct file *f, unsigned int qid)
117+{
118+ int retval;
119+
120+ retval = 0;
121+
122+ /* Doorbell initialized in user space*/
123+ q_properties->doorbell_ptr = NULL;
124+
125+ q_properties->doorbell_off =
126+ kfd_queue_id_to_doorbell(dev, pqm->process, qid);
127+
128+ /* let DQM handle it*/
129+ q_properties->vmid = 0;
130+ q_properties->queue_id = qid;
131+ q_properties->type = KFD_QUEUE_TYPE_COMPUTE;
132+
133+ retval = init_queue(q, *q_properties);
134+ if (retval != 0)
135+ goto err_init_queue;
136+
137+ (*q)->device = dev;
138+ (*q)->process = pqm->process;
139+
140+ pr_debug("kfd: PQM After init queue");
141+
142+ return retval;
143+
144+err_init_queue:
145+ return retval;
146+}
147+
148+int pqm_create_queue(struct process_queue_manager *pqm,
149+ struct kfd_dev *dev,
150+ struct file *f,
151+ struct queue_properties *properties,
152+ unsigned int flags,
153+ enum kfd_queue_type type,
154+ unsigned int *qid)
155+{
156+ int retval;
157+ struct kfd_process_device *pdd;
158+ struct queue_properties q_properties;
159+ struct queue *q;
160+ struct process_queue_node *pqn;
161+ struct kernel_queue *kq;
162+
163+ BUG_ON(!pqm || !dev || !properties || !qid);
164+
165+ memset(&q_properties, 0, sizeof(struct queue_properties));
166+ memcpy(&q_properties, properties, sizeof(struct queue_properties));
167+ q = NULL;
168+ kq = NULL;
169+
170+ pdd = kfd_get_process_device_data(dev, pqm->process, 1);
171+ BUG_ON(!pdd);
172+
173+ retval = find_available_queue_slot(pqm, qid);
174+ if (retval != 0)
175+ return retval;
176+
177+ if (list_empty(&pqm->queues)) {
178+ pdd->qpd.pqm = pqm;
179+ dev->dqm->register_process(dev->dqm, &pdd->qpd);
180+ }
181+
182+ pqn = kzalloc(sizeof(struct process_queue_node), GFP_KERNEL);
183+ if (!pqn) {
184+ retval = -ENOMEM;
185+ goto err_allocate_pqn;
186+ }
187+
188+ switch (type) {
189+ case KFD_QUEUE_TYPE_COMPUTE:
190+ /* check if there is over subscription */
191+ if ((sched_policy == KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION) &&
192+ ((dev->dqm->processes_count >= VMID_PER_DEVICE) ||
193+ (dev->dqm->queue_count >= PIPE_PER_ME_CP_SCHEDULING * QUEUES_PER_PIPE))) {
194+ pr_err("kfd: over-subscription is not allowed in radeon_kfd.sched_policy == 1\n");
195+ retval = -EPERM;
196+ goto err_create_queue;
197+ }
198+
199+ retval = create_cp_queue(pqm, dev, &q, &q_properties, f, *qid);
200+ if (retval != 0)
201+ goto err_create_queue;
202+ pqn->q = q;
203+ pqn->kq = NULL;
204+ retval = dev->dqm->create_queue(dev->dqm, q, &pdd->qpd,
205+ &q->properties.vmid);
206+ print_queue(q);
207+ break;
208+ case KFD_QUEUE_TYPE_DIQ:
209+ kq = kernel_queue_init(dev, KFD_QUEUE_TYPE_DIQ);
210+ if (kq == NULL) {
211+ retval = -ENOMEM;
212+ goto err_create_queue;
213+ }
214+ kq->queue->properties.queue_id = *qid;
215+ pqn->kq = kq;
216+ pqn->q = NULL;
217+ retval = dev->dqm->create_kernel_queue(dev->dqm, kq, &pdd->qpd);
218+ break;
219+ default:
220+ BUG();
221+ break;
222+ }
223+
224+ if (retval != 0) {
225+ pr_err("kfd: error dqm create queue\n");
226+ goto err_create_queue;
227+ }
228+
229+ pr_debug("kfd: PQM After DQM create queue\n");
230+
231+ list_add(&pqn->process_queue_list, &pqm->queues);
232+
233+ if (q) {
234+ *properties = q->properties;
235+ pr_debug("kfd: PQM done creating queue\n");
236+ print_queue_properties(properties);
237+ }
238+
239+ return retval;
240+
241+err_create_queue:
242+ kfree(pqn);
243+err_allocate_pqn:
244+ clear_bit(*qid, pqm->queue_slot_bitmap);
245+ return retval;
246+}
247+
248+int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid)
249+{
250+ struct process_queue_node *pqn;
251+ struct kfd_process_device *pdd;
252+ struct device_queue_manager *dqm;
253+ struct kfd_dev *dev;
254+ int retval;
255+
256+ dqm = NULL;
257+
258+ BUG_ON(!pqm);
259+ retval = 0;
260+
261+ pr_debug("kfd: In Func %s\n", __func__);
262+
263+ pqn = get_queue_by_qid(pqm, qid);
264+ if (pqn == NULL) {
265+ pr_err("kfd: queue id does not match any known queue\n");
266+ return -EINVAL;
267+ }
268+
269+ dev = NULL;
270+ if (pqn->kq)
271+ dev = pqn->kq->dev;
272+ if (pqn->q)
273+ dev = pqn->q->device;
274+ BUG_ON(!dev);
275+
276+ pdd = kfd_get_process_device_data(dev, pqm->process, 1);
277+ BUG_ON(!pdd);
278+
279+ if (pqn->kq) {
280+ /* destroy kernel queue (DIQ) */
281+ dqm = pqn->kq->dev->dqm;
282+ dqm->destroy_kernel_queue(dqm, pqn->kq, &pdd->qpd);
283+ kernel_queue_uninit(pqn->kq);
284+ }
285+
286+ if (pqn->q) {
287+ dqm = pqn->q->device->dqm;
288+ retval = dqm->destroy_queue(dqm, &pdd->qpd, pqn->q);
289+ if (retval != 0)
290+ return retval;
291+
292+ uninit_queue(pqn->q);
293+ }
294+
295+ list_del(&pqn->process_queue_list);
296+ kfree(pqn);
297+ clear_bit(qid, pqm->queue_slot_bitmap);
298+
299+ if (list_empty(&pqm->queues))
300+ dqm->unregister_process(dqm, &pdd->qpd);
301+
302+ return retval;
303+}
304+
305+int pqm_update_queue(struct process_queue_manager *pqm, unsigned int qid,
306+ struct queue_properties *p)
307+{
308+ int retval;
309+ struct process_queue_node *pqn;
310+
311+ BUG_ON(!pqm);
312+
313+ pqn = get_queue_by_qid(pqm, qid);
314+ BUG_ON(!pqn);
315+
316+ pqn->q->properties.queue_address = p->queue_address;
317+ pqn->q->properties.queue_size = p->queue_size;
318+ pqn->q->properties.queue_percent = p->queue_percent;
319+ pqn->q->properties.priority = p->priority;
320+
321+ retval = pqn->q->device->dqm->update_queue(pqn->q->device->dqm, pqn->q);
322+ if (retval != 0)
323+ return retval;
324+
325+ return 0;
326+}
327+
328+static __attribute__((unused)) struct kernel_queue *pqm_get_kernel_queue(
329+ struct process_queue_manager *pqm,
330+ unsigned int qid)
331+{
332+ struct process_queue_node *pqn;
333+
334+ BUG_ON(!pqm);
335+
336+ pqn = get_queue_by_qid(pqm, qid);
337+ if (pqn && pqn->kq)
338+ return pqn->kq;
339+
340+ return NULL;
341+}
342+
343+
drivers/gpu/drm/amd/amdkfd/kfd_queue.c+85−0
@@ -0,0 +1,85 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ *
22+ */
23+
24+#include <linux/slab.h>
25+#include "kfd_priv.h"
26+
27+void print_queue_properties(struct queue_properties *q)
28+{
29+ if (!q)
30+ return;
31+
32+ pr_debug("Printing queue properties:\n");
33+ pr_debug("Queue Type: %u\n", q->type);
34+ pr_debug("Queue Size: %llu\n", q->queue_size);
35+ pr_debug("Queue percent: %u\n", q->queue_percent);
36+ pr_debug("Queue Address: 0x%llX\n", q->queue_address);
37+ pr_debug("Queue Id: %u\n", q->queue_id);
38+ pr_debug("Queue Process Vmid: %u\n", q->vmid);
39+ pr_debug("Queue Read Pointer: 0x%p\n", q->read_ptr);
40+ pr_debug("Queue Write Pointer: 0x%p\n", q->write_ptr);
41+ pr_debug("Queue Doorbell Pointer: 0x%p\n", q->doorbell_ptr);
42+ pr_debug("Queue Doorbell Offset: %u\n", q->doorbell_off);
43+}
44+
45+void print_queue(struct queue *q)
46+{
47+ if (!q)
48+ return;
49+ pr_debug("Printing queue:\n");
50+ pr_debug("Queue Type: %u\n", q->properties.type);
51+ pr_debug("Queue Size: %llu\n", q->properties.queue_size);
52+ pr_debug("Queue percent: %u\n", q->properties.queue_percent);
53+ pr_debug("Queue Address: 0x%llX\n", q->properties.queue_address);
54+ pr_debug("Queue Id: %u\n", q->properties.queue_id);
55+ pr_debug("Queue Process Vmid: %u\n", q->properties.vmid);
56+ pr_debug("Queue Read Pointer: 0x%p\n", q->properties.read_ptr);
57+ pr_debug("Queue Write Pointer: 0x%p\n", q->properties.write_ptr);
58+ pr_debug("Queue Doorbell Pointer: 0x%p\n", q->properties.doorbell_ptr);
59+ pr_debug("Queue Doorbell Offset: %u\n", q->properties.doorbell_off);
60+ pr_debug("Queue MQD Address: 0x%p\n", q->mqd);
61+ pr_debug("Queue MQD Gart: 0x%llX\n", q->gart_mqd_addr);
62+ pr_debug("Queue Process Address: 0x%p\n", q->process);
63+ pr_debug("Queue Device Address: 0x%p\n", q->device);
64+}
65+
66+int init_queue(struct queue **q, struct queue_properties properties)
67+{
68+ struct queue *tmp;
69+
70+ BUG_ON(!q);
71+
72+ tmp = kzalloc(sizeof(struct queue), GFP_KERNEL);
73+ if (!tmp)
74+ return -ENOMEM;
75+
76+ memcpy(&tmp->properties, &properties, sizeof(struct queue_properties));
77+
78+ *q = tmp;
79+ return 0;
80+}
81+
82+void uninit_queue(struct queue *q)
83+{
84+ kfree(q);
85+}
drivers/gpu/drm/amd/amdkfd/kfd_topology.c+1235−0
@@ -0,0 +1,1235 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#include <linux/types.h>
24+#include <linux/kernel.h>
25+#include <linux/pci.h>
26+#include <linux/errno.h>
27+#include <linux/acpi.h>
28+#include <linux/hash.h>
29+#include <linux/cpufreq.h>
30+
31+#include "kfd_priv.h"
32+#include "kfd_crat.h"
33+#include "kfd_topology.h"
34+
35+static struct list_head topology_device_list;
36+static int topology_crat_parsed;
37+static struct kfd_system_properties sys_props;
38+
39+static DECLARE_RWSEM(topology_lock);
40+
41+struct kfd_dev *kfd_device_by_id(uint32_t gpu_id)
42+{
43+ struct kfd_topology_device *top_dev;
44+ struct kfd_dev *device = NULL;
45+
46+ down_read(&topology_lock);
47+
48+ list_for_each_entry(top_dev, &topology_device_list, list)
49+ if (top_dev->gpu_id == gpu_id) {
50+ device = top_dev->gpu;
51+ break;
52+ }
53+
54+ up_read(&topology_lock);
55+
56+ return device;
57+}
58+
59+struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev)
60+{
61+ struct kfd_topology_device *top_dev;
62+ struct kfd_dev *device = NULL;
63+
64+ down_read(&topology_lock);
65+
66+ list_for_each_entry(top_dev, &topology_device_list, list)
67+ if (top_dev->gpu->pdev == pdev) {
68+ device = top_dev->gpu;
69+ break;
70+ }
71+
72+ up_read(&topology_lock);
73+
74+ return device;
75+}
76+
77+static int kfd_topology_get_crat_acpi(void *crat_image, size_t *size)
78+{
79+ struct acpi_table_header *crat_table;
80+ acpi_status status;
81+
82+ if (!size)
83+ return -EINVAL;
84+
85+ /*
86+ * Fetch the CRAT table from ACPI
87+ */
88+ status = acpi_get_table(CRAT_SIGNATURE, 0, &crat_table);
89+ if (status == AE_NOT_FOUND) {
90+ pr_warn("CRAT table not found\n");
91+ return -ENODATA;
92+ } else if (ACPI_FAILURE(status)) {
93+ const char *err = acpi_format_exception(status);
94+
95+ pr_err("CRAT table error: %s\n", err);
96+ return -EINVAL;
97+ }
98+
99+ if (*size >= crat_table->length && crat_image != NULL)
100+ memcpy(crat_image, crat_table, crat_table->length);
101+
102+ *size = crat_table->length;
103+
104+ return 0;
105+}
106+
107+static void kfd_populated_cu_info_cpu(struct kfd_topology_device *dev,
108+ struct crat_subtype_computeunit *cu)
109+{
110+ BUG_ON(!dev);
111+ BUG_ON(!cu);
112+
113+ dev->node_props.cpu_cores_count = cu->num_cpu_cores;
114+ dev->node_props.cpu_core_id_base = cu->processor_id_low;
115+ if (cu->hsa_capability & CRAT_CU_FLAGS_IOMMU_PRESENT)
116+ dev->node_props.capability |= HSA_CAP_ATS_PRESENT;
117+
118+ pr_info("CU CPU: cores=%d id_base=%d\n", cu->num_cpu_cores,
119+ cu->processor_id_low);
120+}
121+
122+static void kfd_populated_cu_info_gpu(struct kfd_topology_device *dev,
123+ struct crat_subtype_computeunit *cu)
124+{
125+ BUG_ON(!dev);
126+ BUG_ON(!cu);
127+
128+ dev->node_props.simd_id_base = cu->processor_id_low;
129+ dev->node_props.simd_count = cu->num_simd_cores;
130+ dev->node_props.lds_size_in_kb = cu->lds_size_in_kb;
131+ dev->node_props.max_waves_per_simd = cu->max_waves_simd;
132+ dev->node_props.wave_front_size = cu->wave_front_size;
133+ dev->node_props.mem_banks_count = cu->num_banks;
134+ dev->node_props.array_count = cu->num_arrays;
135+ dev->node_props.cu_per_simd_array = cu->num_cu_per_array;
136+ dev->node_props.simd_per_cu = cu->num_simd_per_cu;
137+ dev->node_props.max_slots_scratch_cu = cu->max_slots_scatch_cu;
138+ if (cu->hsa_capability & CRAT_CU_FLAGS_HOT_PLUGGABLE)
139+ dev->node_props.capability |= HSA_CAP_HOT_PLUGGABLE;
140+ pr_info("CU GPU: simds=%d id_base=%d\n", cu->num_simd_cores,
141+ cu->processor_id_low);
142+}
143+
144+/* kfd_parse_subtype_cu is called when the topology mutex is already acquired */
145+static int kfd_parse_subtype_cu(struct crat_subtype_computeunit *cu)
146+{
147+ struct kfd_topology_device *dev;
148+ int i = 0;
149+
150+ BUG_ON(!cu);
151+
152+ pr_info("Found CU entry in CRAT table with proximity_domain=%d caps=%x\n",
153+ cu->proximity_domain, cu->hsa_capability);
154+ list_for_each_entry(dev, &topology_device_list, list) {
155+ if (cu->proximity_domain == i) {
156+ if (cu->flags & CRAT_CU_FLAGS_CPU_PRESENT)
157+ kfd_populated_cu_info_cpu(dev, cu);
158+
159+ if (cu->flags & CRAT_CU_FLAGS_GPU_PRESENT)
160+ kfd_populated_cu_info_gpu(dev, cu);
161+ break;
162+ }
163+ i++;
164+ }
165+
166+ return 0;
167+}
168+
169+/*
170+ * kfd_parse_subtype_mem is called when the topology mutex is
171+ * already acquired
172+ */
173+static int kfd_parse_subtype_mem(struct crat_subtype_memory *mem)
174+{
175+ struct kfd_mem_properties *props;
176+ struct kfd_topology_device *dev;
177+ int i = 0;
178+
179+ BUG_ON(!mem);
180+
181+ pr_info("Found memory entry in CRAT table with proximity_domain=%d\n",
182+ mem->promixity_domain);
183+ list_for_each_entry(dev, &topology_device_list, list) {
184+ if (mem->promixity_domain == i) {
185+ props = kfd_alloc_struct(props);
186+ if (props == NULL)
187+ return -ENOMEM;
188+
189+ if (dev->node_props.cpu_cores_count == 0)
190+ props->heap_type = HSA_MEM_HEAP_TYPE_FB_PRIVATE;
191+ else
192+ props->heap_type = HSA_MEM_HEAP_TYPE_SYSTEM;
193+
194+ if (mem->flags & CRAT_MEM_FLAGS_HOT_PLUGGABLE)
195+ props->flags |= HSA_MEM_FLAGS_HOT_PLUGGABLE;
196+ if (mem->flags & CRAT_MEM_FLAGS_NON_VOLATILE)
197+ props->flags |= HSA_MEM_FLAGS_NON_VOLATILE;
198+
199+ props->size_in_bytes =
200+ ((uint64_t)mem->length_high << 32) +
201+ mem->length_low;
202+ props->width = mem->width;
203+
204+ dev->mem_bank_count++;
205+ list_add_tail(&props->list, &dev->mem_props);
206+
207+ break;
208+ }
209+ i++;
210+ }
211+
212+ return 0;
213+}
214+
215+/*
216+ * kfd_parse_subtype_cache is called when the topology mutex
217+ * is already acquired
218+ */
219+static int kfd_parse_subtype_cache(struct crat_subtype_cache *cache)
220+{
221+ struct kfd_cache_properties *props;
222+ struct kfd_topology_device *dev;
223+ uint32_t id;
224+
225+ BUG_ON(!cache);
226+
227+ id = cache->processor_id_low;
228+
229+ pr_info("Found cache entry in CRAT table with processor_id=%d\n", id);
230+ list_for_each_entry(dev, &topology_device_list, list)
231+ if (id == dev->node_props.cpu_core_id_base ||
232+ id == dev->node_props.simd_id_base) {
233+ props = kfd_alloc_struct(props);
234+ if (props == NULL)
235+ return -ENOMEM;
236+
237+ props->processor_id_low = id;
238+ props->cache_level = cache->cache_level;
239+ props->cache_size = cache->cache_size;
240+ props->cacheline_size = cache->cache_line_size;
241+ props->cachelines_per_tag = cache->lines_per_tag;
242+ props->cache_assoc = cache->associativity;
243+ props->cache_latency = cache->cache_latency;
244+
245+ if (cache->flags & CRAT_CACHE_FLAGS_DATA_CACHE)
246+ props->cache_type |= HSA_CACHE_TYPE_DATA;
247+ if (cache->flags & CRAT_CACHE_FLAGS_INST_CACHE)
248+ props->cache_type |= HSA_CACHE_TYPE_INSTRUCTION;
249+ if (cache->flags & CRAT_CACHE_FLAGS_CPU_CACHE)
250+ props->cache_type |= HSA_CACHE_TYPE_CPU;
251+ if (cache->flags & CRAT_CACHE_FLAGS_SIMD_CACHE)
252+ props->cache_type |= HSA_CACHE_TYPE_HSACU;
253+
254+ dev->cache_count++;
255+ dev->node_props.caches_count++;
256+ list_add_tail(&props->list, &dev->cache_props);
257+
258+ break;
259+ }
260+
261+ return 0;
262+}
263+
264+/*
265+ * kfd_parse_subtype_iolink is called when the topology mutex
266+ * is already acquired
267+ */
268+static int kfd_parse_subtype_iolink(struct crat_subtype_iolink *iolink)
269+{
270+ struct kfd_iolink_properties *props;
271+ struct kfd_topology_device *dev;
272+ uint32_t i = 0;
273+ uint32_t id_from;
274+ uint32_t id_to;
275+
276+ BUG_ON(!iolink);
277+
278+ id_from = iolink->proximity_domain_from;
279+ id_to = iolink->proximity_domain_to;
280+
281+ pr_info("Found IO link entry in CRAT table with id_from=%d\n", id_from);
282+ list_for_each_entry(dev, &topology_device_list, list) {
283+ if (id_from == i) {
284+ props = kfd_alloc_struct(props);
285+ if (props == NULL)
286+ return -ENOMEM;
287+
288+ props->node_from = id_from;
289+ props->node_to = id_to;
290+ props->ver_maj = iolink->version_major;
291+ props->ver_min = iolink->version_minor;
292+
293+ /*
294+ * weight factor (derived from CDIR), currently always 1
295+ */
296+ props->weight = 1;
297+
298+ props->min_latency = iolink->minimum_latency;
299+ props->max_latency = iolink->maximum_latency;
300+ props->min_bandwidth = iolink->minimum_bandwidth_mbs;
301+ props->max_bandwidth = iolink->maximum_bandwidth_mbs;
302+ props->rec_transfer_size =
303+ iolink->recommended_transfer_size;
304+
305+ dev->io_link_count++;
306+ dev->node_props.io_links_count++;
307+ list_add_tail(&props->list, &dev->io_link_props);
308+
309+ break;
310+ }
311+ i++;
312+ }
313+
314+ return 0;
315+}
316+
317+static int kfd_parse_subtype(struct crat_subtype_generic *sub_type_hdr)
318+{
319+ struct crat_subtype_computeunit *cu;
320+ struct crat_subtype_memory *mem;
321+ struct crat_subtype_cache *cache;
322+ struct crat_subtype_iolink *iolink;
323+ int ret = 0;
324+
325+ BUG_ON(!sub_type_hdr);
326+
327+ switch (sub_type_hdr->type) {
328+ case CRAT_SUBTYPE_COMPUTEUNIT_AFFINITY:
329+ cu = (struct crat_subtype_computeunit *)sub_type_hdr;
330+ ret = kfd_parse_subtype_cu(cu);
331+ break;
332+ case CRAT_SUBTYPE_MEMORY_AFFINITY:
333+ mem = (struct crat_subtype_memory *)sub_type_hdr;
334+ ret = kfd_parse_subtype_mem(mem);
335+ break;
336+ case CRAT_SUBTYPE_CACHE_AFFINITY:
337+ cache = (struct crat_subtype_cache *)sub_type_hdr;
338+ ret = kfd_parse_subtype_cache(cache);
339+ break;
340+ case CRAT_SUBTYPE_TLB_AFFINITY:
341+ /*
342+ * For now, nothing to do here
343+ */
344+ pr_info("Found TLB entry in CRAT table (not processing)\n");
345+ break;
346+ case CRAT_SUBTYPE_CCOMPUTE_AFFINITY:
347+ /*
348+ * For now, nothing to do here
349+ */
350+ pr_info("Found CCOMPUTE entry in CRAT table (not processing)\n");
351+ break;
352+ case CRAT_SUBTYPE_IOLINK_AFFINITY:
353+ iolink = (struct crat_subtype_iolink *)sub_type_hdr;
354+ ret = kfd_parse_subtype_iolink(iolink);
355+ break;
356+ default:
357+ pr_warn("Unknown subtype (%d) in CRAT\n",
358+ sub_type_hdr->type);
359+ }
360+
361+ return ret;
362+}
363+
364+static void kfd_release_topology_device(struct kfd_topology_device *dev)
365+{
366+ struct kfd_mem_properties *mem;
367+ struct kfd_cache_properties *cache;
368+ struct kfd_iolink_properties *iolink;
369+
370+ BUG_ON(!dev);
371+
372+ list_del(&dev->list);
373+
374+ while (dev->mem_props.next != &dev->mem_props) {
375+ mem = container_of(dev->mem_props.next,
376+ struct kfd_mem_properties, list);
377+ list_del(&mem->list);
378+ kfree(mem);
379+ }
380+
381+ while (dev->cache_props.next != &dev->cache_props) {
382+ cache = container_of(dev->cache_props.next,
383+ struct kfd_cache_properties, list);
384+ list_del(&cache->list);
385+ kfree(cache);
386+ }
387+
388+ while (dev->io_link_props.next != &dev->io_link_props) {
389+ iolink = container_of(dev->io_link_props.next,
390+ struct kfd_iolink_properties, list);
391+ list_del(&iolink->list);
392+ kfree(iolink);
393+ }
394+
395+ kfree(dev);
396+
397+ sys_props.num_devices--;
398+}
399+
400+static void kfd_release_live_view(void)
401+{
402+ struct kfd_topology_device *dev;
403+
404+ while (topology_device_list.next != &topology_device_list) {
405+ dev = container_of(topology_device_list.next,
406+ struct kfd_topology_device, list);
407+ kfd_release_topology_device(dev);
408+}
409+
410+ memset(&sys_props, 0, sizeof(sys_props));
411+}
412+
413+static struct kfd_topology_device *kfd_create_topology_device(void)
414+{
415+ struct kfd_topology_device *dev;
416+
417+ dev = kfd_alloc_struct(dev);
418+ if (dev == NULL) {
419+ pr_err("No memory to allocate a topology device");
420+ return NULL;
421+ }
422+
423+ INIT_LIST_HEAD(&dev->mem_props);
424+ INIT_LIST_HEAD(&dev->cache_props);
425+ INIT_LIST_HEAD(&dev->io_link_props);
426+
427+ list_add_tail(&dev->list, &topology_device_list);
428+ sys_props.num_devices++;
429+
430+ return dev;
431+}
432+
433+static int kfd_parse_crat_table(void *crat_image)
434+{
435+ struct kfd_topology_device *top_dev;
436+ struct crat_subtype_generic *sub_type_hdr;
437+ uint16_t node_id;
438+ int ret;
439+ struct crat_header *crat_table = (struct crat_header *)crat_image;
440+ uint16_t num_nodes;
441+ uint32_t image_len;
442+
443+ if (!crat_image)
444+ return -EINVAL;
445+
446+ num_nodes = crat_table->num_domains;
447+ image_len = crat_table->length;
448+
449+ pr_info("Parsing CRAT table with %d nodes\n", num_nodes);
450+
451+ for (node_id = 0; node_id < num_nodes; node_id++) {
452+ top_dev = kfd_create_topology_device();
453+ if (!top_dev) {
454+ kfd_release_live_view();
455+ return -ENOMEM;
456+ }
457+ }
458+
459+ sys_props.platform_id =
460+ (*((uint64_t *)crat_table->oem_id)) & CRAT_OEMID_64BIT_MASK;
461+ sys_props.platform_oem = *((uint64_t *)crat_table->oem_table_id);
462+ sys_props.platform_rev = crat_table->revision;
463+
464+ sub_type_hdr = (struct crat_subtype_generic *)(crat_table+1);
465+ while ((char *)sub_type_hdr + sizeof(struct crat_subtype_generic) <
466+ ((char *)crat_image) + image_len) {
467+ if (sub_type_hdr->flags & CRAT_SUBTYPE_FLAGS_ENABLED) {
468+ ret = kfd_parse_subtype(sub_type_hdr);
469+ if (ret != 0) {
470+ kfd_release_live_view();
471+ return ret;
472+ }
473+ }
474+
475+ sub_type_hdr = (typeof(sub_type_hdr))((char *)sub_type_hdr +
476+ sub_type_hdr->length);
477+ }
478+
479+ sys_props.generation_count++;
480+ topology_crat_parsed = 1;
481+
482+ return 0;
483+}
484+
485+
486+#define sysfs_show_gen_prop(buffer, fmt, ...) \
487+ snprintf(buffer, PAGE_SIZE, "%s"fmt, buffer, __VA_ARGS__)
488+#define sysfs_show_32bit_prop(buffer, name, value) \
489+ sysfs_show_gen_prop(buffer, "%s %u\n", name, value)
490+#define sysfs_show_64bit_prop(buffer, name, value) \
491+ sysfs_show_gen_prop(buffer, "%s %llu\n", name, value)
492+#define sysfs_show_32bit_val(buffer, value) \
493+ sysfs_show_gen_prop(buffer, "%u\n", value)
494+#define sysfs_show_str_val(buffer, value) \
495+ sysfs_show_gen_prop(buffer, "%s\n", value)
496+
497+static ssize_t sysprops_show(struct kobject *kobj, struct attribute *attr,
498+ char *buffer)
499+{
500+ ssize_t ret;
501+
502+ /* Making sure that the buffer is an empty string */
503+ buffer[0] = 0;
504+
505+ if (attr == &sys_props.attr_genid) {
506+ ret = sysfs_show_32bit_val(buffer, sys_props.generation_count);
507+ } else if (attr == &sys_props.attr_props) {
508+ sysfs_show_64bit_prop(buffer, "platform_oem",
509+ sys_props.platform_oem);
510+ sysfs_show_64bit_prop(buffer, "platform_id",
511+ sys_props.platform_id);
512+ ret = sysfs_show_64bit_prop(buffer, "platform_rev",
513+ sys_props.platform_rev);
514+ } else {
515+ ret = -EINVAL;
516+ }
517+
518+ return ret;
519+}
520+
521+static const struct sysfs_ops sysprops_ops = {
522+ .show = sysprops_show,
523+};
524+
525+static struct kobj_type sysprops_type = {
526+ .sysfs_ops = &sysprops_ops,
527+};
528+
529+static ssize_t iolink_show(struct kobject *kobj, struct attribute *attr,
530+ char *buffer)
531+{
532+ ssize_t ret;
533+ struct kfd_iolink_properties *iolink;
534+
535+ /* Making sure that the buffer is an empty string */
536+ buffer[0] = 0;
537+
538+ iolink = container_of(attr, struct kfd_iolink_properties, attr);
539+ sysfs_show_32bit_prop(buffer, "type", iolink->iolink_type);
540+ sysfs_show_32bit_prop(buffer, "version_major", iolink->ver_maj);
541+ sysfs_show_32bit_prop(buffer, "version_minor", iolink->ver_min);
542+ sysfs_show_32bit_prop(buffer, "node_from", iolink->node_from);
543+ sysfs_show_32bit_prop(buffer, "node_to", iolink->node_to);
544+ sysfs_show_32bit_prop(buffer, "weight", iolink->weight);
545+ sysfs_show_32bit_prop(buffer, "min_latency", iolink->min_latency);
546+ sysfs_show_32bit_prop(buffer, "max_latency", iolink->max_latency);
547+ sysfs_show_32bit_prop(buffer, "min_bandwidth", iolink->min_bandwidth);
548+ sysfs_show_32bit_prop(buffer, "max_bandwidth", iolink->max_bandwidth);
549+ sysfs_show_32bit_prop(buffer, "recommended_transfer_size",
550+ iolink->rec_transfer_size);
551+ ret = sysfs_show_32bit_prop(buffer, "flags", iolink->flags);
552+
553+ return ret;
554+}
555+
556+static const struct sysfs_ops iolink_ops = {
557+ .show = iolink_show,
558+};
559+
560+static struct kobj_type iolink_type = {
561+ .sysfs_ops = &iolink_ops,
562+};
563+
564+static ssize_t mem_show(struct kobject *kobj, struct attribute *attr,
565+ char *buffer)
566+{
567+ ssize_t ret;
568+ struct kfd_mem_properties *mem;
569+
570+ /* Making sure that the buffer is an empty string */
571+ buffer[0] = 0;
572+
573+ mem = container_of(attr, struct kfd_mem_properties, attr);
574+ sysfs_show_32bit_prop(buffer, "heap_type", mem->heap_type);
575+ sysfs_show_64bit_prop(buffer, "size_in_bytes", mem->size_in_bytes);
576+ sysfs_show_32bit_prop(buffer, "flags", mem->flags);
577+ sysfs_show_32bit_prop(buffer, "width", mem->width);
578+ ret = sysfs_show_32bit_prop(buffer, "mem_clk_max", mem->mem_clk_max);
579+
580+ return ret;
581+}
582+
583+static const struct sysfs_ops mem_ops = {
584+ .show = mem_show,
585+};
586+
587+static struct kobj_type mem_type = {
588+ .sysfs_ops = &mem_ops,
589+};
590+
591+static ssize_t kfd_cache_show(struct kobject *kobj, struct attribute *attr,
592+ char *buffer)
593+{
594+ ssize_t ret;
595+ uint32_t i;
596+ struct kfd_cache_properties *cache;
597+
598+ /* Making sure that the buffer is an empty string */
599+ buffer[0] = 0;
600+
601+ cache = container_of(attr, struct kfd_cache_properties, attr);
602+ sysfs_show_32bit_prop(buffer, "processor_id_low",
603+ cache->processor_id_low);
604+ sysfs_show_32bit_prop(buffer, "level", cache->cache_level);
605+ sysfs_show_32bit_prop(buffer, "size", cache->cache_size);
606+ sysfs_show_32bit_prop(buffer, "cache_line_size", cache->cacheline_size);
607+ sysfs_show_32bit_prop(buffer, "cache_lines_per_tag",
608+ cache->cachelines_per_tag);
609+ sysfs_show_32bit_prop(buffer, "association", cache->cache_assoc);
610+ sysfs_show_32bit_prop(buffer, "latency", cache->cache_latency);
611+ sysfs_show_32bit_prop(buffer, "type", cache->cache_type);
612+ snprintf(buffer, PAGE_SIZE, "%ssibling_map ", buffer);
613+ for (i = 0; i < KFD_TOPOLOGY_CPU_SIBLINGS; i++)
614+ ret = snprintf(buffer, PAGE_SIZE, "%s%d%s",
615+ buffer, cache->sibling_map[i],
616+ (i == KFD_TOPOLOGY_CPU_SIBLINGS-1) ?
617+ "\n" : ",");
618+
619+ return ret;
620+}
621+
622+static const struct sysfs_ops cache_ops = {
623+ .show = kfd_cache_show,
624+};
625+
626+static struct kobj_type cache_type = {
627+ .sysfs_ops = &cache_ops,
628+};
629+
630+static ssize_t node_show(struct kobject *kobj, struct attribute *attr,
631+ char *buffer)
632+{
633+ ssize_t ret;
634+ struct kfd_topology_device *dev;
635+ char public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE];
636+ uint32_t i;
637+
638+ /* Making sure that the buffer is an empty string */
639+ buffer[0] = 0;
640+
641+ if (strcmp(attr->name, "gpu_id") == 0) {
642+ dev = container_of(attr, struct kfd_topology_device,
643+ attr_gpuid);
644+ ret = sysfs_show_32bit_val(buffer, dev->gpu_id);
645+ } else if (strcmp(attr->name, "name") == 0) {
646+ dev = container_of(attr, struct kfd_topology_device,
647+ attr_name);
648+ for (i = 0; i < KFD_TOPOLOGY_PUBLIC_NAME_SIZE; i++) {
649+ public_name[i] =
650+ (char)dev->node_props.marketing_name[i];
651+ if (dev->node_props.marketing_name[i] == 0)
652+ break;
653+ }
654+ public_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE-1] = 0x0;
655+ ret = sysfs_show_str_val(buffer, public_name);
656+ } else {
657+ dev = container_of(attr, struct kfd_topology_device,
658+ attr_props);
659+ sysfs_show_32bit_prop(buffer, "cpu_cores_count",
660+ dev->node_props.cpu_cores_count);
661+ sysfs_show_32bit_prop(buffer, "simd_count",
662+ dev->node_props.simd_count);
663+
664+ if (dev->mem_bank_count < dev->node_props.mem_banks_count) {
665+ pr_warn("kfd: mem_banks_count truncated from %d to %d\n",
666+ dev->node_props.mem_banks_count,
667+ dev->mem_bank_count);
668+ sysfs_show_32bit_prop(buffer, "mem_banks_count",
669+ dev->mem_bank_count);
670+ } else {
671+ sysfs_show_32bit_prop(buffer, "mem_banks_count",
672+ dev->node_props.mem_banks_count);
673+ }
674+
675+ sysfs_show_32bit_prop(buffer, "caches_count",
676+ dev->node_props.caches_count);
677+ sysfs_show_32bit_prop(buffer, "io_links_count",
678+ dev->node_props.io_links_count);
679+ sysfs_show_32bit_prop(buffer, "cpu_core_id_base",
680+ dev->node_props.cpu_core_id_base);
681+ sysfs_show_32bit_prop(buffer, "simd_id_base",
682+ dev->node_props.simd_id_base);
683+ sysfs_show_32bit_prop(buffer, "capability",
684+ dev->node_props.capability);
685+ sysfs_show_32bit_prop(buffer, "max_waves_per_simd",
686+ dev->node_props.max_waves_per_simd);
687+ sysfs_show_32bit_prop(buffer, "lds_size_in_kb",
688+ dev->node_props.lds_size_in_kb);
689+ sysfs_show_32bit_prop(buffer, "gds_size_in_kb",
690+ dev->node_props.gds_size_in_kb);
691+ sysfs_show_32bit_prop(buffer, "wave_front_size",
692+ dev->node_props.wave_front_size);
693+ sysfs_show_32bit_prop(buffer, "array_count",
694+ dev->node_props.array_count);
695+ sysfs_show_32bit_prop(buffer, "simd_arrays_per_engine",
696+ dev->node_props.simd_arrays_per_engine);
697+ sysfs_show_32bit_prop(buffer, "cu_per_simd_array",
698+ dev->node_props.cu_per_simd_array);
699+ sysfs_show_32bit_prop(buffer, "simd_per_cu",
700+ dev->node_props.simd_per_cu);
701+ sysfs_show_32bit_prop(buffer, "max_slots_scratch_cu",
702+ dev->node_props.max_slots_scratch_cu);
703+ sysfs_show_32bit_prop(buffer, "engine_id",
704+ dev->node_props.engine_id);
705+ sysfs_show_32bit_prop(buffer, "vendor_id",
706+ dev->node_props.vendor_id);
707+ sysfs_show_32bit_prop(buffer, "device_id",
708+ dev->node_props.device_id);
709+ sysfs_show_32bit_prop(buffer, "location_id",
710+ dev->node_props.location_id);
711+
712+ if (dev->gpu) {
713+ sysfs_show_32bit_prop(buffer, "max_engine_clk_fcompute",
714+ kfd2kgd->get_max_engine_clock_in_mhz(
715+ dev->gpu->kgd));
716+ sysfs_show_64bit_prop(buffer, "local_mem_size",
717+ kfd2kgd->get_vmem_size(dev->gpu->kgd));
718+ }
719+
720+ ret = sysfs_show_32bit_prop(buffer, "max_engine_clk_ccompute",
721+ cpufreq_quick_get_max(0)/1000);
722+ }
723+
724+ return ret;
725+}
726+
727+static const struct sysfs_ops node_ops = {
728+ .show = node_show,
729+};
730+
731+static struct kobj_type node_type = {
732+ .sysfs_ops = &node_ops,
733+};
734+
735+static void kfd_remove_sysfs_file(struct kobject *kobj, struct attribute *attr)
736+{
737+ sysfs_remove_file(kobj, attr);
738+ kobject_del(kobj);
739+ kobject_put(kobj);
740+}
741+
742+static void kfd_remove_sysfs_node_entry(struct kfd_topology_device *dev)
743+{
744+ struct kfd_iolink_properties *iolink;
745+ struct kfd_cache_properties *cache;
746+ struct kfd_mem_properties *mem;
747+
748+ BUG_ON(!dev);
749+
750+ if (dev->kobj_iolink) {
751+ list_for_each_entry(iolink, &dev->io_link_props, list)
752+ if (iolink->kobj) {
753+ kfd_remove_sysfs_file(iolink->kobj,
754+ &iolink->attr);
755+ iolink->kobj = NULL;
756+ }
757+ kobject_del(dev->kobj_iolink);
758+ kobject_put(dev->kobj_iolink);
759+ dev->kobj_iolink = NULL;
760+ }
761+
762+ if (dev->kobj_cache) {
763+ list_for_each_entry(cache, &dev->cache_props, list)
764+ if (cache->kobj) {
765+ kfd_remove_sysfs_file(cache->kobj,
766+ &cache->attr);
767+ cache->kobj = NULL;
768+ }
769+ kobject_del(dev->kobj_cache);
770+ kobject_put(dev->kobj_cache);
771+ dev->kobj_cache = NULL;
772+ }
773+
774+ if (dev->kobj_mem) {
775+ list_for_each_entry(mem, &dev->mem_props, list)
776+ if (mem->kobj) {
777+ kfd_remove_sysfs_file(mem->kobj, &mem->attr);
778+ mem->kobj = NULL;
779+ }
780+ kobject_del(dev->kobj_mem);
781+ kobject_put(dev->kobj_mem);
782+ dev->kobj_mem = NULL;
783+ }
784+
785+ if (dev->kobj_node) {
786+ sysfs_remove_file(dev->kobj_node, &dev->attr_gpuid);
787+ sysfs_remove_file(dev->kobj_node, &dev->attr_name);
788+ sysfs_remove_file(dev->kobj_node, &dev->attr_props);
789+ kobject_del(dev->kobj_node);
790+ kobject_put(dev->kobj_node);
791+ dev->kobj_node = NULL;
792+ }
793+}
794+
795+static int kfd_build_sysfs_node_entry(struct kfd_topology_device *dev,
796+ uint32_t id)
797+{
798+ struct kfd_iolink_properties *iolink;
799+ struct kfd_cache_properties *cache;
800+ struct kfd_mem_properties *mem;
801+ int ret;
802+ uint32_t i;
803+
804+ BUG_ON(!dev);
805+
806+ /*
807+ * Creating the sysfs folders
808+ */
809+ BUG_ON(dev->kobj_node);
810+ dev->kobj_node = kfd_alloc_struct(dev->kobj_node);
811+ if (!dev->kobj_node)
812+ return -ENOMEM;
813+
814+ ret = kobject_init_and_add(dev->kobj_node, &node_type,
815+ sys_props.kobj_nodes, "%d", id);
816+ if (ret < 0)
817+ return ret;
818+
819+ dev->kobj_mem = kobject_create_and_add("mem_banks", dev->kobj_node);
820+ if (!dev->kobj_mem)
821+ return -ENOMEM;
822+
823+ dev->kobj_cache = kobject_create_and_add("caches", dev->kobj_node);
824+ if (!dev->kobj_cache)
825+ return -ENOMEM;
826+
827+ dev->kobj_iolink = kobject_create_and_add("io_links", dev->kobj_node);
828+ if (!dev->kobj_iolink)
829+ return -ENOMEM;
830+
831+ /*
832+ * Creating sysfs files for node properties
833+ */
834+ dev->attr_gpuid.name = "gpu_id";
835+ dev->attr_gpuid.mode = KFD_SYSFS_FILE_MODE;
836+ sysfs_attr_init(&dev->attr_gpuid);
837+ dev->attr_name.name = "name";
838+ dev->attr_name.mode = KFD_SYSFS_FILE_MODE;
839+ sysfs_attr_init(&dev->attr_name);
840+ dev->attr_props.name = "properties";
841+ dev->attr_props.mode = KFD_SYSFS_FILE_MODE;
842+ sysfs_attr_init(&dev->attr_props);
843+ ret = sysfs_create_file(dev->kobj_node, &dev->attr_gpuid);
844+ if (ret < 0)
845+ return ret;
846+ ret = sysfs_create_file(dev->kobj_node, &dev->attr_name);
847+ if (ret < 0)
848+ return ret;
849+ ret = sysfs_create_file(dev->kobj_node, &dev->attr_props);
850+ if (ret < 0)
851+ return ret;
852+
853+ i = 0;
854+ list_for_each_entry(mem, &dev->mem_props, list) {
855+ mem->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
856+ if (!mem->kobj)
857+ return -ENOMEM;
858+ ret = kobject_init_and_add(mem->kobj, &mem_type,
859+ dev->kobj_mem, "%d", i);
860+ if (ret < 0)
861+ return ret;
862+
863+ mem->attr.name = "properties";
864+ mem->attr.mode = KFD_SYSFS_FILE_MODE;
865+ sysfs_attr_init(&mem->attr);
866+ ret = sysfs_create_file(mem->kobj, &mem->attr);
867+ if (ret < 0)
868+ return ret;
869+ i++;
870+ }
871+
872+ i = 0;
873+ list_for_each_entry(cache, &dev->cache_props, list) {
874+ cache->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
875+ if (!cache->kobj)
876+ return -ENOMEM;
877+ ret = kobject_init_and_add(cache->kobj, &cache_type,
878+ dev->kobj_cache, "%d", i);
879+ if (ret < 0)
880+ return ret;
881+
882+ cache->attr.name = "properties";
883+ cache->attr.mode = KFD_SYSFS_FILE_MODE;
884+ sysfs_attr_init(&cache->attr);
885+ ret = sysfs_create_file(cache->kobj, &cache->attr);
886+ if (ret < 0)
887+ return ret;
888+ i++;
889+ }
890+
891+ i = 0;
892+ list_for_each_entry(iolink, &dev->io_link_props, list) {
893+ iolink->kobj = kzalloc(sizeof(struct kobject), GFP_KERNEL);
894+ if (!iolink->kobj)
895+ return -ENOMEM;
896+ ret = kobject_init_and_add(iolink->kobj, &iolink_type,
897+ dev->kobj_iolink, "%d", i);
898+ if (ret < 0)
899+ return ret;
900+
901+ iolink->attr.name = "properties";
902+ iolink->attr.mode = KFD_SYSFS_FILE_MODE;
903+ sysfs_attr_init(&iolink->attr);
904+ ret = sysfs_create_file(iolink->kobj, &iolink->attr);
905+ if (ret < 0)
906+ return ret;
907+ i++;
908+}
909+
910+ return 0;
911+}
912+
913+static int kfd_build_sysfs_node_tree(void)
914+{
915+ struct kfd_topology_device *dev;
916+ int ret;
917+ uint32_t i = 0;
918+
919+ list_for_each_entry(dev, &topology_device_list, list) {
920+ ret = kfd_build_sysfs_node_entry(dev, 0);
921+ if (ret < 0)
922+ return ret;
923+ i++;
924+ }
925+
926+ return 0;
927+}
928+
929+static void kfd_remove_sysfs_node_tree(void)
930+{
931+ struct kfd_topology_device *dev;
932+
933+ list_for_each_entry(dev, &topology_device_list, list)
934+ kfd_remove_sysfs_node_entry(dev);
935+}
936+
937+static int kfd_topology_update_sysfs(void)
938+{
939+ int ret;
940+
941+ pr_info("Creating topology SYSFS entries\n");
942+ if (sys_props.kobj_topology == NULL) {
943+ sys_props.kobj_topology =
944+ kfd_alloc_struct(sys_props.kobj_topology);
945+ if (!sys_props.kobj_topology)
946+ return -ENOMEM;
947+
948+ ret = kobject_init_and_add(sys_props.kobj_topology,
949+ &sysprops_type, &kfd_device->kobj,
950+ "topology");
951+ if (ret < 0)
952+ return ret;
953+
954+ sys_props.kobj_nodes = kobject_create_and_add("nodes",
955+ sys_props.kobj_topology);
956+ if (!sys_props.kobj_nodes)
957+ return -ENOMEM;
958+
959+ sys_props.attr_genid.name = "generation_id";
960+ sys_props.attr_genid.mode = KFD_SYSFS_FILE_MODE;
961+ sysfs_attr_init(&sys_props.attr_genid);
962+ ret = sysfs_create_file(sys_props.kobj_topology,
963+ &sys_props.attr_genid);
964+ if (ret < 0)
965+ return ret;
966+
967+ sys_props.attr_props.name = "system_properties";
968+ sys_props.attr_props.mode = KFD_SYSFS_FILE_MODE;
969+ sysfs_attr_init(&sys_props.attr_props);
970+ ret = sysfs_create_file(sys_props.kobj_topology,
971+ &sys_props.attr_props);
972+ if (ret < 0)
973+ return ret;
974+ }
975+
976+ kfd_remove_sysfs_node_tree();
977+
978+ return kfd_build_sysfs_node_tree();
979+}
980+
981+static void kfd_topology_release_sysfs(void)
982+{
983+ kfd_remove_sysfs_node_tree();
984+ if (sys_props.kobj_topology) {
985+ sysfs_remove_file(sys_props.kobj_topology,
986+ &sys_props.attr_genid);
987+ sysfs_remove_file(sys_props.kobj_topology,
988+ &sys_props.attr_props);
989+ if (sys_props.kobj_nodes) {
990+ kobject_del(sys_props.kobj_nodes);
991+ kobject_put(sys_props.kobj_nodes);
992+ sys_props.kobj_nodes = NULL;
993+ }
994+ kobject_del(sys_props.kobj_topology);
995+ kobject_put(sys_props.kobj_topology);
996+ sys_props.kobj_topology = NULL;
997+ }
998+}
999+
1000+int kfd_topology_init(void)
1001+{
1002+ void *crat_image = NULL;
1003+ size_t image_size = 0;
1004+ int ret;
1005+
1006+ /*
1007+ * Initialize the head for the topology device list
1008+ */
1009+ INIT_LIST_HEAD(&topology_device_list);
1010+ init_rwsem(&topology_lock);
1011+ topology_crat_parsed = 0;
1012+
1013+ memset(&sys_props, 0, sizeof(sys_props));
1014+
1015+ /*
1016+ * Get the CRAT image from the ACPI
1017+ */
1018+ ret = kfd_topology_get_crat_acpi(crat_image, &image_size);
1019+ if (ret == 0 && image_size > 0) {
1020+ pr_info("Found CRAT image with size=%zd\n", image_size);
1021+ crat_image = kmalloc(image_size, GFP_KERNEL);
1022+ if (!crat_image) {
1023+ ret = -ENOMEM;
1024+ pr_err("No memory for allocating CRAT image\n");
1025+ goto err;
1026+ }
1027+ ret = kfd_topology_get_crat_acpi(crat_image, &image_size);
1028+
1029+ if (ret == 0) {
1030+ down_write(&topology_lock);
1031+ ret = kfd_parse_crat_table(crat_image);
1032+ if (ret == 0)
1033+ ret = kfd_topology_update_sysfs();
1034+ up_write(&topology_lock);
1035+ } else {
1036+ pr_err("Couldn't get CRAT table size from ACPI\n");
1037+ }
1038+ kfree(crat_image);
1039+ } else if (ret == -ENODATA) {
1040+ ret = 0;
1041+ } else {
1042+ pr_err("Couldn't get CRAT table size from ACPI\n");
1043+ }
1044+
1045+err:
1046+ pr_info("Finished initializing topology ret=%d\n", ret);
1047+ return ret;
1048+}
1049+
1050+void kfd_topology_shutdown(void)
1051+{
1052+ kfd_topology_release_sysfs();
1053+ kfd_release_live_view();
1054+}
1055+
1056+static void kfd_debug_print_topology(void)
1057+{
1058+ struct kfd_topology_device *dev;
1059+ uint32_t i = 0;
1060+
1061+ pr_info("DEBUG PRINT OF TOPOLOGY:");
1062+ list_for_each_entry(dev, &topology_device_list, list) {
1063+ pr_info("Node: %d\n", i);
1064+ pr_info("\tGPU assigned: %s\n", (dev->gpu ? "yes" : "no"));
1065+ pr_info("\tCPU count: %d\n", dev->node_props.cpu_cores_count);
1066+ pr_info("\tSIMD count: %d", dev->node_props.simd_count);
1067+ i++;
1068+ }
1069+}
1070+
1071+static uint32_t kfd_generate_gpu_id(struct kfd_dev *gpu)
1072+{
1073+ uint32_t hashout;
1074+ uint32_t buf[7];
1075+ int i;
1076+
1077+ if (!gpu)
1078+ return 0;
1079+
1080+ buf[0] = gpu->pdev->devfn;
1081+ buf[1] = gpu->pdev->subsystem_vendor;
1082+ buf[2] = gpu->pdev->subsystem_device;
1083+ buf[3] = gpu->pdev->device;
1084+ buf[4] = gpu->pdev->bus->number;
1085+ buf[5] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) & 0xffffffff);
1086+ buf[6] = (uint32_t)(kfd2kgd->get_vmem_size(gpu->kgd) >> 32);
1087+
1088+ for (i = 0, hashout = 0; i < 7; i++)
1089+ hashout ^= hash_32(buf[i], KFD_GPU_ID_HASH_WIDTH);
1090+
1091+ return hashout;
1092+}
1093+
1094+static struct kfd_topology_device *kfd_assign_gpu(struct kfd_dev *gpu)
1095+{
1096+ struct kfd_topology_device *dev;
1097+ struct kfd_topology_device *out_dev = NULL;
1098+
1099+ BUG_ON(!gpu);
1100+
1101+ list_for_each_entry(dev, &topology_device_list, list)
1102+ if (dev->gpu == NULL && dev->node_props.simd_count > 0) {
1103+ dev->gpu = gpu;
1104+ out_dev = dev;
1105+ break;
1106+ }
1107+
1108+ return out_dev;
1109+}
1110+
1111+static void kfd_notify_gpu_change(uint32_t gpu_id, int arrival)
1112+{
1113+ /*
1114+ * TODO: Generate an event for thunk about the arrival/removal
1115+ * of the GPU
1116+ */
1117+}
1118+
1119+int kfd_topology_add_device(struct kfd_dev *gpu)
1120+{
1121+ uint32_t gpu_id;
1122+ struct kfd_topology_device *dev;
1123+ int res;
1124+
1125+ BUG_ON(!gpu);
1126+
1127+ gpu_id = kfd_generate_gpu_id(gpu);
1128+
1129+ pr_debug("kfd: Adding new GPU (ID: 0x%x) to topology\n", gpu_id);
1130+
1131+ down_write(&topology_lock);
1132+ /*
1133+ * Try to assign the GPU to existing topology device (generated from
1134+ * CRAT table
1135+ */
1136+ dev = kfd_assign_gpu(gpu);
1137+ if (!dev) {
1138+ pr_info("GPU was not found in the current topology. Extending.\n");
1139+ kfd_debug_print_topology();
1140+ dev = kfd_create_topology_device();
1141+ if (!dev) {
1142+ res = -ENOMEM;
1143+ goto err;
1144+ }
1145+ dev->gpu = gpu;
1146+
1147+ /*
1148+ * TODO: Make a call to retrieve topology information from the
1149+ * GPU vBIOS
1150+ */
1151+
1152+ /*
1153+ * Update the SYSFS tree, since we added another topology device
1154+ */
1155+ if (kfd_topology_update_sysfs() < 0)
1156+ kfd_topology_release_sysfs();
1157+
1158+ }
1159+
1160+ dev->gpu_id = gpu_id;
1161+ gpu->id = gpu_id;
1162+ dev->node_props.vendor_id = gpu->pdev->vendor;
1163+ dev->node_props.device_id = gpu->pdev->device;
1164+ dev->node_props.location_id = (gpu->pdev->bus->number << 24) +
1165+ (gpu->pdev->devfn & 0xffffff);
1166+ /*
1167+ * TODO: Retrieve max engine clock values from KGD
1168+ */
1169+
1170+ res = 0;
1171+
1172+err:
1173+ up_write(&topology_lock);
1174+
1175+ if (res == 0)
1176+ kfd_notify_gpu_change(gpu_id, 1);
1177+
1178+ return res;
1179+}
1180+
1181+int kfd_topology_remove_device(struct kfd_dev *gpu)
1182+{
1183+ struct kfd_topology_device *dev;
1184+ uint32_t gpu_id;
1185+ int res = -ENODEV;
1186+
1187+ BUG_ON(!gpu);
1188+
1189+ down_write(&topology_lock);
1190+
1191+ list_for_each_entry(dev, &topology_device_list, list)
1192+ if (dev->gpu == gpu) {
1193+ gpu_id = dev->gpu_id;
1194+ kfd_remove_sysfs_node_entry(dev);
1195+ kfd_release_topology_device(dev);
1196+ res = 0;
1197+ if (kfd_topology_update_sysfs() < 0)
1198+ kfd_topology_release_sysfs();
1199+ break;
1200+ }
1201+
1202+ up_write(&topology_lock);
1203+
1204+ if (res == 0)
1205+ kfd_notify_gpu_change(gpu_id, 0);
1206+
1207+ return res;
1208+}
1209+
1210+/*
1211+ * When idx is out of bounds, the function will return NULL
1212+ */
1213+struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx)
1214+{
1215+
1216+ struct kfd_topology_device *top_dev;
1217+ struct kfd_dev *device = NULL;
1218+ uint8_t device_idx = 0;
1219+
1220+ down_read(&topology_lock);
1221+
1222+ list_for_each_entry(top_dev, &topology_device_list, list) {
1223+ if (device_idx == idx) {
1224+ device = top_dev->gpu;
1225+ break;
1226+ }
1227+
1228+ device_idx++;
1229+ }
1230+
1231+ up_read(&topology_lock);
1232+
1233+ return device;
1234+
1235+}
drivers/gpu/drm/amd/amdkfd/kfd_topology.h+168−0
@@ -0,0 +1,168 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+#ifndef __KFD_TOPOLOGY_H__
24+#define __KFD_TOPOLOGY_H__
25+
26+#include <linux/types.h>
27+#include <linux/list.h>
28+#include "kfd_priv.h"
29+
30+#define KFD_TOPOLOGY_PUBLIC_NAME_SIZE 128
31+
32+#define HSA_CAP_HOT_PLUGGABLE 0x00000001
33+#define HSA_CAP_ATS_PRESENT 0x00000002
34+#define HSA_CAP_SHARED_WITH_GRAPHICS 0x00000004
35+#define HSA_CAP_QUEUE_SIZE_POW2 0x00000008
36+#define HSA_CAP_QUEUE_SIZE_32BIT 0x00000010
37+#define HSA_CAP_QUEUE_IDLE_EVENT 0x00000020
38+#define HSA_CAP_VA_LIMIT 0x00000040
39+#define HSA_CAP_WATCH_POINTS_SUPPORTED 0x00000080
40+#define HSA_CAP_WATCH_POINTS_TOTALBITS_MASK 0x00000f00
41+#define HSA_CAP_WATCH_POINTS_TOTALBITS_SHIFT 8
42+#define HSA_CAP_RESERVED 0xfffff000
43+
44+struct kfd_node_properties {
45+ uint32_t cpu_cores_count;
46+ uint32_t simd_count;
47+ uint32_t mem_banks_count;
48+ uint32_t caches_count;
49+ uint32_t io_links_count;
50+ uint32_t cpu_core_id_base;
51+ uint32_t simd_id_base;
52+ uint32_t capability;
53+ uint32_t max_waves_per_simd;
54+ uint32_t lds_size_in_kb;
55+ uint32_t gds_size_in_kb;
56+ uint32_t wave_front_size;
57+ uint32_t array_count;
58+ uint32_t simd_arrays_per_engine;
59+ uint32_t cu_per_simd_array;
60+ uint32_t simd_per_cu;
61+ uint32_t max_slots_scratch_cu;
62+ uint32_t engine_id;
63+ uint32_t vendor_id;
64+ uint32_t device_id;
65+ uint32_t location_id;
66+ uint32_t max_engine_clk_fcompute;
67+ uint32_t max_engine_clk_ccompute;
68+ uint16_t marketing_name[KFD_TOPOLOGY_PUBLIC_NAME_SIZE];
69+};
70+
71+#define HSA_MEM_HEAP_TYPE_SYSTEM 0
72+#define HSA_MEM_HEAP_TYPE_FB_PUBLIC 1
73+#define HSA_MEM_HEAP_TYPE_FB_PRIVATE 2
74+#define HSA_MEM_HEAP_TYPE_GPU_GDS 3
75+#define HSA_MEM_HEAP_TYPE_GPU_LDS 4
76+#define HSA_MEM_HEAP_TYPE_GPU_SCRATCH 5
77+
78+#define HSA_MEM_FLAGS_HOT_PLUGGABLE 0x00000001
79+#define HSA_MEM_FLAGS_NON_VOLATILE 0x00000002
80+#define HSA_MEM_FLAGS_RESERVED 0xfffffffc
81+
82+struct kfd_mem_properties {
83+ struct list_head list;
84+ uint32_t heap_type;
85+ uint64_t size_in_bytes;
86+ uint32_t flags;
87+ uint32_t width;
88+ uint32_t mem_clk_max;
89+ struct kobject *kobj;
90+ struct attribute attr;
91+};
92+
93+#define KFD_TOPOLOGY_CPU_SIBLINGS 256
94+
95+#define HSA_CACHE_TYPE_DATA 0x00000001
96+#define HSA_CACHE_TYPE_INSTRUCTION 0x00000002
97+#define HSA_CACHE_TYPE_CPU 0x00000004
98+#define HSA_CACHE_TYPE_HSACU 0x00000008
99+#define HSA_CACHE_TYPE_RESERVED 0xfffffff0
100+
101+struct kfd_cache_properties {
102+ struct list_head list;
103+ uint32_t processor_id_low;
104+ uint32_t cache_level;
105+ uint32_t cache_size;
106+ uint32_t cacheline_size;
107+ uint32_t cachelines_per_tag;
108+ uint32_t cache_assoc;
109+ uint32_t cache_latency;
110+ uint32_t cache_type;
111+ uint8_t sibling_map[KFD_TOPOLOGY_CPU_SIBLINGS];
112+ struct kobject *kobj;
113+ struct attribute attr;
114+};
115+
116+struct kfd_iolink_properties {
117+ struct list_head list;
118+ uint32_t iolink_type;
119+ uint32_t ver_maj;
120+ uint32_t ver_min;
121+ uint32_t node_from;
122+ uint32_t node_to;
123+ uint32_t weight;
124+ uint32_t min_latency;
125+ uint32_t max_latency;
126+ uint32_t min_bandwidth;
127+ uint32_t max_bandwidth;
128+ uint32_t rec_transfer_size;
129+ uint32_t flags;
130+ struct kobject *kobj;
131+ struct attribute attr;
132+};
133+
134+struct kfd_topology_device {
135+ struct list_head list;
136+ uint32_t gpu_id;
137+ struct kfd_node_properties node_props;
138+ uint32_t mem_bank_count;
139+ struct list_head mem_props;
140+ uint32_t cache_count;
141+ struct list_head cache_props;
142+ uint32_t io_link_count;
143+ struct list_head io_link_props;
144+ struct kfd_dev *gpu;
145+ struct kobject *kobj_node;
146+ struct kobject *kobj_mem;
147+ struct kobject *kobj_cache;
148+ struct kobject *kobj_iolink;
149+ struct attribute attr_gpuid;
150+ struct attribute attr_name;
151+ struct attribute attr_props;
152+};
153+
154+struct kfd_system_properties {
155+ uint32_t num_devices; /* Number of H-NUMA nodes */
156+ uint32_t generation_count;
157+ uint64_t platform_oem;
158+ uint64_t platform_id;
159+ uint64_t platform_rev;
160+ struct kobject *kobj_topology;
161+ struct kobject *kobj_nodes;
162+ struct attribute attr_genid;
163+ struct attribute attr_props;
164+};
165+
166+
167+
168+#endif /* __KFD_TOPOLOGY_H__ */
drivers/gpu/drm/amd/include/kgd_kfd_interface.h+185−0
@@ -0,0 +1,185 @@
1+/*
2+ * Copyright 2014 Advanced Micro Devices, 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 "Software"),
6+ * to deal in the Software without restriction, including without limitation
7+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8+ * and/or sell copies of the Software, and to permit persons to whom the
9+ * Software is furnished to do so, subject to the following conditions:
10+ *
11+ * The above copyright notice and this permission notice shall be included in
12+ * all copies or substantial portions of the Software.
13+ *
14+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20+ * OTHER DEALINGS IN THE SOFTWARE.
21+ */
22+
23+/*
24+ * This file defines the private interface between the
25+ * AMD kernel graphics drivers and the AMD KFD.
26+ */
27+
28+#ifndef KGD_KFD_INTERFACE_H_INCLUDED
29+#define KGD_KFD_INTERFACE_H_INCLUDED
30+
31+#include <linux/types.h>
32+
33+struct pci_dev;
34+
35+#define KFD_INTERFACE_VERSION 1
36+
37+struct kfd_dev;
38+struct kgd_dev;
39+
40+struct kgd_mem;
41+
42+enum kgd_memory_pool {
43+ KGD_POOL_SYSTEM_CACHEABLE = 1,
44+ KGD_POOL_SYSTEM_WRITECOMBINE = 2,
45+ KGD_POOL_FRAMEBUFFER = 3,
46+};
47+
48+struct kgd2kfd_shared_resources {
49+ /* Bit n == 1 means VMID n is available for KFD. */
50+ unsigned int compute_vmid_bitmap;
51+
52+ /* Compute pipes are counted starting from MEC0/pipe0 as 0. */
53+ unsigned int first_compute_pipe;
54+
55+ /* Number of MEC pipes available for KFD. */
56+ unsigned int compute_pipe_count;
57+
58+ /* Base address of doorbell aperture. */
59+ phys_addr_t doorbell_physical_address;
60+
61+ /* Size in bytes of doorbell aperture. */
62+ size_t doorbell_aperture_size;
63+
64+ /* Number of bytes at start of aperture reserved for KGD. */
65+ size_t doorbell_start_offset;
66+};
67+
68+/**
69+ * struct kgd2kfd_calls
70+ *
71+ * @exit: Notifies amdkfd that kgd module is unloaded
72+ *
73+ * @probe: Notifies amdkfd about a probe done on a device in the kgd driver.
74+ *
75+ * @device_init: Initialize the newly probed device (if it is a device that
76+ * amdkfd supports)
77+ *
78+ * @device_exit: Notifies amdkfd about a removal of a kgd device
79+ *
80+ * @suspend: Notifies amdkfd about a suspend action done to a kgd device
81+ *
82+ * @resume: Notifies amdkfd about a resume action done to a kgd device
83+ *
84+ * This structure contains function callback pointers so the kgd driver
85+ * will notify to the amdkfd about certain status changes.
86+ *
87+ */
88+struct kgd2kfd_calls {
89+ void (*exit)(void);
90+ struct kfd_dev* (*probe)(struct kgd_dev *kgd, struct pci_dev *pdev);
91+ bool (*device_init)(struct kfd_dev *kfd,
92+ const struct kgd2kfd_shared_resources *gpu_resources);
93+ void (*device_exit)(struct kfd_dev *kfd);
94+ void (*interrupt)(struct kfd_dev *kfd, const void *ih_ring_entry);
95+ void (*suspend)(struct kfd_dev *kfd);
96+ int (*resume)(struct kfd_dev *kfd);
97+};
98+
99+/**
100+ * struct kfd2kgd_calls
101+ *
102+ * @init_sa_manager: Initialize an instance of the sa manager, used by
103+ * amdkfd for all system memory allocations that are mapped to the GART
104+ * address space
105+ *
106+ * @fini_sa_manager: Releases all memory allocations for amdkfd that are
107+ * handled by kgd sa manager
108+ *
109+ * @allocate_mem: Allocate a buffer from amdkfd's sa manager. The buffer can
110+ * be used for mqds, hpds, kernel queue, fence and runlists
111+ *
112+ * @free_mem: Frees a buffer that was allocated by amdkfd's sa manager
113+ *
114+ * @get_vmem_size: Retrieves (physical) size of VRAM
115+ *
116+ * @get_gpu_clock_counter: Retrieves GPU clock counter
117+ *
118+ * @get_max_engine_clock_in_mhz: Retrieves maximum GPU clock in MHz
119+ *
120+ * @program_sh_mem_settings: A function that should initiate the memory
121+ * properties such as main aperture memory type (cache / non cached) and
122+ * secondary aperture base address, size and memory type.
123+ * This function is used only for no cp scheduling mode.
124+ *
125+ * @set_pasid_vmid_mapping: Exposes pasid/vmid pair to the H/W for no cp
126+ * scheduling mode. Only used for no cp scheduling mode.
127+ *
128+ * @init_memory: Initializes memory apertures to fixed base/limit address
129+ * and non cached memory types.
130+ *
131+ * @init_pipeline: Initialized the compute pipelines.
132+ *
133+ * @hqd_load: Loads the mqd structure to a H/W hqd slot. used only for no cp
134+ * sceduling mode.
135+ *
136+ * @hqd_is_occupies: Checks if a hqd slot is occupied.
137+ *
138+ * @hqd_destroy: Destructs and preempts the queue assigned to that hqd slot.
139+ *
140+ * This structure contains function pointers to services that the kgd driver
141+ * provides to amdkfd driver.
142+ *
143+ */
144+struct kfd2kgd_calls {
145+ /* Memory management. */
146+ int (*init_sa_manager)(struct kgd_dev *kgd, unsigned int size);
147+ void (*fini_sa_manager)(struct kgd_dev *kgd);
148+ int (*allocate_mem)(struct kgd_dev *kgd, size_t size, size_t alignment,
149+ enum kgd_memory_pool pool, struct kgd_mem **mem);
150+
151+ void (*free_mem)(struct kgd_dev *kgd, struct kgd_mem *mem);
152+
153+ uint64_t (*get_vmem_size)(struct kgd_dev *kgd);
154+ uint64_t (*get_gpu_clock_counter)(struct kgd_dev *kgd);
155+
156+ uint32_t (*get_max_engine_clock_in_mhz)(struct kgd_dev *kgd);
157+
158+ /* Register access functions */
159+ void (*program_sh_mem_settings)(struct kgd_dev *kgd, uint32_t vmid,
160+ uint32_t sh_mem_config, uint32_t sh_mem_ape1_base,
161+ uint32_t sh_mem_ape1_limit, uint32_t sh_mem_bases);
162+
163+ int (*set_pasid_vmid_mapping)(struct kgd_dev *kgd, unsigned int pasid,
164+ unsigned int vmid);
165+
166+ int (*init_memory)(struct kgd_dev *kgd);
167+ int (*init_pipeline)(struct kgd_dev *kgd, uint32_t pipe_id,
168+ uint32_t hpd_size, uint64_t hpd_gpu_addr);
169+
170+ int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
171+ uint32_t queue_id, uint32_t __user *wptr);
172+
173+ bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address,
174+ uint32_t pipe_id, uint32_t queue_id);
175+
176+ int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
177+ unsigned int timeout, uint32_t pipe_id,
178+ uint32_t queue_id);
179+};
180+
181+bool kgd2kfd_init(unsigned interface_version,
182+ const struct kfd2kgd_calls *f2g,
183+ const struct kgd2kfd_calls **g2f);
184+
185+#endif /* KGD_KFD_INTERFACE_H_INCLUDED */
drivers/gpu/drm/armada/armada_crtc.c+1−0
@@ -12,6 +12,7 @@ · 11 unmodified lines
1212 #include <linux/platform_device.h>
1313 #include <drm/drmP.h>
1414 #include <drm/drm_crtc_helper.h>
15+#include <drm/drm_plane_helper.h>
1516 #include "armada_crtc.h"
1617 #include "armada_drm.h"
1718 #include "armada_fb.h"
drivers/gpu/drm/ast/ast_mode.c+1−0
@@ -31,6 +31,7 @@ · 30 unmodified lines
3131 #include <drm/drmP.h>
3232 #include <drm/drm_crtc.h>
3333 #include <drm/drm_crtc_helper.h>
34+#include <drm/drm_plane_helper.h>
3435 #include "ast_drv.h"
3536
3637 #include "ast_tables.h"
drivers/gpu/drm/bochs/bochs_fbdev.c+14−4
@@ -9,6 +9,17 @@ · 8 unmodified lines
99
1010 /* ---------------------------------------------------------------------- */
1111
12+static int bochsfb_mmap(struct fb_info *info,
13+ struct vm_area_struct *vma)
14+{
15+ struct drm_fb_helper *fb_helper = info->par;
16+ struct bochs_device *bochs =
17+ container_of(fb_helper, struct bochs_device, fb.helper);
18+ struct bochs_bo *bo = gem_to_bochs_bo(bochs->fb.gfb.obj);
19+
20+ return ttm_fbdev_mmap(vma, &bo->bo);
21+}
22+
1223 static struct fb_ops bochsfb_ops = {
1324 .owner = THIS_MODULE,
1425 .fb_check_var = drm_fb_helper_check_var,
@@ -19,6 +30,7 @@ static struct fb_ops bochsfb_ops = { · 4 unmodified lines
1930 .fb_pan_display = drm_fb_helper_pan_display,
2031 .fb_blank = drm_fb_helper_blank,
2132 .fb_setcmap = drm_fb_helper_setcmap,
33+ .fb_mmap = bochsfb_mmap,
2234 };
2335
2436 static int bochsfb_create_object(struct bochs_device *bochs,
@@ -123,11 +135,9 @@ static int bochsfb_create(struct drm_fb_helper *helper, · 98 unmodified lines
123135 info->screen_base = bo->kmap.virtual;
124136 info->screen_size = size;
125137
126−#if 0
127− /* FIXME: get this right for mmap(/dev/fb0) */
128− info->fix.smem_start = bochs_bo_mmap_offset(bo);
138+ drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node);
139+ info->fix.smem_start = 0;
129140 info->fix.smem_len = size;
130−#endif
131141
132142 ret = fb_alloc_cmap(&info->cmap, 256, 0);
133143 if (ret) {
drivers/gpu/drm/bochs/bochs_hw.c+20−3
@@ -51,11 +51,10 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) · 50 unmodified lines
5151 {
5252 struct bochs_device *bochs = dev->dev_private;
5353 struct pci_dev *pdev = dev->pdev;
54− unsigned long addr, size, mem, ioaddr, iosize;
54+ unsigned long addr, size, mem, ioaddr, iosize, qext_size;
5555 u16 id;
5656
57− if (/* (ent->driver_data == BOCHS_QEMU_STDVGA) && */
58− (pdev->resource[2].flags & IORESOURCE_MEM)) {
57+ if (pdev->resource[2].flags & IORESOURCE_MEM) {
5958 /* mmio bar with vga and bochs registers present */
6059 if (pci_request_region(pdev, 2, "bochs-drm") != 0) {
6160 DRM_ERROR("Cannot request mmio region\n");
@@ -116,6 +115,24 @@ int bochs_hw_init(struct drm_device *dev, uint32_t flags) · 54 unmodified lines
116115 size / 1024, addr,
117116 bochs->ioports ? "ioports" : "mmio",
118117 ioaddr);
118+
119+ if (bochs->mmio && pdev->revision >= 2) {
120+ qext_size = readl(bochs->mmio + 0x600);
121+ if (qext_size < 4 || qext_size > iosize)
122+ goto noext;
123+ DRM_DEBUG("Found qemu ext regs, size %ld\n", qext_size);
124+ if (qext_size >= 8) {
125+#ifdef __BIG_ENDIAN
126+ writel(0xbebebebe, bochs->mmio + 0x604);
127+#else
128+ writel(0x1e1e1e1e, bochs->mmio + 0x604);
129+#endif
130+ DRM_DEBUG(" qext endian: 0x%x\n",
131+ readl(bochs->mmio + 0x604));
132+ }
133+ }
134+
135+noext:
119136 return 0;
120137 }
121138
drivers/gpu/drm/bochs/bochs_kms.c+22−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
66 */
77
88 #include "bochs.h"
9+#include <drm/drm_plane_helper.h>
910
1011 static int defx = 1024;
1112 static int defy = 768;
@@ -108,11 +109,32 @@ static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, · 96 unmodified lines
108109 {
109110 }
110111
112+static int bochs_crtc_page_flip(struct drm_crtc *crtc,
113+ struct drm_framebuffer *fb,
114+ struct drm_pending_vblank_event *event,
115+ uint32_t page_flip_flags)
116+{
117+ struct bochs_device *bochs =
118+ container_of(crtc, struct bochs_device, crtc);
119+ struct drm_framebuffer *old_fb = crtc->primary->fb;
120+ unsigned long irqflags;
121+
122+ crtc->primary->fb = fb;
123+ bochs_crtc_mode_set_base(crtc, 0, 0, old_fb);
124+ if (event) {
125+ spin_lock_irqsave(&bochs->dev->event_lock, irqflags);
126+ drm_send_vblank_event(bochs->dev, -1, event);
127+ spin_unlock_irqrestore(&bochs->dev->event_lock, irqflags);
128+ }
129+ return 0;
130+}
131+
111132 /* These provide the minimum set of functions required to handle a CRTC */
112133 static const struct drm_crtc_funcs bochs_crtc_funcs = {
113134 .gamma_set = bochs_crtc_gamma_set,
114135 .set_config = drm_crtc_helper_set_config,
115136 .destroy = drm_crtc_cleanup,
137+ .page_flip = bochs_crtc_page_flip,
116138 };
117139
118140 static const struct drm_crtc_helper_funcs bochs_helper_funcs = {
drivers/gpu/drm/cirrus/cirrus_drv.h+3−0
@@ -210,6 +210,9 @@ int cirrus_framebuffer_init(struct drm_device *dev, · 209 unmodified lines
210210 struct drm_mode_fb_cmd2 *mode_cmd,
211211 struct drm_gem_object *obj);
212212
213+bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
214+ int bpp, int pitch);
215+
213216 /* cirrus_display.c */
214217 int cirrus_modeset_init(struct cirrus_device *cdev);
215218 void cirrus_modeset_fini(struct cirrus_device *cdev);
drivers/gpu/drm/cirrus/cirrus_fbdev.c+4−1
@@ -139,6 +139,7 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev, · 138 unmodified lines
139139 struct drm_gem_object **gobj_p)
140140 {
141141 struct drm_device *dev = afbdev->helper.dev;
142+ struct cirrus_device *cdev = dev->dev_private;
142143 u32 bpp, depth;
143144 u32 size;
144145 struct drm_gem_object *gobj;
@@ -146,8 +147,10 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev, · 1 unmodified line
146147 int ret = 0;
147148 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
148149
149− if (bpp > 24)
150+ if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
151+ bpp, mode_cmd->pitches[0]))
150152 return -EINVAL;
153+
151154 size = mode_cmd->pitches[0] * mode_cmd->height;
152155 ret = cirrus_gem_create(dev, size, true, &gobj);
153156 if (ret)
drivers/gpu/drm/cirrus/cirrus_main.c+32−8
@@ -49,14 +49,16 @@ cirrus_user_framebuffer_create(struct drm_device *dev, · 48 unmodified lines
4949 struct drm_file *filp,
5050 struct drm_mode_fb_cmd2 *mode_cmd)
5151 {
52+ struct cirrus_device *cdev = dev->dev_private;
5253 struct drm_gem_object *obj;
5354 struct cirrus_framebuffer *cirrus_fb;
5455 int ret;
5556 u32 bpp, depth;
5657
5758 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
58− /* cirrus can't handle > 24bpp framebuffers at all */
59− if (bpp > 24)
59+
60+ if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
61+ bpp, mode_cmd->pitches[0]))
6062 return ERR_PTR(-EINVAL);
6163
6264 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);
@@ -96,8 +98,7 @@ static int cirrus_vram_init(struct cirrus_device *cdev) · 33 unmodified lines
9698 {
9799 /* BAR 0 is VRAM */
98100 cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);
99− /* We have 4MB of VRAM */
100− cdev->mc.vram_size = 4 * 1024 * 1024;
101+ cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0);
101102
102103 if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
103104 "cirrusdrmfb_vram")) {
@@ -179,17 +180,22 @@ int cirrus_driver_load(struct drm_device *dev, unsigned long flags) · 75 unmodified lines
179180 }
180181
181182 r = cirrus_mm_init(cdev);
182− if (r)
183+ if (r) {
183184 dev_err(&dev->pdev->dev, "fatal err on mm init\n");
185+ goto out;
186+ }
184187
185188 r = cirrus_modeset_init(cdev);
186− if (r)
189+ if (r) {
187190 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
191+ goto out;
192+ }
188193
189194 dev->mode_config.funcs = (void *)&cirrus_mode_funcs;
195+
196+ return 0;
190197 out:
191− if (r)
192− cirrus_driver_unload(dev);
198+ cirrus_driver_unload(dev);
193199 return r;
194200 }
195201
@@ -307,3 +313,21 @@ out_unlock: · 111 unmodified lines
307313 return ret;
308314
309315 }
316+
317+bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
318+ int bpp, int pitch)
319+{
320+ const int max_pitch = 0x1FF << 3; /* (4096 - 1) & ~111b bytes */
321+ const int max_size = cdev->mc.vram_size;
322+
323+ if (bpp > 32)
324+ return false;
325+
326+ if (pitch > max_pitch)
327+ return false;
328+
329+ if (pitch * height > max_size)
330+ return false;
331+
332+ return true;
333+}
drivers/gpu/drm/cirrus/cirrus_mode.c+1−0
@@ -16,6 +16,7 @@ · 15 unmodified lines
1616 */
1717 #include <drm/drmP.h>
1818 #include <drm/drm_crtc_helper.h>
19+#include <drm/drm_plane_helper.h>
1920
2021 #include <video/cirrus.h>
2122
drivers/gpu/drm/drm_atomic.c+657−0
@@ -0,0 +1,657 @@
1+/*
2+ * Copyright (C) 2014 Red Hat
3+ * Copyright (C) 2014 Intel Corp.
4+ *
5+ * Permission is hereby granted, free of charge, to any person obtaining a
6+ * copy of this software and associated documentation files (the "Software"),
7+ * to deal in the Software without restriction, including without limitation
8+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+ * and/or sell copies of the Software, and to permit persons to whom the
10+ * Software is furnished to do so, subject to the following conditions:
11+ *
12+ * The above copyright notice and this permission notice shall be included in
13+ * all copies or substantial portions of the Software.
14+ *
15+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21+ * OTHER DEALINGS IN THE SOFTWARE.
22+ *
23+ * Authors:
24+ * Rob Clark <robdclark@gmail.com>
25+ * Daniel Vetter <daniel.vetter@ffwll.ch>
26+ */
27+
28+
29+#include <drm/drmP.h>
30+#include <drm/drm_atomic.h>
31+#include <drm/drm_plane_helper.h>
32+
33+static void kfree_state(struct drm_atomic_state *state)
34+{
35+ kfree(state->connectors);
36+ kfree(state->connector_states);
37+ kfree(state->crtcs);
38+ kfree(state->crtc_states);
39+ kfree(state->planes);
40+ kfree(state->plane_states);
41+ kfree(state);
42+}
43+
44+/**
45+ * drm_atomic_state_alloc - allocate atomic state
46+ * @dev: DRM device
47+ *
48+ * This allocates an empty atomic state to track updates.
49+ */
50+struct drm_atomic_state *
51+drm_atomic_state_alloc(struct drm_device *dev)
52+{
53+ struct drm_atomic_state *state;
54+
55+ state = kzalloc(sizeof(*state), GFP_KERNEL);
56+ if (!state)
57+ return NULL;
58+
59+ state->num_connector = ACCESS_ONCE(dev->mode_config.num_connector);
60+
61+ state->crtcs = kcalloc(dev->mode_config.num_crtc,
62+ sizeof(*state->crtcs), GFP_KERNEL);
63+ if (!state->crtcs)
64+ goto fail;
65+ state->crtc_states = kcalloc(dev->mode_config.num_crtc,
66+ sizeof(*state->crtc_states), GFP_KERNEL);
67+ if (!state->crtc_states)
68+ goto fail;
69+ state->planes = kcalloc(dev->mode_config.num_total_plane,
70+ sizeof(*state->planes), GFP_KERNEL);
71+ if (!state->planes)
72+ goto fail;
73+ state->plane_states = kcalloc(dev->mode_config.num_total_plane,
74+ sizeof(*state->plane_states), GFP_KERNEL);
75+ if (!state->plane_states)
76+ goto fail;
77+ state->connectors = kcalloc(state->num_connector,
78+ sizeof(*state->connectors),
79+ GFP_KERNEL);
80+ if (!state->connectors)
81+ goto fail;
82+ state->connector_states = kcalloc(state->num_connector,
83+ sizeof(*state->connector_states),
84+ GFP_KERNEL);
85+ if (!state->connector_states)
86+ goto fail;
87+
88+ state->dev = dev;
89+
90+ DRM_DEBUG_KMS("Allocate atomic state %p\n", state);
91+
92+ return state;
93+fail:
94+ kfree_state(state);
95+
96+ return NULL;
97+}
98+EXPORT_SYMBOL(drm_atomic_state_alloc);
99+
100+/**
101+ * drm_atomic_state_clear - clear state object
102+ * @state: atomic state
103+ *
104+ * When the w/w mutex algorithm detects a deadlock we need to back off and drop
105+ * all locks. So someone else could sneak in and change the current modeset
106+ * configuration. Which means that all the state assembled in @state is no
107+ * longer an atomic update to the current state, but to some arbitrary earlier
108+ * state. Which could break assumptions the driver's ->atomic_check likely
109+ * relies on.
110+ *
111+ * Hence we must clear all cached state and completely start over, using this
112+ * function.
113+ */
114+void drm_atomic_state_clear(struct drm_atomic_state *state)
115+{
116+ struct drm_device *dev = state->dev;
117+ struct drm_mode_config *config = &dev->mode_config;
118+ int i;
119+
120+ DRM_DEBUG_KMS("Clearing atomic state %p\n", state);
121+
122+ for (i = 0; i < state->num_connector; i++) {
123+ struct drm_connector *connector = state->connectors[i];
124+
125+ if (!connector)
126+ continue;
127+
128+ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
129+
130+ connector->funcs->atomic_destroy_state(connector,
131+ state->connector_states[i]);
132+ }
133+
134+ for (i = 0; i < config->num_crtc; i++) {
135+ struct drm_crtc *crtc = state->crtcs[i];
136+
137+ if (!crtc)
138+ continue;
139+
140+ crtc->funcs->atomic_destroy_state(crtc,
141+ state->crtc_states[i]);
142+ }
143+
144+ for (i = 0; i < config->num_total_plane; i++) {
145+ struct drm_plane *plane = state->planes[i];
146+
147+ if (!plane)
148+ continue;
149+
150+ plane->funcs->atomic_destroy_state(plane,
151+ state->plane_states[i]);
152+ }
153+}
154+EXPORT_SYMBOL(drm_atomic_state_clear);
155+
156+/**
157+ * drm_atomic_state_free - free all memory for an atomic state
158+ * @state: atomic state to deallocate
159+ *
160+ * This frees all memory associated with an atomic state, including all the
161+ * per-object state for planes, crtcs and connectors.
162+ */
163+void drm_atomic_state_free(struct drm_atomic_state *state)
164+{
165+ drm_atomic_state_clear(state);
166+
167+ DRM_DEBUG_KMS("Freeing atomic state %p\n", state);
168+
169+ kfree_state(state);
170+}
171+EXPORT_SYMBOL(drm_atomic_state_free);
172+
173+/**
174+ * drm_atomic_get_crtc_state - get crtc state
175+ * @state: global atomic state object
176+ * @crtc: crtc to get state object for
177+ *
178+ * This function returns the crtc state for the given crtc, allocating it if
179+ * needed. It will also grab the relevant crtc lock to make sure that the state
180+ * is consistent.
181+ *
182+ * Returns:
183+ *
184+ * Either the allocated state or the error code encoded into the pointer. When
185+ * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
186+ * entire atomic sequence must be restarted. All other errors are fatal.
187+ */
188+struct drm_crtc_state *
189+drm_atomic_get_crtc_state(struct drm_atomic_state *state,
190+ struct drm_crtc *crtc)
191+{
192+ int ret, index;
193+ struct drm_crtc_state *crtc_state;
194+
195+ index = drm_crtc_index(crtc);
196+
197+ if (state->crtc_states[index])
198+ return state->crtc_states[index];
199+
200+ ret = drm_modeset_lock(&crtc->mutex, state->acquire_ctx);
201+ if (ret)
202+ return ERR_PTR(ret);
203+
204+ crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
205+ if (!crtc_state)
206+ return ERR_PTR(-ENOMEM);
207+
208+ state->crtc_states[index] = crtc_state;
209+ state->crtcs[index] = crtc;
210+ crtc_state->state = state;
211+
212+ DRM_DEBUG_KMS("Added [CRTC:%d] %p state to %p\n",
213+ crtc->base.id, crtc_state, state);
214+
215+ return crtc_state;
216+}
217+EXPORT_SYMBOL(drm_atomic_get_crtc_state);
218+
219+/**
220+ * drm_atomic_get_plane_state - get plane state
221+ * @state: global atomic state object
222+ * @plane: plane to get state object for
223+ *
224+ * This function returns the plane state for the given plane, allocating it if
225+ * needed. It will also grab the relevant plane lock to make sure that the state
226+ * is consistent.
227+ *
228+ * Returns:
229+ *
230+ * Either the allocated state or the error code encoded into the pointer. When
231+ * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
232+ * entire atomic sequence must be restarted. All other errors are fatal.
233+ */
234+struct drm_plane_state *
235+drm_atomic_get_plane_state(struct drm_atomic_state *state,
236+ struct drm_plane *plane)
237+{
238+ int ret, index;
239+ struct drm_plane_state *plane_state;
240+
241+ index = drm_plane_index(plane);
242+
243+ if (state->plane_states[index])
244+ return state->plane_states[index];
245+
246+ ret = drm_modeset_lock(&plane->mutex, state->acquire_ctx);
247+ if (ret)
248+ return ERR_PTR(ret);
249+
250+ plane_state = plane->funcs->atomic_duplicate_state(plane);
251+ if (!plane_state)
252+ return ERR_PTR(-ENOMEM);
253+
254+ state->plane_states[index] = plane_state;
255+ state->planes[index] = plane;
256+ plane_state->state = state;
257+
258+ DRM_DEBUG_KMS("Added [PLANE:%d] %p state to %p\n",
259+ plane->base.id, plane_state, state);
260+
261+ if (plane_state->crtc) {
262+ struct drm_crtc_state *crtc_state;
263+
264+ crtc_state = drm_atomic_get_crtc_state(state,
265+ plane_state->crtc);
266+ if (IS_ERR(crtc_state))
267+ return ERR_CAST(crtc_state);
268+ }
269+
270+ return plane_state;
271+}
272+EXPORT_SYMBOL(drm_atomic_get_plane_state);
273+
274+/**
275+ * drm_atomic_get_connector_state - get connector state
276+ * @state: global atomic state object
277+ * @connector: connector to get state object for
278+ *
279+ * This function returns the connector state for the given connector,
280+ * allocating it if needed. It will also grab the relevant connector lock to
281+ * make sure that the state is consistent.
282+ *
283+ * Returns:
284+ *
285+ * Either the allocated state or the error code encoded into the pointer. When
286+ * the error is EDEADLK then the w/w mutex code has detected a deadlock and the
287+ * entire atomic sequence must be restarted. All other errors are fatal.
288+ */
289+struct drm_connector_state *
290+drm_atomic_get_connector_state(struct drm_atomic_state *state,
291+ struct drm_connector *connector)
292+{
293+ int ret, index;
294+ struct drm_mode_config *config = &connector->dev->mode_config;
295+ struct drm_connector_state *connector_state;
296+
297+ ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
298+ if (ret)
299+ return ERR_PTR(ret);
300+
301+ index = drm_connector_index(connector);
302+
303+ /*
304+ * Construction of atomic state updates can race with a connector
305+ * hot-add which might overflow. In this case flip the table and just
306+ * restart the entire ioctl - no one is fast enough to livelock a cpu
307+ * with physical hotplug events anyway.
308+ *
309+ * Note that we only grab the indexes once we have the right lock to
310+ * prevent hotplug/unplugging of connectors. So removal is no problem,
311+ * at most the array is a bit too large.
312+ */
313+ if (index >= state->num_connector) {
314+ DRM_DEBUG_KMS("Hot-added connector would overflow state array, restarting\n");
315+ return ERR_PTR(-EAGAIN);
316+ }
317+
318+ if (state->connector_states[index])
319+ return state->connector_states[index];
320+
321+ connector_state = connector->funcs->atomic_duplicate_state(connector);
322+ if (!connector_state)
323+ return ERR_PTR(-ENOMEM);
324+
325+ state->connector_states[index] = connector_state;
326+ state->connectors[index] = connector;
327+ connector_state->state = state;
328+
329+ DRM_DEBUG_KMS("Added [CONNECTOR:%d] %p state to %p\n",
330+ connector->base.id, connector_state, state);
331+
332+ if (connector_state->crtc) {
333+ struct drm_crtc_state *crtc_state;
334+
335+ crtc_state = drm_atomic_get_crtc_state(state,
336+ connector_state->crtc);
337+ if (IS_ERR(crtc_state))
338+ return ERR_CAST(crtc_state);
339+ }
340+
341+ return connector_state;
342+}
343+EXPORT_SYMBOL(drm_atomic_get_connector_state);
344+
345+/**
346+ * drm_atomic_set_crtc_for_plane - set crtc for plane
347+ * @state: the incoming atomic state
348+ * @plane: the plane whose incoming state to update
349+ * @crtc: crtc to use for the plane
350+ *
351+ * Changing the assigned crtc for a plane requires us to grab the lock and state
352+ * for the new crtc, as needed. This function takes care of all these details
353+ * besides updating the pointer in the state object itself.
354+ *
355+ * Returns:
356+ * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
357+ * then the w/w mutex code has detected a deadlock and the entire atomic
358+ * sequence must be restarted. All other errors are fatal.
359+ */
360+int
361+drm_atomic_set_crtc_for_plane(struct drm_atomic_state *state,
362+ struct drm_plane *plane, struct drm_crtc *crtc)
363+{
364+ struct drm_plane_state *plane_state =
365+ drm_atomic_get_plane_state(state, plane);
366+ struct drm_crtc_state *crtc_state;
367+
368+ if (WARN_ON(IS_ERR(plane_state)))
369+ return PTR_ERR(plane_state);
370+
371+ if (plane_state->crtc) {
372+ crtc_state = drm_atomic_get_crtc_state(plane_state->state,
373+ plane_state->crtc);
374+ if (WARN_ON(IS_ERR(crtc_state)))
375+ return PTR_ERR(crtc_state);
376+
377+ crtc_state->plane_mask &= ~(1 << drm_plane_index(plane));
378+ }
379+
380+ plane_state->crtc = crtc;
381+
382+ if (crtc) {
383+ crtc_state = drm_atomic_get_crtc_state(plane_state->state,
384+ crtc);
385+ if (IS_ERR(crtc_state))
386+ return PTR_ERR(crtc_state);
387+ crtc_state->plane_mask |= (1 << drm_plane_index(plane));
388+ }
389+
390+ if (crtc)
391+ DRM_DEBUG_KMS("Link plane state %p to [CRTC:%d]\n",
392+ plane_state, crtc->base.id);
393+ else
394+ DRM_DEBUG_KMS("Link plane state %p to [NOCRTC]\n", plane_state);
395+
396+ return 0;
397+}
398+EXPORT_SYMBOL(drm_atomic_set_crtc_for_plane);
399+
400+/**
401+ * drm_atomic_set_fb_for_plane - set crtc for plane
402+ * @plane_state: atomic state object for the plane
403+ * @fb: fb to use for the plane
404+ *
405+ * Changing the assigned framebuffer for a plane requires us to grab a reference
406+ * to the new fb and drop the reference to the old fb, if there is one. This
407+ * function takes care of all these details besides updating the pointer in the
408+ * state object itself.
409+ */
410+void
411+drm_atomic_set_fb_for_plane(struct drm_plane_state *plane_state,
412+ struct drm_framebuffer *fb)
413+{
414+ if (plane_state->fb)
415+ drm_framebuffer_unreference(plane_state->fb);
416+ if (fb)
417+ drm_framebuffer_reference(fb);
418+ plane_state->fb = fb;
419+
420+ if (fb)
421+ DRM_DEBUG_KMS("Set [FB:%d] for plane state %p\n",
422+ fb->base.id, plane_state);
423+ else
424+ DRM_DEBUG_KMS("Set [NOFB] for plane state %p\n", plane_state);
425+}
426+EXPORT_SYMBOL(drm_atomic_set_fb_for_plane);
427+
428+/**
429+ * drm_atomic_set_crtc_for_connector - set crtc for connector
430+ * @conn_state: atomic state object for the connector
431+ * @crtc: crtc to use for the connector
432+ *
433+ * Changing the assigned crtc for a connector requires us to grab the lock and
434+ * state for the new crtc, as needed. This function takes care of all these
435+ * details besides updating the pointer in the state object itself.
436+ *
437+ * Returns:
438+ * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
439+ * then the w/w mutex code has detected a deadlock and the entire atomic
440+ * sequence must be restarted. All other errors are fatal.
441+ */
442+int
443+drm_atomic_set_crtc_for_connector(struct drm_connector_state *conn_state,
444+ struct drm_crtc *crtc)
445+{
446+ struct drm_crtc_state *crtc_state;
447+
448+ if (crtc) {
449+ crtc_state = drm_atomic_get_crtc_state(conn_state->state, crtc);
450+ if (IS_ERR(crtc_state))
451+ return PTR_ERR(crtc_state);
452+ }
453+
454+ conn_state->crtc = crtc;
455+
456+ if (crtc)
457+ DRM_DEBUG_KMS("Link connector state %p to [CRTC:%d]\n",
458+ conn_state, crtc->base.id);
459+ else
460+ DRM_DEBUG_KMS("Link connector state %p to [NOCRTC]\n",
461+ conn_state);
462+
463+ return 0;
464+}
465+EXPORT_SYMBOL(drm_atomic_set_crtc_for_connector);
466+
467+/**
468+ * drm_atomic_add_affected_connectors - add connectors for crtc
469+ * @state: atomic state
470+ * @crtc: DRM crtc
471+ *
472+ * This function walks the current configuration and adds all connectors
473+ * currently using @crtc to the atomic configuration @state. Note that this
474+ * function must acquire the connection mutex. This can potentially cause
475+ * unneeded seralization if the update is just for the planes on one crtc. Hence
476+ * drivers and helpers should only call this when really needed (e.g. when a
477+ * full modeset needs to happen due to some change).
478+ *
479+ * Returns:
480+ * 0 on success or can fail with -EDEADLK or -ENOMEM. When the error is EDEADLK
481+ * then the w/w mutex code has detected a deadlock and the entire atomic
482+ * sequence must be restarted. All other errors are fatal.
483+ */
484+int
485+drm_atomic_add_affected_connectors(struct drm_atomic_state *state,
486+ struct drm_crtc *crtc)
487+{
488+ struct drm_mode_config *config = &state->dev->mode_config;
489+ struct drm_connector *connector;
490+ struct drm_connector_state *conn_state;
491+ int ret;
492+
493+ ret = drm_modeset_lock(&config->connection_mutex, state->acquire_ctx);
494+ if (ret)
495+ return ret;
496+
497+ DRM_DEBUG_KMS("Adding all current connectors for [CRTC:%d] to %p\n",
498+ crtc->base.id, state);
499+
500+ /*
501+ * Changed connectors are already in @state, so only need to look at the
502+ * current configuration.
503+ */
504+ list_for_each_entry(connector, &config->connector_list, head) {
505+ if (connector->state->crtc != crtc)
506+ continue;
507+
508+ conn_state = drm_atomic_get_connector_state(state, connector);
509+ if (IS_ERR(conn_state))
510+ return PTR_ERR(conn_state);
511+ }
512+
513+ return 0;
514+}
515+EXPORT_SYMBOL(drm_atomic_add_affected_connectors);
516+
517+/**
518+ * drm_atomic_connectors_for_crtc - count number of connected outputs
519+ * @state: atomic state
520+ * @crtc: DRM crtc
521+ *
522+ * This function counts all connectors which will be connected to @crtc
523+ * according to @state. Useful to recompute the enable state for @crtc.
524+ */
525+int
526+drm_atomic_connectors_for_crtc(struct drm_atomic_state *state,
527+ struct drm_crtc *crtc)
528+{
529+ int i, num_connected_connectors = 0;
530+
531+ for (i = 0; i < state->num_connector; i++) {
532+ struct drm_connector_state *conn_state;
533+
534+ conn_state = state->connector_states[i];
535+
536+ if (conn_state && conn_state->crtc == crtc)
537+ num_connected_connectors++;
538+ }
539+
540+ DRM_DEBUG_KMS("State %p has %i connectors for [CRTC:%d]\n",
541+ state, num_connected_connectors, crtc->base.id);
542+
543+ return num_connected_connectors;
544+}
545+EXPORT_SYMBOL(drm_atomic_connectors_for_crtc);
546+
547+/**
548+ * drm_atomic_legacy_backoff - locking backoff for legacy ioctls
549+ * @state: atomic state
550+ *
551+ * This function should be used by legacy entry points which don't understand
552+ * -EDEADLK semantics. For simplicity this one will grab all modeset locks after
553+ * the slowpath completed.
554+ */
555+void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
556+{
557+ int ret;
558+
559+retry:
560+ drm_modeset_backoff(state->acquire_ctx);
561+
562+ ret = drm_modeset_lock(&state->dev->mode_config.connection_mutex,
563+ state->acquire_ctx);
564+ if (ret)
565+ goto retry;
566+ ret = drm_modeset_lock_all_crtcs(state->dev,
567+ state->acquire_ctx);
568+ if (ret)
569+ goto retry;
570+}
571+EXPORT_SYMBOL(drm_atomic_legacy_backoff);
572+
573+/**
574+ * drm_atomic_check_only - check whether a given config would work
575+ * @state: atomic configuration to check
576+ *
577+ * Note that this function can return -EDEADLK if the driver needed to acquire
578+ * more locks but encountered a deadlock. The caller must then do the usual w/w
579+ * backoff dance and restart. All other errors are fatal.
580+ *
581+ * Returns:
582+ * 0 on success, negative error code on failure.
583+ */
584+int drm_atomic_check_only(struct drm_atomic_state *state)
585+{
586+ struct drm_mode_config *config = &state->dev->mode_config;
587+
588+ DRM_DEBUG_KMS("checking %p\n", state);
589+
590+ if (config->funcs->atomic_check)
591+ return config->funcs->atomic_check(state->dev, state);
592+ else
593+ return 0;
594+}
595+EXPORT_SYMBOL(drm_atomic_check_only);
596+
597+/**
598+ * drm_atomic_commit - commit configuration atomically
599+ * @state: atomic configuration to check
600+ *
601+ * Note that this function can return -EDEADLK if the driver needed to acquire
602+ * more locks but encountered a deadlock. The caller must then do the usual w/w
603+ * backoff dance and restart. All other errors are fatal.
604+ *
605+ * Also note that on successful execution ownership of @state is transferred
606+ * from the caller of this function to the function itself. The caller must not
607+ * free or in any other way access @state. If the function fails then the caller
608+ * must clean up @state itself.
609+ *
610+ * Returns:
611+ * 0 on success, negative error code on failure.
612+ */
613+int drm_atomic_commit(struct drm_atomic_state *state)
614+{
615+ struct drm_mode_config *config = &state->dev->mode_config;
616+ int ret;
617+
618+ ret = drm_atomic_check_only(state);
619+ if (ret)
620+ return ret;
621+
622+ DRM_DEBUG_KMS("commiting %p\n", state);
623+
624+ return config->funcs->atomic_commit(state->dev, state, false);
625+}
626+EXPORT_SYMBOL(drm_atomic_commit);
627+
628+/**
629+ * drm_atomic_async_commit - atomic&async configuration commit
630+ * @state: atomic configuration to check
631+ *
632+ * Note that this function can return -EDEADLK if the driver needed to acquire
633+ * more locks but encountered a deadlock. The caller must then do the usual w/w
634+ * backoff dance and restart. All other errors are fatal.
635+ *
636+ * Also note that on successful execution ownership of @state is transferred
637+ * from the caller of this function to the function itself. The caller must not
638+ * free or in any other way access @state. If the function fails then the caller
639+ * must clean up @state itself.
640+ *
641+ * Returns:
642+ * 0 on success, negative error code on failure.
643+ */
644+int drm_atomic_async_commit(struct drm_atomic_state *state)
645+{
646+ struct drm_mode_config *config = &state->dev->mode_config;
647+ int ret;
648+
649+ ret = drm_atomic_check_only(state);
650+ if (ret)
651+ return ret;
652+
653+ DRM_DEBUG_KMS("commiting %p asynchronously\n", state);
654+
655+ return config->funcs->atomic_commit(state->dev, state, true);
656+}
657+EXPORT_SYMBOL(drm_atomic_async_commit);
drivers/gpu/drm/drm_atomic_helper.c+1966−0
@@ -0,0 +1,1966 @@
1+/*
2+ * Copyright (C) 2014 Red Hat
3+ * Copyright (C) 2014 Intel Corp.
4+ *
5+ * Permission is hereby granted, free of charge, to any person obtaining a
6+ * copy of this software and associated documentation files (the "Software"),
7+ * to deal in the Software without restriction, including without limitation
8+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9+ * and/or sell copies of the Software, and to permit persons to whom the
10+ * Software is furnished to do so, subject to the following conditions:
11+ *
12+ * The above copyright notice and this permission notice shall be included in
13+ * all copies or substantial portions of the Software.
14+ *
15+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18+ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
21+ * OTHER DEALINGS IN THE SOFTWARE.
22+ *
23+ * Authors:
24+ * Rob Clark <robdclark@gmail.com>
25+ * Daniel Vetter <daniel.vetter@ffwll.ch>
26+ */
27+
28+#include <drm/drmP.h>
29+#include <drm/drm_atomic.h>
30+#include <drm/drm_plane_helper.h>
31+#include <drm/drm_crtc_helper.h>
32+#include <drm/drm_atomic_helper.h>
33+#include <linux/fence.h>
34+
35+/**
36+ * DOC: overview
37+ *
38+ * This helper library provides implementations of check and commit functions on
39+ * top of the CRTC modeset helper callbacks and the plane helper callbacks. It
40+ * also provides convenience implementations for the atomic state handling
41+ * callbacks for drivers which don't need to subclass the drm core structures to
42+ * add their own additional internal state.
43+ *
44+ * This library also provides default implementations for the check callback in
45+ * drm_atomic_helper_check and for the commit callback with
46+ * drm_atomic_helper_commit. But the individual stages and callbacks are expose
47+ * to allow drivers to mix and match and e.g. use the plane helpers only
48+ * together with a driver private modeset implementation.
49+ *
50+ * This library also provides implementations for all the legacy driver
51+ * interfaces on top of the atomic interface. See drm_atomic_helper_set_config,
52+ * drm_atomic_helper_disable_plane, drm_atomic_helper_disable_plane and the
53+ * various functions to implement set_property callbacks. New drivers must not
54+ * implement these functions themselves but must use the provided helpers.
55+ */
56+static void
57+drm_atomic_helper_plane_changed(struct drm_atomic_state *state,
58+ struct drm_plane_state *plane_state,
59+ struct drm_plane *plane)
60+{
61+ struct drm_crtc_state *crtc_state;
62+
63+ if (plane->state->crtc) {
64+ crtc_state = state->crtc_states[drm_crtc_index(plane->crtc)];
65+
66+ if (WARN_ON(!crtc_state))
67+ return;
68+
69+ crtc_state->planes_changed = true;
70+ }
71+
72+ if (plane_state->crtc) {
73+ crtc_state =
74+ state->crtc_states[drm_crtc_index(plane_state->crtc)];
75+
76+ if (WARN_ON(!crtc_state))
77+ return;
78+
79+ crtc_state->planes_changed = true;
80+ }
81+}
82+
83+static struct drm_crtc *
84+get_current_crtc_for_encoder(struct drm_device *dev,
85+ struct drm_encoder *encoder)
86+{
87+ struct drm_mode_config *config = &dev->mode_config;
88+ struct drm_connector *connector;
89+
90+ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
91+
92+ list_for_each_entry(connector, &config->connector_list, head) {
93+ if (connector->state->best_encoder != encoder)
94+ continue;
95+
96+ return connector->state->crtc;
97+ }
98+
99+ return NULL;
100+}
101+
102+static int
103+steal_encoder(struct drm_atomic_state *state,
104+ struct drm_encoder *encoder,
105+ struct drm_crtc *encoder_crtc)
106+{
107+ struct drm_mode_config *config = &state->dev->mode_config;
108+ struct drm_crtc_state *crtc_state;
109+ struct drm_connector *connector;
110+ struct drm_connector_state *connector_state;
111+ int ret;
112+
113+ /*
114+ * We can only steal an encoder coming from a connector, which means we
115+ * must already hold the connection_mutex.
116+ */
117+ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
118+
119+ DRM_DEBUG_KMS("[ENCODER:%d:%s] in use on [CRTC:%d], stealing it\n",
120+ encoder->base.id, encoder->name,
121+ encoder_crtc->base.id);
122+
123+ crtc_state = drm_atomic_get_crtc_state(state, encoder_crtc);
124+ if (IS_ERR(crtc_state))
125+ return PTR_ERR(crtc_state);
126+
127+ crtc_state->mode_changed = true;
128+
129+ list_for_each_entry(connector, &config->connector_list, head) {
130+ if (connector->state->best_encoder != encoder)
131+ continue;
132+
133+ DRM_DEBUG_KMS("Stealing encoder from [CONNECTOR:%d:%s]\n",
134+ connector->base.id,
135+ connector->name);
136+
137+ connector_state = drm_atomic_get_connector_state(state,
138+ connector);
139+ if (IS_ERR(connector_state))
140+ return PTR_ERR(connector_state);
141+
142+ ret = drm_atomic_set_crtc_for_connector(connector_state, NULL);
143+ if (ret)
144+ return ret;
145+ connector_state->best_encoder = NULL;
146+ }
147+
148+ return 0;
149+}
150+
151+static int
152+update_connector_routing(struct drm_atomic_state *state, int conn_idx)
153+{
154+ struct drm_connector_helper_funcs *funcs;
155+ struct drm_encoder *new_encoder;
156+ struct drm_crtc *encoder_crtc;
157+ struct drm_connector *connector;
158+ struct drm_connector_state *connector_state;
159+ struct drm_crtc_state *crtc_state;
160+ int idx, ret;
161+
162+ connector = state->connectors[conn_idx];
163+ connector_state = state->connector_states[conn_idx];
164+
165+ if (!connector)
166+ return 0;
167+
168+ DRM_DEBUG_KMS("Updating routing for [CONNECTOR:%d:%s]\n",
169+ connector->base.id,
170+ connector->name);
171+
172+ if (connector->state->crtc != connector_state->crtc) {
173+ if (connector->state->crtc) {
174+ idx = drm_crtc_index(connector->state->crtc);
175+
176+ crtc_state = state->crtc_states[idx];
177+ crtc_state->mode_changed = true;
178+ }
179+
180+ if (connector_state->crtc) {
181+ idx = drm_crtc_index(connector_state->crtc);
182+
183+ crtc_state = state->crtc_states[idx];
184+ crtc_state->mode_changed = true;
185+ }
186+ }
187+
188+ if (!connector_state->crtc) {
189+ DRM_DEBUG_KMS("Disabling [CONNECTOR:%d:%s]\n",
190+ connector->base.id,
191+ connector->name);
192+
193+ connector_state->best_encoder = NULL;
194+
195+ return 0;
196+ }
197+
198+ funcs = connector->helper_private;
199+ new_encoder = funcs->best_encoder(connector);
200+
201+ if (!new_encoder) {
202+ DRM_DEBUG_KMS("No suitable encoder found for [CONNECTOR:%d:%s]\n",
203+ connector->base.id,
204+ connector->name);
205+ return -EINVAL;
206+ }
207+
208+ if (new_encoder == connector_state->best_encoder) {
209+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] keeps [ENCODER:%d:%s], now on [CRTC:%d]\n",
210+ connector->base.id,
211+ connector->name,
212+ new_encoder->base.id,
213+ new_encoder->name,
214+ connector_state->crtc->base.id);
215+
216+ return 0;
217+ }
218+
219+ encoder_crtc = get_current_crtc_for_encoder(state->dev,
220+ new_encoder);
221+
222+ if (encoder_crtc) {
223+ ret = steal_encoder(state, new_encoder, encoder_crtc);
224+ if (ret) {
225+ DRM_DEBUG_KMS("Encoder stealing failed for [CONNECTOR:%d:%s]\n",
226+ connector->base.id,
227+ connector->name);
228+ return ret;
229+ }
230+ }
231+
232+ connector_state->best_encoder = new_encoder;
233+ idx = drm_crtc_index(connector_state->crtc);
234+
235+ crtc_state = state->crtc_states[idx];
236+ crtc_state->mode_changed = true;
237+
238+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] using [ENCODER:%d:%s] on [CRTC:%d]\n",
239+ connector->base.id,
240+ connector->name,
241+ new_encoder->base.id,
242+ new_encoder->name,
243+ connector_state->crtc->base.id);
244+
245+ return 0;
246+}
247+
248+static int
249+mode_fixup(struct drm_atomic_state *state)
250+{
251+ int ncrtcs = state->dev->mode_config.num_crtc;
252+ struct drm_crtc_state *crtc_state;
253+ struct drm_connector_state *conn_state;
254+ int i;
255+ bool ret;
256+
257+ for (i = 0; i < ncrtcs; i++) {
258+ crtc_state = state->crtc_states[i];
259+
260+ if (!crtc_state || !crtc_state->mode_changed)
261+ continue;
262+
263+ drm_mode_copy(&crtc_state->adjusted_mode, &crtc_state->mode);
264+ }
265+
266+ for (i = 0; i < state->num_connector; i++) {
267+ struct drm_encoder_helper_funcs *funcs;
268+ struct drm_encoder *encoder;
269+
270+ conn_state = state->connector_states[i];
271+
272+ if (!conn_state)
273+ continue;
274+
275+ WARN_ON(!!conn_state->best_encoder != !!conn_state->crtc);
276+
277+ if (!conn_state->crtc || !conn_state->best_encoder)
278+ continue;
279+
280+ crtc_state =
281+ state->crtc_states[drm_crtc_index(conn_state->crtc)];
282+
283+ /*
284+ * Each encoder has at most one connector (since we always steal
285+ * it away), so we won't call ->mode_fixup twice.
286+ */
287+ encoder = conn_state->best_encoder;
288+ funcs = encoder->helper_private;
289+
290+ if (encoder->bridge && encoder->bridge->funcs->mode_fixup) {
291+ ret = encoder->bridge->funcs->mode_fixup(
292+ encoder->bridge, &crtc_state->mode,
293+ &crtc_state->adjusted_mode);
294+ if (!ret) {
295+ DRM_DEBUG_KMS("Bridge fixup failed\n");
296+ return -EINVAL;
297+ }
298+ }
299+
300+
301+ ret = funcs->mode_fixup(encoder, &crtc_state->mode,
302+ &crtc_state->adjusted_mode);
303+ if (!ret) {
304+ DRM_DEBUG_KMS("[ENCODER:%d:%s] fixup failed\n",
305+ encoder->base.id, encoder->name);
306+ return -EINVAL;
307+ }
308+ }
309+
310+ for (i = 0; i < ncrtcs; i++) {
311+ struct drm_crtc_helper_funcs *funcs;
312+ struct drm_crtc *crtc;
313+
314+ crtc_state = state->crtc_states[i];
315+ crtc = state->crtcs[i];
316+
317+ if (!crtc_state || !crtc_state->mode_changed)
318+ continue;
319+
320+ funcs = crtc->helper_private;
321+ ret = funcs->mode_fixup(crtc, &crtc_state->mode,
322+ &crtc_state->adjusted_mode);
323+ if (!ret) {
324+ DRM_DEBUG_KMS("[CRTC:%d] fixup failed\n",
325+ crtc->base.id);
326+ return -EINVAL;
327+ }
328+ }
329+
330+ return 0;
331+}
332+
333+static int
334+drm_atomic_helper_check_modeset(struct drm_device *dev,
335+ struct drm_atomic_state *state)
336+{
337+ int ncrtcs = dev->mode_config.num_crtc;
338+ struct drm_crtc *crtc;
339+ struct drm_crtc_state *crtc_state;
340+ int i, ret;
341+
342+ for (i = 0; i < ncrtcs; i++) {
343+ crtc = state->crtcs[i];
344+ crtc_state = state->crtc_states[i];
345+
346+ if (!crtc)
347+ continue;
348+
349+ if (!drm_mode_equal(&crtc->state->mode, &crtc_state->mode)) {
350+ DRM_DEBUG_KMS("[CRTC:%d] mode changed\n",
351+ crtc->base.id);
352+ crtc_state->mode_changed = true;
353+ }
354+
355+ if (crtc->state->enable != crtc_state->enable) {
356+ DRM_DEBUG_KMS("[CRTC:%d] enable changed\n",
357+ crtc->base.id);
358+ crtc_state->mode_changed = true;
359+ }
360+ }
361+
362+ for (i = 0; i < state->num_connector; i++) {
363+ /*
364+ * This only sets crtc->mode_changed for routing changes,
365+ * drivers must set crtc->mode_changed themselves when connector
366+ * properties need to be updated.
367+ */
368+ ret = update_connector_routing(state, i);
369+ if (ret)
370+ return ret;
371+ }
372+
373+ /*
374+ * After all the routing has been prepared we need to add in any
375+ * connector which is itself unchanged, but who's crtc changes it's
376+ * configuration. This must be done before calling mode_fixup in case a
377+ * crtc only changed its mode but has the same set of connectors.
378+ */
379+ for (i = 0; i < ncrtcs; i++) {
380+ int num_connectors;
381+
382+ crtc = state->crtcs[i];
383+ crtc_state = state->crtc_states[i];
384+
385+ if (!crtc || !crtc_state->mode_changed)
386+ continue;
387+
388+ DRM_DEBUG_KMS("[CRTC:%d] needs full modeset, enable: %c\n",
389+ crtc->base.id,
390+ crtc_state->enable ? 'y' : 'n');
391+
392+ ret = drm_atomic_add_affected_connectors(state, crtc);
393+ if (ret != 0)
394+ return ret;
395+
396+ num_connectors = drm_atomic_connectors_for_crtc(state,
397+ crtc);
398+
399+ if (crtc_state->enable != !!num_connectors) {
400+ DRM_DEBUG_KMS("[CRTC:%d] enabled/connectors mismatch\n",
401+ crtc->base.id);
402+
403+ return -EINVAL;
404+ }
405+ }
406+
407+ return mode_fixup(state);
408+}
409+
410+/**
411+ * drm_atomic_helper_check - validate state object
412+ * @dev: DRM device
413+ * @state: the driver state object
414+ *
415+ * Check the state object to see if the requested state is physically possible.
416+ * Only crtcs and planes have check callbacks, so for any additional (global)
417+ * checking that a driver needs it can simply wrap that around this function.
418+ * Drivers without such needs can directly use this as their ->atomic_check()
419+ * callback.
420+ *
421+ * RETURNS
422+ * Zero for success or -errno
423+ */
424+int drm_atomic_helper_check(struct drm_device *dev,
425+ struct drm_atomic_state *state)
426+{
427+ int nplanes = dev->mode_config.num_total_plane;
428+ int ncrtcs = dev->mode_config.num_crtc;
429+ int i, ret = 0;
430+
431+ for (i = 0; i < nplanes; i++) {
432+ struct drm_plane_helper_funcs *funcs;
433+ struct drm_plane *plane = state->planes[i];
434+ struct drm_plane_state *plane_state = state->plane_states[i];
435+
436+ if (!plane)
437+ continue;
438+
439+ funcs = plane->helper_private;
440+
441+ drm_atomic_helper_plane_changed(state, plane_state, plane);
442+
443+ if (!funcs || !funcs->atomic_check)
444+ continue;
445+
446+ ret = funcs->atomic_check(plane, plane_state);
447+ if (ret) {
448+ DRM_DEBUG_KMS("[PLANE:%d] atomic check failed\n",
449+ plane->base.id);
450+ return ret;
451+ }
452+ }
453+
454+ for (i = 0; i < ncrtcs; i++) {
455+ struct drm_crtc_helper_funcs *funcs;
456+ struct drm_crtc *crtc = state->crtcs[i];
457+
458+ if (!crtc)
459+ continue;
460+
461+ funcs = crtc->helper_private;
462+
463+ if (!funcs || !funcs->atomic_check)
464+ continue;
465+
466+ ret = funcs->atomic_check(crtc, state->crtc_states[i]);
467+ if (ret) {
468+ DRM_DEBUG_KMS("[CRTC:%d] atomic check failed\n",
469+ crtc->base.id);
470+ return ret;
471+ }
472+ }
473+
474+ ret = drm_atomic_helper_check_modeset(dev, state);
475+ if (ret)
476+ return ret;
477+
478+ return ret;
479+}
480+EXPORT_SYMBOL(drm_atomic_helper_check);
481+
482+static void
483+disable_outputs(struct drm_device *dev, struct drm_atomic_state *old_state)
484+{
485+ int ncrtcs = old_state->dev->mode_config.num_crtc;
486+ int i;
487+
488+ for (i = 0; i < old_state->num_connector; i++) {
489+ struct drm_connector_state *old_conn_state;
490+ struct drm_connector *connector;
491+ struct drm_encoder_helper_funcs *funcs;
492+ struct drm_encoder *encoder;
493+
494+ old_conn_state = old_state->connector_states[i];
495+ connector = old_state->connectors[i];
496+
497+ /* Shut down everything that's in the changeset and currently
498+ * still on. So need to check the old, saved state. */
499+ if (!old_conn_state || !old_conn_state->crtc)
500+ continue;
501+
502+ encoder = old_conn_state->best_encoder;
503+
504+ /* We shouldn't get this far if we didn't previously have
505+ * an encoder.. but WARN_ON() rather than explode.
506+ */
507+ if (WARN_ON(!encoder))
508+ continue;
509+
510+ funcs = encoder->helper_private;
511+
512+ /*
513+ * Each encoder has at most one connector (since we always steal
514+ * it away), so we won't call call disable hooks twice.
515+ */
516+ if (encoder->bridge)
517+ encoder->bridge->funcs->disable(encoder->bridge);
518+
519+ /* Right function depends upon target state. */
520+ if (connector->state->crtc)
521+ funcs->prepare(encoder);
522+ else if (funcs->disable)
523+ funcs->disable(encoder);
524+ else
525+ funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
526+
527+ if (encoder->bridge)
528+ encoder->bridge->funcs->post_disable(encoder->bridge);
529+ }
530+
531+ for (i = 0; i < ncrtcs; i++) {
532+ struct drm_crtc_helper_funcs *funcs;
533+ struct drm_crtc *crtc;
534+
535+ crtc = old_state->crtcs[i];
536+
537+ /* Shut down everything that needs a full modeset. */
538+ if (!crtc || !crtc->state->mode_changed)
539+ continue;
540+
541+ funcs = crtc->helper_private;
542+
543+ /* Right function depends upon target state. */
544+ if (crtc->state->enable)
545+ funcs->prepare(crtc);
546+ else if (funcs->disable)
547+ funcs->disable(crtc);
548+ else
549+ funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
550+ }
551+}
552+
553+static void
554+set_routing_links(struct drm_device *dev, struct drm_atomic_state *old_state)
555+{
556+ int ncrtcs = old_state->dev->mode_config.num_crtc;
557+ int i;
558+
559+ /* clear out existing links */
560+ for (i = 0; i < old_state->num_connector; i++) {
561+ struct drm_connector *connector;
562+
563+ connector = old_state->connectors[i];
564+
565+ if (!connector || !connector->encoder)
566+ continue;
567+
568+ WARN_ON(!connector->encoder->crtc);
569+
570+ connector->encoder->crtc = NULL;
571+ connector->encoder = NULL;
572+ }
573+
574+ /* set new links */
575+ for (i = 0; i < old_state->num_connector; i++) {
576+ struct drm_connector *connector;
577+
578+ connector = old_state->connectors[i];
579+
580+ if (!connector || !connector->state->crtc)
581+ continue;
582+
583+ if (WARN_ON(!connector->state->best_encoder))
584+ continue;
585+
586+ connector->encoder = connector->state->best_encoder;
587+ connector->encoder->crtc = connector->state->crtc;
588+ }
589+
590+ /* set legacy state in the crtc structure */
591+ for (i = 0; i < ncrtcs; i++) {
592+ struct drm_crtc *crtc;
593+
594+ crtc = old_state->crtcs[i];
595+
596+ if (!crtc)
597+ continue;
598+
599+ crtc->mode = crtc->state->mode;
600+ crtc->enabled = crtc->state->enable;
601+ crtc->x = crtc->primary->state->src_x >> 16;
602+ crtc->y = crtc->primary->state->src_y >> 16;
603+ }
604+}
605+
606+static void
607+crtc_set_mode(struct drm_device *dev, struct drm_atomic_state *old_state)
608+{
609+ int ncrtcs = old_state->dev->mode_config.num_crtc;
610+ int i;
611+
612+ for (i = 0; i < ncrtcs; i++) {
613+ struct drm_crtc_helper_funcs *funcs;
614+ struct drm_crtc *crtc;
615+
616+ crtc = old_state->crtcs[i];
617+
618+ if (!crtc || !crtc->state->mode_changed)
619+ continue;
620+
621+ funcs = crtc->helper_private;
622+
623+ if (crtc->state->enable)
624+ funcs->mode_set_nofb(crtc);
625+ }
626+
627+ for (i = 0; i < old_state->num_connector; i++) {
628+ struct drm_connector *connector;
629+ struct drm_crtc_state *new_crtc_state;
630+ struct drm_encoder_helper_funcs *funcs;
631+ struct drm_encoder *encoder;
632+ struct drm_display_mode *mode, *adjusted_mode;
633+
634+ connector = old_state->connectors[i];
635+
636+ if (!connector || !connector->state->best_encoder)
637+ continue;
638+
639+ encoder = connector->state->best_encoder;
640+ funcs = encoder->helper_private;
641+ new_crtc_state = connector->state->crtc->state;
642+ mode = &new_crtc_state->mode;
643+ adjusted_mode = &new_crtc_state->adjusted_mode;
644+
645+ /*
646+ * Each encoder has at most one connector (since we always steal
647+ * it away), so we won't call call mode_set hooks twice.
648+ */
649+ funcs->mode_set(encoder, mode, adjusted_mode);
650+
651+ if (encoder->bridge && encoder->bridge->funcs->mode_set)
652+ encoder->bridge->funcs->mode_set(encoder->bridge,
653+ mode, adjusted_mode);
654+ }
655+}
656+
657+/**
658+ * drm_atomic_helper_commit_pre_planes - modeset commit before plane updates
659+ * @dev: DRM device
660+ * @state: atomic state
661+ *
662+ * This function commits the modeset changes that need to be committed before
663+ * updating planes. It shuts down all the outputs that need to be shut down and
664+ * prepares them (if required) with the new mode.
665+ */
666+void drm_atomic_helper_commit_pre_planes(struct drm_device *dev,
667+ struct drm_atomic_state *state)
668+{
669+ disable_outputs(dev, state);
670+ set_routing_links(dev, state);
671+ crtc_set_mode(dev, state);
672+}
673+EXPORT_SYMBOL(drm_atomic_helper_commit_pre_planes);
674+
675+/**
676+ * drm_atomic_helper_commit_post_planes - modeset commit after plane updates
677+ * @dev: DRM device
678+ * @old_state: atomic state object with old state structures
679+ *
680+ * This function commits the modeset changes that need to be committed after
681+ * updating planes: It enables all the outputs with the new configuration which
682+ * had to be turned off for the update.
683+ */
684+void drm_atomic_helper_commit_post_planes(struct drm_device *dev,
685+ struct drm_atomic_state *old_state)
686+{
687+ int ncrtcs = old_state->dev->mode_config.num_crtc;
688+ int i;
689+
690+ for (i = 0; i < ncrtcs; i++) {
691+ struct drm_crtc_helper_funcs *funcs;
692+ struct drm_crtc *crtc;
693+
694+ crtc = old_state->crtcs[i];
695+
696+ /* Need to filter out CRTCs where only planes change. */
697+ if (!crtc || !crtc->state->mode_changed)
698+ continue;
699+
700+ funcs = crtc->helper_private;
701+
702+ if (crtc->state->enable)
703+ funcs->commit(crtc);
704+ }
705+
706+ for (i = 0; i < old_state->num_connector; i++) {
707+ struct drm_connector *connector;
708+ struct drm_encoder_helper_funcs *funcs;
709+ struct drm_encoder *encoder;
710+
711+ connector = old_state->connectors[i];
712+
713+ if (!connector || !connector->state->best_encoder)
714+ continue;
715+
716+ encoder = connector->state->best_encoder;
717+ funcs = encoder->helper_private;
718+
719+ /*
720+ * Each encoder has at most one connector (since we always steal
721+ * it away), so we won't call call enable hooks twice.
722+ */
723+ if (encoder->bridge)
724+ encoder->bridge->funcs->pre_enable(encoder->bridge);
725+
726+ funcs->commit(encoder);
727+
728+ if (encoder->bridge)
729+ encoder->bridge->funcs->enable(encoder->bridge);
730+ }
731+}
732+EXPORT_SYMBOL(drm_atomic_helper_commit_post_planes);
733+
734+static void wait_for_fences(struct drm_device *dev,
735+ struct drm_atomic_state *state)
736+{
737+ int nplanes = dev->mode_config.num_total_plane;
738+ int i;
739+
740+ for (i = 0; i < nplanes; i++) {
741+ struct drm_plane *plane = state->planes[i];
742+
743+ if (!plane || !plane->state->fence)
744+ continue;
745+
746+ WARN_ON(!plane->state->fb);
747+
748+ fence_wait(plane->state->fence, false);
749+ fence_put(plane->state->fence);
750+ plane->state->fence = NULL;
751+ }
752+}
753+
754+static bool framebuffer_changed(struct drm_device *dev,
755+ struct drm_atomic_state *old_state,
756+ struct drm_crtc *crtc)
757+{
758+ struct drm_plane *plane;
759+ struct drm_plane_state *old_plane_state;
760+ int nplanes = old_state->dev->mode_config.num_total_plane;
761+ int i;
762+
763+ for (i = 0; i < nplanes; i++) {
764+ plane = old_state->planes[i];
765+ old_plane_state = old_state->plane_states[i];
766+
767+ if (!plane)
768+ continue;
769+
770+ if (plane->state->crtc != crtc &&
771+ old_plane_state->crtc != crtc)
772+ continue;
773+
774+ if (plane->state->fb != old_plane_state->fb)
775+ return true;
776+ }
777+
778+ return false;
779+}
780+
781+/**
782+ * drm_atomic_helper_wait_for_vblanks - wait for vblank on crtcs
783+ * @dev: DRM device
784+ * @old_state: atomic state object with old state structures
785+ *
786+ * Helper to, after atomic commit, wait for vblanks on all effected
787+ * crtcs (ie. before cleaning up old framebuffers using
788+ * drm_atomic_helper_cleanup_planes()). It will only wait on crtcs where the
789+ * framebuffers have actually changed to optimize for the legacy cursor and
790+ * plane update use-case.
791+ */
792+void
793+drm_atomic_helper_wait_for_vblanks(struct drm_device *dev,
794+ struct drm_atomic_state *old_state)
795+{
796+ struct drm_crtc *crtc;
797+ struct drm_crtc_state *old_crtc_state;
798+ int ncrtcs = old_state->dev->mode_config.num_crtc;
799+ int i, ret;
800+
801+ for (i = 0; i < ncrtcs; i++) {
802+ crtc = old_state->crtcs[i];
803+ old_crtc_state = old_state->crtc_states[i];
804+
805+ if (!crtc)
806+ continue;
807+
808+ /* No one cares about the old state, so abuse it for tracking
809+ * and store whether we hold a vblank reference (and should do a
810+ * vblank wait) in the ->enable boolean. */
811+ old_crtc_state->enable = false;
812+
813+ if (!crtc->state->enable)
814+ continue;
815+
816+ if (!framebuffer_changed(dev, old_state, crtc))
817+ continue;
818+
819+ ret = drm_crtc_vblank_get(crtc);
820+ if (ret != 0)
821+ continue;
822+
823+ old_crtc_state->enable = true;
824+ old_crtc_state->last_vblank_count = drm_vblank_count(dev, i);
825+ }
826+
827+ for (i = 0; i < ncrtcs; i++) {
828+ crtc = old_state->crtcs[i];
829+ old_crtc_state = old_state->crtc_states[i];
830+
831+ if (!crtc || !old_crtc_state->enable)
832+ continue;
833+
834+ ret = wait_event_timeout(dev->vblank[i].queue,
835+ old_crtc_state->last_vblank_count !=
836+ drm_vblank_count(dev, i),
837+ msecs_to_jiffies(50));
838+
839+ drm_crtc_vblank_put(crtc);
840+ }
841+}
842+EXPORT_SYMBOL(drm_atomic_helper_wait_for_vblanks);
843+
844+/**
845+ * drm_atomic_helper_commit - commit validated state object
846+ * @dev: DRM device
847+ * @state: the driver state object
848+ * @async: asynchronous commit
849+ *
850+ * This function commits a with drm_atomic_helper_check() pre-validated state
851+ * object. This can still fail when e.g. the framebuffer reservation fails. For
852+ * now this doesn't implement asynchronous commits.
853+ *
854+ * RETURNS
855+ * Zero for success or -errno.
856+ */
857+int drm_atomic_helper_commit(struct drm_device *dev,
858+ struct drm_atomic_state *state,
859+ bool async)
860+{
861+ int ret;
862+
863+ if (async)
864+ return -EBUSY;
865+
866+ ret = drm_atomic_helper_prepare_planes(dev, state);
867+ if (ret)
868+ return ret;
869+
870+ /*
871+ * This is the point of no return - everything below never fails except
872+ * when the hw goes bonghits. Which means we can commit the new state on
873+ * the software side now.
874+ */
875+
876+ drm_atomic_helper_swap_state(dev, state);
877+
878+ /*
879+ * Everything below can be run asynchronously without the need to grab
880+ * any modeset locks at all under one conditions: It must be guaranteed
881+ * that the asynchronous work has either been cancelled (if the driver
882+ * supports it, which at least requires that the framebuffers get
883+ * cleaned up with drm_atomic_helper_cleanup_planes()) or completed
884+ * before the new state gets committed on the software side with
885+ * drm_atomic_helper_swap_state().
886+ *
887+ * This scheme allows new atomic state updates to be prepared and
888+ * checked in parallel to the asynchronous completion of the previous
889+ * update. Which is important since compositors need to figure out the
890+ * composition of the next frame right after having submitted the
891+ * current layout.
892+ */
893+
894+ wait_for_fences(dev, state);
895+
896+ drm_atomic_helper_commit_pre_planes(dev, state);
897+
898+ drm_atomic_helper_commit_planes(dev, state);
899+
900+ drm_atomic_helper_commit_post_planes(dev, state);
901+
902+ drm_atomic_helper_wait_for_vblanks(dev, state);
903+
904+ drm_atomic_helper_cleanup_planes(dev, state);
905+
906+ drm_atomic_state_free(state);
907+
908+ return 0;
909+}
910+EXPORT_SYMBOL(drm_atomic_helper_commit);
911+
912+/**
913+ * DOC: implementing async commit
914+ *
915+ * For now the atomic helpers don't support async commit directly. If there is
916+ * real need it could be added though, using the dma-buf fence infrastructure
917+ * for generic synchronization with outstanding rendering.
918+ *
919+ * For now drivers have to implement async commit themselves, with the following
920+ * sequence being the recommended one:
921+ *
922+ * 1. Run drm_atomic_helper_prepare_planes() first. This is the only function
923+ * which commit needs to call which can fail, so we want to run it first and
924+ * synchronously.
925+ *
926+ * 2. Synchronize with any outstanding asynchronous commit worker threads which
927+ * might be affected the new state update. This can be done by either cancelling
928+ * or flushing the work items, depending upon whether the driver can deal with
929+ * cancelled updates. Note that it is important to ensure that the framebuffer
930+ * cleanup is still done when cancelling.
931+ *
932+ * For sufficient parallelism it is recommended to have a work item per crtc
933+ * (for updates which don't touch global state) and a global one. Then we only
934+ * need to synchronize with the crtc work items for changed crtcs and the global
935+ * work item, which allows nice concurrent updates on disjoint sets of crtcs.
936+ *
937+ * 3. The software state is updated synchronously with
938+ * drm_atomic_helper_swap_state. Doing this under the protection of all modeset
939+ * locks means concurrent callers never see inconsistent state. And doing this
940+ * while it's guaranteed that no relevant async worker runs means that async
941+ * workers do not need grab any locks. Actually they must not grab locks, for
942+ * otherwise the work flushing will deadlock.
943+ *
944+ * 4. Schedule a work item to do all subsequent steps, using the split-out
945+ * commit helpers: a) pre-plane commit b) plane commit c) post-plane commit and
946+ * then cleaning up the framebuffers after the old framebuffer is no longer
947+ * being displayed.
948+ */
949+
950+/**
951+ * drm_atomic_helper_prepare_planes - prepare plane resources after commit
952+ * @dev: DRM device
953+ * @state: atomic state object with old state structures
954+ *
955+ * This function prepares plane state, specifically framebuffers, for the new
956+ * configuration. If any failure is encountered this function will call
957+ * ->cleanup_fb on any already successfully prepared framebuffer.
958+ *
959+ * Returns:
960+ * 0 on success, negative error code on failure.
961+ */
962+int drm_atomic_helper_prepare_planes(struct drm_device *dev,
963+ struct drm_atomic_state *state)
964+{
965+ int nplanes = dev->mode_config.num_total_plane;
966+ int ret, i;
967+
968+ for (i = 0; i < nplanes; i++) {
969+ struct drm_plane_helper_funcs *funcs;
970+ struct drm_plane *plane = state->planes[i];
971+ struct drm_framebuffer *fb;
972+
973+ if (!plane)
974+ continue;
975+
976+ funcs = plane->helper_private;
977+
978+ fb = state->plane_states[i]->fb;
979+
980+ if (fb && funcs->prepare_fb) {
981+ ret = funcs->prepare_fb(plane, fb);
982+ if (ret)
983+ goto fail;
984+ }
985+ }
986+
987+ return 0;
988+
989+fail:
990+ for (i--; i >= 0; i--) {
991+ struct drm_plane_helper_funcs *funcs;
992+ struct drm_plane *plane = state->planes[i];
993+ struct drm_framebuffer *fb;
994+
995+ if (!plane)
996+ continue;
997+
998+ funcs = plane->helper_private;
999+
1000+ fb = state->plane_states[i]->fb;
1001+
1002+ if (fb && funcs->cleanup_fb)
1003+ funcs->cleanup_fb(plane, fb);
1004+
1005+ }
1006+
1007+ return ret;
1008+}
1009+EXPORT_SYMBOL(drm_atomic_helper_prepare_planes);
1010+
1011+/**
1012+ * drm_atomic_helper_commit_planes - commit plane state
1013+ * @dev: DRM device
1014+ * @old_state: atomic state object with old state structures
1015+ *
1016+ * This function commits the new plane state using the plane and atomic helper
1017+ * functions for planes and crtcs. It assumes that the atomic state has already
1018+ * been pushed into the relevant object state pointers, since this step can no
1019+ * longer fail.
1020+ *
1021+ * It still requires the global state object @old_state to know which planes and
1022+ * crtcs need to be updated though.
1023+ */
1024+void drm_atomic_helper_commit_planes(struct drm_device *dev,
1025+ struct drm_atomic_state *old_state)
1026+{
1027+ int nplanes = dev->mode_config.num_total_plane;
1028+ int ncrtcs = dev->mode_config.num_crtc;
1029+ int i;
1030+
1031+ for (i = 0; i < ncrtcs; i++) {
1032+ struct drm_crtc_helper_funcs *funcs;
1033+ struct drm_crtc *crtc = old_state->crtcs[i];
1034+
1035+ if (!crtc)
1036+ continue;
1037+
1038+ funcs = crtc->helper_private;
1039+
1040+ if (!funcs || !funcs->atomic_begin)
1041+ continue;
1042+
1043+ funcs->atomic_begin(crtc);
1044+ }
1045+
1046+ for (i = 0; i < nplanes; i++) {
1047+ struct drm_plane_helper_funcs *funcs;
1048+ struct drm_plane *plane = old_state->planes[i];
1049+ struct drm_plane_state *old_plane_state;
1050+
1051+ if (!plane)
1052+ continue;
1053+
1054+ funcs = plane->helper_private;
1055+
1056+ if (!funcs || !funcs->atomic_update)
1057+ continue;
1058+
1059+ old_plane_state = old_state->plane_states[i];
1060+
1061+ funcs->atomic_update(plane, old_plane_state);
1062+ }
1063+
1064+ for (i = 0; i < ncrtcs; i++) {
1065+ struct drm_crtc_helper_funcs *funcs;
1066+ struct drm_crtc *crtc = old_state->crtcs[i];
1067+
1068+ if (!crtc)
1069+ continue;
1070+
1071+ funcs = crtc->helper_private;
1072+
1073+ if (!funcs || !funcs->atomic_flush)
1074+ continue;
1075+
1076+ funcs->atomic_flush(crtc);
1077+ }
1078+}
1079+EXPORT_SYMBOL(drm_atomic_helper_commit_planes);
1080+
1081+/**
1082+ * drm_atomic_helper_cleanup_planes - cleanup plane resources after commit
1083+ * @dev: DRM device
1084+ * @old_state: atomic state object with old state structures
1085+ *
1086+ * This function cleans up plane state, specifically framebuffers, from the old
1087+ * configuration. Hence the old configuration must be perserved in @old_state to
1088+ * be able to call this function.
1089+ *
1090+ * This function must also be called on the new state when the atomic update
1091+ * fails at any point after calling drm_atomic_helper_prepare_planes().
1092+ */
1093+void drm_atomic_helper_cleanup_planes(struct drm_device *dev,
1094+ struct drm_atomic_state *old_state)
1095+{
1096+ int nplanes = dev->mode_config.num_total_plane;
1097+ int i;
1098+
1099+ for (i = 0; i < nplanes; i++) {
1100+ struct drm_plane_helper_funcs *funcs;
1101+ struct drm_plane *plane = old_state->planes[i];
1102+ struct drm_framebuffer *old_fb;
1103+
1104+ if (!plane)
1105+ continue;
1106+
1107+ funcs = plane->helper_private;
1108+
1109+ old_fb = old_state->plane_states[i]->fb;
1110+
1111+ if (old_fb && funcs->cleanup_fb)
1112+ funcs->cleanup_fb(plane, old_fb);
1113+ }
1114+}
1115+EXPORT_SYMBOL(drm_atomic_helper_cleanup_planes);
1116+
1117+/**
1118+ * drm_atomic_helper_swap_state - store atomic state into current sw state
1119+ * @dev: DRM device
1120+ * @state: atomic state
1121+ *
1122+ * This function stores the atomic state into the current state pointers in all
1123+ * driver objects. It should be called after all failing steps have been done
1124+ * and succeeded, but before the actual hardware state is committed.
1125+ *
1126+ * For cleanup and error recovery the current state for all changed objects will
1127+ * be swaped into @state.
1128+ *
1129+ * With that sequence it fits perfectly into the plane prepare/cleanup sequence:
1130+ *
1131+ * 1. Call drm_atomic_helper_prepare_planes() with the staged atomic state.
1132+ *
1133+ * 2. Do any other steps that might fail.
1134+ *
1135+ * 3. Put the staged state into the current state pointers with this function.
1136+ *
1137+ * 4. Actually commit the hardware state.
1138+ *
1139+ * 5. Call drm_atomic_helper_cleanup_planes with @state, which since step 3
1140+ * contains the old state. Also do any other cleanup required with that state.
1141+ */
1142+void drm_atomic_helper_swap_state(struct drm_device *dev,
1143+ struct drm_atomic_state *state)
1144+{
1145+ int i;
1146+
1147+ for (i = 0; i < dev->mode_config.num_connector; i++) {
1148+ struct drm_connector *connector = state->connectors[i];
1149+
1150+ if (!connector)
1151+ continue;
1152+
1153+ connector->state->state = state;
1154+ swap(state->connector_states[i], connector->state);
1155+ connector->state->state = NULL;
1156+ }
1157+
1158+ for (i = 0; i < dev->mode_config.num_crtc; i++) {
1159+ struct drm_crtc *crtc = state->crtcs[i];
1160+
1161+ if (!crtc)
1162+ continue;
1163+
1164+ crtc->state->state = state;
1165+ swap(state->crtc_states[i], crtc->state);
1166+ crtc->state->state = NULL;
1167+ }
1168+
1169+ for (i = 0; i < dev->mode_config.num_total_plane; i++) {
1170+ struct drm_plane *plane = state->planes[i];
1171+
1172+ if (!plane)
1173+ continue;
1174+
1175+ plane->state->state = state;
1176+ swap(state->plane_states[i], plane->state);
1177+ plane->state->state = NULL;
1178+ }
1179+}
1180+EXPORT_SYMBOL(drm_atomic_helper_swap_state);
1181+
1182+/**
1183+ * drm_atomic_helper_update_plane - Helper for primary plane update using atomic
1184+ * @plane: plane object to update
1185+ * @crtc: owning CRTC of owning plane
1186+ * @fb: framebuffer to flip onto plane
1187+ * @crtc_x: x offset of primary plane on crtc
1188+ * @crtc_y: y offset of primary plane on crtc
1189+ * @crtc_w: width of primary plane rectangle on crtc
1190+ * @crtc_h: height of primary plane rectangle on crtc
1191+ * @src_x: x offset of @fb for panning
1192+ * @src_y: y offset of @fb for panning
1193+ * @src_w: width of source rectangle in @fb
1194+ * @src_h: height of source rectangle in @fb
1195+ *
1196+ * Provides a default plane update handler using the atomic driver interface.
1197+ *
1198+ * RETURNS:
1199+ * Zero on success, error code on failure
1200+ */
1201+int drm_atomic_helper_update_plane(struct drm_plane *plane,
1202+ struct drm_crtc *crtc,
1203+ struct drm_framebuffer *fb,
1204+ int crtc_x, int crtc_y,
1205+ unsigned int crtc_w, unsigned int crtc_h,
1206+ uint32_t src_x, uint32_t src_y,
1207+ uint32_t src_w, uint32_t src_h)
1208+{
1209+ struct drm_atomic_state *state;
1210+ struct drm_plane_state *plane_state;
1211+ int ret = 0;
1212+
1213+ state = drm_atomic_state_alloc(plane->dev);
1214+ if (!state)
1215+ return -ENOMEM;
1216+
1217+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1218+retry:
1219+ plane_state = drm_atomic_get_plane_state(state, plane);
1220+ if (IS_ERR(plane_state)) {
1221+ ret = PTR_ERR(plane_state);
1222+ goto fail;
1223+ }
1224+
1225+ ret = drm_atomic_set_crtc_for_plane(state, plane, crtc);
1226+ if (ret != 0)
1227+ goto fail;
1228+ drm_atomic_set_fb_for_plane(plane_state, fb);
1229+ plane_state->crtc_x = crtc_x;
1230+ plane_state->crtc_y = crtc_y;
1231+ plane_state->crtc_h = crtc_h;
1232+ plane_state->crtc_w = crtc_w;
1233+ plane_state->src_x = src_x;
1234+ plane_state->src_y = src_y;
1235+ plane_state->src_h = src_h;
1236+ plane_state->src_w = src_w;
1237+
1238+ ret = drm_atomic_commit(state);
1239+ if (ret != 0)
1240+ goto fail;
1241+
1242+ /* Driver takes ownership of state on successful commit. */
1243+ return 0;
1244+fail:
1245+ if (ret == -EDEADLK)
1246+ goto backoff;
1247+
1248+ drm_atomic_state_free(state);
1249+
1250+ return ret;
1251+backoff:
1252+ drm_atomic_state_clear(state);
1253+ drm_atomic_legacy_backoff(state);
1254+
1255+ /*
1256+ * Someone might have exchanged the framebuffer while we dropped locks
1257+ * in the backoff code. We need to fix up the fb refcount tracking the
1258+ * core does for us.
1259+ */
1260+ plane->old_fb = plane->fb;
1261+
1262+ goto retry;
1263+}
1264+EXPORT_SYMBOL(drm_atomic_helper_update_plane);
1265+
1266+/**
1267+ * drm_atomic_helper_disable_plane - Helper for primary plane disable using * atomic
1268+ * @plane: plane to disable
1269+ *
1270+ * Provides a default plane disable handler using the atomic driver interface.
1271+ *
1272+ * RETURNS:
1273+ * Zero on success, error code on failure
1274+ */
1275+int drm_atomic_helper_disable_plane(struct drm_plane *plane)
1276+{
1277+ struct drm_atomic_state *state;
1278+ struct drm_plane_state *plane_state;
1279+ int ret = 0;
1280+
1281+ /*
1282+ * FIXME: Without plane->crtc set we can't get at the implicit legacy
1283+ * acquire context. The real fix will be to wire the acquire ctx through
1284+ * everywhere we need it, but meanwhile prevent chaos by just skipping
1285+ * this noop. The critical case is the cursor ioctls which a) only grab
1286+ * crtc/cursor-plane locks (so we need the crtc to get at the right
1287+ * acquire context) and b) can try to disable the plane multiple times.
1288+ */
1289+ if (!plane->crtc)
1290+ return 0;
1291+
1292+ state = drm_atomic_state_alloc(plane->dev);
1293+ if (!state)
1294+ return -ENOMEM;
1295+
1296+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(plane->crtc);
1297+retry:
1298+ plane_state = drm_atomic_get_plane_state(state, plane);
1299+ if (IS_ERR(plane_state)) {
1300+ ret = PTR_ERR(plane_state);
1301+ goto fail;
1302+ }
1303+
1304+ ret = drm_atomic_set_crtc_for_plane(state, plane, NULL);
1305+ if (ret != 0)
1306+ goto fail;
1307+ drm_atomic_set_fb_for_plane(plane_state, NULL);
1308+ plane_state->crtc_x = 0;
1309+ plane_state->crtc_y = 0;
1310+ plane_state->crtc_h = 0;
1311+ plane_state->crtc_w = 0;
1312+ plane_state->src_x = 0;
1313+ plane_state->src_y = 0;
1314+ plane_state->src_h = 0;
1315+ plane_state->src_w = 0;
1316+
1317+ ret = drm_atomic_commit(state);
1318+ if (ret != 0)
1319+ goto fail;
1320+
1321+ /* Driver takes ownership of state on successful commit. */
1322+ return 0;
1323+fail:
1324+ if (ret == -EDEADLK)
1325+ goto backoff;
1326+
1327+ drm_atomic_state_free(state);
1328+
1329+ return ret;
1330+backoff:
1331+ drm_atomic_state_clear(state);
1332+ drm_atomic_legacy_backoff(state);
1333+
1334+ /*
1335+ * Someone might have exchanged the framebuffer while we dropped locks
1336+ * in the backoff code. We need to fix up the fb refcount tracking the
1337+ * core does for us.
1338+ */
1339+ plane->old_fb = plane->fb;
1340+
1341+ goto retry;
1342+}
1343+EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
1344+
1345+static int update_output_state(struct drm_atomic_state *state,
1346+ struct drm_mode_set *set)
1347+{
1348+ struct drm_device *dev = set->crtc->dev;
1349+ struct drm_connector_state *conn_state;
1350+ int ncrtcs = state->dev->mode_config.num_crtc;
1351+ int ret, i, j;
1352+
1353+ ret = drm_modeset_lock(&dev->mode_config.connection_mutex,
1354+ state->acquire_ctx);
1355+ if (ret)
1356+ return ret;
1357+
1358+ /* First grab all affected connector/crtc states. */
1359+ for (i = 0; i < set->num_connectors; i++) {
1360+ conn_state = drm_atomic_get_connector_state(state,
1361+ set->connectors[i]);
1362+ if (IS_ERR(conn_state))
1363+ return PTR_ERR(conn_state);
1364+ }
1365+
1366+ for (i = 0; i < ncrtcs; i++) {
1367+ struct drm_crtc *crtc = state->crtcs[i];
1368+
1369+ if (!crtc)
1370+ continue;
1371+
1372+ ret = drm_atomic_add_affected_connectors(state, crtc);
1373+ if (ret)
1374+ return ret;
1375+ }
1376+
1377+ /* Then recompute connector->crtc links and crtc enabling state. */
1378+ for (i = 0; i < state->num_connector; i++) {
1379+ struct drm_connector *connector;
1380+
1381+ connector = state->connectors[i];
1382+ conn_state = state->connector_states[i];
1383+
1384+ if (!connector)
1385+ continue;
1386+
1387+ if (conn_state->crtc == set->crtc) {
1388+ ret = drm_atomic_set_crtc_for_connector(conn_state,
1389+ NULL);
1390+ if (ret)
1391+ return ret;
1392+ }
1393+
1394+ for (j = 0; j < set->num_connectors; j++) {
1395+ if (set->connectors[j] == connector) {
1396+ ret = drm_atomic_set_crtc_for_connector(conn_state,
1397+ set->crtc);
1398+ if (ret)
1399+ return ret;
1400+ break;
1401+ }
1402+ }
1403+ }
1404+
1405+ for (i = 0; i < ncrtcs; i++) {
1406+ struct drm_crtc *crtc = state->crtcs[i];
1407+ struct drm_crtc_state *crtc_state = state->crtc_states[i];
1408+
1409+ if (!crtc)
1410+ continue;
1411+
1412+ /* Don't update ->enable for the CRTC in the set_config request,
1413+ * since a mismatch would indicate a bug in the upper layers.
1414+ * The actual modeset code later on will catch any
1415+ * inconsistencies here. */
1416+ if (crtc == set->crtc)
1417+ continue;
1418+
1419+ crtc_state->enable =
1420+ drm_atomic_connectors_for_crtc(state, crtc);
1421+ }
1422+
1423+ return 0;
1424+}
1425+
1426+/**
1427+ * drm_atomic_helper_set_config - set a new config from userspace
1428+ * @set: mode set configuration
1429+ *
1430+ * Provides a default crtc set_config handler using the atomic driver interface.
1431+ *
1432+ * Returns:
1433+ * Returns 0 on success, negative errno numbers on failure.
1434+ */
1435+int drm_atomic_helper_set_config(struct drm_mode_set *set)
1436+{
1437+ struct drm_atomic_state *state;
1438+ struct drm_crtc *crtc = set->crtc;
1439+ struct drm_crtc_state *crtc_state;
1440+ struct drm_plane_state *primary_state;
1441+ int ret = 0;
1442+
1443+ state = drm_atomic_state_alloc(crtc->dev);
1444+ if (!state)
1445+ return -ENOMEM;
1446+
1447+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1448+retry:
1449+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
1450+ if (IS_ERR(crtc_state)) {
1451+ ret = PTR_ERR(crtc_state);
1452+ goto fail;
1453+ }
1454+
1455+ primary_state = drm_atomic_get_plane_state(state, crtc->primary);
1456+ if (IS_ERR(primary_state)) {
1457+ ret = PTR_ERR(primary_state);
1458+ goto fail;
1459+ }
1460+
1461+ if (!set->mode) {
1462+ WARN_ON(set->fb);
1463+ WARN_ON(set->num_connectors);
1464+
1465+ crtc_state->enable = false;
1466+
1467+ ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, NULL);
1468+ if (ret != 0)
1469+ goto fail;
1470+
1471+ drm_atomic_set_fb_for_plane(primary_state, NULL);
1472+
1473+ goto commit;
1474+ }
1475+
1476+ WARN_ON(!set->fb);
1477+ WARN_ON(!set->num_connectors);
1478+
1479+ crtc_state->enable = true;
1480+ drm_mode_copy(&crtc_state->mode, set->mode);
1481+
1482+ ret = drm_atomic_set_crtc_for_plane(state, crtc->primary, crtc);
1483+ if (ret != 0)
1484+ goto fail;
1485+ drm_atomic_set_fb_for_plane(primary_state, set->fb);
1486+ primary_state->crtc_x = 0;
1487+ primary_state->crtc_y = 0;
1488+ primary_state->crtc_h = set->mode->vdisplay;
1489+ primary_state->crtc_w = set->mode->hdisplay;
1490+ primary_state->src_x = set->x << 16;
1491+ primary_state->src_y = set->y << 16;
1492+ primary_state->src_h = set->mode->vdisplay << 16;
1493+ primary_state->src_w = set->mode->hdisplay << 16;
1494+
1495+commit:
1496+ ret = update_output_state(state, set);
1497+ if (ret)
1498+ goto fail;
1499+
1500+ ret = drm_atomic_commit(state);
1501+ if (ret != 0)
1502+ goto fail;
1503+
1504+ /* Driver takes ownership of state on successful commit. */
1505+ return 0;
1506+fail:
1507+ if (ret == -EDEADLK)
1508+ goto backoff;
1509+
1510+ drm_atomic_state_free(state);
1511+
1512+ return ret;
1513+backoff:
1514+ drm_atomic_state_clear(state);
1515+ drm_atomic_legacy_backoff(state);
1516+
1517+ /*
1518+ * Someone might have exchanged the framebuffer while we dropped locks
1519+ * in the backoff code. We need to fix up the fb refcount tracking the
1520+ * core does for us.
1521+ */
1522+ crtc->primary->old_fb = crtc->primary->fb;
1523+
1524+ goto retry;
1525+}
1526+EXPORT_SYMBOL(drm_atomic_helper_set_config);
1527+
1528+/**
1529+ * drm_atomic_helper_crtc_set_property - helper for crtc prorties
1530+ * @crtc: DRM crtc
1531+ * @property: DRM property
1532+ * @val: value of property
1533+ *
1534+ * Provides a default plane disablle handler using the atomic driver interface.
1535+ *
1536+ * RETURNS:
1537+ * Zero on success, error code on failure
1538+ */
1539+int
1540+drm_atomic_helper_crtc_set_property(struct drm_crtc *crtc,
1541+ struct drm_property *property,
1542+ uint64_t val)
1543+{
1544+ struct drm_atomic_state *state;
1545+ struct drm_crtc_state *crtc_state;
1546+ int ret = 0;
1547+
1548+ state = drm_atomic_state_alloc(crtc->dev);
1549+ if (!state)
1550+ return -ENOMEM;
1551+
1552+ /* ->set_property is always called with all locks held. */
1553+ state->acquire_ctx = crtc->dev->mode_config.acquire_ctx;
1554+retry:
1555+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
1556+ if (IS_ERR(crtc_state)) {
1557+ ret = PTR_ERR(crtc_state);
1558+ goto fail;
1559+ }
1560+
1561+ ret = crtc->funcs->atomic_set_property(crtc, crtc_state,
1562+ property, val);
1563+ if (ret)
1564+ goto fail;
1565+
1566+ ret = drm_atomic_commit(state);
1567+ if (ret != 0)
1568+ goto fail;
1569+
1570+ /* Driver takes ownership of state on successful commit. */
1571+ return 0;
1572+fail:
1573+ if (ret == -EDEADLK)
1574+ goto backoff;
1575+
1576+ drm_atomic_state_free(state);
1577+
1578+ return ret;
1579+backoff:
1580+ drm_atomic_state_clear(state);
1581+ drm_atomic_legacy_backoff(state);
1582+
1583+ goto retry;
1584+}
1585+EXPORT_SYMBOL(drm_atomic_helper_crtc_set_property);
1586+
1587+/**
1588+ * drm_atomic_helper_plane_set_property - helper for plane prorties
1589+ * @plane: DRM plane
1590+ * @property: DRM property
1591+ * @val: value of property
1592+ *
1593+ * Provides a default plane disable handler using the atomic driver interface.
1594+ *
1595+ * RETURNS:
1596+ * Zero on success, error code on failure
1597+ */
1598+int
1599+drm_atomic_helper_plane_set_property(struct drm_plane *plane,
1600+ struct drm_property *property,
1601+ uint64_t val)
1602+{
1603+ struct drm_atomic_state *state;
1604+ struct drm_plane_state *plane_state;
1605+ int ret = 0;
1606+
1607+ state = drm_atomic_state_alloc(plane->dev);
1608+ if (!state)
1609+ return -ENOMEM;
1610+
1611+ /* ->set_property is always called with all locks held. */
1612+ state->acquire_ctx = plane->dev->mode_config.acquire_ctx;
1613+retry:
1614+ plane_state = drm_atomic_get_plane_state(state, plane);
1615+ if (IS_ERR(plane_state)) {
1616+ ret = PTR_ERR(plane_state);
1617+ goto fail;
1618+ }
1619+
1620+ ret = plane->funcs->atomic_set_property(plane, plane_state,
1621+ property, val);
1622+ if (ret)
1623+ goto fail;
1624+
1625+ ret = drm_atomic_commit(state);
1626+ if (ret != 0)
1627+ goto fail;
1628+
1629+ /* Driver takes ownership of state on successful commit. */
1630+ return 0;
1631+fail:
1632+ if (ret == -EDEADLK)
1633+ goto backoff;
1634+
1635+ drm_atomic_state_free(state);
1636+
1637+ return ret;
1638+backoff:
1639+ drm_atomic_state_clear(state);
1640+ drm_atomic_legacy_backoff(state);
1641+
1642+ goto retry;
1643+}
1644+EXPORT_SYMBOL(drm_atomic_helper_plane_set_property);
1645+
1646+/**
1647+ * drm_atomic_helper_connector_set_property - helper for connector prorties
1648+ * @connector: DRM connector
1649+ * @property: DRM property
1650+ * @val: value of property
1651+ *
1652+ * Provides a default plane disablle handler using the atomic driver interface.
1653+ *
1654+ * RETURNS:
1655+ * Zero on success, error code on failure
1656+ */
1657+int
1658+drm_atomic_helper_connector_set_property(struct drm_connector *connector,
1659+ struct drm_property *property,
1660+ uint64_t val)
1661+{
1662+ struct drm_atomic_state *state;
1663+ struct drm_connector_state *connector_state;
1664+ int ret = 0;
1665+
1666+ state = drm_atomic_state_alloc(connector->dev);
1667+ if (!state)
1668+ return -ENOMEM;
1669+
1670+ /* ->set_property is always called with all locks held. */
1671+ state->acquire_ctx = connector->dev->mode_config.acquire_ctx;
1672+retry:
1673+ connector_state = drm_atomic_get_connector_state(state, connector);
1674+ if (IS_ERR(connector_state)) {
1675+ ret = PTR_ERR(connector_state);
1676+ goto fail;
1677+ }
1678+
1679+ ret = connector->funcs->atomic_set_property(connector, connector_state,
1680+ property, val);
1681+ if (ret)
1682+ goto fail;
1683+
1684+ ret = drm_atomic_commit(state);
1685+ if (ret != 0)
1686+ goto fail;
1687+
1688+ /* Driver takes ownership of state on successful commit. */
1689+ return 0;
1690+fail:
1691+ if (ret == -EDEADLK)
1692+ goto backoff;
1693+
1694+ drm_atomic_state_free(state);
1695+
1696+ return ret;
1697+backoff:
1698+ drm_atomic_state_clear(state);
1699+ drm_atomic_legacy_backoff(state);
1700+
1701+ goto retry;
1702+}
1703+EXPORT_SYMBOL(drm_atomic_helper_connector_set_property);
1704+
1705+/**
1706+ * drm_atomic_helper_page_flip - execute a legacy page flip
1707+ * @crtc: DRM crtc
1708+ * @fb: DRM framebuffer
1709+ * @event: optional DRM event to signal upon completion
1710+ * @flags: flip flags for non-vblank sync'ed updates
1711+ *
1712+ * Provides a default page flip implementation using the atomic driver interface.
1713+ *
1714+ * Note that for now so called async page flips (i.e. updates which are not
1715+ * synchronized to vblank) are not supported, since the atomic interfaces have
1716+ * no provisions for this yet.
1717+ *
1718+ * Returns:
1719+ * Returns 0 on success, negative errno numbers on failure.
1720+ */
1721+int drm_atomic_helper_page_flip(struct drm_crtc *crtc,
1722+ struct drm_framebuffer *fb,
1723+ struct drm_pending_vblank_event *event,
1724+ uint32_t flags)
1725+{
1726+ struct drm_plane *plane = crtc->primary;
1727+ struct drm_atomic_state *state;
1728+ struct drm_plane_state *plane_state;
1729+ struct drm_crtc_state *crtc_state;
1730+ int ret = 0;
1731+
1732+ if (flags & DRM_MODE_PAGE_FLIP_ASYNC)
1733+ return -EINVAL;
1734+
1735+ state = drm_atomic_state_alloc(plane->dev);
1736+ if (!state)
1737+ return -ENOMEM;
1738+
1739+ state->acquire_ctx = drm_modeset_legacy_acquire_ctx(crtc);
1740+retry:
1741+ crtc_state = drm_atomic_get_crtc_state(state, crtc);
1742+ if (IS_ERR(crtc_state)) {
1743+ ret = PTR_ERR(crtc_state);
1744+ goto fail;
1745+ }
1746+ crtc_state->event = event;
1747+
1748+ plane_state = drm_atomic_get_plane_state(state, plane);
1749+ if (IS_ERR(plane_state)) {
1750+ ret = PTR_ERR(plane_state);
1751+ goto fail;
1752+ }
1753+
1754+ ret = drm_atomic_set_crtc_for_plane(state, plane, crtc);
1755+ if (ret != 0)
1756+ goto fail;
1757+ drm_atomic_set_fb_for_plane(plane_state, fb);
1758+
1759+ ret = drm_atomic_async_commit(state);
1760+ if (ret != 0)
1761+ goto fail;
1762+
1763+ /* TODO: ->page_flip is the only driver callback where the core
1764+ * doesn't update plane->fb. For now patch it up here. */
1765+ plane->fb = plane->state->fb;
1766+
1767+ /* Driver takes ownership of state on successful async commit. */
1768+ return 0;
1769+fail:
1770+ if (ret == -EDEADLK)
1771+ goto backoff;
1772+
1773+ drm_atomic_state_free(state);
1774+
1775+ return ret;
1776+backoff:
1777+ drm_atomic_state_clear(state);
1778+ drm_atomic_legacy_backoff(state);
1779+
1780+ /*
1781+ * Someone might have exchanged the framebuffer while we dropped locks
1782+ * in the backoff code. We need to fix up the fb refcount tracking the
1783+ * core does for us.
1784+ */
1785+ plane->old_fb = plane->fb;
1786+
1787+ goto retry;
1788+}
1789+EXPORT_SYMBOL(drm_atomic_helper_page_flip);
1790+
1791+/**
1792+ * DOC: atomic state reset and initialization
1793+ *
1794+ * Both the drm core and the atomic helpers assume that there is always the full
1795+ * and correct atomic software state for all connectors, CRTCs and planes
1796+ * available. Which is a bit a problem on driver load and also after system
1797+ * suspend. One way to solve this is to have a hardware state read-out
1798+ * infrastructure which reconstructs the full software state (e.g. the i915
1799+ * driver).
1800+ *
1801+ * The simpler solution is to just reset the software state to everything off,
1802+ * which is easiest to do by calling drm_mode_config_reset(). To facilitate this
1803+ * the atomic helpers provide default reset implementations for all hooks.
1804+ */
1805+
1806+/**
1807+ * drm_atomic_helper_crtc_reset - default ->reset hook for CRTCs
1808+ * @crtc: drm CRTC
1809+ *
1810+ * Resets the atomic state for @crtc by freeing the state pointer (which might
1811+ * be NULL, e.g. at driver load time) and allocating a new empty state object.
1812+ */
1813+void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
1814+{
1815+ kfree(crtc->state);
1816+ crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
1817+}
1818+EXPORT_SYMBOL(drm_atomic_helper_crtc_reset);
1819+
1820+/**
1821+ * drm_atomic_helper_crtc_duplicate_state - default state duplicate hook
1822+ * @crtc: drm CRTC
1823+ *
1824+ * Default CRTC state duplicate hook for drivers which don't have their own
1825+ * subclassed CRTC state structure.
1826+ */
1827+struct drm_crtc_state *
1828+drm_atomic_helper_crtc_duplicate_state(struct drm_crtc *crtc)
1829+{
1830+ struct drm_crtc_state *state;
1831+
1832+ if (WARN_ON(!crtc->state))
1833+ return NULL;
1834+
1835+ state = kmemdup(crtc->state, sizeof(*crtc->state), GFP_KERNEL);
1836+
1837+ if (state) {
1838+ state->mode_changed = false;
1839+ state->planes_changed = false;
1840+ state->event = NULL;
1841+ }
1842+
1843+ return state;
1844+}
1845+EXPORT_SYMBOL(drm_atomic_helper_crtc_duplicate_state);
1846+
1847+/**
1848+ * drm_atomic_helper_crtc_destroy_state - default state destroy hook
1849+ * @crtc: drm CRTC
1850+ * @state: CRTC state object to release
1851+ *
1852+ * Default CRTC state destroy hook for drivers which don't have their own
1853+ * subclassed CRTC state structure.
1854+ */
1855+void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
1856+ struct drm_crtc_state *state)
1857+{
1858+ kfree(state);
1859+}
1860+EXPORT_SYMBOL(drm_atomic_helper_crtc_destroy_state);
1861+
1862+/**
1863+ * drm_atomic_helper_plane_reset - default ->reset hook for planes
1864+ * @plane: drm plane
1865+ *
1866+ * Resets the atomic state for @plane by freeing the state pointer (which might
1867+ * be NULL, e.g. at driver load time) and allocating a new empty state object.
1868+ */
1869+void drm_atomic_helper_plane_reset(struct drm_plane *plane)
1870+{
1871+ if (plane->state && plane->state->fb)
1872+ drm_framebuffer_unreference(plane->state->fb);
1873+
1874+ kfree(plane->state);
1875+ plane->state = kzalloc(sizeof(*plane->state), GFP_KERNEL);
1876+}
1877+EXPORT_SYMBOL(drm_atomic_helper_plane_reset);
1878+
1879+/**
1880+ * drm_atomic_helper_plane_duplicate_state - default state duplicate hook
1881+ * @plane: drm plane
1882+ *
1883+ * Default plane state duplicate hook for drivers which don't have their own
1884+ * subclassed plane state structure.
1885+ */
1886+struct drm_plane_state *
1887+drm_atomic_helper_plane_duplicate_state(struct drm_plane *plane)
1888+{
1889+ struct drm_plane_state *state;
1890+
1891+ if (WARN_ON(!plane->state))
1892+ return NULL;
1893+
1894+ state = kmemdup(plane->state, sizeof(*plane->state), GFP_KERNEL);
1895+
1896+ if (state && state->fb)
1897+ drm_framebuffer_reference(state->fb);
1898+
1899+ return state;
1900+}
1901+EXPORT_SYMBOL(drm_atomic_helper_plane_duplicate_state);
1902+
1903+/**
1904+ * drm_atomic_helper_plane_destroy_state - default state destroy hook
1905+ * @plane: drm plane
1906+ * @state: plane state object to release
1907+ *
1908+ * Default plane state destroy hook for drivers which don't have their own
1909+ * subclassed plane state structure.
1910+ */
1911+void drm_atomic_helper_plane_destroy_state(struct drm_plane *plane,
1912+ struct drm_plane_state *state)
1913+{
1914+ if (state->fb)
1915+ drm_framebuffer_unreference(state->fb);
1916+
1917+ kfree(state);
1918+}
1919+EXPORT_SYMBOL(drm_atomic_helper_plane_destroy_state);
1920+
1921+/**
1922+ * drm_atomic_helper_connector_reset - default ->reset hook for connectors
1923+ * @connector: drm connector
1924+ *
1925+ * Resets the atomic state for @connector by freeing the state pointer (which
1926+ * might be NULL, e.g. at driver load time) and allocating a new empty state
1927+ * object.
1928+ */
1929+void drm_atomic_helper_connector_reset(struct drm_connector *connector)
1930+{
1931+ kfree(connector->state);
1932+ connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
1933+}
1934+EXPORT_SYMBOL(drm_atomic_helper_connector_reset);
1935+
1936+/**
1937+ * drm_atomic_helper_connector_duplicate_state - default state duplicate hook
1938+ * @connector: drm connector
1939+ *
1940+ * Default connector state duplicate hook for drivers which don't have their own
1941+ * subclassed connector state structure.
1942+ */
1943+struct drm_connector_state *
1944+drm_atomic_helper_connector_duplicate_state(struct drm_connector *connector)
1945+{
1946+ if (WARN_ON(!connector->state))
1947+ return NULL;
1948+
1949+ return kmemdup(connector->state, sizeof(*connector->state), GFP_KERNEL);
1950+}
1951+EXPORT_SYMBOL(drm_atomic_helper_connector_duplicate_state);
1952+
1953+/**
1954+ * drm_atomic_helper_connector_destroy_state - default state destroy hook
1955+ * @connector: drm connector
1956+ * @state: connector state object to release
1957+ *
1958+ * Default connector state destroy hook for drivers which don't have their own
1959+ * subclassed connector state structure.
1960+ */
1961+void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
1962+ struct drm_connector_state *state)
1963+{
1964+ kfree(state);
1965+}
1966+EXPORT_SYMBOL(drm_atomic_helper_connector_destroy_state);
drivers/gpu/drm/drm_crtc.c+400−181
@@ -683,7 +683,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, · 682 unmodified lines
683683 drm_modeset_lock_init(&crtc->mutex);
684684 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
685685 if (ret)
686− goto out;
686+ return ret;
687687
688688 crtc->base.properties = &crtc->properties;
689689
@@ -697,9 +697,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, · 7 unmodified lines
697697 if (cursor)
698698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
699699
700− out:
701−
702− return ret;
700+ return 0;
703701 }
704702 EXPORT_SYMBOL(drm_crtc_init_with_planes);
705703
@@ -723,6 +721,12 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) · 17 unmodified lines
723721 drm_mode_object_put(dev, &crtc->base);
724722 list_del(&crtc->head);
725723 dev->mode_config.num_crtc--;
724+
725+ WARN_ON(crtc->state && !crtc->funcs->atomic_destroy_state);
726+ if (crtc->state && crtc->funcs->atomic_destroy_state)
727+ crtc->funcs->atomic_destroy_state(crtc, crtc->state);
728+
729+ memset(crtc, 0, sizeof(*crtc));
726730 }
727731 EXPORT_SYMBOL(drm_crtc_cleanup);
728732
@@ -766,7 +770,6 @@ static void drm_mode_remove(struct drm_connector *connector, · 37 unmodified lines
766770 /**
767771 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
768772 * @connector: connector to quwery
769− * @mode: returned mode
770773 *
771774 * The kernel supports per-connector configration of its consoles through
772775 * use of the video= parameter. This function parses that option and
@@ -870,6 +873,8 @@ int drm_connector_init(struct drm_device *dev, · 97 unmodified lines
870873
871874 drm_connector_get_cmdline_mode(connector);
872875
876+ /* We should add connectors at the end to avoid upsetting the connector
877+ * index too much. */
873878 list_add_tail(&connector->head, &dev->mode_config.connector_list);
874879 dev->mode_config.num_connector++;
875880
@@ -905,6 +910,11 @@ void drm_connector_cleanup(struct drm_connector *connector) · 29 unmodified lines
905910 struct drm_device *dev = connector->dev;
906911 struct drm_display_mode *mode, *t;
907912
913+ if (connector->tile_group) {
914+ drm_mode_put_tile_group(dev, connector->tile_group);
915+ connector->tile_group = NULL;
916+ }
917+
908918 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
909919 drm_mode_remove(connector, mode);
910920
@@ -919,6 +929,13 @@ void drm_connector_cleanup(struct drm_connector *connector) · 8 unmodified lines
919929 connector->name = NULL;
920930 list_del(&connector->head);
921931 dev->mode_config.num_connector--;
932+
933+ WARN_ON(connector->state && !connector->funcs->atomic_destroy_state);
934+ if (connector->state && connector->funcs->atomic_destroy_state)
935+ connector->funcs->atomic_destroy_state(connector,
936+ connector->state);
937+
938+ memset(connector, 0, sizeof(*connector));
922939 }
923940 EXPORT_SYMBOL(drm_connector_cleanup);
924941
@@ -933,6 +950,9 @@ unsigned int drm_connector_index(struct drm_connector *connector) · 8 unmodified lines
933950 {
934951 unsigned int index = 0;
935952 struct drm_connector *tmp;
953+ struct drm_mode_config *config = &connector->dev->mode_config;
954+
955+ WARN_ON(!drm_modeset_is_locked(&config->connection_mutex));
936956
937957 list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) {
938958 if (tmp == connector)
@@ -1057,6 +1077,8 @@ void drm_bridge_cleanup(struct drm_bridge *bridge) · 118 unmodified lines
10571077 list_del(&bridge->head);
10581078 dev->mode_config.num_bridge--;
10591079 drm_modeset_unlock_all(dev);
1080+
1081+ memset(bridge, 0, sizeof(*bridge));
10601082 }
10611083 EXPORT_SYMBOL(drm_bridge_cleanup);
10621084
@@ -1123,10 +1145,11 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) · 60 unmodified lines
11231145 drm_modeset_lock_all(dev);
11241146 drm_mode_object_put(dev, &encoder->base);
11251147 kfree(encoder->name);
1126− encoder->name = NULL;
11271148 list_del(&encoder->head);
11281149 dev->mode_config.num_encoder--;
11291150 drm_modeset_unlock_all(dev);
1151+
1152+ memset(encoder, 0, sizeof(*encoder));
11301153 }
11311154 EXPORT_SYMBOL(drm_encoder_cleanup);
11321155
@@ -1153,11 +1176,11 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, · 20 unmodified lines
11531176 {
11541177 int ret;
11551178
1156− drm_modeset_lock_all(dev);
1157−
11581179 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
11591180 if (ret)
1160− goto out;
1181+ return ret;
1182+
1183+ drm_modeset_lock_init(&plane->mutex);
11611184
11621185 plane->base.properties = &plane->properties;
11631186 plane->dev = dev;
@@ -1167,8 +1190,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, · 3 unmodified lines
11671190 if (!plane->format_types) {
11681191 DRM_DEBUG_KMS("out of memory when allocating plane\n");
11691192 drm_mode_object_put(dev, &plane->base);
1170− ret = -ENOMEM;
1171− goto out;
1193+ return -ENOMEM;
11721194 }
11731195
11741196 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));
@@ -1185,10 +1207,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, · 10 unmodified lines
11851207 dev->mode_config.plane_type_property,
11861208 plane->type);
11871209
1188− out:
1189− drm_modeset_unlock_all(dev);
1190−
1191− return ret;
1210+ return 0;
11921211 }
11931212 EXPORT_SYMBOL(drm_universal_plane_init);
11941213
@@ -1246,6 +1265,12 @@ void drm_plane_cleanup(struct drm_plane *plane) · 51 unmodified lines
12461265 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
12471266 dev->mode_config.num_overlay_plane--;
12481267 drm_modeset_unlock_all(dev);
1268+
1269+ WARN_ON(plane->state && !plane->funcs->atomic_destroy_state);
1270+ if (plane->state && plane->funcs->atomic_destroy_state)
1271+ plane->funcs->atomic_destroy_state(plane, plane->state);
1272+
1273+ memset(plane, 0, sizeof(*plane));
12491274 }
12501275 EXPORT_SYMBOL(drm_plane_cleanup);
12511276
@@ -1328,6 +1353,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) · 76 unmodified lines
13281353 "PATH", 0);
13291354 dev->mode_config.path_property = dev_path;
13301355
1356+ dev->mode_config.tile_property = drm_property_create(dev,
1357+ DRM_MODE_PROP_BLOB |
1358+ DRM_MODE_PROP_IMMUTABLE,
1359+ "TILE", 0);
1360+
13311361 return 0;
13321362 }
13331363
@@ -1388,12 +1418,13 @@ EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); · 54 unmodified lines
13881418 * responsible for allocating a list of format names and passing them to
13891419 * this routine.
13901420 */
1391−int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,
1421+int drm_mode_create_tv_properties(struct drm_device *dev,
1422+ unsigned int num_modes,
13921423 char *modes[])
13931424 {
13941425 struct drm_property *tv_selector;
13951426 struct drm_property *tv_subconnector;
1396− int i;
1427+ unsigned int i;
13971428
13981429 if (dev->mode_config.tv_select_subconnector_property)
13991430 return 0;
@@ -1491,7 +1522,7 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); · 91 unmodified lines
14911522 * connectors.
14921523 *
14931524 * Returns:
1494− * Zero on success, errno on failure.
1525+ * Zero on success, negative errno on failure.
14951526 */
14961527 int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
14971528 {
@@ -1535,6 +1566,30 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev) · 37 unmodified lines
15351566 }
15361567 EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
15371568
1569+/**
1570+ * drm_mode_create_suggested_offset_properties - create suggests offset properties
1571+ * @dev: DRM device
1572+ *
1573+ * Create the the suggested x/y offset property for connectors.
1574+ */
1575+int drm_mode_create_suggested_offset_properties(struct drm_device *dev)
1576+{
1577+ if (dev->mode_config.suggested_x_property && dev->mode_config.suggested_y_property)
1578+ return 0;
1579+
1580+ dev->mode_config.suggested_x_property =
1581+ drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested X", 0, 0xffffffff);
1582+
1583+ dev->mode_config.suggested_y_property =
1584+ drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, "suggested Y", 0, 0xffffffff);
1585+
1586+ if (dev->mode_config.suggested_x_property == NULL ||
1587+ dev->mode_config.suggested_y_property == NULL)
1588+ return -ENOMEM;
1589+ return 0;
1590+}
1591+EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
1592+
15381593 static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
15391594 {
15401595 uint32_t total_objects = 0;
@@ -1651,7 +1706,7 @@ static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, · 110 unmodified lines
16511706 * the caller.
16521707 *
16531708 * Returns:
1654− * Zero on success, errno on failure.
1709+ * Zero on success, negative errno on failure.
16551710 */
16561711 static int drm_crtc_convert_umode(struct drm_display_mode *out,
16571712 const struct drm_mode_modeinfo *in)
@@ -1694,7 +1749,7 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out, · 36 unmodified lines
16941749 * Called by the user via ioctl.
16951750 *
16961751 * Returns:
1697− * Zero on success, errno on failure.
1752+ * Zero on success, negative errno on failure.
16981753 */
16991754 int drm_mode_getresources(struct drm_device *dev, void *data,
17001755 struct drm_file *file_priv)
@@ -1745,7 +1800,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, · 44 unmodified lines
17451800 card_res->count_fbs = fb_count;
17461801 mutex_unlock(&file_priv->fbs_lock);
17471802
1748− drm_modeset_lock_all(dev);
1803+ /* mode_config.mutex protects the connector list against e.g. DP MST
1804+ * connector hot-adding. CRTC/Plane lists are invariant. */
1805+ mutex_lock(&dev->mode_config.mutex);
17491806 if (!drm_is_primary_client(file_priv)) {
17501807
17511808 mode_group = NULL;
@@ -1865,7 +1922,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, · 113 unmodified lines
18651922 card_res->count_connectors, card_res->count_encoders);
18661923
18671924 out:
1868− drm_modeset_unlock_all(dev);
1925+ mutex_unlock(&dev->mode_config.mutex);
18691926 return ret;
18701927 }
18711928
@@ -1880,26 +1937,22 @@ out: · 8 unmodified lines
18801937 * Called by the user via ioctl.
18811938 *
18821939 * Returns:
1883− * Zero on success, errno on failure.
1940+ * Zero on success, negative errno on failure.
18841941 */
18851942 int drm_mode_getcrtc(struct drm_device *dev,
18861943 void *data, struct drm_file *file_priv)
18871944 {
18881945 struct drm_mode_crtc *crtc_resp = data;
18891946 struct drm_crtc *crtc;
1890− int ret = 0;
18911947
18921948 if (!drm_core_check_feature(dev, DRIVER_MODESET))
18931949 return -EINVAL;
18941950
1895− drm_modeset_lock_all(dev);
1896−
18971951 crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
1898− if (!crtc) {
1899− ret = -ENOENT;
1900− goto out;
1901− }
1952+ if (!crtc)
1953+ return -ENOENT;
19021954
1955+ drm_modeset_lock_crtc(crtc, crtc->primary);
19031956 crtc_resp->x = crtc->x;
19041957 crtc_resp->y = crtc->y;
19051958 crtc_resp->gamma_size = crtc->gamma_size;
@@ -1916,10 +1969,9 @@ int drm_mode_getcrtc(struct drm_device *dev, · 10 unmodified lines
19161969 } else {
19171970 crtc_resp->mode_valid = 0;
19181971 }
1972+ drm_modeset_unlock_crtc(crtc);
19191973
1920−out:
1921− drm_modeset_unlock_all(dev);
1922− return ret;
1974+ return 0;
19231975 }
19241976
19251977 static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,
@@ -1935,6 +1987,15 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, · 9 unmodified lines
19351987 return true;
19361988 }
19371989
1990+static struct drm_encoder *drm_connector_get_encoder(struct drm_connector *connector)
1991+{
1992+ /* For atomic drivers only state objects are synchronously updated and
1993+ * protected by modeset locks, so check those first. */
1994+ if (connector->state)
1995+ return connector->state->best_encoder;
1996+ return connector->encoder;
1997+}
1998+
19381999 /**
19392000 * drm_mode_getconnector - get connector configuration
19402001 * @dev: drm device for the ioctl
@@ -1946,13 +2007,14 @@ static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode, · 5 unmodified lines
19462007 * Called by the user via ioctl.
19472008 *
19482009 * Returns:
1949− * Zero on success, errno on failure.
2010+ * Zero on success, negative errno on failure.
19502011 */
19512012 int drm_mode_getconnector(struct drm_device *dev, void *data,
19522013 struct drm_file *file_priv)
19532014 {
19542015 struct drm_mode_get_connector *out_resp = data;
19552016 struct drm_connector *connector;
2017+ struct drm_encoder *encoder;
19562018 struct drm_display_mode *mode;
19572019 int mode_count = 0;
19582020 int props_count = 0;
@@ -2008,8 +2070,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, · 49 unmodified lines
20082070 out_resp->subpixel = connector->display_info.subpixel_order;
20092071 out_resp->connection = connector->status;
20102072 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2011− if (connector->encoder)
2012− out_resp->encoder_id = connector->encoder->base.id;
2073+
2074+ encoder = drm_connector_get_encoder(connector);
2075+ if (encoder)
2076+ out_resp->encoder_id = encoder->base.id;
20132077 else
20142078 out_resp->encoder_id = 0;
20152079 drm_modeset_unlock(&dev->mode_config.connection_mutex);
@@ -2079,6 +2143,33 @@ out: · 63 unmodified lines
20792143 return ret;
20802144 }
20812145
2146+static struct drm_crtc *drm_encoder_get_crtc(struct drm_encoder *encoder)
2147+{
2148+ struct drm_connector *connector;
2149+ struct drm_device *dev = encoder->dev;
2150+ bool uses_atomic = false;
2151+
2152+ /* For atomic drivers only state objects are synchronously updated and
2153+ * protected by modeset locks, so check those first. */
2154+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
2155+ if (!connector->state)
2156+ continue;
2157+
2158+ uses_atomic = true;
2159+
2160+ if (connector->state->best_encoder != encoder)
2161+ continue;
2162+
2163+ return connector->state->crtc;
2164+ }
2165+
2166+ /* Don't return stale data (e.g. pending async disable). */
2167+ if (uses_atomic)
2168+ return NULL;
2169+
2170+ return encoder->crtc;
2171+}
2172+
20822173 /**
20832174 * drm_mode_getencoder - get encoder configuration
20842175 * @dev: drm device for the ioctl
@@ -2090,37 +2181,38 @@ out: · 5 unmodified lines
20902181 * Called by the user via ioctl.
20912182 *
20922183 * Returns:
2093− * Zero on success, errno on failure.
2184+ * Zero on success, negative errno on failure.
20942185 */
20952186 int drm_mode_getencoder(struct drm_device *dev, void *data,
20962187 struct drm_file *file_priv)
20972188 {
20982189 struct drm_mode_get_encoder *enc_resp = data;
20992190 struct drm_encoder *encoder;
2100− int ret = 0;
2191+ struct drm_crtc *crtc;
21012192
21022193 if (!drm_core_check_feature(dev, DRIVER_MODESET))
21032194 return -EINVAL;
21042195
2105− drm_modeset_lock_all(dev);
21062196 encoder = drm_encoder_find(dev, enc_resp->encoder_id);
2107− if (!encoder) {
2108− ret = -ENOENT;
2109− goto out;
2110− }
2197+ if (!encoder)
2198+ return -ENOENT;
21112199
2112− if (encoder->crtc)
2200+ drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2201+ crtc = drm_encoder_get_crtc(encoder);
2202+ if (crtc)
2203+ enc_resp->crtc_id = crtc->base.id;
2204+ else if (encoder->crtc)
21132205 enc_resp->crtc_id = encoder->crtc->base.id;
21142206 else
21152207 enc_resp->crtc_id = 0;
2208+ drm_modeset_unlock(&dev->mode_config.connection_mutex);
2209+
21162210 enc_resp->encoder_type = encoder->encoder_type;
21172211 enc_resp->encoder_id = encoder->base.id;
21182212 enc_resp->possible_crtcs = encoder->possible_crtcs;
21192213 enc_resp->possible_clones = encoder->possible_clones;
21202214
2121−out:
2122− drm_modeset_unlock_all(dev);
2123− return ret;
2215+ return 0;
21242216 }
21252217
21262218 /**
@@ -2134,7 +2226,7 @@ out: · 7 unmodified lines
21342226 * Called by the user via ioctl.
21352227 *
21362228 * Returns:
2137− * Zero on success, errno on failure.
2229+ * Zero on success, negative errno on failure.
21382230 */
21392231 int drm_mode_getplane_res(struct drm_device *dev, void *data,
21402232 struct drm_file *file_priv)
@@ -2143,13 +2235,12 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 2 unmodified lines
21432235 struct drm_mode_config *config;
21442236 struct drm_plane *plane;
21452237 uint32_t __user *plane_ptr;
2146− int copied = 0, ret = 0;
2238+ int copied = 0;
21472239 unsigned num_planes;
21482240
21492241 if (!drm_core_check_feature(dev, DRIVER_MODESET))
21502242 return -EINVAL;
21512243
2152− drm_modeset_lock_all(dev);
21532244 config = &dev->mode_config;
21542245
21552246 if (file_priv->universal_planes)
@@ -2165,6 +2256,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 9 unmodified lines
21652256 (plane_resp->count_planes >= num_planes)) {
21662257 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
21672258
2259+ /* Plane lists are invariant, no locking needed. */
21682260 list_for_each_entry(plane, &config->plane_list, head) {
21692261 /*
21702262 * Unless userspace set the 'universal planes'
@@ -2174,18 +2266,14 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 3 unmodified lines
21742266 !file_priv->universal_planes)
21752267 continue;
21762268
2177− if (put_user(plane->base.id, plane_ptr + copied)) {
2178− ret = -EFAULT;
2179− goto out;
2180− }
2269+ if (put_user(plane->base.id, plane_ptr + copied))
2270+ return -EFAULT;
21812271 copied++;
21822272 }
21832273 }
21842274 plane_resp->count_planes = num_planes;
21852275
2186−out:
2187− drm_modeset_unlock_all(dev);
2188− return ret;
2276+ return 0;
21892277 }
21902278
21912279 /**
@@ -2199,7 +2287,7 @@ out: · 7 unmodified lines
21992287 * Called by the user via ioctl.
22002288 *
22012289 * Returns:
2202− * Zero on success, errno on failure.
2290+ * Zero on success, negative errno on failure.
22032291 */
22042292 int drm_mode_getplane(struct drm_device *dev, void *data,
22052293 struct drm_file *file_priv)
@@ -2207,18 +2295,15 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 1 unmodified line
22072295 struct drm_mode_get_plane *plane_resp = data;
22082296 struct drm_plane *plane;
22092297 uint32_t __user *format_ptr;
2210− int ret = 0;
22112298
22122299 if (!drm_core_check_feature(dev, DRIVER_MODESET))
22132300 return -EINVAL;
22142301
2215− drm_modeset_lock_all(dev);
22162302 plane = drm_plane_find(dev, plane_resp->plane_id);
2217− if (!plane) {
2218− ret = -ENOENT;
2219− goto out;
2220− }
2303+ if (!plane)
2304+ return -ENOENT;
22212305
2306+ drm_modeset_lock(&plane->mutex, NULL);
22222307 if (plane->crtc)
22232308 plane_resp->crtc_id = plane->crtc->base.id;
22242309 else
@@ -2228,6 +2313,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 3 unmodified lines
22282313 plane_resp->fb_id = plane->fb->base.id;
22292314 else
22302315 plane_resp->fb_id = 0;
2316+ drm_modeset_unlock(&plane->mutex);
22312317
22322318 plane_resp->plane_id = plane->base.id;
22332319 plane_resp->possible_crtcs = plane->possible_crtcs;
@@ -2243,15 +2329,12 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 9 unmodified lines
22432329 if (copy_to_user(format_ptr,
22442330 plane->format_types,
22452331 sizeof(uint32_t) * plane->format_count)) {
2246− ret = -EFAULT;
2247− goto out;
2332+ return -EFAULT;
22482333 }
22492334 }
22502335 plane_resp->count_format_types = plane->format_count;
22512336
2252−out:
2253− drm_modeset_unlock_all(dev);
2254− return ret;
2337+ return 0;
22552338 }
22562339
22572340 /*
@@ -2274,7 +2357,7 @@ static int __setplane_internal(struct drm_plane *plane, · 16 unmodified lines
22742357 {
22752358 int ret = 0;
22762359 unsigned int fb_width, fb_height;
2277− int i;
2360+ unsigned int i;
22782361
22792362 /* No fb means shut it down */
22802363 if (!fb) {
@@ -2378,13 +2461,12 @@ static int setplane_internal(struct drm_plane *plane, · 97 unmodified lines
23782461 * valid crtc).
23792462 *
23802463 * Returns:
2381− * Zero on success, errno on failure.
2464+ * Zero on success, negative errno on failure.
23822465 */
23832466 int drm_mode_setplane(struct drm_device *dev, void *data,
23842467 struct drm_file *file_priv)
23852468 {
23862469 struct drm_mode_set_plane *plane_req = data;
2387− struct drm_mode_object *obj;
23882470 struct drm_plane *plane;
23892471 struct drm_crtc *crtc = NULL;
23902472 struct drm_framebuffer *fb = NULL;
@@ -2407,14 +2489,12 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 16 unmodified lines
24072489 * First, find the plane, crtc, and fb objects. If not available,
24082490 * we don't bother to call the driver.
24092491 */
2410− obj = drm_mode_object_find(dev, plane_req->plane_id,
2411− DRM_MODE_OBJECT_PLANE);
2412− if (!obj) {
2492+ plane = drm_plane_find(dev, plane_req->plane_id);
2493+ if (!plane) {
24132494 DRM_DEBUG_KMS("Unknown plane ID %d\n",
24142495 plane_req->plane_id);
24152496 return -ENOENT;
24162497 }
2417− plane = obj_to_plane(obj);
24182498
24192499 if (plane_req->fb_id) {
24202500 fb = drm_framebuffer_lookup(dev, plane_req->fb_id);
@@ -2424,14 +2504,12 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 3 unmodified lines
24242504 return -ENOENT;
24252505 }
24262506
2427− obj = drm_mode_object_find(dev, plane_req->crtc_id,
2428− DRM_MODE_OBJECT_CRTC);
2429− if (!obj) {
2507+ crtc = drm_crtc_find(dev, plane_req->crtc_id);
2508+ if (!crtc) {
24302509 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
24312510 plane_req->crtc_id);
24322511 return -ENOENT;
24332512 }
2434− crtc = obj_to_crtc(obj);
24352513 }
24362514
24372515 /*
@@ -2453,7 +2531,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 15 unmodified lines
24532531 * interface. The only thing it adds is correct refcounting dance.
24542532 *
24552533 * Returns:
2456− * Zero on success, errno on failure.
2534+ * Zero on success, negative errno on failure.
24572535 */
24582536 int drm_mode_set_config_internal(struct drm_mode_set *set)
24592537 {
@@ -2546,7 +2624,7 @@ EXPORT_SYMBOL(drm_crtc_check_viewport); · 86 unmodified lines
25462624 * Called by the user via ioctl.
25472625 *
25482626 * Returns:
2549− * Zero on success, errno on failure.
2627+ * Zero on success, negative errno on failure.
25502628 */
25512629 int drm_mode_setcrtc(struct drm_device *dev, void *data,
25522630 struct drm_file *file_priv)
@@ -2709,7 +2787,7 @@ out: · 156 unmodified lines
27092787 * userspace wants to make use of these capabilities.
27102788 *
27112789 * Returns:
2712− * Zero on success, errno on failure.
2790+ * Zero on success, negative errno on failure.
27132791 */
27142792 static int drm_mode_cursor_universal(struct drm_crtc *crtc,
27152793 struct drm_mode_cursor2 *req,
@@ -2810,7 +2888,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, · 94 unmodified lines
28102888 * If this crtc has a universal cursor plane, call that plane's update
28112889 * handler rather than using legacy cursor handlers.
28122890 */
2813− drm_modeset_lock_crtc(crtc);
2891+ drm_modeset_lock_crtc(crtc, crtc->cursor);
28142892 if (crtc->cursor) {
28152893 ret = drm_mode_cursor_universal(crtc, req, file_priv);
28162894 goto out;
@@ -2857,7 +2935,7 @@ out: · 40 unmodified lines
28572935 * Called by the user via ioctl.
28582936 *
28592937 * Returns:
2860− * Zero on success, errno on failure.
2938+ * Zero on success, negative errno on failure.
28612939 */
28622940 int drm_mode_cursor_ioctl(struct drm_device *dev,
28632941 void *data, struct drm_file *file_priv)
@@ -2884,7 +2962,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, · 20 unmodified lines
28842962 * Called by the user via ioctl.
28852963 *
28862964 * Returns:
2887− * Zero on success, errno on failure.
2965+ * Zero on success, negative errno on failure.
28882966 */
28892967 int drm_mode_cursor2_ioctl(struct drm_device *dev,
28902968 void *data, struct drm_file *file_priv)
@@ -2943,23 +3021,21 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format); · 52 unmodified lines
29433021 * @file_priv: drm file for the ioctl call
29443022 *
29453023 * Add a new FB to the specified CRTC, given a user request. This is the
2946− * original addfb ioclt which only supported RGB formats.
3024+ * original addfb ioctl which only supported RGB formats.
29473025 *
29483026 * Called by the user via ioctl.
29493027 *
29503028 * Returns:
2951− * Zero on success, errno on failure.
3029+ * Zero on success, negative errno on failure.
29523030 */
29533031 int drm_mode_addfb(struct drm_device *dev,
29543032 void *data, struct drm_file *file_priv)
29553033 {
29563034 struct drm_mode_fb_cmd *or = data;
29573035 struct drm_mode_fb_cmd2 r = {};
2958− struct drm_mode_config *config = &dev->mode_config;
2959− struct drm_framebuffer *fb;
2960− int ret = 0;
3036+ int ret;
29613037
2962− /* Use new struct with format internally */
3038+ /* convert to new format and call new ioctl */
29633039 r.fb_id = or->fb_id;
29643040 r.width = or->width;
29653041 r.height = or->height;
@@ -2967,28 +3043,13 @@ int drm_mode_addfb(struct drm_device *dev, · 1 unmodified line
29673043 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
29683044 r.handles[0] = or->handle;
29693045
2970− if (!drm_core_check_feature(dev, DRIVER_MODESET))
2971− return -EINVAL;
2972−
2973− if ((config->min_width > r.width) || (r.width > config->max_width))
2974− return -EINVAL;
2975−
2976− if ((config->min_height > r.height) || (r.height > config->max_height))
2977− return -EINVAL;
3046+ ret = drm_mode_addfb2(dev, &r, file_priv);
3047+ if (ret)
3048+ return ret;
29783049
2979− fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);
2980− if (IS_ERR(fb)) {
2981− DRM_DEBUG_KMS("could not create framebuffer\n");
2982− return PTR_ERR(fb);
2983− }
3050+ or->fb_id = r.fb_id;
29843051
2985− mutex_lock(&file_priv->fbs_lock);
2986− or->fb_id = fb->base.id;
2987− list_add(&fb->filp_head, &file_priv->fbs);
2988− DRM_DEBUG_KMS("[FB:%d]\n", fb->base.id);
2989− mutex_unlock(&file_priv->fbs_lock);
2990−
2991− return ret;
3052+ return 0;
29923053 }
29933054
29943055 static int format_check(const struct drm_mode_fb_cmd2 *r)
@@ -3080,7 +3141,7 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r) · 85 unmodified lines
30803141 num_planes = drm_format_num_planes(r->pixel_format);
30813142
30823143 if (r->width == 0 || r->width % hsub) {
3083− DRM_DEBUG_KMS("bad framebuffer width %u\n", r->height);
3144+ DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
30843145 return -EINVAL;
30853146 }
30863147
@@ -3170,7 +3231,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, · 83 unmodified lines
31703231 * Called by the user via ioctl.
31713232 *
31723233 * Returns:
3173− * Zero on success, errno on failure.
3234+ * Zero on success, negative errno on failure.
31743235 */
31753236 int drm_mode_addfb2(struct drm_device *dev,
31763237 void *data, struct drm_file *file_priv)
@@ -3198,7 +3259,7 @@ int drm_mode_addfb2(struct drm_device *dev, · 21 unmodified lines
31983259 * Called by the user via ioctl.
31993260 *
32003261 * Returns:
3201− * Zero on success, errno on failure.
3262+ * Zero on success, negative errno on failure.
32023263 */
32033264 int drm_mode_rmfb(struct drm_device *dev,
32043265 void *data, struct drm_file *file_priv)
@@ -3252,7 +3313,7 @@ fail_lookup: · 47 unmodified lines
32523313 * Called by the user via ioctl.
32533314 *
32543315 * Returns:
3255− * Zero on success, errno on failure.
3316+ * Zero on success, negative errno on failure.
32563317 */
32573318 int drm_mode_getfb(struct drm_device *dev,
32583319 void *data, struct drm_file *file_priv)
@@ -3313,7 +3374,7 @@ int drm_mode_getfb(struct drm_device *dev, · 54 unmodified lines
33133374 * Called by the user via ioctl.
33143375 *
33153376 * Returns:
3316− * Zero on success, errno on failure.
3377+ * Zero on success, negative errno on failure.
33173378 */
33183379 int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
33193380 void *data, struct drm_file *file_priv)
@@ -3393,7 +3454,7 @@ out_err1: · 73 unmodified lines
33933454 * Called by the user via ioctl.
33943455 *
33953456 * Returns:
3396− * Zero on success, errno on failure.
3457+ * Zero on success, negative errno on failure.
33973458 */
33983459 void drm_fb_release(struct drm_file *priv)
33993460 {
@@ -3402,7 +3463,7 @@ void drm_fb_release(struct drm_file *priv) · 2 unmodified lines
34023463
34033464 /*
34043465 * When the file gets released that means no one else can access the fb
3405− * list any more, so no need to grab fpriv->fbs_lock. And we need to to
3466+ * list any more, so no need to grab fpriv->fbs_lock. And we need to
34063467 * avoid upsetting lockdep since the universal cursor code adds a
34073468 * framebuffer while holding mutex locks.
34083469 *
@@ -3435,6 +3496,10 @@ void drm_fb_release(struct drm_file *priv) · 26 unmodified lines
34353496 * object with drm_object_attach_property. The returned property object must be
34363497 * freed with drm_property_destroy.
34373498 *
3499+ * Note that the DRM core keeps a per-device list of properties and that, if
3500+ * drm_mode_config_cleanup() is called, it will destroy all properties created
3501+ * by the driver.
3502+ *
34383503 * Returns:
34393504 * A pointer to the newly created property on success, NULL on failure.
34403505 */
@@ -3462,7 +3527,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, · 21 unmodified lines
34623527
34633528 property->flags = flags;
34643529 property->num_values = num_values;
3465− INIT_LIST_HEAD(&property->enum_blob_list);
3530+ INIT_LIST_HEAD(&property->enum_list);
34663531
34673532 if (name) {
34683533 strncpy(property->name, name, DRM_PROP_NAME_LEN);
@@ -3611,7 +3676,7 @@ static struct drm_property *property_create_range(struct drm_device *dev, · 142 unmodified lines
36113676 * object with drm_object_attach_property. The returned property object must be
36123677 * freed with drm_property_destroy.
36133678 *
3614− * Userspace is allowed to set any interger value in the (min, max) range
3679+ * Userspace is allowed to set any integer value in the (min, max) range
36153680 * inclusive.
36163681 *
36173682 * Returns:
@@ -3684,8 +3749,8 @@ int drm_property_add_enum(struct drm_property *property, int index, · 66 unmodified lines
36843749 (value > 63))
36853750 return -EINVAL;
36863751
3687− if (!list_empty(&property->enum_blob_list)) {
3688− list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
3752+ if (!list_empty(&property->enum_list)) {
3753+ list_for_each_entry(prop_enum, &property->enum_list, head) {
36893754 if (prop_enum->value == value) {
36903755 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
36913756 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';
@@ -3703,7 +3768,7 @@ int drm_property_add_enum(struct drm_property *property, int index, · 11 unmodified lines
37033768 prop_enum->value = value;
37043769
37053770 property->values[index] = value;
3706− list_add_tail(&prop_enum->head, &property->enum_blob_list);
3771+ list_add_tail(&prop_enum->head, &property->enum_list);
37073772 return 0;
37083773 }
37093774 EXPORT_SYMBOL(drm_property_add_enum);
@@ -3720,7 +3785,7 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property) · 10 unmodified lines
37203785 {
37213786 struct drm_property_enum *prop_enum, *pt;
37223787
3723− list_for_each_entry_safe(prop_enum, pt, &property->enum_blob_list, head) {
3788+ list_for_each_entry_safe(prop_enum, pt, &property->enum_list, head) {
37243789 list_del(&prop_enum->head);
37253790 kfree(prop_enum);
37263791 }
@@ -3823,17 +3888,20 @@ int drm_object_property_get_value(struct drm_mode_object *obj, · 96 unmodified lines
38233888 EXPORT_SYMBOL(drm_object_property_get_value);
38243889
38253890 /**
3826− * drm_mode_getproperty_ioctl - get the current value of a connector's property
3891+ * drm_mode_getproperty_ioctl - get the property metadata
38273892 * @dev: DRM device
38283893 * @data: ioctl data
38293894 * @file_priv: DRM file info
38303895 *
3831− * This function retrieves the current value for an connectors's property.
3896+ * This function retrieves the metadata for a given property, like the different
3897+ * possible values for an enum property or the limits for a range property.
3898+ *
3899+ * Blob properties are special
38323900 *
38333901 * Called by the user via ioctl.
38343902 *
38353903 * Returns:
3836− * Zero on success, errno on failure.
3904+ * Zero on success, negative errno on failure.
38373905 */
38383906 int drm_mode_getproperty_ioctl(struct drm_device *dev,
38393907 void *data, struct drm_file *file_priv)
@@ -3841,16 +3909,12 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 1 unmodified line
38413909 struct drm_mode_get_property *out_resp = data;
38423910 struct drm_property *property;
38433911 int enum_count = 0;
3844− int blob_count = 0;
38453912 int value_count = 0;
38463913 int ret = 0, i;
38473914 int copied;
38483915 struct drm_property_enum *prop_enum;
38493916 struct drm_mode_property_enum __user *enum_ptr;
3850− struct drm_property_blob *prop_blob;
3851− uint32_t __user *blob_id_ptr;
38523917 uint64_t __user *values_ptr;
3853− uint32_t __user *blob_length_ptr;
38543918
38553919 if (!drm_core_check_feature(dev, DRIVER_MODESET))
38563920 return -EINVAL;
@@ -3864,11 +3928,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 7 unmodified lines
38643928
38653929 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
38663930 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {
3867− list_for_each_entry(prop_enum, &property->enum_blob_list, head)
3931+ list_for_each_entry(prop_enum, &property->enum_list, head)
38683932 enum_count++;
3869− } else if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3870− list_for_each_entry(prop_blob, &property->enum_blob_list, head)
3871− blob_count++;
38723933 }
38733934
38743935 value_count = property->num_values;
@@ -3893,7 +3954,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 18 unmodified lines
38933954 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
38943955 copied = 0;
38953956 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;
3896− list_for_each_entry(prop_enum, &property->enum_blob_list, head) {
3957+ list_for_each_entry(prop_enum, &property->enum_list, head) {
38973958
38983959 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
38993960 ret = -EFAULT;
@@ -3911,35 +3972,24 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 11 unmodified lines
39113972 out_resp->count_enum_blobs = enum_count;
39123973 }
39133974
3914− if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {
3915− if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {
3916− copied = 0;
3917− blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;
3918− blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;
3919−
3920− list_for_each_entry(prop_blob, &property->enum_blob_list, head) {
3921− if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {
3922− ret = -EFAULT;
3923− goto done;
3924− }
3925−
3926− if (put_user(prop_blob->length, blob_length_ptr + copied)) {
3927− ret = -EFAULT;
3928− goto done;
3929− }
3930−
3931− copied++;
3932− }
3933− }
3934− out_resp->count_enum_blobs = blob_count;
3935− }
3975+ /*
3976+ * NOTE: The idea seems to have been to use this to read all the blob
3977+ * property values. But nothing ever added them to the corresponding
3978+ * list, userspace always used the special-purpose get_blob ioctl to
3979+ * read the value for a blob property. It also doesn't make a lot of
3980+ * sense to return values here when everything else is just metadata for
3981+ * the property itself.
3982+ */
3983+ if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
3984+ out_resp->count_enum_blobs = 0;
39363985 done:
39373986 drm_modeset_unlock_all(dev);
39383987 return ret;
39393988 }
39403989
3941−static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,
3942− void *data)
3990+static struct drm_property_blob *
3991+drm_property_create_blob(struct drm_device *dev, size_t length,
3992+ const void *data)
39433993 {
39443994 struct drm_property_blob *blob;
39453995 int ret;
@@ -3985,7 +4035,7 @@ static void drm_property_destroy_blob(struct drm_device *dev, · 39 unmodified lines
39854035 * Called by the user via ioctl.
39864036 *
39874037 * Returns:
3988− * Zero on success, errno on failure.
4038+ * Zero on success, negative errno on failure.
39894039 */
39904040 int drm_mode_getblob_ioctl(struct drm_device *dev,
39914041 void *data, struct drm_file *file_priv)
@@ -4019,12 +4069,25 @@ done: · 27 unmodified lines
40194069 return ret;
40204070 }
40214071
4072+/**
4073+ * drm_mode_connector_set_path_property - set tile property on connector
4074+ * @connector: connector to set property on.
4075+ * @path: path to use for property.
4076+ *
4077+ * This creates a property to expose to userspace to specify a
4078+ * connector path. This is mainly used for DisplayPort MST where
4079+ * connectors have a topology and we want to allow userspace to give
4080+ * them more meaningful names.
4081+ *
4082+ * Returns:
4083+ * Zero on success, negative errno on failure.
4084+ */
40224085 int drm_mode_connector_set_path_property(struct drm_connector *connector,
4023− char *path)
4086+ const char *path)
40244087 {
40254088 struct drm_device *dev = connector->dev;
4026− int ret, size;
4027− size = strlen(path) + 1;
4089+ size_t size = strlen(path) + 1;
4090+ int ret;
40284091
40294092 connector->path_blob_ptr = drm_property_create_blob(connector->dev,
40304093 size, path);
@@ -4038,6 +4101,52 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, · 7 unmodified lines
40384101 }
40394102 EXPORT_SYMBOL(drm_mode_connector_set_path_property);
40404103
4104+/**
4105+ * drm_mode_connector_set_tile_property - set tile property on connector
4106+ * @connector: connector to set property on.
4107+ *
4108+ * This looks up the tile information for a connector, and creates a
4109+ * property for userspace to parse if it exists. The property is of
4110+ * the form of 8 integers using ':' as a separator.
4111+ *
4112+ * Returns:
4113+ * Zero on success, errno on failure.
4114+ */
4115+int drm_mode_connector_set_tile_property(struct drm_connector *connector)
4116+{
4117+ struct drm_device *dev = connector->dev;
4118+ int ret, size;
4119+ char tile[256];
4120+
4121+ if (connector->tile_blob_ptr)
4122+ drm_property_destroy_blob(dev, connector->tile_blob_ptr);
4123+
4124+ if (!connector->has_tile) {
4125+ connector->tile_blob_ptr = NULL;
4126+ ret = drm_object_property_set_value(&connector->base,
4127+ dev->mode_config.tile_property, 0);
4128+ return ret;
4129+ }
4130+
4131+ snprintf(tile, 256, "%d:%d:%d:%d:%d:%d:%d:%d",
4132+ connector->tile_group->id, connector->tile_is_single_monitor,
4133+ connector->num_h_tile, connector->num_v_tile,
4134+ connector->tile_h_loc, connector->tile_v_loc,
4135+ connector->tile_h_size, connector->tile_v_size);
4136+ size = strlen(tile) + 1;
4137+
4138+ connector->tile_blob_ptr = drm_property_create_blob(connector->dev,
4139+ size, tile);
4140+ if (!connector->tile_blob_ptr)
4141+ return -EINVAL;
4142+
4143+ ret = drm_object_property_set_value(&connector->base,
4144+ dev->mode_config.tile_property,
4145+ connector->tile_blob_ptr->base.id);
4146+ return ret;
4147+}
4148+EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
4149+
40414150 /**
40424151 * drm_mode_connector_update_edid_property - update the edid property of a connector
40434152 * @connector: drm connector
@@ -4047,13 +4156,14 @@ EXPORT_SYMBOL(drm_mode_connector_set_path_property); · 3 unmodified lines
40474156 * connector's edid property.
40484157 *
40494158 * Returns:
4050− * Zero on success, errno on failure.
4159+ * Zero on success, negative errno on failure.
40514160 */
40524161 int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4053− struct edid *edid)
4162+ const struct edid *edid)
40544163 {
40554164 struct drm_device *dev = connector->dev;
4056− int ret, size;
4165+ size_t size;
4166+ int ret;
40574167
40584168 /* ignore requests to set edid when overridden */
40594169 if (connector->override_edid)
@@ -4143,7 +4253,7 @@ static bool drm_property_change_is_valid(struct drm_property *property, · 83 unmodified lines
41434253 * Called by the user via ioctl.
41444254 *
41454255 * Returns:
4146− * Zero on success, errno on failure.
4256+ * Zero on success, negative errno on failure.
41474257 */
41484258 int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
41494259 void *data, struct drm_file *file_priv)
@@ -4226,7 +4336,7 @@ int drm_mode_plane_set_obj_prop(struct drm_plane *plane, · 76 unmodified lines
42264336 EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
42274337
42284338 /**
4229− * drm_mode_getproperty_ioctl - get the current value of a object's property
4339+ * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
42304340 * @dev: DRM device
42314341 * @data: ioctl data
42324342 * @file_priv: DRM file info
@@ -4238,7 +4348,7 @@ EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); · 5 unmodified lines
42384348 * Called by the user via ioctl.
42394349 *
42404350 * Returns:
4241− * Zero on success, errno on failure.
4351+ * Zero on success, negative errno on failure.
42424352 */
42434353 int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
42444354 struct drm_file *file_priv)
@@ -4310,7 +4420,7 @@ out: · 65 unmodified lines
43104420 * Called by the user via ioctl.
43114421 *
43124422 * Returns:
4313− * Zero on success, errno on failure.
4423+ * Zero on success, negative errno on failure.
43144424 */
43154425 int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
43164426 struct drm_file *file_priv)
@@ -4382,7 +4492,7 @@ out: · 65 unmodified lines
43824492 * possible_clones and possible_crtcs bitmasks.
43834493 *
43844494 * Returns:
4385− * Zero on success, errno on failure.
4495+ * Zero on success, negative errno on failure.
43864496 */
43874497 int drm_mode_connector_attach_encoder(struct drm_connector *connector,
43884498 struct drm_encoder *encoder)
@@ -4409,7 +4519,7 @@ EXPORT_SYMBOL(drm_mode_connector_attach_encoder); · 20 unmodified lines
44094519 * fixed gamma table size.
44104520 *
44114521 * Returns:
4412− * Zero on success, errno on failure.
4522+ * Zero on success, negative errno on failure.
44134523 */
44144524 int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
44154525 int gamma_size)
@@ -4438,7 +4548,7 @@ EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); · 22 unmodified lines
44384548 * Called by the user via ioctl.
44394549 *
44404550 * Returns:
4441− * Zero on success, errno on failure.
4551+ * Zero on success, negative errno on failure.
44424552 */
44434553 int drm_mode_gamma_set_ioctl(struct drm_device *dev,
44444554 void *data, struct drm_file *file_priv)
@@ -4510,7 +4620,7 @@ out: · 65 unmodified lines
45104620 * Called by the user via ioctl.
45114621 *
45124622 * Returns:
4513− * Zero on success, errno on failure.
4623+ * Zero on success, negative errno on failure.
45144624 */
45154625 int drm_mode_gamma_get_ioctl(struct drm_device *dev,
45164626 void *data, struct drm_file *file_priv)
@@ -4576,7 +4686,7 @@ out: · 59 unmodified lines
45764686 * Called by the user via ioctl.
45774687 *
45784688 * Returns:
4579− * Zero on success, errno on failure.
4689+ * Zero on success, negative errno on failure.
45804690 */
45814691 int drm_mode_page_flip_ioctl(struct drm_device *dev,
45824692 void *data, struct drm_file *file_priv)
@@ -4599,7 +4709,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, · 16 unmodified lines
45994709 if (!crtc)
46004710 return -ENOENT;
46014711
4602− drm_modeset_lock_crtc(crtc);
4712+ drm_modeset_lock_crtc(crtc, crtc->primary);
46034713 if (crtc->primary->fb == NULL) {
46044714 /* The framebuffer is currently unbound, presumably
46054715 * due to a hotplug event, that userspace has not
@@ -4742,7 +4852,7 @@ EXPORT_SYMBOL(drm_mode_config_reset); · 136 unmodified lines
47424852 * Called by the user via ioctl.
47434853 *
47444854 * Returns:
4745− * Zero on success, errno on failure.
4855+ * Zero on success, negative errno on failure.
47464856 */
47474857 int drm_mode_create_dumb_ioctl(struct drm_device *dev,
47484858 void *data, struct drm_file *file_priv)
@@ -4769,6 +4879,16 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, · 20 unmodified lines
47694879 if (PAGE_ALIGN(size) == 0)
47704880 return -EINVAL;
47714881
4882+ /*
4883+ * handle, pitch and size are output parameters. Zero them out to
4884+ * prevent drivers from accidentally using uninitialized data. Since
4885+ * not all existing userspace is clearing these fields properly we
4886+ * cannot reject IOCTL with garbage in them.
4887+ */
4888+ args->handle = 0;
4889+ args->pitch = 0;
4890+ args->size = 0;
4891+
47724892 return dev->driver->dumb_create(file_priv, dev, args);
47734893 }
47744894
@@ -4784,7 +4904,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, · 9 unmodified lines
47844904 * Called by the user via ioctl.
47854905 *
47864906 * Returns:
4787− * Zero on success, errno on failure.
4907+ * Zero on success, negative errno on failure.
47884908 */
47894909 int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
47904910 void *data, struct drm_file *file_priv)
@@ -4811,7 +4931,7 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, · 20 unmodified lines
48114931 * Called by the user via ioctl.
48124932 *
48134933 * Returns:
4814− * Zero on success, errno on failure.
4934+ * Zero on success, negative errno on failure.
48154935 */
48164936 int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
48174937 void *data, struct drm_file *file_priv)
@@ -5097,6 +5217,7 @@ void drm_mode_config_init(struct drm_device *dev) · 279 unmodified lines
50975217 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
50985218 INIT_LIST_HEAD(&dev->mode_config.plane_list);
50995219 idr_init(&dev->mode_config.crtc_idr);
5220+ idr_init(&dev->mode_config.tile_idr);
51005221
51015222 drm_modeset_lock_all(dev);
51025223 drm_mode_create_standard_connector_properties(dev);
@@ -5184,6 +5305,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) · 81 unmodified lines
51845305 crtc->funcs->destroy(crtc);
51855306 }
51865307
5308+ idr_destroy(&dev->mode_config.tile_idr);
51875309 idr_destroy(&dev->mode_config.crtc_idr);
51885310 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
51895311 }
@@ -5206,3 +5328,100 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, · 16 unmodified lines
52065328 supported_rotations);
52075329 }
52085330 EXPORT_SYMBOL(drm_mode_create_rotation_property);
5331+
5332+/**
5333+ * DOC: Tile group
5334+ *
5335+ * Tile groups are used to represent tiled monitors with a unique
5336+ * integer identifier. Tiled monitors using DisplayID v1.3 have
5337+ * a unique 8-byte handle, we store this in a tile group, so we
5338+ * have a common identifier for all tiles in a monitor group.
5339+ */
5340+static void drm_tile_group_free(struct kref *kref)
5341+{
5342+ struct drm_tile_group *tg = container_of(kref, struct drm_tile_group, refcount);
5343+ struct drm_device *dev = tg->dev;
5344+ mutex_lock(&dev->mode_config.idr_mutex);
5345+ idr_remove(&dev->mode_config.tile_idr, tg->id);
5346+ mutex_unlock(&dev->mode_config.idr_mutex);
5347+ kfree(tg);
5348+}
5349+
5350+/**
5351+ * drm_mode_put_tile_group - drop a reference to a tile group.
5352+ * @dev: DRM device
5353+ * @tg: tile group to drop reference to.
5354+ *
5355+ * drop reference to tile group and free if 0.
5356+ */
5357+void drm_mode_put_tile_group(struct drm_device *dev,
5358+ struct drm_tile_group *tg)
5359+{
5360+ kref_put(&tg->refcount, drm_tile_group_free);
5361+}
5362+
5363+/**
5364+ * drm_mode_get_tile_group - get a reference to an existing tile group
5365+ * @dev: DRM device
5366+ * @topology: 8-bytes unique per monitor.
5367+ *
5368+ * Use the unique bytes to get a reference to an existing tile group.
5369+ *
5370+ * RETURNS:
5371+ * tile group or NULL if not found.
5372+ */
5373+struct drm_tile_group *drm_mode_get_tile_group(struct drm_device *dev,
5374+ char topology[8])
5375+{
5376+ struct drm_tile_group *tg;
5377+ int id;
5378+ mutex_lock(&dev->mode_config.idr_mutex);
5379+ idr_for_each_entry(&dev->mode_config.tile_idr, tg, id) {
5380+ if (!memcmp(tg->group_data, topology, 8)) {
5381+ if (!kref_get_unless_zero(&tg->refcount))
5382+ tg = NULL;
5383+ mutex_unlock(&dev->mode_config.idr_mutex);
5384+ return tg;
5385+ }
5386+ }
5387+ mutex_unlock(&dev->mode_config.idr_mutex);
5388+ return NULL;
5389+}
5390+
5391+/**
5392+ * drm_mode_create_tile_group - create a tile group from a displayid description
5393+ * @dev: DRM device
5394+ * @topology: 8-bytes unique per monitor.
5395+ *
5396+ * Create a tile group for the unique monitor, and get a unique
5397+ * identifier for the tile group.
5398+ *
5399+ * RETURNS:
5400+ * new tile group or error.
5401+ */
5402+struct drm_tile_group *drm_mode_create_tile_group(struct drm_device *dev,
5403+ char topology[8])
5404+{
5405+ struct drm_tile_group *tg;
5406+ int ret;
5407+
5408+ tg = kzalloc(sizeof(*tg), GFP_KERNEL);
5409+ if (!tg)
5410+ return ERR_PTR(-ENOMEM);
5411+
5412+ kref_init(&tg->refcount);
5413+ memcpy(tg->group_data, topology, 8);
5414+ tg->dev = dev;
5415+
5416+ mutex_lock(&dev->mode_config.idr_mutex);
5417+ ret = idr_alloc(&dev->mode_config.tile_idr, tg, 1, 0, GFP_KERNEL);
5418+ if (ret >= 0) {
5419+ tg->id = ret;
5420+ } else {
5421+ kfree(tg);
5422+ tg = ERR_PTR(ret);
5423+ }
5424+
5425+ mutex_unlock(&dev->mode_config.idr_mutex);
5426+ return tg;
5427+}
drivers/gpu/drm/drm_crtc_helper.c+132−0
@@ -34,12 +34,35 @@ · 33 unmodified lines
3434 #include <linux/moduleparam.h>
3535
3636 #include <drm/drmP.h>
37+#include <drm/drm_atomic.h>
3738 #include <drm/drm_crtc.h>
3839 #include <drm/drm_fourcc.h>
3940 #include <drm/drm_crtc_helper.h>
4041 #include <drm/drm_fb_helper.h>
42+#include <drm/drm_plane_helper.h>
43+#include <drm/drm_atomic_helper.h>
4144 #include <drm/drm_edid.h>
4245
46+/**
47+ * DOC: overview
48+ *
49+ * The CRTC modeset helper library provides a default set_config implementation
50+ * in drm_crtc_helper_set_config(). Plus a few other convenience functions using
51+ * the same callbacks which drivers can use to e.g. restore the modeset
52+ * configuration on resume with drm_helper_resume_force_mode().
53+ *
54+ * The driver callbacks are mostly compatible with the atomic modeset helpers,
55+ * except for the handling of the primary plane: Atomic helpers require that the
56+ * primary plane is implemented as a real standalone plane and not directly tied
57+ * to the CRTC state. For easier transition this library provides functions to
58+ * implement the old semantics required by the CRTC helpers using the new plane
59+ * and atomic helper callbacks.
60+ *
61+ * Drivers are strongly urged to convert to the atomic helpers (by way of first
62+ * converting to the plane helpers). New drivers must not use these functions
63+ * but need to implement the atomic interface instead, potentially using the
64+ * atomic helpers for that.
65+ */
4366 MODULE_AUTHOR("David Airlie, Jesse Barnes");
4467 MODULE_DESCRIPTION("DRM KMS helper");
4568 MODULE_LICENSE("GPL and additional rights");
@@ -888,3 +911,112 @@ void drm_helper_resume_force_mode(struct drm_device *dev) · 842 unmodified lines
888911 drm_modeset_unlock_all(dev);
889912 }
890913 EXPORT_SYMBOL(drm_helper_resume_force_mode);
914+
915+/**
916+ * drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers
917+ * @crtc: DRM CRTC
918+ * @mode: DRM display mode which userspace requested
919+ * @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
920+ * @x: x offset of the CRTC scanout area on the underlying framebuffer
921+ * @y: y offset of the CRTC scanout area on the underlying framebuffer
922+ * @old_fb: previous framebuffer
923+ *
924+ * This function implements a callback useable as the ->mode_set callback
925+ * required by the crtc helpers. Besides the atomic plane helper functions for
926+ * the primary plane the driver must also provide the ->mode_set_nofb callback
927+ * to set up the crtc.
928+ *
929+ * This is a transitional helper useful for converting drivers to the atomic
930+ * interfaces.
931+ */
932+int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
933+ struct drm_display_mode *adjusted_mode, int x, int y,
934+ struct drm_framebuffer *old_fb)
935+{
936+ struct drm_crtc_state *crtc_state;
937+ struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
938+ int ret;
939+
940+ if (crtc->funcs->atomic_duplicate_state)
941+ crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
942+ else if (crtc->state)
943+ crtc_state = kmemdup(crtc->state, sizeof(*crtc_state),
944+ GFP_KERNEL);
945+ else
946+ crtc_state = kzalloc(sizeof(*crtc_state), GFP_KERNEL);
947+ if (!crtc_state)
948+ return -ENOMEM;
949+
950+ crtc_state->enable = true;
951+ crtc_state->planes_changed = true;
952+ crtc_state->mode_changed = true;
953+ drm_mode_copy(&crtc_state->mode, mode);
954+ drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
955+
956+ if (crtc_funcs->atomic_check) {
957+ ret = crtc_funcs->atomic_check(crtc, crtc_state);
958+ if (ret) {
959+ kfree(crtc_state);
960+
961+ return ret;
962+ }
963+ }
964+
965+ swap(crtc->state, crtc_state);
966+
967+ crtc_funcs->mode_set_nofb(crtc);
968+
969+ if (crtc_state) {
970+ if (crtc->funcs->atomic_destroy_state)
971+ crtc->funcs->atomic_destroy_state(crtc, crtc_state);
972+ else
973+ kfree(crtc_state);
974+ }
975+
976+ return drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
977+}
978+EXPORT_SYMBOL(drm_helper_crtc_mode_set);
979+
980+/**
981+ * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers
982+ * @crtc: DRM CRTC
983+ * @x: x offset of the CRTC scanout area on the underlying framebuffer
984+ * @y: y offset of the CRTC scanout area on the underlying framebuffer
985+ * @old_fb: previous framebuffer
986+ *
987+ * This function implements a callback useable as the ->mode_set_base used
988+ * required by the crtc helpers. The driver must provide the atomic plane helper
989+ * functions for the primary plane.
990+ *
991+ * This is a transitional helper useful for converting drivers to the atomic
992+ * interfaces.
993+ */
994+int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
995+ struct drm_framebuffer *old_fb)
996+{
997+ struct drm_plane_state *plane_state;
998+ struct drm_plane *plane = crtc->primary;
999+
1000+ if (plane->funcs->atomic_duplicate_state)
1001+ plane_state = plane->funcs->atomic_duplicate_state(plane);
1002+ else if (plane->state)
1003+ plane_state = drm_atomic_helper_plane_duplicate_state(plane);
1004+ else
1005+ plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
1006+ if (!plane_state)
1007+ return -ENOMEM;
1008+
1009+ plane_state->crtc = crtc;
1010+ drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
1011+ plane_state->crtc_x = 0;
1012+ plane_state->crtc_y = 0;
1013+ plane_state->crtc_h = crtc->mode.vdisplay;
1014+ plane_state->crtc_w = crtc->mode.hdisplay;
1015+ plane_state->src_x = x << 16;
1016+ plane_state->src_y = y << 16;
1017+ plane_state->src_h = crtc->mode.vdisplay << 16;
1018+ plane_state->src_w = crtc->mode.hdisplay << 16;
1019+
1020+ return drm_plane_helper_commit(plane, plane_state, old_fb);
1021+}
1022+EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
drivers/gpu/drm/drm_dp_helper.c+6−195
@@ -39,198 +39,6 @@ · 38 unmodified lines
3939 * blocks, ...
4040 */
4141
42−/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
43−static int
44−i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
45− uint8_t write_byte, uint8_t *read_byte)
46−{
47− struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
48− int ret;
49−
50− ret = (*algo_data->aux_ch)(adapter, mode,
51− write_byte, read_byte);
52− return ret;
53−}
54−
55−/*
56− * I2C over AUX CH
57− */
58−
59−/*
60− * Send the address. If the I2C link is running, this 'restarts'
61− * the connection with the new address, this is used for doing
62− * a write followed by a read (as needed for DDC)
63− */
64−static int
65−i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
66−{
67− struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
68− int mode = MODE_I2C_START;
69− int ret;
70−
71− if (reading)
72− mode |= MODE_I2C_READ;
73− else
74− mode |= MODE_I2C_WRITE;
75− algo_data->address = address;
76− algo_data->running = true;
77− ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
78− return ret;
79−}
80−
81−/*
82− * Stop the I2C transaction. This closes out the link, sending
83− * a bare address packet with the MOT bit turned off
84− */
85−static void
86−i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
87−{
88− struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
89− int mode = MODE_I2C_STOP;
90−
91− if (reading)
92− mode |= MODE_I2C_READ;
93− else
94− mode |= MODE_I2C_WRITE;
95− if (algo_data->running) {
96− (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
97− algo_data->running = false;
98− }
99−}
100−
101−/*
102− * Write a single byte to the current I2C address, the
103− * the I2C link must be running or this returns -EIO
104− */
105−static int
106−i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
107−{
108− struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
109− int ret;
110−
111− if (!algo_data->running)
112− return -EIO;
113−
114− ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
115− return ret;
116−}
117−
118−/*
119− * Read a single byte from the current I2C address, the
120− * I2C link must be running or this returns -EIO
121− */
122−static int
123−i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
124−{
125− struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
126− int ret;
127−
128− if (!algo_data->running)
129− return -EIO;
130−
131− ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
132− return ret;
133−}
134−
135−static int
136−i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
137− struct i2c_msg *msgs,
138− int num)
139−{
140− int ret = 0;
141− bool reading = false;
142− int m;
143− int b;
144−
145− for (m = 0; m < num; m++) {
146− u16 len = msgs[m].len;
147− u8 *buf = msgs[m].buf;
148− reading = (msgs[m].flags & I2C_M_RD) != 0;
149− ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
150− if (ret < 0)
151− break;
152− if (reading) {
153− for (b = 0; b < len; b++) {
154− ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
155− if (ret < 0)
156− break;
157− }
158− } else {
159− for (b = 0; b < len; b++) {
160− ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
161− if (ret < 0)
162− break;
163− }
164− }
165− if (ret < 0)
166− break;
167− }
168− if (ret >= 0)
169− ret = num;
170− i2c_algo_dp_aux_stop(adapter, reading);
171− DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
172− return ret;
173−}
174−
175−static u32
176−i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
177−{
178− return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
179− I2C_FUNC_SMBUS_READ_BLOCK_DATA |
180− I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
181− I2C_FUNC_10BIT_ADDR;
182−}
183−
184−static const struct i2c_algorithm i2c_dp_aux_algo = {
185− .master_xfer = i2c_algo_dp_aux_xfer,
186− .functionality = i2c_algo_dp_aux_functionality,
187−};
188−
189−static void
190−i2c_dp_aux_reset_bus(struct i2c_adapter *adapter)
191−{
192− (void) i2c_algo_dp_aux_address(adapter, 0, false);
193− (void) i2c_algo_dp_aux_stop(adapter, false);
194−}
195−
196−static int
197−i2c_dp_aux_prepare_bus(struct i2c_adapter *adapter)
198−{
199− adapter->algo = &i2c_dp_aux_algo;
200− adapter->retries = 3;
201− i2c_dp_aux_reset_bus(adapter);
202− return 0;
203−}
204−
205−/**
206− * i2c_dp_aux_add_bus() - register an i2c adapter using the aux ch helper
207− * @adapter: i2c adapter to register
208− *
209− * This registers an i2c adapter that uses dp aux channel as it's underlaying
210− * transport. The driver needs to fill out the &i2c_algo_dp_aux_data structure
211− * and store it in the algo_data member of the @adapter argument. This will be
212− * used by the i2c over dp aux algorithm to drive the hardware.
213− *
214− * RETURNS:
215− * 0 on success, -ERRNO on failure.
216− *
217− * IMPORTANT:
218− * This interface is deprecated, please switch to the new dp aux helpers and
219− * drm_dp_aux_register().
220− */
221−int
222−i2c_dp_aux_add_bus(struct i2c_adapter *adapter)
223−{
224− int error;
225−
226− error = i2c_dp_aux_prepare_bus(adapter);
227− if (error)
228− return error;
229− error = i2c_add_adapter(adapter);
230− return error;
231−}
232−EXPORT_SYMBOL(i2c_dp_aux_add_bus);
233−
23442 /* Helpers for DP link training */
23543 static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
23644 {
@@ -378,10 +186,11 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request, · 141 unmodified lines
378186
379187 /*
380188 * The specification doesn't give any recommendation on how often to
381− * retry native transactions, so retry 7 times like for I2C-over-AUX
382− * transactions.
189+ * retry native transactions. We used to retry 7 times like for
190+ * aux i2c transactions but real world devices this wasn't
191+ * sufficient, bump to 32 which makes Dell 4k monitors happier.
383192 */
384− for (retry = 0; retry < 7; retry++) {
193+ for (retry = 0; retry < 32; retry++) {
385194
386195 mutex_lock(&aux->hw_mutex);
387196 err = aux->transfer(aux, &msg);
@@ -654,10 +463,12 @@ static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg) · 266 unmodified lines
654463
655464 case DP_AUX_I2C_REPLY_NACK:
656465 DRM_DEBUG_KMS("I2C nack\n");
466+ aux->i2c_nack_count++;
657467 return -EREMOTEIO;
658468
659469 case DP_AUX_I2C_REPLY_DEFER:
660470 DRM_DEBUG_KMS("I2C defer\n");
471+ aux->i2c_defer_count++;
661472 usleep_range(400, 500);
662473 continue;
663474
drivers/gpu/drm/drm_dp_mst_topology.c+52−16
@@ -839,6 +839,8 @@ static void drm_dp_put_mst_branch_device(struct drm_dp_mst_branch *mstb) · 838 unmodified lines
839839
840840 static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
841841 {
842+ struct drm_dp_mst_branch *mstb;
843+
842844 switch (old_pdt) {
843845 case DP_PEER_DEVICE_DP_LEGACY_CONV:
844846 case DP_PEER_DEVICE_SST_SINK:
@@ -846,8 +848,9 @@ static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt) · 1 unmodified line
846848 drm_dp_mst_unregister_i2c_bus(&port->aux);
847849 break;
848850 case DP_PEER_DEVICE_MST_BRANCHING:
849− drm_dp_put_mst_branch_device(port->mstb);
851+ mstb = port->mstb;
850852 port->mstb = NULL;
853+ drm_dp_put_mst_branch_device(mstb);
851854 break;
852855 }
853856 }
@@ -858,6 +861,8 @@ static void drm_dp_destroy_port(struct kref *kref) · 4 unmodified lines
858861 struct drm_dp_mst_topology_mgr *mgr = port->mgr;
859862 if (!port->input) {
860863 port->vcpi.num_slots = 0;
864+
865+ kfree(port->cached_edid);
861866 if (port->connector)
862867 (*port->mgr->cbs->destroy_connector)(mgr, port->connector);
863868 drm_dp_port_teardown_pdt(port, port->pdt);
@@ -1011,19 +1016,20 @@ static void drm_dp_check_port_guid(struct drm_dp_mst_branch *mstb, · 147 unmodified lines
10111016
10121017 static void build_mst_prop_path(struct drm_dp_mst_port *port,
10131018 struct drm_dp_mst_branch *mstb,
1014− char *proppath)
1019+ char *proppath,
1020+ size_t proppath_size)
10151021 {
10161022 int i;
10171023 char temp[8];
1018− snprintf(proppath, 255, "mst:%d", mstb->mgr->conn_base_id);
1024+ snprintf(proppath, proppath_size, "mst:%d", mstb->mgr->conn_base_id);
10191025 for (i = 0; i < (mstb->lct - 1); i++) {
10201026 int shift = (i % 2) ? 0 : 4;
10211027 int port_num = mstb->rad[i / 2] >> shift;
1022− snprintf(temp, 8, "-%d", port_num);
1023− strncat(proppath, temp, 255);
1028+ snprintf(temp, sizeof(temp), "-%d", port_num);
1029+ strlcat(proppath, temp, proppath_size);
10241030 }
1025− snprintf(temp, 8, "-%d", port->port_num);
1026− strncat(proppath, temp, 255);
1031+ snprintf(temp, sizeof(temp), "-%d", port->port_num);
1032+ strlcat(proppath, temp, proppath_size);
10271033 }
10281034
10291035 static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,
@@ -1094,8 +1100,12 @@ static void drm_dp_add_port(struct drm_dp_mst_branch *mstb, · 64 unmodified lines
10941100
10951101 if (created && !port->input) {
10961102 char proppath[255];
1097− build_mst_prop_path(port, mstb, proppath);
1103+ build_mst_prop_path(port, mstb, proppath, sizeof(proppath));
10981104 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);
1105+
1106+ if (port->port_num >= 8) {
1107+ port->cached_edid = drm_get_edid(port->connector, &port->aux.ddc);
1108+ }
10991109 }
11001110
11011111 /* put reference to this port */
@@ -1798,17 +1808,27 @@ static int drm_dp_send_up_ack_reply(struct drm_dp_mst_topology_mgr *mgr, · 696 unmodified lines
17981808 return 0;
17991809 }
18001810
1801−static int drm_dp_get_vc_payload_bw(int dp_link_bw, int dp_link_count)
1811+static bool drm_dp_get_vc_payload_bw(int dp_link_bw,
1812+ int dp_link_count,
1813+ int *out)
18021814 {
18031815 switch (dp_link_bw) {
1816+ default:
1817+ DRM_DEBUG_KMS("invalid link bandwidth in DPCD: %x (link count: %d)\n",
1818+ dp_link_bw, dp_link_count);
1819+ return false;
1820+
18041821 case DP_LINK_BW_1_62:
1805− return 3 * dp_link_count;
1822+ *out = 3 * dp_link_count;
1823+ break;
18061824 case DP_LINK_BW_2_7:
1807− return 5 * dp_link_count;
1825+ *out = 5 * dp_link_count;
1826+ break;
18081827 case DP_LINK_BW_5_4:
1809− return 10 * dp_link_count;
1828+ *out = 10 * dp_link_count;
1829+ break;
18101830 }
1811− BUG();
1831+ return true;
18121832 }
18131833
18141834 /**
@@ -1840,7 +1860,13 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms · 25 unmodified lines
18401860 goto out_unlock;
18411861 }
18421862
1843− mgr->pbn_div = drm_dp_get_vc_payload_bw(mgr->dpcd[1], mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK);
1863+ if (!drm_dp_get_vc_payload_bw(mgr->dpcd[1],
1864+ mgr->dpcd[2] & DP_MAX_LANE_COUNT_MASK,
1865+ &mgr->pbn_div)) {
1866+ ret = -EINVAL;
1867+ goto out_unlock;
1868+ }
1869+
18441870 mgr->total_pbn = 2560;
18451871 mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
18461872 mgr->avail_slots = mgr->total_slots;
@@ -2150,7 +2176,8 @@ EXPORT_SYMBOL(drm_dp_mst_hpd_irq); · 303 unmodified lines
21502176 * This returns the current connection state for a port. It validates the
21512177 * port pointer still exists so the caller doesn't require a reference
21522178 */
2153−enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
2179+enum drm_connector_status drm_dp_mst_detect_port(struct drm_connector *connector,
2180+ struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)
21542181 {
21552182 enum drm_connector_status status = connector_status_disconnected;
21562183
@@ -2169,6 +2196,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr · 12 unmodified lines
21692196
21702197 case DP_PEER_DEVICE_SST_SINK:
21712198 status = connector_status_connected;
2199+ /* for logical ports - cache the EDID */
2200+ if (port->port_num >= 8 && !port->cached_edid) {
2201+ port->cached_edid = drm_get_edid(connector, &port->aux.ddc);
2202+ }
21722203 break;
21732204 case DP_PEER_DEVICE_DP_LEGACY_CONV:
21742205 if (port->ldps)
@@ -2200,7 +2231,12 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_ · 25 unmodified lines
22002231 if (!port)
22012232 return NULL;
22022233
2203− edid = drm_get_edid(connector, &port->aux.ddc);
2234+ if (port->cached_edid)
2235+ edid = drm_edid_duplicate(port->cached_edid);
2236+ else
2237+ edid = drm_get_edid(connector, &port->aux.ddc);
2238+
2239+ drm_mode_connector_set_tile_property(connector);
22042240 drm_dp_put_port(port);
22052241 return edid;
22062242 }
drivers/gpu/drm/drm_drv.c+5−2
@@ -56,7 +56,7 @@ static struct idr drm_minors_idr; · 55 unmodified lines
5656 struct class *drm_class;
5757 static struct dentry *drm_debugfs_root;
5858
59−void drm_err(const char *func, const char *format, ...)
59+void drm_err(const char *format, ...)
6060 {
6161 struct va_format vaf;
6262 va_list args;
@@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...) · 3 unmodified lines
6666 vaf.fmt = format;
6767 vaf.va = &args;
6868
69− printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* %pV", func, &vaf);
69+ printk(KERN_ERR "[" DRM_NAME ":%pf] *ERROR* %pV",
70+ __builtin_return_address(0), &vaf);
7071
7172 va_end(args);
7273 }
@@ -534,6 +535,8 @@ static void drm_fs_inode_free(struct inode *inode) · 461 unmodified lines
534535 * The initial ref-count of the object is 1. Use drm_dev_ref() and
535536 * drm_dev_unref() to take and drop further ref-counts.
536537 *
538+ * Note that for purely virtual devices @parent can be NULL.
539+ *
537540 * RETURNS:
538541 * Pointer to new DRM device, or NULL if out of memory.
539542 */
drivers/gpu/drm/drm_edid.c+201−30
@@ -34,6 +34,7 @@ · 33 unmodified lines
3434 #include <linux/module.h>
3535 #include <drm/drmP.h>
3636 #include <drm/drm_edid.h>
37+#include <drm/drm_displayid.h>
3738
3839 #define version_greater(edid, maj, min) \
3940 (((edid)->version > (maj)) || \
@@ -1014,6 +1015,27 @@ module_param_named(edid_fixup, edid_fixup, int, 0400); · 974 unmodified lines
10141015 MODULE_PARM_DESC(edid_fixup,
10151016 "Minimum number of valid EDID header bytes (0-8, default 6)");
10161017
1018+static void drm_get_displayid(struct drm_connector *connector,
1019+ struct edid *edid);
1020+
1021+static int drm_edid_block_checksum(const u8 *raw_edid)
1022+{
1023+ int i;
1024+ u8 csum = 0;
1025+ for (i = 0; i < EDID_LENGTH; i++)
1026+ csum += raw_edid[i];
1027+
1028+ return csum;
1029+}
1030+
1031+static bool drm_edid_is_zero(const u8 *in_edid, int length)
1032+{
1033+ if (memchr_inv(in_edid, 0, length))
1034+ return false;
1035+
1036+ return true;
1037+}
1038+
10171039 /**
10181040 * drm_edid_block_valid - Sanity check the EDID block (base or extension)
10191041 * @raw_edid: pointer to raw EDID block
@@ -1027,8 +1049,7 @@ MODULE_PARM_DESC(edid_fixup, · 7 unmodified lines
10271049 */
10281050 bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
10291051 {
1030− int i;
1031− u8 csum = 0;
1052+ u8 csum;
10321053 struct edid *edid = (struct edid *)raw_edid;
10331054
10341055 if (WARN_ON(!raw_edid))
@@ -1048,8 +1069,7 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) · 13 unmodified lines
10481069 }
10491070 }
10501071
1051− for (i = 0; i < EDID_LENGTH; i++)
1052− csum += raw_edid[i];
1072+ csum = drm_edid_block_checksum(raw_edid);
10531073 if (csum) {
10541074 if (print_bad_edid) {
10551075 DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);
@@ -1080,9 +1100,13 @@ bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid) · 24 unmodified lines
10801100
10811101 bad:
10821102 if (print_bad_edid) {
1083− printk(KERN_ERR "Raw EDID:\n");
1084− print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
1103+ if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
1104+ printk(KERN_ERR "EDID block is all zeroes\n");
1105+ } else {
1106+ printk(KERN_ERR "Raw EDID:\n");
1107+ print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,
10851108 raw_edid, EDID_LENGTH, false);
1109+ }
10861110 }
10871111 return false;
10881112 }
@@ -1115,7 +1139,7 @@ EXPORT_SYMBOL(drm_edid_is_valid); · 26 unmodified lines
11151139 #define DDC_SEGMENT_ADDR 0x30
11161140 /**
11171141 * drm_do_probe_ddc_edid() - get EDID information via I2C
1118− * @adapter: I2C device adaptor
1142+ * @data: I2C device adapter
11191143 * @buf: EDID data buffer to be filled
11201144 * @block: 128 byte EDID block to start fetching from
11211145 * @len: EDID data buffer length to fetch
@@ -1125,9 +1149,9 @@ EXPORT_SYMBOL(drm_edid_is_valid); · 3 unmodified lines
11251149 * Return: 0 on success or -1 on failure.
11261150 */
11271151 static int
1128−drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,
1129− int block, int len)
1152+drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
11301153 {
1154+ struct i2c_adapter *adapter = data;
11311155 unsigned char start = block * EDID_LENGTH;
11321156 unsigned char segment = block >> 1;
11331157 unsigned char xfers = segment ? 3 : 2;
@@ -1176,16 +1200,26 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, · 42 unmodified lines
11761200 return ret == xfers ? 0 : -1;
11771201 }
11781202
1179−static bool drm_edid_is_zero(u8 *in_edid, int length)
1180−{
1181− if (memchr_inv(in_edid, 0, length))
1182− return false;
1183−
1184− return true;
1185−}
1186−
1187−static u8 *
1188−drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)
1203+/**
1204+ * drm_do_get_edid - get EDID data using a custom EDID block read function
1205+ * @connector: connector we're probing
1206+ * @get_edid_block: EDID block read function
1207+ * @data: private data passed to the block read function
1208+ *
1209+ * When the I2C adapter connected to the DDC bus is hidden behind a device that
1210+ * exposes a different interface to read EDID blocks this function can be used
1211+ * to get EDID data using a custom block read function.
1212+ *
1213+ * As in the general case the DDC bus is accessible by the kernel at the I2C
1214+ * level, drivers must make all reasonable efforts to expose it as an I2C
1215+ * adapter and use drm_get_edid() instead of abusing this function.
1216+ *
1217+ * Return: Pointer to valid EDID or NULL if we couldn't find any.
1218+ */
1219+struct edid *drm_do_get_edid(struct drm_connector *connector,
1220+ int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
1221+ size_t len),
1222+ void *data)
11891223 {
11901224 int i, j = 0, valid_extensions = 0;
11911225 u8 *block, *new;
@@ -1196,7 +1230,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 4 unmodified lines
11961230
11971231 /* base block fetch */
11981232 for (i = 0; i < 4; i++) {
1199− if (drm_do_probe_ddc_edid(adapter, block, 0, EDID_LENGTH))
1233+ if (get_edid_block(data, block, 0, EDID_LENGTH))
12001234 goto out;
12011235 if (drm_edid_block_valid(block, 0, print_bad_edid))
12021236 break;
@@ -1210,7 +1244,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 7 unmodified lines
12101244
12111245 /* if there's no extensions, we're done */
12121246 if (block[0x7e] == 0)
1213− return block;
1247+ return (struct edid *)block;
12141248
12151249 new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
12161250 if (!new)
@@ -1219,7 +1253,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 2 unmodified lines
12191253
12201254 for (j = 1; j <= block[0x7e]; j++) {
12211255 for (i = 0; i < 4; i++) {
1222− if (drm_do_probe_ddc_edid(adapter,
1256+ if (get_edid_block(data,
12231257 block + (valid_extensions + 1) * EDID_LENGTH,
12241258 j, EDID_LENGTH))
12251259 goto out;
@@ -1247,7 +1281,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 21 unmodified lines
12471281 block = new;
12481282 }
12491283
1250− return block;
1284+ return (struct edid *)block;
12511285
12521286 carp:
12531287 if (print_bad_edid) {
@@ -1260,6 +1294,7 @@ out: · 6 unmodified lines
12601294 kfree(block);
12611295 return NULL;
12621296 }
1297+EXPORT_SYMBOL_GPL(drm_do_get_edid);
12631298
12641299 /**
12651300 * drm_probe_ddc() - probe DDC presence
@@ -1289,11 +1324,14 @@ EXPORT_SYMBOL(drm_probe_ddc); · 23 unmodified lines
12891324 struct edid *drm_get_edid(struct drm_connector *connector,
12901325 struct i2c_adapter *adapter)
12911326 {
1292− struct edid *edid = NULL;
1327+ struct edid *edid;
12931328
1294− if (drm_probe_ddc(adapter))
1295− edid = (struct edid *)drm_do_get_edid(connector, adapter);
1329+ if (!drm_probe_ddc(adapter))
1330+ return NULL;
12961331
1332+ edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
1333+ if (edid)
1334+ drm_get_displayid(connector, edid);
12971335 return edid;
12981336 }
12991337 EXPORT_SYMBOL(drm_get_edid);
@@ -2389,7 +2427,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, · 1089 unmodified lines
23892427 /*
23902428 * Search EDID for CEA extension block.
23912429 */
2392−static u8 *drm_find_cea_extension(struct edid *edid)
2430+static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
23932431 {
23942432 u8 *edid_ext = NULL;
23952433 int i;
@@ -2401,7 +2439,7 @@ static u8 *drm_find_cea_extension(struct edid *edid) · 5 unmodified lines
24012439 /* Find CEA extension */
24022440 for (i = 0; i < edid->extensions; i++) {
24032441 edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
2404− if (edid_ext[0] == CEA_EXT)
2442+ if (edid_ext[0] == ext_id)
24052443 break;
24062444 }
24072445
@@ -2411,6 +2449,16 @@ static u8 *drm_find_cea_extension(struct edid *edid) · 3 unmodified lines
24112449 return edid_ext;
24122450 }
24132451
2452+static u8 *drm_find_cea_extension(struct edid *edid)
2453+{
2454+ return drm_find_edid_extension(edid, CEA_EXT);
2455+}
2456+
2457+static u8 *drm_find_displayid_extension(struct edid *edid)
2458+{
2459+ return drm_find_edid_extension(edid, DISPLAYID_EXT);
2460+}
2461+
24142462 /*
24152463 * Calculate the alternate clock for the CEA mode
24162464 * (60Hz vs. 59.94Hz etc.)
@@ -3128,9 +3176,12 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) · 711 unmodified lines
31283176 }
31293177 }
31303178 eld[5] |= sad_count << 4;
3131− eld[2] = (20 + mnl + sad_count * 3 + 3) / 4;
31323179
3133− DRM_DEBUG_KMS("ELD size %d, SAD count %d\n", (int)eld[2], sad_count);
3180+ eld[DRM_ELD_BASELINE_ELD_LEN] =
3181+ DIV_ROUND_UP(drm_eld_calc_baseline_block_size(eld), 4);
3182+
3183+ DRM_DEBUG_KMS("ELD size %d, SAD count %d\n",
3184+ drm_eld_size(eld), sad_count);
31343185 }
31353186 EXPORT_SYMBOL(drm_edid_to_eld);
31363187
@@ -3868,3 +3919,123 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, · 731 unmodified lines
38683919 return 0;
38693920 }
38703921 EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
3922+
3923+static int drm_parse_display_id(struct drm_connector *connector,
3924+ u8 *displayid, int length,
3925+ bool is_edid_extension)
3926+{
3927+ /* if this is an EDID extension the first byte will be 0x70 */
3928+ int idx = 0;
3929+ struct displayid_hdr *base;
3930+ struct displayid_block *block;
3931+ u8 csum = 0;
3932+ int i;
3933+
3934+ if (is_edid_extension)
3935+ idx = 1;
3936+
3937+ base = (struct displayid_hdr *)&displayid[idx];
3938+
3939+ DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",
3940+ base->rev, base->bytes, base->prod_id, base->ext_count);
3941+
3942+ if (base->bytes + 5 > length - idx)
3943+ return -EINVAL;
3944+
3945+ for (i = idx; i <= base->bytes + 5; i++) {
3946+ csum += displayid[i];
3947+ }
3948+ if (csum) {
3949+ DRM_ERROR("DisplayID checksum invalid, remainder is %d\n", csum);
3950+ return -EINVAL;
3951+ }
3952+
3953+ block = (struct displayid_block *)&displayid[idx + 4];
3954+ DRM_DEBUG_KMS("block id %d, rev %d, len %d\n",
3955+ block->tag, block->rev, block->num_bytes);
3956+
3957+ switch (block->tag) {
3958+ case DATA_BLOCK_TILED_DISPLAY: {
3959+ struct displayid_tiled_block *tile = (struct displayid_tiled_block *)block;
3960+
3961+ u16 w, h;
3962+ u8 tile_v_loc, tile_h_loc;
3963+ u8 num_v_tile, num_h_tile;
3964+ struct drm_tile_group *tg;
3965+
3966+ w = tile->tile_size[0] | tile->tile_size[1] << 8;
3967+ h = tile->tile_size[2] | tile->tile_size[3] << 8;
3968+
3969+ num_v_tile = (tile->topo[0] & 0xf) | (tile->topo[2] & 0x30);
3970+ num_h_tile = (tile->topo[0] >> 4) | ((tile->topo[2] >> 2) & 0x30);
3971+ tile_v_loc = (tile->topo[1] & 0xf) | ((tile->topo[2] & 0x3) << 4);
3972+ tile_h_loc = (tile->topo[1] >> 4) | (((tile->topo[2] >> 2) & 0x3) << 4);
3973+
3974+ connector->has_tile = true;
3975+ if (tile->tile_cap & 0x80)
3976+ connector->tile_is_single_monitor = true;
3977+
3978+ connector->num_h_tile = num_h_tile + 1;
3979+ connector->num_v_tile = num_v_tile + 1;
3980+ connector->tile_h_loc = tile_h_loc;
3981+ connector->tile_v_loc = tile_v_loc;
3982+ connector->tile_h_size = w + 1;
3983+ connector->tile_v_size = h + 1;
3984+
3985+ DRM_DEBUG_KMS("tile cap 0x%x\n", tile->tile_cap);
3986+ DRM_DEBUG_KMS("tile_size %d x %d\n", w + 1, h + 1);
3987+ DRM_DEBUG_KMS("topo num tiles %dx%d, location %dx%d\n",
3988+ num_h_tile + 1, num_v_tile + 1, tile_h_loc, tile_v_loc);
3989+ DRM_DEBUG_KMS("vend %c%c%c\n", tile->topology_id[0], tile->topology_id[1], tile->topology_id[2]);
3990+
3991+ tg = drm_mode_get_tile_group(connector->dev, tile->topology_id);
3992+ if (!tg) {
3993+ tg = drm_mode_create_tile_group(connector->dev, tile->topology_id);
3994+ }
3995+ if (!tg)
3996+ return -ENOMEM;
3997+
3998+ if (connector->tile_group != tg) {
3999+ /* if we haven't got a pointer,
4000+ take the reference, drop ref to old tile group */
4001+ if (connector->tile_group) {
4002+ drm_mode_put_tile_group(connector->dev, connector->tile_group);
4003+ }
4004+ connector->tile_group = tg;
4005+ } else
4006+ /* if same tile group, then release the ref we just took. */
4007+ drm_mode_put_tile_group(connector->dev, tg);
4008+ }
4009+ break;
4010+ default:
4011+ printk("unknown displayid tag %d\n", block->tag);
4012+ break;
4013+ }
4014+ return 0;
4015+}
4016+
4017+static void drm_get_displayid(struct drm_connector *connector,
4018+ struct edid *edid)
4019+{
4020+ void *displayid = NULL;
4021+ int ret;
4022+ connector->has_tile = false;
4023+ displayid = drm_find_displayid_extension(edid);
4024+ if (!displayid) {
4025+ /* drop reference to any tile group we had */
4026+ goto out_drop_ref;
4027+ }
4028+
4029+ ret = drm_parse_display_id(connector, displayid, EDID_LENGTH, true);
4030+ if (ret < 0)
4031+ goto out_drop_ref;
4032+ if (!connector->has_tile)
4033+ goto out_drop_ref;
4034+ return;
4035+out_drop_ref:
4036+ if (connector->tile_group) {
4037+ drm_mode_put_tile_group(connector->dev, connector->tile_group);
4038+ connector->tile_group = NULL;
4039+ }
4040+ return;
4041+}
drivers/gpu/drm/drm_edid_load.c+1−2
@@ -254,8 +254,7 @@ static void *edid_load(struct drm_connector *connector, const char *name, · 253 unmodified lines
254254 name, connector_name);
255255
256256 out:
257− if (fw)
258− release_firmware(fw);
257+ release_firmware(fw);
259258 return edid;
260259 }
261260
drivers/gpu/drm/drm_fb_helper.c+110−25
@@ -347,9 +347,18 @@ bool drm_fb_helper_restore_fbdev_mode_unlocked(struct drm_fb_helper *fb_helper) · 346 unmodified lines
347347 {
348348 struct drm_device *dev = fb_helper->dev;
349349 bool ret;
350+ bool do_delayed = false;
351+
350352 drm_modeset_lock_all(dev);
351353 ret = restore_fbdev_mode(fb_helper);
354+
355+ do_delayed = fb_helper->delayed_hotplug;
356+ if (do_delayed)
357+ fb_helper->delayed_hotplug = false;
352358 drm_modeset_unlock_all(dev);
359+
360+ if (do_delayed)
361+ drm_fb_helper_hotplug_event(fb_helper);
353362 return ret;
354363 }
355364 EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);
@@ -888,10 +897,6 @@ int drm_fb_helper_set_par(struct fb_info *info) · 532 unmodified lines
888897
889898 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
890899
891− if (fb_helper->delayed_hotplug) {
892− fb_helper->delayed_hotplug = false;
893− drm_fb_helper_hotplug_event(fb_helper);
894− }
895900 return 0;
896901 }
897902 EXPORT_SYMBOL(drm_fb_helper_set_par);
@@ -995,19 +1000,21 @@ static int drm_fb_helper_single_fb_probe(struct drm_fb_helper *fb_helper, · 97 unmodified lines
9951000 crtc_count = 0;
9961001 for (i = 0; i < fb_helper->crtc_count; i++) {
9971002 struct drm_display_mode *desired_mode;
1003+ int x, y;
9981004 desired_mode = fb_helper->crtc_info[i].desired_mode;
999−
1005+ x = fb_helper->crtc_info[i].x;
1006+ y = fb_helper->crtc_info[i].y;
10001007 if (desired_mode) {
10011008 if (gamma_size == 0)
10021009 gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
1003− if (desired_mode->hdisplay < sizes.fb_width)
1004− sizes.fb_width = desired_mode->hdisplay;
1005− if (desired_mode->vdisplay < sizes.fb_height)
1006− sizes.fb_height = desired_mode->vdisplay;
1007− if (desired_mode->hdisplay > sizes.surface_width)
1008− sizes.surface_width = desired_mode->hdisplay;
1009− if (desired_mode->vdisplay > sizes.surface_height)
1010− sizes.surface_height = desired_mode->vdisplay;
1010+ if (desired_mode->hdisplay + x < sizes.fb_width)
1011+ sizes.fb_width = desired_mode->hdisplay + x;
1012+ if (desired_mode->vdisplay + y < sizes.fb_height)
1013+ sizes.fb_height = desired_mode->vdisplay + y;
1014+ if (desired_mode->hdisplay + x > sizes.surface_width)
1015+ sizes.surface_width = desired_mode->hdisplay + x;
1016+ if (desired_mode->vdisplay + y > sizes.surface_height)
1017+ sizes.surface_height = desired_mode->vdisplay + y;
10111018 crtc_count++;
10121019 }
10131020 }
@@ -1307,6 +1314,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper, · 293 unmodified lines
13071314
13081315 static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
13091316 struct drm_display_mode **modes,
1317+ struct drm_fb_offset *offsets,
13101318 bool *enabled, int width, int height)
13111319 {
13121320 int count, i, j;
@@ -1378,27 +1386,88 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, · 65 unmodified lines
13781386 return false;
13791387 }
13801388
1389+static int drm_get_tile_offsets(struct drm_fb_helper *fb_helper,
1390+ struct drm_display_mode **modes,
1391+ struct drm_fb_offset *offsets,
1392+ int idx,
1393+ int h_idx, int v_idx)
1394+{
1395+ struct drm_fb_helper_connector *fb_helper_conn;
1396+ int i;
1397+ int hoffset = 0, voffset = 0;
1398+
1399+ for (i = 0; i < fb_helper->connector_count; i++) {
1400+ fb_helper_conn = fb_helper->connector_info[i];
1401+ if (!fb_helper_conn->connector->has_tile)
1402+ continue;
1403+
1404+ if (!modes[i] && (h_idx || v_idx)) {
1405+ DRM_DEBUG_KMS("no modes for connector tiled %d %d\n", i,
1406+ fb_helper_conn->connector->base.id);
1407+ continue;
1408+ }
1409+ if (fb_helper_conn->connector->tile_h_loc < h_idx)
1410+ hoffset += modes[i]->hdisplay;
1411+
1412+ if (fb_helper_conn->connector->tile_v_loc < v_idx)
1413+ voffset += modes[i]->vdisplay;
1414+ }
1415+ offsets[idx].x = hoffset;
1416+ offsets[idx].y = voffset;
1417+ DRM_DEBUG_KMS("returned %d %d for %d %d\n", hoffset, voffset, h_idx, v_idx);
1418+ return 0;
1419+}
1420+
13811421 static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
13821422 struct drm_display_mode **modes,
1423+ struct drm_fb_offset *offsets,
13831424 bool *enabled, int width, int height)
13841425 {
13851426 struct drm_fb_helper_connector *fb_helper_conn;
13861427 int i;
1387−
1428+ uint64_t conn_configured = 0, mask;
1429+ int tile_pass = 0;
1430+ mask = (1 << fb_helper->connector_count) - 1;
1431+retry:
13881432 for (i = 0; i < fb_helper->connector_count; i++) {
13891433 fb_helper_conn = fb_helper->connector_info[i];
13901434
1391− if (enabled[i] == false)
1435+ if (conn_configured & (1 << i))
13921436 continue;
13931437
1438+ if (enabled[i] == false) {
1439+ conn_configured |= (1 << i);
1440+ continue;
1441+ }
1442+
1443+ /* first pass over all the untiled connectors */
1444+ if (tile_pass == 0 && fb_helper_conn->connector->has_tile)
1445+ continue;
1446+
1447+ if (tile_pass == 1) {
1448+ if (fb_helper_conn->connector->tile_h_loc != 0 ||
1449+ fb_helper_conn->connector->tile_v_loc != 0)
1450+ continue;
1451+
1452+ } else {
1453+ if (fb_helper_conn->connector->tile_h_loc != tile_pass -1 &&
1454+ fb_helper_conn->connector->tile_v_loc != tile_pass - 1)
1455+ /* if this tile_pass doesn't cover any of the tiles - keep going */
1456+ continue;
1457+
1458+ /* find the tile offsets for this pass - need
1459+ to find all tiles left and above */
1460+ drm_get_tile_offsets(fb_helper, modes, offsets,
1461+ i, fb_helper_conn->connector->tile_h_loc, fb_helper_conn->connector->tile_v_loc);
1462+ }
13941463 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
13951464 fb_helper_conn->connector->base.id);
13961465
13971466 /* got for command line mode first */
13981467 modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height);
13991468 if (!modes[i]) {
1400− DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",
1401− fb_helper_conn->connector->base.id);
1469+ DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
1470+ fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0);
14021471 modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height);
14031472 }
14041473 /* No preferred modes, pick one off the list */
@@ -1408,6 +1477,12 @@ static bool drm_target_preferred(struct drm_fb_helper *fb_helper, · 3 unmodified lines
14081477 }
14091478 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
14101479 "none");
1480+ conn_configured |= (1 << i);
1481+ }
1482+
1483+ if ((conn_configured & mask) != mask) {
1484+ tile_pass++;
1485+ goto retry;
14111486 }
14121487 return true;
14131488 }
@@ -1497,6 +1572,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 83 unmodified lines
14971572 struct drm_device *dev = fb_helper->dev;
14981573 struct drm_fb_helper_crtc **crtcs;
14991574 struct drm_display_mode **modes;
1575+ struct drm_fb_offset *offsets;
15001576 struct drm_mode_set *modeset;
15011577 bool *enabled;
15021578 int width, height;
@@ -1511,9 +1587,11 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 8 unmodified lines
15111587 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
15121588 modes = kcalloc(dev->mode_config.num_connector,
15131589 sizeof(struct drm_display_mode *), GFP_KERNEL);
1590+ offsets = kcalloc(dev->mode_config.num_connector,
1591+ sizeof(struct drm_fb_offset), GFP_KERNEL);
15141592 enabled = kcalloc(dev->mode_config.num_connector,
15151593 sizeof(bool), GFP_KERNEL);
1516− if (!crtcs || !modes || !enabled) {
1594+ if (!crtcs || !modes || !enabled || !offsets) {
15171595 DRM_ERROR("Memory allocation failed\n");
15181596 goto out;
15191597 }
@@ -1523,14 +1601,16 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 3 unmodified lines
15231601
15241602 if (!(fb_helper->funcs->initial_config &&
15251603 fb_helper->funcs->initial_config(fb_helper, crtcs, modes,
1604+ offsets,
15261605 enabled, width, height))) {
15271606 memset(modes, 0, dev->mode_config.num_connector*sizeof(modes[0]));
15281607 memset(crtcs, 0, dev->mode_config.num_connector*sizeof(crtcs[0]));
1608+ memset(offsets, 0, dev->mode_config.num_connector*sizeof(offsets[0]));
15291609
1530− if (!drm_target_cloned(fb_helper,
1531− modes, enabled, width, height) &&
1532− !drm_target_preferred(fb_helper,
1533− modes, enabled, width, height))
1610+ if (!drm_target_cloned(fb_helper, modes, offsets,
1611+ enabled, width, height) &&
1612+ !drm_target_preferred(fb_helper, modes, offsets,
1613+ enabled, width, height))
15341614 DRM_ERROR("Unable to find initial modes\n");
15351615
15361616 DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",
@@ -1550,18 +1630,23 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 13 unmodified lines
15501630 for (i = 0; i < fb_helper->connector_count; i++) {
15511631 struct drm_display_mode *mode = modes[i];
15521632 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
1633+ struct drm_fb_offset *offset = &offsets[i];
15531634 modeset = &fb_crtc->mode_set;
15541635
15551636 if (mode && fb_crtc) {
1556− DRM_DEBUG_KMS("desired mode %s set on crtc %d\n",
1557− mode->name, fb_crtc->mode_set.crtc->base.id);
1637+ DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
1638+ mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
15581639 fb_crtc->desired_mode = mode;
1640+ fb_crtc->x = offset->x;
1641+ fb_crtc->y = offset->y;
15591642 if (modeset->mode)
15601643 drm_mode_destroy(dev, modeset->mode);
15611644 modeset->mode = drm_mode_duplicate(dev,
15621645 fb_crtc->desired_mode);
15631646 modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
15641647 modeset->fb = fb_helper->fb;
1648+ modeset->x = offset->x;
1649+ modeset->y = offset->y;
15651650 }
15661651 }
15671652
@@ -1570,7 +1655,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 2 unmodified lines
15701655 modeset = &fb_helper->crtc_info[i].mode_set;
15711656 if (modeset->num_connectors == 0) {
15721657 BUG_ON(modeset->fb);
1573− BUG_ON(modeset->num_connectors);
15741658 if (modeset->mode)
15751659 drm_mode_destroy(dev, modeset->mode);
15761660 modeset->mode = NULL;
@@ -1579,6 +1663,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 2 unmodified lines
15791663 out:
15801664 kfree(crtcs);
15811665 kfree(modes);
1666+ kfree(offsets);
15821667 kfree(enabled);
15831668 }
15841669
drivers/gpu/drm/drm_flip_work.c+74−31
@@ -24,6 +24,44 @@ · 23 unmodified lines
2424 #include "drmP.h"
2525 #include "drm_flip_work.h"
2626
27+/**
28+ * drm_flip_work_allocate_task - allocate a flip-work task
29+ * @data: data associated to the task
30+ * @flags: allocator flags
31+ *
32+ * Allocate a drm_flip_task object and attach private data to it.
33+ */
34+struct drm_flip_task *drm_flip_work_allocate_task(void *data, gfp_t flags)
35+{
36+ struct drm_flip_task *task;
37+
38+ task = kzalloc(sizeof(*task), flags);
39+ if (task)
40+ task->data = data;
41+
42+ return task;
43+}
44+EXPORT_SYMBOL(drm_flip_work_allocate_task);
45+
46+/**
47+ * drm_flip_work_queue_task - queue a specific task
48+ * @work: the flip-work
49+ * @task: the task to handle
50+ *
51+ * Queues task, that will later be run (passed back to drm_flip_func_t
52+ * func) on a work queue after drm_flip_work_commit() is called.
53+ */
54+void drm_flip_work_queue_task(struct drm_flip_work *work,
55+ struct drm_flip_task *task)
56+{
57+ unsigned long flags;
58+
59+ spin_lock_irqsave(&work->lock, flags);
60+ list_add_tail(&task->node, &work->queued);
61+ spin_unlock_irqrestore(&work->lock, flags);
62+}
63+EXPORT_SYMBOL(drm_flip_work_queue_task);
64+
2765 /**
2866 * drm_flip_work_queue - queue work
2967 * @work: the flip-work
@@ -34,10 +72,14 @@ · 4 unmodified lines
3472 */
3573 void drm_flip_work_queue(struct drm_flip_work *work, void *val)
3674 {
37− if (kfifo_put(&work->fifo, val)) {
38− atomic_inc(&work->pending);
75+ struct drm_flip_task *task;
76+
77+ task = drm_flip_work_allocate_task(val,
78+ drm_can_sleep() ? GFP_KERNEL : GFP_ATOMIC);
79+ if (task) {
80+ drm_flip_work_queue_task(work, task);
3981 } else {
40− DRM_ERROR("%s fifo full!\n", work->name);
82+ DRM_ERROR("%s could not allocate task!\n", work->name);
4183 work->func(work, val);
4284 }
4385 }
@@ -56,9 +98,12 @@ EXPORT_SYMBOL(drm_flip_work_queue); · 12 unmodified lines
5698 void drm_flip_work_commit(struct drm_flip_work *work,
5799 struct workqueue_struct *wq)
58100 {
59− uint32_t pending = atomic_read(&work->pending);
60− atomic_add(pending, &work->count);
61− atomic_sub(pending, &work->pending);
101+ unsigned long flags;
102+
103+ spin_lock_irqsave(&work->lock, flags);
104+ list_splice_tail(&work->queued, &work->commited);
105+ INIT_LIST_HEAD(&work->queued);
106+ spin_unlock_irqrestore(&work->lock, flags);
62107 queue_work(wq, &work->worker);
63108 }
64109 EXPORT_SYMBOL(drm_flip_work_commit);
@@ -66,47 +111,46 @@ EXPORT_SYMBOL(drm_flip_work_commit); · 1 unmodified line
66111 static void flip_worker(struct work_struct *w)
67112 {
68113 struct drm_flip_work *work = container_of(w, struct drm_flip_work, worker);
69− uint32_t count = atomic_read(&work->count);
70− void *val = NULL;
114+ struct list_head tasks;
115+ unsigned long flags;
116+
117+ while (1) {
118+ struct drm_flip_task *task, *tmp;
119+
120+ INIT_LIST_HEAD(&tasks);
121+ spin_lock_irqsave(&work->lock, flags);
122+ list_splice_tail(&work->commited, &tasks);
123+ INIT_LIST_HEAD(&work->commited);
124+ spin_unlock_irqrestore(&work->lock, flags);
71125
72− atomic_sub(count, &work->count);
126+ if (list_empty(&tasks))
127+ break;
73128
74− while(count--)
75− if (!WARN_ON(!kfifo_get(&work->fifo, &val)))
76− work->func(work, val);
129+ list_for_each_entry_safe(task, tmp, &tasks, node) {
130+ work->func(work, task->data);
131+ kfree(task);
132+ }
133+ }
77134 }
78135
79136 /**
80137 * drm_flip_work_init - initialize flip-work
81138 * @work: the flip-work to initialize
82− * @size: the max queue depth
83139 * @name: debug name
84140 * @func: the callback work function
85141 *
86142 * Initializes/allocates resources for the flip-work
87− *
88− * RETURNS:
89− * Zero on success, error code on failure.
90143 */
91−int drm_flip_work_init(struct drm_flip_work *work, int size,
144+void drm_flip_work_init(struct drm_flip_work *work,
92145 const char *name, drm_flip_func_t func)
93146 {
94− int ret;
95−
96147 work->name = name;
97− atomic_set(&work->count, 0);
98− atomic_set(&work->pending, 0);
148+ INIT_LIST_HEAD(&work->queued);
149+ INIT_LIST_HEAD(&work->commited);
150+ spin_lock_init(&work->lock);
99151 work->func = func;
100152
101− ret = kfifo_alloc(&work->fifo, size, GFP_KERNEL);
102− if (ret) {
103− DRM_ERROR("could not allocate %s fifo\n", name);
104− return ret;
105− }
106−
107153 INIT_WORK(&work->worker, flip_worker);
108−
109− return 0;
110154 }
111155 EXPORT_SYMBOL(drm_flip_work_init);
112156
@@ -118,7 +162,6 @@ EXPORT_SYMBOL(drm_flip_work_init); · 5 unmodified lines
118162 */
119163 void drm_flip_work_cleanup(struct drm_flip_work *work)
120164 {
121− WARN_ON(!kfifo_is_empty(&work->fifo));
122− kfifo_free(&work->fifo);
165+ WARN_ON(!list_empty(&work->queued) || !list_empty(&work->commited));
123166 }
124167 EXPORT_SYMBOL(drm_flip_work_cleanup);
drivers/gpu/drm/drm_fops.c+8−5
@@ -515,16 +515,19 @@ ssize_t drm_read(struct file *filp, char __user *buffer, · 514 unmodified lines
515515 size_t total;
516516 ssize_t ret;
517517
518− ret = wait_event_interruptible(file_priv->event_wait,
519− !list_empty(&file_priv->event_list));
520− if (ret < 0)
521− return ret;
518+ if ((filp->f_flags & O_NONBLOCK) == 0) {
519+ ret = wait_event_interruptible(file_priv->event_wait,
520+ !list_empty(&file_priv->event_list));
521+ if (ret < 0)
522+ return ret;
523+ }
522524
523525 total = 0;
524526 while (drm_dequeue_event(file_priv, total, count, &e)) {
525527 if (copy_to_user(buffer + total,
526528 e->event, e->event->length)) {
527529 total = -EFAULT;
530+ e->destroy(e);
528531 break;
529532 }
530533
@@ -532,7 +535,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, · 1 unmodified line
532535 e->destroy(e);
533536 }
534537
535− return total;
538+ return total ?: -EAGAIN;
536539 }
537540 EXPORT_SYMBOL(drm_read);
538541
drivers/gpu/drm/drm_gem.c+6−7
@@ -188,7 +188,7 @@ drm_gem_remove_prime_handles(struct drm_gem_object *obj, struct drm_file *filp) · 187 unmodified lines
188188 }
189189
190190 /**
191− * drm_gem_object_free - release resources bound to userspace handles
191+ * drm_gem_object_handle_free - release resources bound to userspace handles
192192 * @obj: GEM object to clean up.
193193 *
194194 * Called after the last handle to the object has been closed
@@ -309,7 +309,7 @@ EXPORT_SYMBOL(drm_gem_dumb_destroy); · 114 unmodified lines
309309 * drm_gem_handle_create_tail - internal functions to create a handle
310310 * @file_priv: drm file-private structure to register the handle for
311311 * @obj: object to register
312− * @handlep: pionter to return the created handle to the caller
312+ * @handlep: pointer to return the created handle to the caller
313313 *
314314 * This expects the dev->object_name_lock to be held already and will drop it
315315 * before returning. Used to avoid races in establishing new handles when
@@ -362,7 +362,7 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, · 46 unmodified lines
362362 }
363363
364364 /**
365− * gem_handle_create - create a gem handle for an object
365+ * drm_gem_handle_create - create a gem handle for an object
366366 * @file_priv: drm file-private structure to register the handle for
367367 * @obj: object to register
368368 * @handlep: pionter to return the created handle to the caller
@@ -371,10 +371,9 @@ drm_gem_handle_create_tail(struct drm_file *file_priv, · 2 unmodified lines
371371 * to the object, which includes a regular reference count. Callers
372372 * will likely want to dereference the object afterwards.
373373 */
374−int
375−drm_gem_handle_create(struct drm_file *file_priv,
376− struct drm_gem_object *obj,
377− u32 *handlep)
374+int drm_gem_handle_create(struct drm_file *file_priv,
375+ struct drm_gem_object *obj,
376+ u32 *handlep)
378377 {
379378 mutex_lock(&obj->dev->object_name_lock);
380379
drivers/gpu/drm/drm_gem_cma_helper.c+215−44
@@ -29,18 +29,31 @@ · 28 unmodified lines
2929 #include <drm/drm_gem_cma_helper.h>
3030 #include <drm/drm_vma_manager.h>
3131
32−/*
32+/**
33+ * DOC: cma helpers
34+ *
35+ * The Contiguous Memory Allocator reserves a pool of memory at early boot
36+ * that is used to service requests for large blocks of contiguous memory.
37+ *
38+ * The DRM GEM/CMA helpers use this allocator as a means to provide buffer
39+ * objects that are physically contiguous in memory. This is useful for
40+ * display drivers that are unable to map scattered buffers via an IOMMU.
41+ */
42+
43+/**
3344 * __drm_gem_cma_create - Create a GEM CMA object without allocating memory
34− * @drm: The drm device
35− * @size: The GEM object size
45+ * @drm: DRM device
46+ * @size: size of the object to allocate
3647 *
37− * This function creates and initializes a GEM CMA object of the given size, but
38− * doesn't allocate any memory to back the object.
48+ * This function creates and initializes a GEM CMA object of the given size,
49+ * but doesn't allocate any memory to back the object.
3950 *
40− * Return a struct drm_gem_cma_object* on success or ERR_PTR values on failure.
51+ * Returns:
52+ * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
53+ * error code on failure.
4154 */
4255 static struct drm_gem_cma_object *
43−__drm_gem_cma_create(struct drm_device *drm, unsigned int size)
56+__drm_gem_cma_create(struct drm_device *drm, size_t size)
4457 {
4558 struct drm_gem_cma_object *cma_obj;
4659 struct drm_gem_object *gem_obj;
@@ -69,14 +82,21 @@ error: · 22 unmodified lines
6982 return ERR_PTR(ret);
7083 }
7184
72−/*
85+/**
7386 * drm_gem_cma_create - allocate an object with the given size
87+ * @drm: DRM device
88+ * @size: size of the object to allocate
89+ *
90+ * This function creates a CMA GEM object and allocates a contiguous chunk of
91+ * memory as backing store. The backing memory has the writecombine attribute
92+ * set.
7493 *
75− * returns a struct drm_gem_cma_object* on success or ERR_PTR values
76− * on failure.
94+ * Returns:
95+ * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
96+ * error code on failure.
7797 */
7898 struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
79− unsigned int size)
99+ size_t size)
80100 {
81101 struct drm_gem_cma_object *cma_obj;
82102 int ret;
@@ -104,17 +124,26 @@ error: · 21 unmodified lines
104124 }
105125 EXPORT_SYMBOL_GPL(drm_gem_cma_create);
106126
107−/*
108− * drm_gem_cma_create_with_handle - allocate an object with the given
109− * size and create a gem handle on it
127+/**
128+ * drm_gem_cma_create_with_handle - allocate an object with the given size and
129+ * return a GEM handle to it
130+ * @file_priv: DRM file-private structure to register the handle for
131+ * @drm: DRM device
132+ * @size: size of the object to allocate
133+ * @handle: return location for the GEM handle
134+ *
135+ * This function creates a CMA GEM object, allocating a physically contiguous
136+ * chunk of memory as backing store. The GEM object is then added to the list
137+ * of object associated with the given file and a handle to it is returned.
110138 *
111− * returns a struct drm_gem_cma_object* on success or ERR_PTR values
112− * on failure.
139+ * Returns:
140+ * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
141+ * error code on failure.
113142 */
114−static struct drm_gem_cma_object *drm_gem_cma_create_with_handle(
115− struct drm_file *file_priv,
116− struct drm_device *drm, unsigned int size,
117− unsigned int *handle)
143+static struct drm_gem_cma_object *
144+drm_gem_cma_create_with_handle(struct drm_file *file_priv,
145+ struct drm_device *drm, size_t size,
146+ uint32_t *handle)
118147 {
119148 struct drm_gem_cma_object *cma_obj;
120149 struct drm_gem_object *gem_obj;
@@ -145,16 +174,19 @@ err_handle_create: · 24 unmodified lines
145174 return ERR_PTR(ret);
146175 }
147176
148−/*
149− * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback
150− * function
177+/**
178+ * drm_gem_cma_free_object - free resources associated with a CMA GEM object
179+ * @gem_obj: GEM object to free
180+ *
181+ * This function frees the backing memory of the CMA GEM object, cleans up the
182+ * GEM object state and frees the memory used to store the object itself.
183+ * Drivers using the CMA helpers should set this as their DRM driver's
184+ * ->gem_free_object() callback.
151185 */
152186 void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
153187 {
154188 struct drm_gem_cma_object *cma_obj;
155189
156− drm_gem_free_mmap_offset(gem_obj);
157−
158190 cma_obj = to_drm_gem_cma_obj(gem_obj);
159191
160192 if (cma_obj->vaddr) {
@@ -170,18 +202,26 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) · 9 unmodified lines
170202 }
171203 EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);
172204
173−/*
174− * drm_gem_cma_dumb_create - (struct drm_driver)->dumb_create callback
175− * function
205+/**
206+ * drm_gem_cma_dumb_create_internal - create a dumb buffer object
207+ * @file_priv: DRM file-private structure to create the dumb buffer for
208+ * @drm: DRM device
209+ * @args: IOCTL data
210+ *
211+ * This aligns the pitch and size arguments to the minimum required. This is
212+ * an internal helper that can be wrapped by a driver to account for hardware
213+ * with more specific alignment requirements. It should not be used directly
214+ * as the ->dumb_create() callback in a DRM driver.
176215 *
177− * This aligns the pitch and size arguments to the minimum required. wrap
178− * this into your own function if you need bigger alignment.
216+ * Returns:
217+ * 0 on success or a negative error code on failure.
179218 */
180−int drm_gem_cma_dumb_create(struct drm_file *file_priv,
181− struct drm_device *dev, struct drm_mode_create_dumb *args)
219+int drm_gem_cma_dumb_create_internal(struct drm_file *file_priv,
220+ struct drm_device *drm,
221+ struct drm_mode_create_dumb *args)
182222 {
223+ unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
183224 struct drm_gem_cma_object *cma_obj;
184− int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
185225
186226 if (args->pitch < min_pitch)
187227 args->pitch = min_pitch;
@@ -189,18 +229,63 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, · 1 unmodified line
189229 if (args->size < args->pitch * args->height)
190230 args->size = args->pitch * args->height;
191231
192− cma_obj = drm_gem_cma_create_with_handle(file_priv, dev,
193− args->size, &args->handle);
232+ cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size,
233+ &args->handle);
234+ return PTR_ERR_OR_ZERO(cma_obj);
235+}
236+EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create_internal);
237+
238+/**
239+ * drm_gem_cma_dumb_create - create a dumb buffer object
240+ * @file_priv: DRM file-private structure to create the dumb buffer for
241+ * @drm: DRM device
242+ * @args: IOCTL data
243+ *
244+ * This function computes the pitch of the dumb buffer and rounds it up to an
245+ * integer number of bytes per pixel. Drivers for hardware that doesn't have
246+ * any additional restrictions on the pitch can directly use this function as
247+ * their ->dumb_create() callback.
248+ *
249+ * For hardware with additional restrictions, drivers can adjust the fields
250+ * set up by userspace and pass the IOCTL data along to the
251+ * drm_gem_cma_dumb_create_internal() function.
252+ *
253+ * Returns:
254+ * 0 on success or a negative error code on failure.
255+ */
256+int drm_gem_cma_dumb_create(struct drm_file *file_priv,
257+ struct drm_device *drm,
258+ struct drm_mode_create_dumb *args)
259+{
260+ struct drm_gem_cma_object *cma_obj;
261+
262+ args->pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
263+ args->size = args->pitch * args->height;
264+
265+ cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size,
266+ &args->handle);
194267 return PTR_ERR_OR_ZERO(cma_obj);
195268 }
196269 EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
197270
198−/*
199− * drm_gem_cma_dumb_map_offset - (struct drm_driver)->dumb_map_offset callback
200− * function
271+/**
272+ * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM
273+ * object
274+ * @file_priv: DRM file-private structure containing the GEM object
275+ * @drm: DRM device
276+ * @handle: GEM object handle
277+ * @offset: return location for the fake mmap offset
278+ *
279+ * This function look up an object by its handle and returns the fake mmap
280+ * offset associated with it. Drivers using the CMA helpers should set this
281+ * as their DRM driver's ->dumb_map_offset() callback.
282+ *
283+ * Returns:
284+ * 0 on success or a negative error code on failure.
201285 */
202286 int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,
203− struct drm_device *drm, uint32_t handle, uint64_t *offset)
287+ struct drm_device *drm, u32 handle,
288+ u64 *offset)
204289 {
205290 struct drm_gem_object *gem_obj;
206291
@@ -208,7 +293,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, · 1 unmodified line
208293
209294 gem_obj = drm_gem_object_lookup(drm, file_priv, handle);
210295 if (!gem_obj) {
211− dev_err(drm->dev, "failed to lookup gem object\n");
296+ dev_err(drm->dev, "failed to lookup GEM object\n");
212297 mutex_unlock(&drm->struct_mutex);
213298 return -EINVAL;
214299 }
@@ -251,8 +336,20 @@ static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, · 36 unmodified lines
251336 return ret;
252337 }
253338
254−/*
255− * drm_gem_cma_mmap - (struct file_operation)->mmap callback function
339+/**
340+ * drm_gem_cma_mmap - memory-map a CMA GEM object
341+ * @filp: file object
342+ * @vma: VMA for the area to be mapped
343+ *
344+ * This function implements an augmented version of the GEM DRM file mmap
345+ * operation for CMA objects: In addition to the usual GEM VMA setup it
346+ * immediately faults in the entire object instead of using on-demaind
347+ * faulting. Drivers which employ the CMA helpers should use this function
348+ * as their ->mmap() handler in the DRM device file's file_operations
349+ * structure.
350+ *
351+ * Returns:
352+ * 0 on success or a negative error code on failure.
256353 */
257354 int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
258355 {
@@ -272,7 +369,16 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) · 13 unmodified lines
272369 EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
273370
274371 #ifdef CONFIG_DEBUG_FS
275−void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m)
372+/**
373+ * drm_gem_cma_describe - describe a CMA GEM object for debugfs
374+ * @cma_obj: CMA GEM object
375+ * @m: debugfs file handle
376+ *
377+ * This function can be used to dump a human-readable representation of the
378+ * CMA GEM object into a synthetic file.
379+ */
380+void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj,
381+ struct seq_file *m)
276382 {
277383 struct drm_gem_object *obj = &cma_obj->base;
278384 struct drm_device *dev = obj->dev;
@@ -291,7 +397,18 @@ void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj, struct seq_file *m · 12 unmodified lines
291397 EXPORT_SYMBOL_GPL(drm_gem_cma_describe);
292398 #endif
293399
294−/* low-level interface prime helpers */
400+/**
401+ * drm_gem_cma_prime_get_sg_table - provide a scatter/gather table of pinned
402+ * pages for a CMA GEM object
403+ * @obj: GEM object
404+ *
405+ * This function exports a scatter/gather table suitable for PRIME usage by
406+ * calling the standard DMA mapping API. Drivers using the CMA helpers should
407+ * set this as their DRM driver's ->gem_prime_get_sg_table() callback.
408+ *
409+ * Returns:
410+ * A pointer to the scatter/gather table of pinned pages or NULL on failure.
411+ */
295412 struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj)
296413 {
297414 struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
@@ -315,6 +432,23 @@ out: · 17 unmodified lines
315432 }
316433 EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table);
317434
435+/**
436+ * drm_gem_cma_prime_import_sg_table - produce a CMA GEM object from another
437+ * driver's scatter/gather table of pinned pages
438+ * @dev: device to import into
439+ * @attach: DMA-BUF attachment
440+ * @sgt: scatter/gather table of pinned pages
441+ *
442+ * This function imports a scatter/gather table exported via DMA-BUF by
443+ * another driver. Imported buffers must be physically contiguous in memory
444+ * (i.e. the scatter/gather table must contain a single entry). Drivers that
445+ * use the CMA helpers should set this as their DRM driver's
446+ * ->gem_prime_import_sg_table() callback.
447+ *
448+ * Returns:
449+ * A pointer to a newly created GEM object or an ERR_PTR-encoded negative
450+ * error code on failure.
451+ */
318452 struct drm_gem_object *
319453 drm_gem_cma_prime_import_sg_table(struct drm_device *dev,
320454 struct dma_buf_attachment *attach,
@@ -339,6 +473,18 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, · 18 unmodified lines
339473 }
340474 EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);
341475
476+/**
477+ * drm_gem_cma_prime_mmap - memory-map an exported CMA GEM object
478+ * @obj: GEM object
479+ * @vma: VMA for the area to be mapped
480+ *
481+ * This function maps a buffer imported via DRM PRIME into a userspace
482+ * process's address space. Drivers that use the CMA helpers should set this
483+ * as their DRM driver's ->gem_prime_mmap() callback.
484+ *
485+ * Returns:
486+ * 0 on success or a negative error code on failure.
487+ */
342488 int drm_gem_cma_prime_mmap(struct drm_gem_object *obj,
343489 struct vm_area_struct *vma)
344490 {
@@ -357,6 +503,20 @@ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, · 12 unmodified lines
357503 }
358504 EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);
359505
506+/**
507+ * drm_gem_cma_prime_vmap - map a CMA GEM object into the kernel's virtual
508+ * address space
509+ * @obj: GEM object
510+ *
511+ * This function maps a buffer exported via DRM PRIME into the kernel's
512+ * virtual address space. Since the CMA buffers are already mapped into the
513+ * kernel virtual address space this simply returns the cached virtual
514+ * address. Drivers using the CMA helpers should set this as their DRM
515+ * driver's ->gem_prime_vmap() callback.
516+ *
517+ * Returns:
518+ * The kernel virtual address of the CMA GEM object's backing store.
519+ */
360520 void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj)
361521 {
362522 struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
@@ -365,6 +525,17 @@ void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj) · 2 unmodified lines
365525 }
366526 EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap);
367527
528+/**
529+ * drm_gem_cma_prime_vunmap - unmap a CMA GEM object from the kernel's virtual
530+ * address space
531+ * @obj: GEM object
532+ * @vaddr: kernel virtual address where the CMA GEM object was mapped
533+ *
534+ * This function removes a buffer exported via DRM PRIME from the kernel's
535+ * virtual address space. This is a no-op because CMA buffers cannot be
536+ * unmapped from kernel space. Drivers using the CMA helpers should set this
537+ * as their DRM driver's ->gem_prime_vunmap() callback.
538+ */
368539 void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
369540 {
370541 /* Nothing to do */
drivers/gpu/drm/drm_irq.c+5−4
@@ -166,7 +166,7 @@ static void vblank_disable_and_save(struct drm_device *dev, int crtc) · 165 unmodified lines
166166 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
167167
168168 /*
169− * If the vblank interrupt was already disbled update the count
169+ * If the vblank interrupt was already disabled update the count
170170 * and timestamp to maintain the appearance that the counter
171171 * has been ticking all along until this time. This makes the
172172 * count account for the entire time between drm_vblank_on() and
@@ -1029,7 +1029,8 @@ void drm_vblank_put(struct drm_device *dev, int crtc) · 856 unmodified lines
10291029 {
10301030 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
10311031
1032− BUG_ON(atomic_read(&vblank->refcount) == 0);
1032+ if (WARN_ON(atomic_read(&vblank->refcount) == 0))
1033+ return;
10331034
10341035 if (WARN_ON(crtc >= dev->num_crtcs))
10351036 return;
@@ -1190,7 +1191,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off); · 154 unmodified lines
11901191 *
11911192 * This functions restores the vblank interrupt state captured with
11921193 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
1193− * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
1194+ * drm_vblank_off() can be unbalanced and so can also be unconditionally called
11941195 * in driver load code to reflect the current hardware state of the crtc.
11951196 *
11961197 * This is the legacy version of drm_crtc_vblank_on().
@@ -1237,7 +1238,7 @@ EXPORT_SYMBOL(drm_vblank_on); · 40 unmodified lines
12371238 *
12381239 * This functions restores the vblank interrupt state captured with
12391240 * drm_vblank_off() again. Note that calls to drm_vblank_on() and
1240− * drm_vblank_off() can be unbalanced and so can also be unconditionaly called
1241+ * drm_vblank_off() can be unbalanced and so can also be unconditionally called
12411242 * in driver load code to reflect the current hardware state of the crtc.
12421243 *
12431244 * This is the native kms version of drm_vblank_on().
drivers/gpu/drm/drm_mipi_dsi.c+630−30
@@ -35,6 +35,16 @@ · 34 unmodified lines
3535
3636 #include <video/mipi_display.h>
3737
38+/**
39+ * DOC: dsi helpers
40+ *
41+ * These functions contain some common logic and helpers to deal with MIPI DSI
42+ * peripherals.
43+ *
44+ * Helpers are provided for a number of standard MIPI DSI command as well as a
45+ * subset of the MIPI DCS command set.
46+ */
47+
3848 static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
3949 {
4050 return of_driver_match_device(dev, drv);
@@ -57,6 +67,29 @@ static struct bus_type mipi_dsi_bus_type = { · 16 unmodified lines
5767 .pm = &mipi_dsi_device_pm_ops,
5868 };
5969
70+static int of_device_match(struct device *dev, void *data)
71+{
72+ return dev->of_node == data;
73+}
74+
75+/**
76+ * of_find_mipi_dsi_device_by_node() - find the MIPI DSI device matching a
77+ * device tree node
78+ * @np: device tree node
79+ *
80+ * Return: A pointer to the MIPI DSI device corresponding to @np or NULL if no
81+ * such device exists (or has not been registered yet).
82+ */
83+struct mipi_dsi_device *of_find_mipi_dsi_device_by_node(struct device_node *np)
84+{
85+ struct device *dev;
86+
87+ dev = bus_find_device(&mipi_dsi_bus_type, NULL, np, of_device_match);
88+
89+ return dev ? to_mipi_dsi_device(dev) : NULL;
90+}
91+EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
92+
6093 static void mipi_dsi_dev_release(struct device *dev)
6194 {
6295 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);
@@ -198,59 +231,351 @@ int mipi_dsi_detach(struct mipi_dsi_device *dsi) · 135 unmodified lines
198231 }
199232 EXPORT_SYMBOL(mipi_dsi_detach);
200233
234+static ssize_t mipi_dsi_device_transfer(struct mipi_dsi_device *dsi,
235+ struct mipi_dsi_msg *msg)
236+{
237+ const struct mipi_dsi_host_ops *ops = dsi->host->ops;
238+
239+ if (!ops || !ops->transfer)
240+ return -ENOSYS;
241+
242+ if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
243+ msg->flags |= MIPI_DSI_MSG_USE_LPM;
244+
245+ return ops->transfer(dsi->host, msg);
246+}
247+
201248 /**
202− * mipi_dsi_dcs_write - send DCS write command
203− * @dsi: DSI device
204− * @data: pointer to the command followed by parameters
205− * @len: length of @data
249+ * mipi_dsi_packet_format_is_short - check if a packet is of the short format
250+ * @type: MIPI DSI data type of the packet
251+ *
252+ * Return: true if the packet for the given data type is a short packet, false
253+ * otherwise.
206254 */
207−ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data,
208− size_t len)
255+bool mipi_dsi_packet_format_is_short(u8 type)
256+{
257+ switch (type) {
258+ case MIPI_DSI_V_SYNC_START:
259+ case MIPI_DSI_V_SYNC_END:
260+ case MIPI_DSI_H_SYNC_START:
261+ case MIPI_DSI_H_SYNC_END:
262+ case MIPI_DSI_END_OF_TRANSMISSION:
263+ case MIPI_DSI_COLOR_MODE_OFF:
264+ case MIPI_DSI_COLOR_MODE_ON:
265+ case MIPI_DSI_SHUTDOWN_PERIPHERAL:
266+ case MIPI_DSI_TURN_ON_PERIPHERAL:
267+ case MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM:
268+ case MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM:
269+ case MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM:
270+ case MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM:
271+ case MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM:
272+ case MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM:
273+ case MIPI_DSI_DCS_SHORT_WRITE:
274+ case MIPI_DSI_DCS_SHORT_WRITE_PARAM:
275+ case MIPI_DSI_DCS_READ:
276+ case MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE:
277+ return true;
278+ }
279+
280+ return false;
281+}
282+EXPORT_SYMBOL(mipi_dsi_packet_format_is_short);
283+
284+/**
285+ * mipi_dsi_packet_format_is_long - check if a packet is of the long format
286+ * @type: MIPI DSI data type of the packet
287+ *
288+ * Return: true if the packet for the given data type is a long packet, false
289+ * otherwise.
290+ */
291+bool mipi_dsi_packet_format_is_long(u8 type)
292+{
293+ switch (type) {
294+ case MIPI_DSI_NULL_PACKET:
295+ case MIPI_DSI_BLANKING_PACKET:
296+ case MIPI_DSI_GENERIC_LONG_WRITE:
297+ case MIPI_DSI_DCS_LONG_WRITE:
298+ case MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20:
299+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24:
300+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16:
301+ case MIPI_DSI_PACKED_PIXEL_STREAM_30:
302+ case MIPI_DSI_PACKED_PIXEL_STREAM_36:
303+ case MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12:
304+ case MIPI_DSI_PACKED_PIXEL_STREAM_16:
305+ case MIPI_DSI_PACKED_PIXEL_STREAM_18:
306+ case MIPI_DSI_PIXEL_STREAM_3BYTE_18:
307+ case MIPI_DSI_PACKED_PIXEL_STREAM_24:
308+ return true;
309+ }
310+
311+ return false;
312+}
313+EXPORT_SYMBOL(mipi_dsi_packet_format_is_long);
314+
315+/**
316+ * mipi_dsi_create_packet - create a packet from a message according to the
317+ * DSI protocol
318+ * @packet: pointer to a DSI packet structure
319+ * @msg: message to translate into a packet
320+ *
321+ * Return: 0 on success or a negative error code on failure.
322+ */
323+int mipi_dsi_create_packet(struct mipi_dsi_packet *packet,
324+ const struct mipi_dsi_msg *msg)
325+{
326+ const u8 *tx = msg->tx_buf;
327+
328+ if (!packet || !msg)
329+ return -EINVAL;
330+
331+ /* do some minimum sanity checking */
332+ if (!mipi_dsi_packet_format_is_short(msg->type) &&
333+ !mipi_dsi_packet_format_is_long(msg->type))
334+ return -EINVAL;
335+
336+ if (msg->channel > 3)
337+ return -EINVAL;
338+
339+ memset(packet, 0, sizeof(*packet));
340+ packet->header[0] = ((msg->channel & 0x3) << 6) | (msg->type & 0x3f);
341+
342+ /* TODO: compute ECC if hardware support is not available */
343+
344+ /*
345+ * Long write packets contain the word count in header bytes 1 and 2.
346+ * The payload follows the header and is word count bytes long.
347+ *
348+ * Short write packets encode up to two parameters in header bytes 1
349+ * and 2.
350+ */
351+ if (mipi_dsi_packet_format_is_long(msg->type)) {
352+ packet->header[1] = (msg->tx_len >> 0) & 0xff;
353+ packet->header[2] = (msg->tx_len >> 8) & 0xff;
354+
355+ packet->payload_length = msg->tx_len;
356+ packet->payload = tx;
357+ } else {
358+ packet->header[1] = (msg->tx_len > 0) ? tx[0] : 0;
359+ packet->header[2] = (msg->tx_len > 1) ? tx[1] : 0;
360+ }
361+
362+ packet->size = sizeof(packet->header) + packet->payload_length;
363+
364+ return 0;
365+}
366+EXPORT_SYMBOL(mipi_dsi_create_packet);
367+
368+/*
369+ * mipi_dsi_set_maximum_return_packet_size() - specify the maximum size of the
370+ * the payload in a long packet transmitted from the peripheral back to the
371+ * host processor
372+ * @dsi: DSI peripheral device
373+ * @value: the maximum size of the payload
374+ *
375+ * Return: 0 on success or a negative error code on failure.
376+ */
377+int mipi_dsi_set_maximum_return_packet_size(struct mipi_dsi_device *dsi,
378+ u16 value)
379+{
380+ u8 tx[2] = { value & 0xff, value >> 8 };
381+ struct mipi_dsi_msg msg = {
382+ .channel = dsi->channel,
383+ .type = MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE,
384+ .tx_len = sizeof(tx),
385+ .tx_buf = tx,
386+ };
387+
388+ return mipi_dsi_device_transfer(dsi, &msg);
389+}
390+EXPORT_SYMBOL(mipi_dsi_set_maximum_return_packet_size);
391+
392+/**
393+ * mipi_dsi_generic_write() - transmit data using a generic write packet
394+ * @dsi: DSI peripheral device
395+ * @payload: buffer containing the payload
396+ * @size: size of payload buffer
397+ *
398+ * This function will automatically choose the right data type depending on
399+ * the payload length.
400+ *
401+ * Return: The number of bytes transmitted on success or a negative error code
402+ * on failure.
403+ */
404+ssize_t mipi_dsi_generic_write(struct mipi_dsi_device *dsi, const void *payload,
405+ size_t size)
406+{
407+ struct mipi_dsi_msg msg = {
408+ .channel = dsi->channel,
409+ .tx_buf = payload,
410+ .tx_len = size
411+ };
412+
413+ switch (size) {
414+ case 0:
415+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM;
416+ break;
417+
418+ case 1:
419+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM;
420+ break;
421+
422+ case 2:
423+ msg.type = MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM;
424+ break;
425+
426+ default:
427+ msg.type = MIPI_DSI_GENERIC_LONG_WRITE;
428+ break;
429+ }
430+
431+ return mipi_dsi_device_transfer(dsi, &msg);
432+}
433+EXPORT_SYMBOL(mipi_dsi_generic_write);
434+
435+/**
436+ * mipi_dsi_generic_read() - receive data using a generic read packet
437+ * @dsi: DSI peripheral device
438+ * @params: buffer containing the request parameters
439+ * @num_params: number of request parameters
440+ * @data: buffer in which to return the received data
441+ * @size: size of receive buffer
442+ *
443+ * This function will automatically choose the right data type depending on
444+ * the number of parameters passed in.
445+ *
446+ * Return: The number of bytes successfully read or a negative error code on
447+ * failure.
448+ */
449+ssize_t mipi_dsi_generic_read(struct mipi_dsi_device *dsi, const void *params,
450+ size_t num_params, void *data, size_t size)
451+{
452+ struct mipi_dsi_msg msg = {
453+ .channel = dsi->channel,
454+ .tx_len = num_params,
455+ .tx_buf = params,
456+ .rx_len = size,
457+ .rx_buf = data
458+ };
459+
460+ switch (num_params) {
461+ case 0:
462+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM;
463+ break;
464+
465+ case 1:
466+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM;
467+ break;
468+
469+ case 2:
470+ msg.type = MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM;
471+ break;
472+
473+ default:
474+ return -EINVAL;
475+ }
476+
477+ return mipi_dsi_device_transfer(dsi, &msg);
478+}
479+EXPORT_SYMBOL(mipi_dsi_generic_read);
480+
481+/**
482+ * mipi_dsi_dcs_write_buffer() - transmit a DCS command with payload
483+ * @dsi: DSI peripheral device
484+ * @data: buffer containing data to be transmitted
485+ * @len: size of transmission buffer
486+ *
487+ * This function will automatically choose the right data type depending on
488+ * the command payload length.
489+ *
490+ * Return: The number of bytes successfully transmitted or a negative error
491+ * code on failure.
492+ */
493+ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
494+ const void *data, size_t len)
209495 {
210− const struct mipi_dsi_host_ops *ops = dsi->host->ops;
211496 struct mipi_dsi_msg msg = {
212497 .channel = dsi->channel,
213498 .tx_buf = data,
214499 .tx_len = len
215500 };
216501
217− if (!ops || !ops->transfer)
218− return -ENOSYS;
219−
220502 switch (len) {
221503 case 0:
222504 return -EINVAL;
505+
223506 case 1:
224507 msg.type = MIPI_DSI_DCS_SHORT_WRITE;
225508 break;
509+
226510 case 2:
227511 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
228512 break;
513+
229514 default:
230515 msg.type = MIPI_DSI_DCS_LONG_WRITE;
231516 break;
232517 }
233518
234− if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
235− msg.flags = MIPI_DSI_MSG_USE_LPM;
519+ return mipi_dsi_device_transfer(dsi, &msg);
520+}
521+EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
236522
237− return ops->transfer(dsi->host, &msg);
523+/**
524+ * mipi_dsi_dcs_write() - send DCS write command
525+ * @dsi: DSI peripheral device
526+ * @cmd: DCS command
527+ * @data: buffer containing the command payload
528+ * @len: command payload length
529+ *
530+ * This function will automatically choose the right data type depending on
531+ * the command payload length.
532+ *
533+ * Return: The number of bytes successfully transmitted or a negative error
534+ * code on failure.
535+ */
536+ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, u8 cmd,
537+ const void *data, size_t len)
538+{
539+ ssize_t err;
540+ size_t size;
541+ u8 *tx;
542+
543+ if (len > 0) {
544+ size = 1 + len;
545+
546+ tx = kmalloc(size, GFP_KERNEL);
547+ if (!tx)
548+ return -ENOMEM;
549+
550+ /* concatenate the DCS command byte and the payload */
551+ tx[0] = cmd;
552+ memcpy(&tx[1], data, len);
553+ } else {
554+ tx = &cmd;
555+ size = 1;
556+ }
557+
558+ err = mipi_dsi_dcs_write_buffer(dsi, tx, size);
559+
560+ if (len > 0)
561+ kfree(tx);
562+
563+ return err;
238564 }
239565 EXPORT_SYMBOL(mipi_dsi_dcs_write);
240566
241567 /**
242− * mipi_dsi_dcs_read - send DCS read request command
243− * @dsi: DSI device
244− * @cmd: DCS read command
245− * @data: pointer to read buffer
246− * @len: length of @data
568+ * mipi_dsi_dcs_read() - send DCS read request command
569+ * @dsi: DSI peripheral device
570+ * @cmd: DCS command
571+ * @data: buffer in which to receive data
572+ * @len: size of receive buffer
247573 *
248− * Function returns number of read bytes or error code.
574+ * Return: The number of bytes read or a negative error code on failure.
249575 */
250576 ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
251577 size_t len)
252578 {
253− const struct mipi_dsi_host_ops *ops = dsi->host->ops;
254579 struct mipi_dsi_msg msg = {
255580 .channel = dsi->channel,
256581 .type = MIPI_DSI_DCS_READ,
@@ -260,15 +585,282 @@ ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data, · 3 unmodified lines
260585 .rx_len = len
261586 };
262587
263− if (!ops || !ops->transfer)
264− return -ENOSYS;
588+ return mipi_dsi_device_transfer(dsi, &msg);
589+}
590+EXPORT_SYMBOL(mipi_dsi_dcs_read);
265591
266− if (dsi->mode_flags & MIPI_DSI_MODE_LPM)
267− msg.flags = MIPI_DSI_MSG_USE_LPM;
592+/**
593+ * mipi_dsi_dcs_nop() - send DCS nop packet
594+ * @dsi: DSI peripheral device
595+ *
596+ * Return: 0 on success or a negative error code on failure.
597+ */
598+int mipi_dsi_dcs_nop(struct mipi_dsi_device *dsi)
599+{
600+ ssize_t err;
601+
602+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_NOP, NULL, 0);
603+ if (err < 0)
604+ return err;
268605
269− return ops->transfer(dsi->host, &msg);
606+ return 0;
270607 }
271−EXPORT_SYMBOL(mipi_dsi_dcs_read);
608+EXPORT_SYMBOL(mipi_dsi_dcs_nop);
609+
610+/**
611+ * mipi_dsi_dcs_soft_reset() - perform a software reset of the display module
612+ * @dsi: DSI peripheral device
613+ *
614+ * Return: 0 on success or a negative error code on failure.
615+ */
616+int mipi_dsi_dcs_soft_reset(struct mipi_dsi_device *dsi)
617+{
618+ ssize_t err;
619+
620+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SOFT_RESET, NULL, 0);
621+ if (err < 0)
622+ return err;
623+
624+ return 0;
625+}
626+EXPORT_SYMBOL(mipi_dsi_dcs_soft_reset);
627+
628+/**
629+ * mipi_dsi_dcs_get_power_mode() - query the display module's current power
630+ * mode
631+ * @dsi: DSI peripheral device
632+ * @mode: return location for the current power mode
633+ *
634+ * Return: 0 on success or a negative error code on failure.
635+ */
636+int mipi_dsi_dcs_get_power_mode(struct mipi_dsi_device *dsi, u8 *mode)
637+{
638+ ssize_t err;
639+
640+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_POWER_MODE, mode,
641+ sizeof(*mode));
642+ if (err <= 0) {
643+ if (err == 0)
644+ err = -ENODATA;
645+
646+ return err;
647+ }
648+
649+ return 0;
650+}
651+EXPORT_SYMBOL(mipi_dsi_dcs_get_power_mode);
652+
653+/**
654+ * mipi_dsi_dcs_get_pixel_format() - gets the pixel format for the RGB image
655+ * data used by the interface
656+ * @dsi: DSI peripheral device
657+ * @format: return location for the pixel format
658+ *
659+ * Return: 0 on success or a negative error code on failure.
660+ */
661+int mipi_dsi_dcs_get_pixel_format(struct mipi_dsi_device *dsi, u8 *format)
662+{
663+ ssize_t err;
664+
665+ err = mipi_dsi_dcs_read(dsi, MIPI_DCS_GET_PIXEL_FORMAT, format,
666+ sizeof(*format));
667+ if (err <= 0) {
668+ if (err == 0)
669+ err = -ENODATA;
670+
671+ return err;
672+ }
673+
674+ return 0;
675+}
676+EXPORT_SYMBOL(mipi_dsi_dcs_get_pixel_format);
677+
678+/**
679+ * mipi_dsi_dcs_enter_sleep_mode() - disable all unnecessary blocks inside the
680+ * display module except interface communication
681+ * @dsi: DSI peripheral device
682+ *
683+ * Return: 0 on success or a negative error code on failure.
684+ */
685+int mipi_dsi_dcs_enter_sleep_mode(struct mipi_dsi_device *dsi)
686+{
687+ ssize_t err;
688+
689+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_ENTER_SLEEP_MODE, NULL, 0);
690+ if (err < 0)
691+ return err;
692+
693+ return 0;
694+}
695+EXPORT_SYMBOL(mipi_dsi_dcs_enter_sleep_mode);
696+
697+/**
698+ * mipi_dsi_dcs_exit_sleep_mode() - enable all blocks inside the display
699+ * module
700+ * @dsi: DSI peripheral device
701+ *
702+ * Return: 0 on success or a negative error code on failure.
703+ */
704+int mipi_dsi_dcs_exit_sleep_mode(struct mipi_dsi_device *dsi)
705+{
706+ ssize_t err;
707+
708+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_EXIT_SLEEP_MODE, NULL, 0);
709+ if (err < 0)
710+ return err;
711+
712+ return 0;
713+}
714+EXPORT_SYMBOL(mipi_dsi_dcs_exit_sleep_mode);
715+
716+/**
717+ * mipi_dsi_dcs_set_display_off() - stop displaying the image data on the
718+ * display device
719+ * @dsi: DSI peripheral device
720+ *
721+ * Return: 0 on success or a negative error code on failure.
722+ */
723+int mipi_dsi_dcs_set_display_off(struct mipi_dsi_device *dsi)
724+{
725+ ssize_t err;
726+
727+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_OFF, NULL, 0);
728+ if (err < 0)
729+ return err;
730+
731+ return 0;
732+}
733+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_off);
734+
735+/**
736+ * mipi_dsi_dcs_set_display_on() - start displaying the image data on the
737+ * display device
738+ * @dsi: DSI peripheral device
739+ *
740+ * Return: 0 on success or a negative error code on failure
741+ */
742+int mipi_dsi_dcs_set_display_on(struct mipi_dsi_device *dsi)
743+{
744+ ssize_t err;
745+
746+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_DISPLAY_ON, NULL, 0);
747+ if (err < 0)
748+ return err;
749+
750+ return 0;
751+}
752+EXPORT_SYMBOL(mipi_dsi_dcs_set_display_on);
753+
754+/**
755+ * mipi_dsi_dcs_set_column_address() - define the column extent of the frame
756+ * memory accessed by the host processor
757+ * @dsi: DSI peripheral device
758+ * @start: first column of frame memory
759+ * @end: last column of frame memory
760+ *
761+ * Return: 0 on success or a negative error code on failure.
762+ */
763+int mipi_dsi_dcs_set_column_address(struct mipi_dsi_device *dsi, u16 start,
764+ u16 end)
765+{
766+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
767+ ssize_t err;
768+
769+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_COLUMN_ADDRESS, payload,
770+ sizeof(payload));
771+ if (err < 0)
772+ return err;
773+
774+ return 0;
775+}
776+EXPORT_SYMBOL(mipi_dsi_dcs_set_column_address);
777+
778+/**
779+ * mipi_dsi_dcs_set_page_address() - define the page extent of the frame
780+ * memory accessed by the host processor
781+ * @dsi: DSI peripheral device
782+ * @start: first page of frame memory
783+ * @end: last page of frame memory
784+ *
785+ * Return: 0 on success or a negative error code on failure.
786+ */
787+int mipi_dsi_dcs_set_page_address(struct mipi_dsi_device *dsi, u16 start,
788+ u16 end)
789+{
790+ u8 payload[4] = { start >> 8, start & 0xff, end >> 8, end & 0xff };
791+ ssize_t err;
792+
793+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PAGE_ADDRESS, payload,
794+ sizeof(payload));
795+ if (err < 0)
796+ return err;
797+
798+ return 0;
799+}
800+EXPORT_SYMBOL(mipi_dsi_dcs_set_page_address);
801+
802+/**
803+ * mipi_dsi_dcs_set_tear_off() - turn off the display module's Tearing Effect
804+ * output signal on the TE signal line
805+ * @dsi: DSI peripheral device
806+ *
807+ * Return: 0 on success or a negative error code on failure
808+ */
809+int mipi_dsi_dcs_set_tear_off(struct mipi_dsi_device *dsi)
810+{
811+ ssize_t err;
812+
813+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_OFF, NULL, 0);
814+ if (err < 0)
815+ return err;
816+
817+ return 0;
818+}
819+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_off);
820+
821+/**
822+ * mipi_dsi_dcs_set_tear_on() - turn on the display module's Tearing Effect
823+ * output signal on the TE signal line.
824+ * @dsi: DSI peripheral device
825+ * @mode: the Tearing Effect Output Line mode
826+ *
827+ * Return: 0 on success or a negative error code on failure
828+ */
829+int mipi_dsi_dcs_set_tear_on(struct mipi_dsi_device *dsi,
830+ enum mipi_dsi_dcs_tear_mode mode)
831+{
832+ u8 value = mode;
833+ ssize_t err;
834+
835+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_TEAR_ON, &value,
836+ sizeof(value));
837+ if (err < 0)
838+ return err;
839+
840+ return 0;
841+}
842+EXPORT_SYMBOL(mipi_dsi_dcs_set_tear_on);
843+
844+/**
845+ * mipi_dsi_dcs_set_pixel_format() - sets the pixel format for the RGB image
846+ * data used by the interface
847+ * @dsi: DSI peripheral device
848+ * @format: pixel format
849+ *
850+ * Return: 0 on success or a negative error code on failure.
851+ */
852+int mipi_dsi_dcs_set_pixel_format(struct mipi_dsi_device *dsi, u8 format)
853+{
854+ ssize_t err;
855+
856+ err = mipi_dsi_dcs_write(dsi, MIPI_DCS_SET_PIXEL_FORMAT, &format,
857+ sizeof(format));
858+ if (err < 0)
859+ return err;
860+
861+ return 0;
862+}
863+EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
272864
273865 static int mipi_dsi_drv_probe(struct device *dev)
274866 {
@@ -295,12 +887,18 @@ static void mipi_dsi_drv_shutdown(struct device *dev) · 20 unmodified lines
295887 }
296888
297889 /**
298− * mipi_dsi_driver_register - register a driver for DSI devices
890+ * mipi_dsi_driver_register_full() - register a driver for DSI devices
299891 * @drv: DSI driver structure
892+ * @owner: owner module
893+ *
894+ * Return: 0 on success or a negative error code on failure.
300895 */
301−int mipi_dsi_driver_register(struct mipi_dsi_driver *drv)
896+int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
897+ struct module *owner)
302898 {
303899 drv->driver.bus = &mipi_dsi_bus_type;
900+ drv->driver.owner = owner;
901+
304902 if (drv->probe)
305903 drv->driver.probe = mipi_dsi_drv_probe;
306904 if (drv->remove)
@@ -310,11 +908,13 @@ int mipi_dsi_driver_register(struct mipi_dsi_driver *drv) · 3 unmodified lines
310908
311909 return driver_register(&drv->driver);
312910 }
313−EXPORT_SYMBOL(mipi_dsi_driver_register);
911+EXPORT_SYMBOL(mipi_dsi_driver_register_full);
314912
315913 /**
316− * mipi_dsi_driver_unregister - unregister a driver for DSI devices
914+ * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
317915 * @drv: DSI driver structure
916+ *
917+ * Return: 0 on success or a negative error code on failure.
318918 */
319919 void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
320920 {
drivers/gpu/drm/drm_modes.c+1−1
@@ -914,7 +914,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); · 913 unmodified lines
914914 *
915915 * This function is a helper which can be used to validate modes against size
916916 * limitations of the DRM device/connector. If a mode is too big its status
917− * memeber is updated with the appropriate validation failure code. The list
917+ * member is updated with the appropriate validation failure code. The list
918918 * itself is not changed.
919919 */
920920 void drm_mode_validate_size(struct drm_device *dev,
drivers/gpu/drm/drm_modeset_lock.c+33−10
@@ -157,14 +157,20 @@ void drm_modeset_unlock_all(struct drm_device *dev) · 156 unmodified lines
157157 EXPORT_SYMBOL(drm_modeset_unlock_all);
158158
159159 /**
160− * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx
161− * @crtc: drm crtc
160+ * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx for a plane update
161+ * @crtc: DRM CRTC
162+ * @plane: DRM plane to be updated on @crtc
163+ *
164+ * This function locks the given crtc and plane (which should be either the
165+ * primary or cursor plane) using a hidden acquire context. This is necessary so
166+ * that drivers internally using the atomic interfaces can grab further locks
167+ * with the lock acquire context.
162168 *
163− * This function locks the given crtc using a hidden acquire context. This is
164− * necessary so that drivers internally using the atomic interfaces can grab
165− * further locks with the lock acquire context.
169+ * Note that @plane can be NULL, e.g. when the cursor support hasn't yet been
170+ * converted to universal planes yet.
166171 */
167−void drm_modeset_lock_crtc(struct drm_crtc *crtc)
172+void drm_modeset_lock_crtc(struct drm_crtc *crtc,
173+ struct drm_plane *plane)
168174 {
169175 struct drm_modeset_acquire_ctx *ctx;
170176 int ret;
@@ -180,6 +186,18 @@ retry: · 9 unmodified lines
180186 if (ret)
181187 goto fail;
182188
189+ if (plane) {
190+ ret = drm_modeset_lock(&plane->mutex, ctx);
191+ if (ret)
192+ goto fail;
193+
194+ if (plane->crtc) {
195+ ret = drm_modeset_lock(&plane->crtc->mutex, ctx);
196+ if (ret)
197+ goto fail;
198+ }
199+ }
200+
183201 WARN_ON(crtc->acquire_ctx);
184202
185203 /* now we hold the locks, so now that it is safe, stash the
@@ -437,15 +455,14 @@ void drm_modeset_unlock(struct drm_modeset_lock *lock) · 251 unmodified lines
437455 }
438456 EXPORT_SYMBOL(drm_modeset_unlock);
439457
440−/* Temporary.. until we have sufficiently fine grained locking, there
441− * are a couple scenarios where it is convenient to grab all crtc locks.
442− * It is planned to remove this:
443− */
458+/* In some legacy codepaths it's convenient to just grab all the crtc and plane
459+ * related locks. */
444460 int drm_modeset_lock_all_crtcs(struct drm_device *dev,
445461 struct drm_modeset_acquire_ctx *ctx)
446462 {
447463 struct drm_mode_config *config = &dev->mode_config;
448464 struct drm_crtc *crtc;
465+ struct drm_plane *plane;
449466 int ret = 0;
450467
451468 list_for_each_entry(crtc, &config->crtc_list, head) {
@@ -454,6 +471,12 @@ int drm_modeset_lock_all_crtcs(struct drm_device *dev, · 2 unmodified lines
454471 return ret;
455472 }
456473
474+ list_for_each_entry(plane, &config->plane_list, head) {
475+ ret = drm_modeset_lock(&plane->mutex, ctx);
476+ if (ret)
477+ return ret;
478+ }
479+
457480 return 0;
458481 }
459482 EXPORT_SYMBOL(drm_modeset_lock_all_crtcs);
drivers/gpu/drm/drm_plane_helper.c+202−1
@@ -27,10 +27,38 @@ · 26 unmodified lines
2727 #include <drm/drmP.h>
2828 #include <drm/drm_plane_helper.h>
2929 #include <drm/drm_rect.h>
30−#include <drm/drm_plane_helper.h>
30+#include <drm/drm_atomic.h>
31+#include <drm/drm_crtc_helper.h>
32+#include <drm/drm_atomic_helper.h>
3133
3234 #define SUBPIXEL_MASK 0xffff
3335
36+/**
37+ * DOC: overview
38+ *
39+ * This helper library has two parts. The first part has support to implement
40+ * primary plane support on top of the normal CRTC configuration interface.
41+ * Since the legacy ->set_config interface ties the primary plane together with
42+ * the CRTC state this does not allow userspace to disable the primary plane
43+ * itself. To avoid too much duplicated code use
44+ * drm_plane_helper_check_update() which can be used to enforce the same
45+ * restrictions as primary planes had thus. The default primary plane only
46+ * expose XRBG8888 and ARGB8888 as valid pixel formats for the attached
47+ * framebuffer.
48+ *
49+ * Drivers are highly recommended to implement proper support for primary
50+ * planes, and newly merged drivers must not rely upon these transitional
51+ * helpers.
52+ *
53+ * The second part also implements transitional helpers which allow drivers to
54+ * gradually switch to the atomic helper infrastructure for plane updates. Once
55+ * that switch is complete drivers shouldn't use these any longer, instead using
56+ * the proper legacy implementations for update and disable plane hooks provided
57+ * by the atomic helpers.
58+ *
59+ * Again drivers are strongly urged to switch to the new interfaces.
60+ */
61+
3462 /*
3563 * This is the minimal list of formats that seem to be safe for modeset use
3664 * with all current DRM drivers. Most hardware can actually support more
@@ -127,6 +155,11 @@ int drm_plane_helper_check_update(struct drm_plane *plane, · 90 unmodified lines
127155 return -ERANGE;
128156 }
129157
158+ if (!fb) {
159+ *visible = false;
160+ return 0;
161+ }
162+
130163 *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
131164 if (!*visible)
132165 /*
@@ -369,3 +402,171 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, · 236 unmodified lines
369402 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs);
370403 }
371404 EXPORT_SYMBOL(drm_crtc_init);
405+
406+int drm_plane_helper_commit(struct drm_plane *plane,
407+ struct drm_plane_state *plane_state,
408+ struct drm_framebuffer *old_fb)
409+{
410+ struct drm_plane_helper_funcs *plane_funcs;
411+ struct drm_crtc *crtc[2];
412+ struct drm_crtc_helper_funcs *crtc_funcs[2];
413+ int i, ret = 0;
414+
415+ plane_funcs = plane->helper_private;
416+
417+ /* Since this is a transitional helper we can't assume that plane->state
418+ * is always valid. Hence we need to use plane->crtc instead of
419+ * plane->state->crtc as the old crtc. */
420+ crtc[0] = plane->crtc;
421+ crtc[1] = crtc[0] != plane_state->crtc ? plane_state->crtc : NULL;
422+
423+ for (i = 0; i < 2; i++)
424+ crtc_funcs[i] = crtc[i] ? crtc[i]->helper_private : NULL;
425+
426+ if (plane_funcs->atomic_check) {
427+ ret = plane_funcs->atomic_check(plane, plane_state);
428+ if (ret)
429+ goto out;
430+ }
431+
432+ if (plane_funcs->prepare_fb && plane_state->fb) {
433+ ret = plane_funcs->prepare_fb(plane, plane_state->fb);
434+ if (ret)
435+ goto out;
436+ }
437+
438+ /* Point of no return, commit sw state. */
439+ swap(plane->state, plane_state);
440+
441+ for (i = 0; i < 2; i++) {
442+ if (crtc_funcs[i] && crtc_funcs[i]->atomic_begin)
443+ crtc_funcs[i]->atomic_begin(crtc[i]);
444+ }
445+
446+ plane_funcs->atomic_update(plane, plane_state);
447+
448+ for (i = 0; i < 2; i++) {
449+ if (crtc_funcs[i] && crtc_funcs[i]->atomic_flush)
450+ crtc_funcs[i]->atomic_flush(crtc[i]);
451+ }
452+
453+ for (i = 0; i < 2; i++) {
454+ if (!crtc[i])
455+ continue;
456+
457+ /* There's no other way to figure out whether the crtc is running. */
458+ ret = drm_crtc_vblank_get(crtc[i]);
459+ if (ret == 0) {
460+ drm_crtc_wait_one_vblank(crtc[i]);
461+ drm_crtc_vblank_put(crtc[i]);
462+ }
463+
464+ ret = 0;
465+ }
466+
467+ if (plane_funcs->cleanup_fb && old_fb)
468+ plane_funcs->cleanup_fb(plane, old_fb);
469+out:
470+ if (plane_state) {
471+ if (plane->funcs->atomic_destroy_state)
472+ plane->funcs->atomic_destroy_state(plane, plane_state);
473+ else
474+ drm_atomic_helper_plane_destroy_state(plane, plane_state);
475+ }
476+
477+ return ret;
478+}
479+
480+/**
481+ * drm_plane_helper_update() - Helper for primary plane update
482+ * @plane: plane object to update
483+ * @crtc: owning CRTC of owning plane
484+ * @fb: framebuffer to flip onto plane
485+ * @crtc_x: x offset of primary plane on crtc
486+ * @crtc_y: y offset of primary plane on crtc
487+ * @crtc_w: width of primary plane rectangle on crtc
488+ * @crtc_h: height of primary plane rectangle on crtc
489+ * @src_x: x offset of @fb for panning
490+ * @src_y: y offset of @fb for panning
491+ * @src_w: width of source rectangle in @fb
492+ * @src_h: height of source rectangle in @fb
493+ *
494+ * Provides a default plane update handler using the atomic plane update
495+ * functions. It is fully left to the driver to check plane constraints and
496+ * handle corner-cases like a fully occluded or otherwise invisible plane.
497+ *
498+ * This is useful for piecewise transitioning of a driver to the atomic helpers.
499+ *
500+ * RETURNS:
501+ * Zero on success, error code on failure
502+ */
503+int drm_plane_helper_update(struct drm_plane *plane, struct drm_crtc *crtc,
504+ struct drm_framebuffer *fb,
505+ int crtc_x, int crtc_y,
506+ unsigned int crtc_w, unsigned int crtc_h,
507+ uint32_t src_x, uint32_t src_y,
508+ uint32_t src_w, uint32_t src_h)
509+{
510+ struct drm_plane_state *plane_state;
511+
512+ if (plane->funcs->atomic_duplicate_state)
513+ plane_state = plane->funcs->atomic_duplicate_state(plane);
514+ else if (plane->state)
515+ plane_state = drm_atomic_helper_plane_duplicate_state(plane);
516+ else
517+ plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
518+ if (!plane_state)
519+ return -ENOMEM;
520+
521+ plane_state->crtc = crtc;
522+ drm_atomic_set_fb_for_plane(plane_state, fb);
523+ plane_state->crtc_x = crtc_x;
524+ plane_state->crtc_y = crtc_y;
525+ plane_state->crtc_h = crtc_h;
526+ plane_state->crtc_w = crtc_w;
527+ plane_state->src_x = src_x;
528+ plane_state->src_y = src_y;
529+ plane_state->src_h = src_h;
530+ plane_state->src_w = src_w;
531+
532+ return drm_plane_helper_commit(plane, plane_state, plane->fb);
533+}
534+EXPORT_SYMBOL(drm_plane_helper_update);
535+
536+/**
537+ * drm_plane_helper_disable() - Helper for primary plane disable
538+ * @plane: plane to disable
539+ *
540+ * Provides a default plane disable handler using the atomic plane update
541+ * functions. It is fully left to the driver to check plane constraints and
542+ * handle corner-cases like a fully occluded or otherwise invisible plane.
543+ *
544+ * This is useful for piecewise transitioning of a driver to the atomic helpers.
545+ *
546+ * RETURNS:
547+ * Zero on success, error code on failure
548+ */
549+int drm_plane_helper_disable(struct drm_plane *plane)
550+{
551+ struct drm_plane_state *plane_state;
552+
553+ /* crtc helpers love to call disable functions for already disabled hw
554+ * functions. So cope with that. */
555+ if (!plane->crtc)
556+ return 0;
557+
558+ if (plane->funcs->atomic_duplicate_state)
559+ plane_state = plane->funcs->atomic_duplicate_state(plane);
560+ else if (plane->state)
561+ plane_state = drm_atomic_helper_plane_duplicate_state(plane);
562+ else
563+ plane_state = kzalloc(sizeof(*plane_state), GFP_KERNEL);
564+ if (!plane_state)
565+ return -ENOMEM;
566+
567+ plane_state->crtc = NULL;
568+ drm_atomic_set_fb_for_plane(plane_state, NULL);
569+
570+ return drm_plane_helper_commit(plane, plane_state, plane->fb);
571+}
572+EXPORT_SYMBOL(drm_plane_helper_disable);
drivers/gpu/drm/drm_prime.c+3−3
@@ -328,7 +328,7 @@ static const struct dma_buf_ops drm_gem_prime_dmabuf_ops = { · 327 unmodified lines
328328 */
329329
330330 /**
331− * drm_gem_prime_export - helper library implemention of the export callback
331+ * drm_gem_prime_export - helper library implementation of the export callback
332332 * @dev: drm_device to export from
333333 * @obj: GEM object to export
334334 * @flags: flags like DRM_CLOEXEC
@@ -483,7 +483,7 @@ out_unlock: · 148 unmodified lines
483483 EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
484484
485485 /**
486− * drm_gem_prime_import - helper library implemention of the import callback
486+ * drm_gem_prime_import - helper library implementation of the import callback
487487 * @dev: drm_device to import into
488488 * @dma_buf: dma-buf object to import
489489 *
@@ -669,7 +669,7 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, · 179 unmodified lines
669669 * the driver is responsible for mapping the pages into the
670670 * importers address space for use with dma_buf itself.
671671 */
672−struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)
672+struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages)
673673 {
674674 struct sg_table *sg = NULL;
675675 int ret;
drivers/gpu/drm/drm_probe_helper.c+2−1
@@ -118,7 +118,8 @@ static int drm_helper_probe_single_connector_modes_merge_bits(struct drm_connect · 117 unmodified lines
118118 mode->status = MODE_UNVERIFIED;
119119
120120 if (connector->force) {
121− if (connector->force == DRM_FORCE_ON)
121+ if (connector->force == DRM_FORCE_ON ||
122+ connector->force == DRM_FORCE_ON_DIGITAL)
122123 connector->status = connector_status_connected;
123124 else
124125 connector->status = connector_status_disconnected;
drivers/gpu/drm/exynos/exynos_dp_core.c+45−87
@@ -30,12 +30,17 @@ · 29 unmodified lines
3030 #include <drm/drm_panel.h>
3131 #include <drm/bridge/ptn3460.h>
3232
33−#include "exynos_drm_drv.h"
3433 #include "exynos_dp_core.h"
3534
3635 #define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
3736 connector)
3837
38+static inline struct exynos_dp_device *
39+display_to_dp(struct exynos_drm_display *d)
40+{
41+ return container_of(d, struct exynos_dp_device, display);
42+}
43+
3944 struct bridge_init {
4045 struct i2c_client *client;
4146 struct device_node *node;
@@ -882,7 +887,7 @@ static void exynos_dp_hotplug(struct work_struct *work) · 840 unmodified lines
882887
883888 static void exynos_dp_commit(struct exynos_drm_display *display)
884889 {
885− struct exynos_dp_device *dp = display->ctx;
890+ struct exynos_dp_device *dp = display_to_dp(display);
886891 int ret;
887892
888893 /* Keep the panel disabled while we configure video */
@@ -1020,7 +1025,7 @@ static int exynos_drm_attach_lcd_bridge(struct drm_device *dev, · 131 unmodified lines
10201025 static int exynos_dp_create_connector(struct exynos_drm_display *display,
10211026 struct drm_encoder *encoder)
10221027 {
1023− struct exynos_dp_device *dp = display->ctx;
1028+ struct exynos_dp_device *dp = display_to_dp(display);
10241029 struct drm_connector *connector = &dp->connector;
10251030 int ret;
10261031
@@ -1052,33 +1057,19 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, · 25 unmodified lines
10521057
10531058 static void exynos_dp_phy_init(struct exynos_dp_device *dp)
10541059 {
1055− if (dp->phy) {
1060+ if (dp->phy)
10561061 phy_power_on(dp->phy);
1057− } else if (dp->phy_addr) {
1058− u32 reg;
1059−
1060− reg = __raw_readl(dp->phy_addr);
1061− reg |= dp->enable_mask;
1062− __raw_writel(reg, dp->phy_addr);
1063− }
10641062 }
10651063
10661064 static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
10671065 {
1068− if (dp->phy) {
1066+ if (dp->phy)
10691067 phy_power_off(dp->phy);
1070− } else if (dp->phy_addr) {
1071− u32 reg;
1072−
1073− reg = __raw_readl(dp->phy_addr);
1074− reg &= ~(dp->enable_mask);
1075− __raw_writel(reg, dp->phy_addr);
1076− }
10771068 }
10781069
10791070 static void exynos_dp_poweron(struct exynos_drm_display *display)
10801071 {
1081− struct exynos_dp_device *dp = display->ctx;
1072+ struct exynos_dp_device *dp = display_to_dp(display);
10821073
10831074 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
10841075 return;
@@ -1099,7 +1090,7 @@ static void exynos_dp_poweron(struct exynos_drm_display *display) · 14 unmodified lines
10991090
11001091 static void exynos_dp_poweroff(struct exynos_drm_display *display)
11011092 {
1102− struct exynos_dp_device *dp = display->ctx;
1093+ struct exynos_dp_device *dp = display_to_dp(display);
11031094
11041095 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
11051096 return;
@@ -1124,7 +1115,7 @@ static void exynos_dp_poweroff(struct exynos_drm_display *display) · 18 unmodified lines
11241115
11251116 static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
11261117 {
1127− struct exynos_dp_device *dp = display->ctx;
1118+ struct exynos_dp_device *dp = display_to_dp(display);
11281119
11291120 switch (mode) {
11301121 case DRM_MODE_DPMS_ON:
@@ -1147,11 +1138,6 @@ static struct exynos_drm_display_ops exynos_dp_display_ops = { · 16 unmodified lines
11471138 .commit = exynos_dp_commit,
11481139 };
11491140
1150−static struct exynos_drm_display exynos_dp_display = {
1151− .type = EXYNOS_DISPLAY_TYPE_LCD,
1152− .ops = &exynos_dp_display_ops,
1153−};
1154−
11551141 static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
11561142 {
11571143 struct device_node *dp_node = dev->of_node;
@@ -1210,44 +1196,6 @@ static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev) · 52 unmodified lines
12101196 return dp_video_config;
12111197 }
12121198
1213−static int exynos_dp_dt_parse_phydata(struct exynos_dp_device *dp)
1214−{
1215− struct device_node *dp_phy_node = of_node_get(dp->dev->of_node);
1216− u32 phy_base;
1217− int ret = 0;
1218−
1219− dp_phy_node = of_find_node_by_name(dp_phy_node, "dptx-phy");
1220− if (!dp_phy_node) {
1221− dp->phy = devm_phy_get(dp->dev, "dp");
1222− return PTR_ERR_OR_ZERO(dp->phy);
1223− }
1224−
1225− if (of_property_read_u32(dp_phy_node, "reg", &phy_base)) {
1226− dev_err(dp->dev, "failed to get reg for dptx-phy\n");
1227− ret = -EINVAL;
1228− goto err;
1229− }
1230−
1231− if (of_property_read_u32(dp_phy_node, "samsung,enable-mask",
1232− &dp->enable_mask)) {
1233− dev_err(dp->dev, "failed to get enable-mask for dptx-phy\n");
1234− ret = -EINVAL;
1235− goto err;
1236− }
1237−
1238− dp->phy_addr = ioremap(phy_base, SZ_4);
1239− if (!dp->phy_addr) {
1240− dev_err(dp->dev, "failed to ioremap dp-phy\n");
1241− ret = -ENOMEM;
1242− goto err;
1243− }
1244−
1245−err:
1246− of_node_put(dp_phy_node);
1247−
1248− return ret;
1249−}
1250−
12511199 static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
12521200 {
12531201 int ret;
@@ -1263,10 +1211,10 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) · 9 unmodified lines
12631211
12641212 static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
12651213 {
1214+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
12661215 struct platform_device *pdev = to_platform_device(dev);
12671216 struct drm_device *drm_dev = data;
12681217 struct resource *res;
1269− struct exynos_dp_device *dp = exynos_dp_display.ctx;
12701218 unsigned int irq_flags;
12711219 int ret = 0;
12721220
@@ -1277,9 +1225,21 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) · 4 unmodified lines
12771225 if (IS_ERR(dp->video_info))
12781226 return PTR_ERR(dp->video_info);
12791227
1280− ret = exynos_dp_dt_parse_phydata(dp);
1281− if (ret)
1282− return ret;
1228+ dp->phy = devm_phy_get(dp->dev, "dp");
1229+ if (IS_ERR(dp->phy)) {
1230+ dev_err(dp->dev, "no DP phy configured\n");
1231+ ret = PTR_ERR(dp->phy);
1232+ if (ret) {
1233+ /*
1234+ * phy itself is not enabled, so we can move forward
1235+ * assigning NULL to phy pointer.
1236+ */
1237+ if (ret == -ENOSYS || ret == -ENODEV)
1238+ dp->phy = NULL;
1239+ else
1240+ return ret;
1241+ }
1242+ }
12831243
12841244 if (!dp->panel) {
12851245 ret = exynos_dp_dt_parse_panel(dp);
@@ -1346,17 +1306,15 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) · 60 unmodified lines
13461306
13471307 dp->drm_dev = drm_dev;
13481308
1349− platform_set_drvdata(pdev, &exynos_dp_display);
1350−
1351− return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display);
1309+ return exynos_drm_create_enc_conn(drm_dev, &dp->display);
13521310 }
13531311
13541312 static void exynos_dp_unbind(struct device *dev, struct device *master,
13551313 void *data)
13561314 {
1357− struct exynos_drm_display *display = dev_get_drvdata(dev);
1315+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
13581316
1359− exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
1317+ exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
13601318 }
13611319
13621320 static const struct component_ops exynos_dp_ops = {
@@ -1371,16 +1329,20 @@ static int exynos_dp_probe(struct platform_device *pdev) · 8 unmodified lines
13711329 struct exynos_dp_device *dp;
13721330 int ret;
13731331
1374− ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1375− exynos_dp_display.type);
1376− if (ret)
1377− return ret;
1378−
13791332 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
13801333 GFP_KERNEL);
13811334 if (!dp)
13821335 return -ENOMEM;
13831336
1337+ dp->display.type = EXYNOS_DISPLAY_TYPE_LCD;
1338+ dp->display.ops = &exynos_dp_display_ops;
1339+ platform_set_drvdata(pdev, dp);
1340+
1341+ ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1342+ dp->display.type);
1343+ if (ret)
1344+ return ret;
1345+
13841346 panel_node = of_parse_phandle(dev->of_node, "panel", 0);
13851347 if (panel_node) {
13861348 dp->panel = of_drm_find_panel(panel_node);
@@ -1389,8 +1351,6 @@ static int exynos_dp_probe(struct platform_device *pdev) · 2 unmodified lines
13891351 return -EPROBE_DEFER;
13901352 }
13911353
1392− exynos_dp_display.ctx = dp;
1393−
13941354 ret = component_add(&pdev->dev, &exynos_dp_ops);
13951355 if (ret)
13961356 exynos_drm_component_del(&pdev->dev,
@@ -1410,19 +1370,17 @@ static int exynos_dp_remove(struct platform_device *pdev) · 13 unmodified lines
14101370 #ifdef CONFIG_PM_SLEEP
14111371 static int exynos_dp_suspend(struct device *dev)
14121372 {
1413− struct platform_device *pdev = to_platform_device(dev);
1414− struct exynos_drm_display *display = platform_get_drvdata(pdev);
1373+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
14151374
1416− exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);
1375+ exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
14171376 return 0;
14181377 }
14191378
14201379 static int exynos_dp_resume(struct device *dev)
14211380 {
1422− struct platform_device *pdev = to_platform_device(dev);
1423− struct exynos_drm_display *display = platform_get_drvdata(pdev);
1381+ struct exynos_dp_device *dp = dev_get_drvdata(dev);
14241382
1425− exynos_dp_dpms(display, DRM_MODE_DPMS_ON);
1383+ exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
14261384 return 0;
14271385 }
14281386 #endif
drivers/gpu/drm/exynos/exynos_dp_core.h+3−2
@@ -17,6 +17,8 @@ · 16 unmodified lines
1717 #include <drm/drm_dp_helper.h>
1818 #include <drm/exynos_drm.h>
1919
20+#include "exynos_drm_drv.h"
21+
2022 #define DP_TIMEOUT_LOOP_COUNT 100
2123 #define MAX_CR_LOOP 5
2224 #define MAX_EQ_LOOP 5
@@ -145,6 +147,7 @@ struct link_train { · 122 unmodified lines
145147 };
146148
147149 struct exynos_dp_device {
150+ struct exynos_drm_display display;
148151 struct device *dev;
149152 struct drm_device *drm_dev;
150153 struct drm_connector connector;
@@ -153,8 +156,6 @@ struct exynos_dp_device { · 2 unmodified lines
153156 struct clk *clock;
154157 unsigned int irq;
155158 void __iomem *reg_base;
156− void __iomem *phy_addr;
157− unsigned int enable_mask;
158159
159160 struct video_info *video_info;
160161 struct link_train link_train;
drivers/gpu/drm/exynos/exynos_drm_crtc.h+1−4
@@ -15,10 +15,7 @@ · 14 unmodified lines
1515 #ifndef _EXYNOS_DRM_CRTC_H_
1616 #define _EXYNOS_DRM_CRTC_H_
1717
18−struct drm_device;
19−struct drm_crtc;
20−struct exynos_drm_manager;
21−struct exynos_drm_overlay;
18+#include "exynos_drm_drv.h"
2219
2320 int exynos_drm_crtc_create(struct exynos_drm_manager *manager);
2421 int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
drivers/gpu/drm/exynos/exynos_drm_dpi.c+22−20
@@ -22,6 +22,7 @@ · 21 unmodified lines
2222 #include "exynos_drm_drv.h"
2323
2424 struct exynos_dpi {
25+ struct exynos_drm_display display;
2526 struct device *dev;
2627 struct device_node *panel_node;
2728
@@ -35,6 +36,11 @@ struct exynos_dpi { · 7 unmodified lines
3536
3637 #define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
3738
39+static inline struct exynos_dpi *display_to_dpi(struct exynos_drm_display *d)
40+{
41+ return container_of(d, struct exynos_dpi, display);
42+}
43+
3844 static enum drm_connector_status
3945 exynos_dpi_detect(struct drm_connector *connector, bool force)
4046 {
@@ -100,7 +106,7 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = { · 59 unmodified lines
100106 static int exynos_dpi_create_connector(struct exynos_drm_display *display,
101107 struct drm_encoder *encoder)
102108 {
103− struct exynos_dpi *ctx = display->ctx;
109+ struct exynos_dpi *ctx = display_to_dpi(display);
104110 struct drm_connector *connector = &ctx->connector;
105111 int ret;
106112
@@ -141,7 +147,7 @@ static void exynos_dpi_poweroff(struct exynos_dpi *ctx) · 34 unmodified lines
141147
142148 static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)
143149 {
144− struct exynos_dpi *ctx = display->ctx;
150+ struct exynos_dpi *ctx = display_to_dpi(display);
145151
146152 switch (mode) {
147153 case DRM_MODE_DPMS_ON:
@@ -165,11 +171,6 @@ static struct exynos_drm_display_ops exynos_dpi_display_ops = { · 17 unmodified lines
165171 .dpms = exynos_dpi_dpms
166172 };
167173
168−static struct exynos_drm_display exynos_dpi_display = {
169− .type = EXYNOS_DISPLAY_TYPE_LCD,
170− .ops = &exynos_dpi_display_ops,
171−};
172−
173174 /* of_* functions will be removed after merge of of_graph patches */
174175 static struct device_node *
175176 of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)
@@ -299,20 +300,21 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) · 123 unmodified lines
299300 struct exynos_dpi *ctx;
300301 int ret;
301302
302− ret = exynos_drm_component_add(dev,
303− EXYNOS_DEVICE_TYPE_CONNECTOR,
304− exynos_dpi_display.type);
305− if (ret)
306− return ERR_PTR(ret);
307−
308303 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
309304 if (!ctx)
310− goto err_del_component;
305+ return ERR_PTR(-ENOMEM);
311306
307+ ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
308+ ctx->display.ops = &exynos_dpi_display_ops;
312309 ctx->dev = dev;
313− exynos_dpi_display.ctx = ctx;
314310 ctx->dpms_mode = DRM_MODE_DPMS_OFF;
315311
312+ ret = exynos_drm_component_add(dev,
313+ EXYNOS_DEVICE_TYPE_CONNECTOR,
314+ ctx->display.type);
315+ if (ret)
316+ return ERR_PTR(ret);
317+
316318 ret = exynos_dpi_parse_dt(ctx);
317319 if (ret < 0) {
318320 devm_kfree(dev, ctx);
@@ -328,7 +330,7 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) · 9 unmodified lines
328330 }
329331 }
330332
331− return &exynos_dpi_display;
333+ return &ctx->display;
332334
333335 err_del_component:
334336 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
@@ -336,16 +338,16 @@ err_del_component: · 1 unmodified line
336338 return NULL;
337339 }
338340
339−int exynos_dpi_remove(struct device *dev)
341+int exynos_dpi_remove(struct exynos_drm_display *display)
340342 {
341− struct exynos_dpi *ctx = exynos_dpi_display.ctx;
343+ struct exynos_dpi *ctx = display_to_dpi(display);
342344
343− exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF);
345+ exynos_dpi_dpms(&ctx->display, DRM_MODE_DPMS_OFF);
344346
345347 if (ctx->panel)
346348 drm_panel_detach(ctx->panel);
347349
348− exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
350+ exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
349351
350352 return 0;
351353 }
drivers/gpu/drm/exynos/exynos_drm_drv.c+95−157
@@ -203,8 +203,6 @@ static int exynos_drm_resume(struct drm_device *dev) · 202 unmodified lines
203203 }
204204 drm_modeset_unlock_all(dev);
205205
206− drm_helper_resume_force_mode(dev);
207−
208206 return 0;
209207 }
210208
@@ -475,8 +473,6 @@ void exynos_drm_component_del(struct device *dev, · 264 unmodified lines
475473 list_del(&cdev->list);
476474 kfree(cdev);
477475 }
478−
479− break;
480476 }
481477
482478 mutex_unlock(&drm_component_lock);
@@ -556,182 +552,68 @@ static const struct component_master_ops exynos_drm_ops = { · 73 unmodified lines
556552 .unbind = exynos_drm_unbind,
557553 };
558554
559−static int exynos_drm_platform_probe(struct platform_device *pdev)
560−{
561− struct component_match *match;
562− int ret;
563−
564− pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
565− exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
566−
555+static struct platform_driver *const exynos_drm_kms_drivers[] = {
567556 #ifdef CONFIG_DRM_EXYNOS_FIMD
568− ret = platform_driver_register(&fimd_driver);
569− if (ret < 0)
570− return ret;
557+ &fimd_driver,
571558 #endif
572−
573559 #ifdef CONFIG_DRM_EXYNOS_DP
574− ret = platform_driver_register(&dp_driver);
575− if (ret < 0)
576− goto err_unregister_fimd_drv;
560+ &dp_driver,
577561 #endif
578−
579562 #ifdef CONFIG_DRM_EXYNOS_DSI
580− ret = platform_driver_register(&dsi_driver);
581− if (ret < 0)
582− goto err_unregister_dp_drv;
563+ &dsi_driver,
583564 #endif
584−
585565 #ifdef CONFIG_DRM_EXYNOS_HDMI
586− ret = platform_driver_register(&mixer_driver);
587− if (ret < 0)
588− goto err_unregister_dsi_drv;
589− ret = platform_driver_register(&hdmi_driver);
590− if (ret < 0)
591− goto err_unregister_mixer_drv;
566+ &mixer_driver,
567+ &hdmi_driver,
592568 #endif
569+};
593570
594− match = exynos_drm_match_add(&pdev->dev);
595− if (IS_ERR(match)) {
596− ret = PTR_ERR(match);
597− goto err_unregister_hdmi_drv;
598− }
599−
600− ret = component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
601− match);
602− if (ret < 0)
603− goto err_unregister_hdmi_drv;
604−
571+static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
605572 #ifdef CONFIG_DRM_EXYNOS_G2D
606− ret = platform_driver_register(&g2d_driver);
607− if (ret < 0)
608− goto err_del_component_master;
573+ &g2d_driver,
609574 #endif
610−
611575 #ifdef CONFIG_DRM_EXYNOS_FIMC
612− ret = platform_driver_register(&fimc_driver);
613− if (ret < 0)
614− goto err_unregister_g2d_drv;
576+ &fimc_driver,
615577 #endif
616−
617578 #ifdef CONFIG_DRM_EXYNOS_ROTATOR
618− ret = platform_driver_register(&rotator_driver);
619− if (ret < 0)
620− goto err_unregister_fimc_drv;
579+ &rotator_driver,
621580 #endif
622−
623581 #ifdef CONFIG_DRM_EXYNOS_GSC
624− ret = platform_driver_register(&gsc_driver);
625− if (ret < 0)
626− goto err_unregister_rotator_drv;
627−#endif
628−
629−#ifdef CONFIG_DRM_EXYNOS_IPP
630− ret = platform_driver_register(&ipp_driver);
631− if (ret < 0)
632− goto err_unregister_gsc_drv;
633−
634− ret = exynos_platform_device_ipp_register();
635− if (ret < 0)
636− goto err_unregister_ipp_drv;
582+ &gsc_driver,
637583 #endif
638−
639− return ret;
640−
641584 #ifdef CONFIG_DRM_EXYNOS_IPP
642−err_unregister_ipp_drv:
643− platform_driver_unregister(&ipp_driver);
644−err_unregister_gsc_drv:
645−#endif
646−
647−#ifdef CONFIG_DRM_EXYNOS_GSC
648− platform_driver_unregister(&gsc_driver);
649−err_unregister_rotator_drv:
585+ &ipp_driver,
650586 #endif
587+};
651588
652−#ifdef CONFIG_DRM_EXYNOS_ROTATOR
653− platform_driver_unregister(&rotator_driver);
654−err_unregister_fimc_drv:
655−#endif
656−
657−#ifdef CONFIG_DRM_EXYNOS_FIMC
658− platform_driver_unregister(&fimc_driver);
659−err_unregister_g2d_drv:
660−#endif
661−
662−#ifdef CONFIG_DRM_EXYNOS_G2D
663− platform_driver_unregister(&g2d_driver);
664−err_del_component_master:
665−#endif
666− component_master_del(&pdev->dev, &exynos_drm_ops);
667−
668−err_unregister_hdmi_drv:
669−#ifdef CONFIG_DRM_EXYNOS_HDMI
670− platform_driver_unregister(&hdmi_driver);
671−err_unregister_mixer_drv:
672− platform_driver_unregister(&mixer_driver);
673−err_unregister_dsi_drv:
674−#endif
589+static int exynos_drm_platform_probe(struct platform_device *pdev)
590+{
591+ struct component_match *match;
675592
676−#ifdef CONFIG_DRM_EXYNOS_DSI
677− platform_driver_unregister(&dsi_driver);
678−err_unregister_dp_drv:
679−#endif
593+ pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
594+ exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
680595
681−#ifdef CONFIG_DRM_EXYNOS_DP
682− platform_driver_unregister(&dp_driver);
683−err_unregister_fimd_drv:
684−#endif
596+ match = exynos_drm_match_add(&pdev->dev);
597+ if (IS_ERR(match)) {
598+ return PTR_ERR(match);
599+ }
685600
686−#ifdef CONFIG_DRM_EXYNOS_FIMD
687− platform_driver_unregister(&fimd_driver);
688−#endif
689− return ret;
601+ return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
602+ match);
690603 }
691604
692605 static int exynos_drm_platform_remove(struct platform_device *pdev)
693606 {
694−#ifdef CONFIG_DRM_EXYNOS_IPP
695− exynos_platform_device_ipp_unregister();
696− platform_driver_unregister(&ipp_driver);
697−#endif
698−
699−#ifdef CONFIG_DRM_EXYNOS_GSC
700− platform_driver_unregister(&gsc_driver);
701−#endif
702−
703−#ifdef CONFIG_DRM_EXYNOS_ROTATOR
704− platform_driver_unregister(&rotator_driver);
705−#endif
706−
707−#ifdef CONFIG_DRM_EXYNOS_FIMC
708− platform_driver_unregister(&fimc_driver);
709−#endif
710−
711−#ifdef CONFIG_DRM_EXYNOS_G2D
712− platform_driver_unregister(&g2d_driver);
713−#endif
714−
715−#ifdef CONFIG_DRM_EXYNOS_HDMI
716− platform_driver_unregister(&mixer_driver);
717− platform_driver_unregister(&hdmi_driver);
718−#endif
719−
720−#ifdef CONFIG_DRM_EXYNOS_FIMD
721− platform_driver_unregister(&fimd_driver);
722−#endif
723−
724−#ifdef CONFIG_DRM_EXYNOS_DSI
725− platform_driver_unregister(&dsi_driver);
726−#endif
727−
728−#ifdef CONFIG_DRM_EXYNOS_DP
729− platform_driver_unregister(&dp_driver);
730−#endif
731607 component_master_del(&pdev->dev, &exynos_drm_ops);
732608 return 0;
733609 }
734610
611+static const char * const strings[] = {
612+ "samsung,exynos3",
613+ "samsung,exynos4",
614+ "samsung,exynos5",
615+};
616+
735617 static struct platform_driver exynos_drm_platform_driver = {
736618 .probe = exynos_drm_platform_probe,
737619 .remove = exynos_drm_platform_remove,
@@ -743,7 +625,25 @@ static struct platform_driver exynos_drm_platform_driver = { · 5 unmodified lines
743625
744626 static int exynos_drm_init(void)
745627 {
746− int ret;
628+ bool is_exynos = false;
629+ int ret, i, j;
630+
631+ /*
632+ * Register device object only in case of Exynos SoC.
633+ *
634+ * Below codes resolves temporarily infinite loop issue incurred
635+ * by Exynos drm driver when using multi-platform kernel.
636+ * So these codes will be replaced with more generic way later.
637+ */
638+ for (i = 0; i < ARRAY_SIZE(strings); i++) {
639+ if (of_machine_is_compatible(strings[i])) {
640+ is_exynos = true;
641+ break;
642+ }
643+ }
644+
645+ if (!is_exynos)
646+ return -ENODEV;
747647
748648 /*
749649 * Register device object only in case of Exynos SoC.
@@ -762,24 +662,50 @@ static int exynos_drm_init(void) · 12 unmodified lines
762662 if (IS_ERR(exynos_drm_pdev))
763663 return PTR_ERR(exynos_drm_pdev);
764664
765−#ifdef CONFIG_DRM_EXYNOS_VIDI
766665 ret = exynos_drm_probe_vidi();
767666 if (ret < 0)
768667 goto err_unregister_pd;
668+
669+ for (i = 0; i < ARRAY_SIZE(exynos_drm_kms_drivers); ++i) {
670+ ret = platform_driver_register(exynos_drm_kms_drivers[i]);
671+ if (ret < 0)
672+ goto err_unregister_kms_drivers;
673+ }
674+
675+ for (j = 0; j < ARRAY_SIZE(exynos_drm_non_kms_drivers); ++j) {
676+ ret = platform_driver_register(exynos_drm_non_kms_drivers[j]);
677+ if (ret < 0)
678+ goto err_unregister_non_kms_drivers;
679+ }
680+
681+#ifdef CONFIG_DRM_EXYNOS_IPP
682+ ret = exynos_platform_device_ipp_register();
683+ if (ret < 0)
684+ goto err_unregister_non_kms_drivers;
769685 #endif
770686
771687 ret = platform_driver_register(&exynos_drm_platform_driver);
772688 if (ret)
773− goto err_remove_vidi;
689+ goto err_unregister_resources;
774690
775691 return 0;
776692
777−err_remove_vidi:
778−#ifdef CONFIG_DRM_EXYNOS_VIDI
693+err_unregister_resources:
694+#ifdef CONFIG_DRM_EXYNOS_IPP
695+ exynos_platform_device_ipp_unregister();
696+#endif
697+
698+err_unregister_non_kms_drivers:
699+ while (--j >= 0)
700+ platform_driver_unregister(exynos_drm_non_kms_drivers[j]);
701+
702+err_unregister_kms_drivers:
703+ while (--i >= 0)
704+ platform_driver_unregister(exynos_drm_kms_drivers[i]);
705+
779706 exynos_drm_remove_vidi();
780707
781708 err_unregister_pd:
782−#endif
783709 platform_device_unregister(exynos_drm_pdev);
784710
785711 return ret;
@@ -787,10 +713,22 @@ err_unregister_pd: · 1 unmodified line
787713
788714 static void exynos_drm_exit(void)
789715 {
716+ int i;
717+
718+#ifdef CONFIG_DRM_EXYNOS_IPP
719+ exynos_platform_device_ipp_unregister();
720+#endif
721+
722+ for (i = ARRAY_SIZE(exynos_drm_non_kms_drivers) - 1; i >= 0; --i)
723+ platform_driver_unregister(exynos_drm_non_kms_drivers[i]);
724+
725+ for (i = ARRAY_SIZE(exynos_drm_kms_drivers) - 1; i >= 0; --i)
726+ platform_driver_unregister(exynos_drm_kms_drivers[i]);
727+
790728 platform_driver_unregister(&exynos_drm_platform_driver);
791−#ifdef CONFIG_DRM_EXYNOS_VIDI
729+
792730 exynos_drm_remove_vidi();
793−#endif
731+
794732 platform_device_unregister(exynos_drm_pdev);
795733 }
796734
drivers/gpu/drm/exynos/exynos_drm_drv.h+26−57
@@ -15,6 +15,7 @@ · 14 unmodified lines
1515 #ifndef _EXYNOS_DRM_DRV_H_
1616 #define _EXYNOS_DRM_DRV_H_
1717
18+#include <drm/drmP.h>
1819 #include <linux/module.h>
1920
2021 #define MAX_CRTC 3
@@ -22,24 +23,6 @@ · 1 unmodified line
2223 #define MAX_FB_BUFFER 4
2324 #define DEFAULT_ZPOS -1
2425
25−#define _wait_for(COND, MS) ({ \
26− unsigned long timeout__ = jiffies + msecs_to_jiffies(MS); \
27− int ret__ = 0; \
28− while (!(COND)) { \
29− if (time_after(jiffies, timeout__)) { \
30− ret__ = -ETIMEDOUT; \
31− break; \
32− } \
33− } \
34− ret__; \
35−})
36−
37−#define wait_for(COND, MS) _wait_for(COND, MS)
38−
39−struct drm_device;
40−struct exynos_drm_overlay;
41−struct drm_connector;
42−
4326 /* This enumerates device type. */
4427 enum exynos_drm_device_type {
4528 EXYNOS_DEVICE_TYPE_NONE,
@@ -83,10 +66,10 @@ enum exynos_drm_output_type { · 37 unmodified lines
8366 * @dma_addr: array of bus(accessed by dma) address to the memory region
8467 * allocated for a overlay.
8568 * @zpos: order of overlay layer(z position).
86− * @default_win: a window to be enabled.
87− * @color_key: color key on or off.
8869 * @index_color: if using color key feature then this value would be used
8970 * as index color.
71+ * @default_win: a window to be enabled.
72+ * @color_key: color key on or off.
9073 * @local_path: in case of lcd type, local path mode on or off.
9174 * @transparency: transparency on or off.
9275 * @activated: activated or not.
@@ -114,19 +97,20 @@ struct exynos_drm_overlay { · 21 unmodified lines
11497 uint32_t pixel_format;
11598 dma_addr_t dma_addr[MAX_FB_BUFFER];
11699 int zpos;
117−
118− bool default_win;
119− bool color_key;
120100 unsigned int index_color;
121− bool local_path;
122− bool transparency;
123− bool activated;
101+
102+ bool default_win:1;
103+ bool color_key:1;
104+ bool local_path:1;
105+ bool transparency:1;
106+ bool activated:1;
124107 };
125108
126109 /*
127110 * Exynos DRM Display Structure.
128111 * - this structure is common to analog tv, digital tv and lcd panel.
129112 *
113+ * @create_connector: initialize and register a new connector
130114 * @remove: cleans up the display for removal
131115 * @mode_fixup: fix mode data comparing to hw specific display mode.
132116 * @mode_set: convert drm_display_mode to hw specific display mode and
@@ -168,7 +152,6 @@ struct exynos_drm_display { · 35 unmodified lines
168152 struct drm_encoder *encoder;
169153 struct drm_connector *connector;
170154 struct exynos_drm_display_ops *ops;
171− void *ctx;
172155 };
173156
174157 /*
@@ -227,7 +210,6 @@ struct exynos_drm_manager { · 52 unmodified lines
227210 struct drm_crtc *crtc;
228211 int pipe;
229212 struct exynos_drm_manager_ops *ops;
230− void *ctx;
231213 };
232214
233215 struct exynos_drm_g2d_private {
@@ -279,8 +261,6 @@ struct exynos_drm_private { · 45 unmodified lines
279261 * @dev: pointer to device object for subdrv device driver.
280262 * @drm_dev: pointer to drm_device and this pointer would be set
281263 * when sub driver calls exynos_drm_subdrv_register().
282− * @manager: subdrv has its own manager to control a hardware appropriately
283− * and we can access a hardware drawing on this manager.
284264 * @probe: this callback would be called by exynos drm driver after
285265 * subdrv is registered to it.
286266 * @remove: this callback is used to release resources created
@@ -312,45 +292,34 @@ int exynos_drm_device_subdrv_remove(struct drm_device *dev); · 25 unmodified lines
312292 int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
313293 void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
314294
315−/*
316− * this function registers exynos drm hdmi platform device. It ensures only one
317− * instance of the device is created.
318− */
319−int exynos_platform_device_hdmi_register(void);
320−
321−/*
322− * this function unregisters exynos drm hdmi platform device if it exists.
323− */
324−void exynos_platform_device_hdmi_unregister(void);
325−
326−/*
327− * this function registers exynos drm ipp platform device.
328− */
295+#ifdef CONFIG_DRM_EXYNOS_IPP
329296 int exynos_platform_device_ipp_register(void);
330−
331−/*
332− * this function unregisters exynos drm ipp platform device if it exists.
333− */
334297 void exynos_platform_device_ipp_unregister(void);
298+#else
299+static inline int exynos_platform_device_ipp_register(void) { return 0; }
300+static inline void exynos_platform_device_ipp_unregister(void) {}
301+#endif
302+
335303
336304 #ifdef CONFIG_DRM_EXYNOS_DPI
337305 struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
338−int exynos_dpi_remove(struct device *dev);
306+int exynos_dpi_remove(struct exynos_drm_display *display);
339307 #else
340308 static inline struct exynos_drm_display *
341309 exynos_dpi_probe(struct device *dev) { return NULL; }
342−static inline int exynos_dpi_remove(struct device *dev) { return 0; }
310+static inline int exynos_dpi_remove(struct exynos_drm_display *display)
311+{
312+ return 0;
313+}
343314 #endif
344315
345−/*
346− * this function registers exynos drm vidi platform device/driver.
347− */
316+#ifdef CONFIG_DRM_EXYNOS_VIDI
348317 int exynos_drm_probe_vidi(void);
349−
350−/*
351− * this function unregister exynos drm vidi platform device/driver.
352− */
353318 void exynos_drm_remove_vidi(void);
319+#else
320+static inline int exynos_drm_probe_vidi(void) { return 0; }
321+static inline void exynos_drm_remove_vidi(void) {}
322+#endif
354323
355324 /* This function creates a encoder and a connector, and initializes them. */
356325 int exynos_drm_create_enc_conn(struct drm_device *dev,
drivers/gpu/drm/exynos/exynos_drm_dsi.c+66−63
@@ -268,9 +268,9 @@ struct exynos_dsi_driver_data { · 267 unmodified lines
268268 };
269269
270270 struct exynos_dsi {
271+ struct exynos_drm_display display;
271272 struct mipi_dsi_host dsi_host;
272273 struct drm_connector connector;
273− struct drm_encoder *encoder;
274274 struct device_node *panel_node;
275275 struct drm_panel *panel;
276276 struct device *dev;
@@ -304,6 +304,11 @@ struct exynos_dsi { · 27 unmodified lines
304304 #define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
305305 #define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
306306
307+static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d)
308+{
309+ return container_of(d, struct exynos_dsi, display);
310+}
311+
307312 static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
308313 .plltmr_reg = 0x50,
309314 .has_freqband = 1,
@@ -316,6 +321,11 @@ static struct exynos_dsi_driver_data exynos4_dsi_driver_data = { · 6 unmodified lines
316321 .has_clklane_stop = 1,
317322 };
318323
324+static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
325+ .plltmr_reg = 0x58,
326+ .has_clklane_stop = 1,
327+};
328+
319329 static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
320330 .plltmr_reg = 0x58,
321331 };
@@ -325,6 +335,8 @@ static struct of_device_id exynos_dsi_of_match[] = { · 3 unmodified lines
325335 .data = &exynos3_dsi_driver_data },
326336 { .compatible = "samsung,exynos4210-mipi-dsi",
327337 .data = &exynos4_dsi_driver_data },
338+ { .compatible = "samsung,exynos4415-mipi-dsi",
339+ .data = &exynos4415_dsi_driver_data },
328340 { .compatible = "samsung,exynos5410-mipi-dsi",
329341 .data = &exynos5_dsi_driver_data },
330342 { }
@@ -1104,7 +1116,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id) · 773 unmodified lines
11041116 static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
11051117 {
11061118 struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
1107− struct drm_encoder *encoder = dsi->encoder;
1119+ struct drm_encoder *encoder = dsi->display.encoder;
11081120
11091121 if (dsi->state & DSIM_STATE_ENABLED)
11101122 exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1143,6 +1155,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) · 32 unmodified lines
11431155 static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
11441156 {
11451157 int ret;
1158+ int te_gpio_irq;
11461159
11471160 dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
11481161 if (!gpio_is_valid(dsi->te_gpio)) {
@@ -1157,14 +1170,10 @@ static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi) · 8 unmodified lines
11571170 goto out;
11581171 }
11591172
1160− /*
1161− * This TE GPIO IRQ should not be set to IRQ_NOAUTOEN, because panel
1162− * calls drm_panel_init() first then calls mipi_dsi_attach() in probe().
1163− * It means that te_gpio is invalid when exynos_dsi_enable_irq() is
1164− * called by drm_panel_init() before panel is attached.
1165− */
1166− ret = request_threaded_irq(gpio_to_irq(dsi->te_gpio),
1167− exynos_dsi_te_irq_handler, NULL,
1173+ te_gpio_irq = gpio_to_irq(dsi->te_gpio);
1174+
1175+ irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN);
1176+ ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL,
11681177 IRQF_TRIGGER_RISING, "TE", dsi);
11691178 if (ret) {
11701179 dev_err(dsi->dev, "request interrupt failed with %d\n", ret);
@@ -1195,9 +1204,6 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, · 24 unmodified lines
11951204 dsi->mode_flags = device->mode_flags;
11961205 dsi->panel_node = device->dev.of_node;
11971206
1198− if (dsi->connector.dev)
1199− drm_helper_hpd_irq_event(dsi->connector.dev);
1200−
12011207 /*
12021208 * This is a temporary solution and should be made by more generic way.
12031209 *
@@ -1211,6 +1217,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, · 7 unmodified lines
12111217 return ret;
12121218 }
12131219
1220+ if (dsi->connector.dev)
1221+ drm_helper_hpd_irq_event(dsi->connector.dev);
1222+
12141223 return 0;
12151224 }
12161225
@@ -1236,7 +1245,7 @@ static bool exynos_dsi_is_short_dsi_type(u8 type) · 19 unmodified lines
12361245 }
12371246
12381247 static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
1239− struct mipi_dsi_msg *msg)
1248+ const struct mipi_dsi_msg *msg)
12401249 {
12411250 struct exynos_dsi *dsi = host_to_dsi(host);
12421251 struct exynos_dsi_transfer xfer;
@@ -1369,16 +1378,17 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi) · 126 unmodified lines
13691378 exynos_dsi_set_display_mode(dsi);
13701379 exynos_dsi_set_display_enable(dsi, true);
13711380
1381+ dsi->state |= DSIM_STATE_ENABLED;
1382+
13721383 ret = drm_panel_enable(dsi->panel);
13731384 if (ret < 0) {
1385+ dsi->state &= ~DSIM_STATE_ENABLED;
13741386 exynos_dsi_set_display_enable(dsi, false);
13751387 drm_panel_unprepare(dsi->panel);
13761388 exynos_dsi_poweroff(dsi);
13771389 return ret;
13781390 }
13791391
1380− dsi->state |= DSIM_STATE_ENABLED;
1381−
13821392 return 0;
13831393 }
13841394
@@ -1397,7 +1407,7 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi) · 12 unmodified lines
13971407
13981408 static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
13991409 {
1400− struct exynos_dsi *dsi = display->ctx;
1410+ struct exynos_dsi *dsi = display_to_dsi(display);
14011411
14021412 if (dsi->panel) {
14031413 switch (mode) {
@@ -1474,7 +1484,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector) · 70 unmodified lines
14741484 {
14751485 struct exynos_dsi *dsi = connector_to_dsi(connector);
14761486
1477− return dsi->encoder;
1487+ return dsi->display.encoder;
14781488 }
14791489
14801490 static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {
@@ -1486,12 +1496,10 @@ static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = { · 5 unmodified lines
14861496 static int exynos_dsi_create_connector(struct exynos_drm_display *display,
14871497 struct drm_encoder *encoder)
14881498 {
1489− struct exynos_dsi *dsi = display->ctx;
1499+ struct exynos_dsi *dsi = display_to_dsi(display);
14901500 struct drm_connector *connector = &dsi->connector;
14911501 int ret;
14921502
1493− dsi->encoder = encoder;
1494−
14951503 connector->polled = DRM_CONNECTOR_POLL_HPD;
14961504
14971505 ret = drm_connector_init(encoder->dev, connector,
@@ -1512,7 +1520,7 @@ static int exynos_dsi_create_connector(struct exynos_drm_display *display, · 14 unmodified lines
15121520 static void exynos_dsi_mode_set(struct exynos_drm_display *display,
15131521 struct drm_display_mode *mode)
15141522 {
1515− struct exynos_dsi *dsi = display->ctx;
1523+ struct exynos_dsi *dsi = display_to_dsi(display);
15161524 struct videomode *vm = &dsi->vm;
15171525
15181526 vm->hactive = mode->hdisplay;
@@ -1531,10 +1539,6 @@ static struct exynos_drm_display_ops exynos_dsi_display_ops = { · 12 unmodified lines
15311539 .dpms = exynos_dsi_dpms
15321540 };
15331541
1534−static struct exynos_drm_display exynos_dsi_display = {
1535− .type = EXYNOS_DISPLAY_TYPE_LCD,
1536− .ops = &exynos_dsi_display_ops,
1537−};
15381542 MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
15391543
15401544 /* of_* functions will be removed after merge of of_graph patches */
@@ -1640,28 +1644,28 @@ end: · 99 unmodified lines
16401644 static int exynos_dsi_bind(struct device *dev, struct device *master,
16411645 void *data)
16421646 {
1647+ struct exynos_drm_display *display = dev_get_drvdata(dev);
1648+ struct exynos_dsi *dsi = display_to_dsi(display);
16431649 struct drm_device *drm_dev = data;
1644− struct exynos_dsi *dsi;
16451650 int ret;
16461651
1647− ret = exynos_drm_create_enc_conn(drm_dev, &exynos_dsi_display);
1652+ ret = exynos_drm_create_enc_conn(drm_dev, display);
16481653 if (ret) {
16491654 DRM_ERROR("Encoder create [%d] failed with %d\n",
1650− exynos_dsi_display.type, ret);
1655+ display->type, ret);
16511656 return ret;
16521657 }
16531658
1654− dsi = exynos_dsi_display.ctx;
1655−
16561659 return mipi_dsi_host_register(&dsi->dsi_host);
16571660 }
16581661
16591662 static void exynos_dsi_unbind(struct device *dev, struct device *master,
16601663 void *data)
16611664 {
1662− struct exynos_dsi *dsi = exynos_dsi_display.ctx;
1665+ struct exynos_drm_display *display = dev_get_drvdata(dev);
1666+ struct exynos_dsi *dsi = display_to_dsi(display);
16631667
1664− exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);
1668+ exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
16651669
16661670 mipi_dsi_host_unregister(&dsi->dsi_host);
16671671 }
@@ -1673,22 +1677,23 @@ static const struct component_ops exynos_dsi_component_ops = { · 5 unmodified lines
16731677
16741678 static int exynos_dsi_probe(struct platform_device *pdev)
16751679 {
1680+ struct device *dev = &pdev->dev;
16761681 struct resource *res;
16771682 struct exynos_dsi *dsi;
16781683 int ret;
16791684
1680− ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1681− exynos_dsi_display.type);
1685+ dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
1686+ if (!dsi)
1687+ return -ENOMEM;
1688+
1689+ dsi->display.type = EXYNOS_DISPLAY_TYPE_LCD;
1690+ dsi->display.ops = &exynos_dsi_display_ops;
1691+
1692+ ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1693+ dsi->display.type);
16821694 if (ret)
16831695 return ret;
16841696
1685− dsi = devm_kzalloc(&pdev->dev, sizeof(*dsi), GFP_KERNEL);
1686− if (!dsi) {
1687− dev_err(&pdev->dev, "failed to allocate dsi object.\n");
1688− ret = -ENOMEM;
1689− goto err_del_component;
1690− }
1691−
16921697 /* To be checked as invalid one */
16931698 dsi->te_gpio = -ENOENT;
16941699
@@ -1697,9 +1702,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 2 unmodified lines
16971702 INIT_LIST_HEAD(&dsi->transfer_list);
16981703
16991704 dsi->dsi_host.ops = &exynos_dsi_ops;
1700− dsi->dsi_host.dev = &pdev->dev;
1705+ dsi->dsi_host.dev = dev;
17011706
1702− dsi->dev = &pdev->dev;
1707+ dsi->dev = dev;
17031708 dsi->driver_data = exynos_dsi_get_driver_data(pdev);
17041709
17051710 ret = exynos_dsi_parse_dt(dsi);
@@ -1708,70 +1713,68 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 2 unmodified lines
17081713
17091714 dsi->supplies[0].supply = "vddcore";
17101715 dsi->supplies[1].supply = "vddio";
1711− ret = devm_regulator_bulk_get(&pdev->dev, ARRAY_SIZE(dsi->supplies),
1716+ ret = devm_regulator_bulk_get(dev, ARRAY_SIZE(dsi->supplies),
17121717 dsi->supplies);
17131718 if (ret) {
1714− dev_info(&pdev->dev, "failed to get regulators: %d\n", ret);
1719+ dev_info(dev, "failed to get regulators: %d\n", ret);
17151720 return -EPROBE_DEFER;
17161721 }
17171722
1718− dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");
1723+ dsi->pll_clk = devm_clk_get(dev, "pll_clk");
17191724 if (IS_ERR(dsi->pll_clk)) {
1720− dev_info(&pdev->dev, "failed to get dsi pll input clock\n");
1725+ dev_info(dev, "failed to get dsi pll input clock\n");
17211726 ret = PTR_ERR(dsi->pll_clk);
17221727 goto err_del_component;
17231728 }
17241729
1725− dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");
1730+ dsi->bus_clk = devm_clk_get(dev, "bus_clk");
17261731 if (IS_ERR(dsi->bus_clk)) {
1727− dev_info(&pdev->dev, "failed to get dsi bus clock\n");
1732+ dev_info(dev, "failed to get dsi bus clock\n");
17281733 ret = PTR_ERR(dsi->bus_clk);
17291734 goto err_del_component;
17301735 }
17311736
17321737 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1733− dsi->reg_base = devm_ioremap_resource(&pdev->dev, res);
1738+ dsi->reg_base = devm_ioremap_resource(dev, res);
17341739 if (IS_ERR(dsi->reg_base)) {
1735− dev_err(&pdev->dev, "failed to remap io region\n");
1740+ dev_err(dev, "failed to remap io region\n");
17361741 ret = PTR_ERR(dsi->reg_base);
17371742 goto err_del_component;
17381743 }
17391744
1740− dsi->phy = devm_phy_get(&pdev->dev, "dsim");
1745+ dsi->phy = devm_phy_get(dev, "dsim");
17411746 if (IS_ERR(dsi->phy)) {
1742− dev_info(&pdev->dev, "failed to get dsim phy\n");
1747+ dev_info(dev, "failed to get dsim phy\n");
17431748 ret = PTR_ERR(dsi->phy);
17441749 goto err_del_component;
17451750 }
17461751
17471752 dsi->irq = platform_get_irq(pdev, 0);
17481753 if (dsi->irq < 0) {
1749− dev_err(&pdev->dev, "failed to request dsi irq resource\n");
1754+ dev_err(dev, "failed to request dsi irq resource\n");
17501755 ret = dsi->irq;
17511756 goto err_del_component;
17521757 }
17531758
17541759 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);
1755− ret = devm_request_threaded_irq(&pdev->dev, dsi->irq, NULL,
1760+ ret = devm_request_threaded_irq(dev, dsi->irq, NULL,
17561761 exynos_dsi_irq, IRQF_ONESHOT,
1757− dev_name(&pdev->dev), dsi);
1762+ dev_name(dev), dsi);
17581763 if (ret) {
1759− dev_err(&pdev->dev, "failed to request dsi irq\n");
1764+ dev_err(dev, "failed to request dsi irq\n");
17601765 goto err_del_component;
17611766 }
17621767
1763− exynos_dsi_display.ctx = dsi;
1764−
1765− platform_set_drvdata(pdev, &exynos_dsi_display);
1768+ platform_set_drvdata(pdev, &dsi->display);
17661769
1767− ret = component_add(&pdev->dev, &exynos_dsi_component_ops);
1770+ ret = component_add(dev, &exynos_dsi_component_ops);
17681771 if (ret)
17691772 goto err_del_component;
17701773
17711774 return ret;
17721775
17731776 err_del_component:
1774− exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1777+ exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
17751778 return ret;
17761779 }
17771780
drivers/gpu/drm/exynos/exynos_drm_encoder.h+0−2
@@ -14,8 +14,6 @@ · 13 unmodified lines
1414 #ifndef _EXYNOS_DRM_ENCODER_H_
1515 #define _EXYNOS_DRM_ENCODER_H_
1616
17−struct exynos_drm_manager;
18−
1917 void exynos_drm_encoder_setup(struct drm_device *dev);
2018 struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
2119 struct exynos_drm_display *mgr,
drivers/gpu/drm/exynos/exynos_drm_fimd.c+148−118
@@ -84,8 +84,6 @@ · 83 unmodified lines
8484 /* FIMD has totally five hardware windows. */
8585 #define WINDOWS_NR 5
8686
87−#define get_fimd_manager(mgr) platform_get_drvdata(to_platform_device(dev))
88−
8987 struct fimd_driver_data {
9088 unsigned int timing_base;
9189 unsigned int lcdblk_offset;
@@ -96,6 +94,7 @@ struct fimd_driver_data { · 4 unmodified lines
9694 unsigned int has_clksel:1;
9795 unsigned int has_limited_fmt:1;
9896 unsigned int has_vidoutcon:1;
97+ unsigned int has_vtsel:1;
9998 };
10099
101100 static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -118,6 +117,17 @@ static struct fimd_driver_data exynos4_fimd_driver_data = { · 16 unmodified lines
118117 .lcdblk_vt_shift = 10,
119118 .lcdblk_bypass_shift = 1,
120119 .has_shadowcon = 1,
120+ .has_vtsel = 1,
121+};
122+
123+static struct fimd_driver_data exynos4415_fimd_driver_data = {
124+ .timing_base = 0x20000,
125+ .lcdblk_offset = 0x210,
126+ .lcdblk_vt_shift = 10,
127+ .lcdblk_bypass_shift = 1,
128+ .has_shadowcon = 1,
129+ .has_vidoutcon = 1,
130+ .has_vtsel = 1,
121131 };
122132
123133 static struct fimd_driver_data exynos5_fimd_driver_data = {
@@ -127,6 +137,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { · 3 unmodified lines
127137 .lcdblk_bypass_shift = 15,
128138 .has_shadowcon = 1,
129139 .has_vidoutcon = 1,
140+ .has_vtsel = 1,
130141 };
131142
132143 struct fimd_win_data {
@@ -146,6 +157,7 @@ struct fimd_win_data { · 13 unmodified lines
146157 };
147158
148159 struct fimd_context {
160+ struct exynos_drm_manager manager;
149161 struct device *dev;
150162 struct drm_device *drm_dev;
151163 struct clk *bus_clk;
@@ -173,6 +185,11 @@ struct fimd_context { · 21 unmodified lines
173185 struct exynos_drm_display *display;
174186 };
175187
188+static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
189+{
190+ return container_of(mgr, struct fimd_context, manager);
191+}
192+
176193 static const struct of_device_id fimd_driver_dt_match[] = {
177194 { .compatible = "samsung,s3c6400-fimd",
178195 .data = &s3c64xx_fimd_driver_data },
@@ -180,6 +197,8 @@ static const struct of_device_id fimd_driver_dt_match[] = { · 1 unmodified line
180197 .data = &exynos3_fimd_driver_data },
181198 { .compatible = "samsung,exynos4210-fimd",
182199 .data = &exynos4_fimd_driver_data },
200+ { .compatible = "samsung,exynos4415-fimd",
201+ .data = &exynos4415_fimd_driver_data },
183202 { .compatible = "samsung,exynos5250-fimd",
184203 .data = &exynos5_fimd_driver_data },
185204 {},
@@ -197,7 +216,7 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data( · 11 unmodified lines
197216
198217 static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
199218 {
200− struct fimd_context *ctx = mgr->ctx;
219+ struct fimd_context *ctx = mgr_to_fimd(mgr);
201220
202221 if (ctx->suspended)
203222 return;
@@ -214,9 +233,35 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) · 10 unmodified lines
214233 DRM_DEBUG_KMS("vblank wait timed out.\n");
215234 }
216235
236+static void fimd_enable_video_output(struct fimd_context *ctx, int win,
237+ bool enable)
238+{
239+ u32 val = readl(ctx->regs + WINCON(win));
240+
241+ if (enable)
242+ val |= WINCONx_ENWIN;
243+ else
244+ val &= ~WINCONx_ENWIN;
245+
246+ writel(val, ctx->regs + WINCON(win));
247+}
248+
249+static void fimd_enable_shadow_channel_path(struct fimd_context *ctx, int win,
250+ bool enable)
251+{
252+ u32 val = readl(ctx->regs + SHADOWCON);
253+
254+ if (enable)
255+ val |= SHADOWCON_CHx_ENABLE(win);
256+ else
257+ val &= ~SHADOWCON_CHx_ENABLE(win);
258+
259+ writel(val, ctx->regs + SHADOWCON);
260+}
261+
217262 static void fimd_clear_channel(struct exynos_drm_manager *mgr)
218263 {
219− struct fimd_context *ctx = mgr->ctx;
264+ struct fimd_context *ctx = mgr_to_fimd(mgr);
220265 int win, ch_enabled = 0;
221266
222267 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -226,16 +271,12 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) · 3 unmodified lines
226271 u32 val = readl(ctx->regs + WINCON(win));
227272
228273 if (val & WINCONx_ENWIN) {
229− /* wincon */
230− val &= ~WINCONx_ENWIN;
231− writel(val, ctx->regs + WINCON(win));
232−
233− /* unprotect windows */
234− if (ctx->driver_data->has_shadowcon) {
235− val = readl(ctx->regs + SHADOWCON);
236− val &= ~SHADOWCON_CHx_ENABLE(win);
237− writel(val, ctx->regs + SHADOWCON);
238− }
274+ fimd_enable_video_output(ctx, win, false);
275+
276+ if (ctx->driver_data->has_shadowcon)
277+ fimd_enable_shadow_channel_path(ctx, win,
278+ false);
279+
239280 ch_enabled = 1;
240281 }
241282 }
@@ -253,7 +294,7 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) · 11 unmodified lines
253294 static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
254295 struct drm_device *drm_dev)
255296 {
256− struct fimd_context *ctx = mgr->ctx;
297+ struct fimd_context *ctx = mgr_to_fimd(mgr);
257298 struct exynos_drm_private *priv;
258299 priv = drm_dev->dev_private;
259300
@@ -275,7 +316,7 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, · 15 unmodified lines
275316
276317 static void fimd_mgr_remove(struct exynos_drm_manager *mgr)
277318 {
278− struct fimd_context *ctx = mgr->ctx;
319+ struct fimd_context *ctx = mgr_to_fimd(mgr);
279320
280321 /* detach this sub driver from iommu mapping if supported. */
281322 if (is_drm_iommu_supported(ctx->drm_dev))
@@ -315,14 +356,14 @@ static bool fimd_mode_fixup(struct exynos_drm_manager *mgr, · 33 unmodified lines
315356 static void fimd_mode_set(struct exynos_drm_manager *mgr,
316357 const struct drm_display_mode *in_mode)
317358 {
318− struct fimd_context *ctx = mgr->ctx;
359+ struct fimd_context *ctx = mgr_to_fimd(mgr);
319360
320361 drm_mode_copy(&ctx->mode, in_mode);
321362 }
322363
323364 static void fimd_commit(struct exynos_drm_manager *mgr)
324365 {
325− struct fimd_context *ctx = mgr->ctx;
366+ struct fimd_context *ctx = mgr_to_fimd(mgr);
326367 struct drm_display_mode *mode = &ctx->mode;
327368 struct fimd_driver_data *driver_data = ctx->driver_data;
328369 void *timing_base = ctx->regs + driver_data->timing_base;
@@ -343,7 +384,8 @@ static void fimd_commit(struct exynos_drm_manager *mgr) · 14 unmodified lines
343384 writel(0, timing_base + I80IFCONFBx(0));
344385
345386 /* set video type selection to I80 interface */
346− if (ctx->sysreg && regmap_update_bits(ctx->sysreg,
387+ if (driver_data->has_vtsel && ctx->sysreg &&
388+ regmap_update_bits(ctx->sysreg,
347389 driver_data->lcdblk_offset,
348390 0x3 << driver_data->lcdblk_vt_shift,
349391 0x1 << driver_data->lcdblk_vt_shift)) {
@@ -421,7 +463,7 @@ static void fimd_commit(struct exynos_drm_manager *mgr) · 71 unmodified lines
421463
422464 static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
423465 {
424− struct fimd_context *ctx = mgr->ctx;
466+ struct fimd_context *ctx = mgr_to_fimd(mgr);
425467 u32 val;
426468
427469 if (ctx->suspended)
@@ -431,12 +473,19 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
431473 val = readl(ctx->regs + VIDINTCON0);
432474
433475 val |= VIDINTCON0_INT_ENABLE;
434− val |= VIDINTCON0_INT_FRAME;
435476
436− val &= ~VIDINTCON0_FRAMESEL0_MASK;
437− val |= VIDINTCON0_FRAMESEL0_VSYNC;
438− val &= ~VIDINTCON0_FRAMESEL1_MASK;
439− val |= VIDINTCON0_FRAMESEL1_NONE;
477+ if (ctx->i80_if) {
478+ val |= VIDINTCON0_INT_I80IFDONE;
479+ val |= VIDINTCON0_INT_SYSMAINCON;
480+ val &= ~VIDINTCON0_INT_SYSSUBCON;
481+ } else {
482+ val |= VIDINTCON0_INT_FRAME;
483+
484+ val &= ~VIDINTCON0_FRAMESEL0_MASK;
485+ val |= VIDINTCON0_FRAMESEL0_VSYNC;
486+ val &= ~VIDINTCON0_FRAMESEL1_MASK;
487+ val |= VIDINTCON0_FRAMESEL1_NONE;
488+ }
440489
441490 writel(val, ctx->regs + VIDINTCON0);
442491 }
@@ -446,7 +495,7 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
446495
447496 static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
448497 {
449− struct fimd_context *ctx = mgr->ctx;
498+ struct fimd_context *ctx = mgr_to_fimd(mgr);
450499 u32 val;
451500
452501 if (ctx->suspended)
@@ -455,9 +504,15 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) · 2 unmodified lines
455504 if (test_and_clear_bit(0, &ctx->irq_flags)) {
456505 val = readl(ctx->regs + VIDINTCON0);
457506
458− val &= ~VIDINTCON0_INT_FRAME;
459507 val &= ~VIDINTCON0_INT_ENABLE;
460508
509+ if (ctx->i80_if) {
510+ val &= ~VIDINTCON0_INT_I80IFDONE;
511+ val &= ~VIDINTCON0_INT_SYSMAINCON;
512+ val &= ~VIDINTCON0_INT_SYSSUBCON;
513+ } else
514+ val &= ~VIDINTCON0_INT_FRAME;
515+
461516 writel(val, ctx->regs + VIDINTCON0);
462517 }
463518 }
@@ -465,7 +520,7 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) · 1 unmodified line
465520 static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
466521 struct exynos_drm_overlay *overlay)
467522 {
468− struct fimd_context *ctx = mgr->ctx;
523+ struct fimd_context *ctx = mgr_to_fimd(mgr);
469524 struct fimd_win_data *win_data;
470525 int win;
471526 unsigned long offset;
@@ -623,7 +678,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, · 151 unmodified lines
623678
624679 static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
625680 {
626− struct fimd_context *ctx = mgr->ctx;
681+ struct fimd_context *ctx = mgr_to_fimd(mgr);
627682 struct fimd_win_data *win_data;
628683 int win = zpos;
629684 unsigned long val, alpha, size;
@@ -730,20 +785,14 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) · 100 unmodified lines
730785 if (win != 0)
731786 fimd_win_set_colkey(ctx, win);
732787
733− /* wincon */
734− val = readl(ctx->regs + WINCON(win));
735− val |= WINCONx_ENWIN;
736− writel(val, ctx->regs + WINCON(win));
788+ fimd_enable_video_output(ctx, win, true);
789+
790+ if (ctx->driver_data->has_shadowcon)
791+ fimd_enable_shadow_channel_path(ctx, win, true);
737792
738793 /* Enable DMA channel and unprotect windows */
739794 fimd_shadow_protect_win(ctx, win, false);
740795
741− if (ctx->driver_data->has_shadowcon) {
742− val = readl(ctx->regs + SHADOWCON);
743− val |= SHADOWCON_CHx_ENABLE(win);
744− writel(val, ctx->regs + SHADOWCON);
745− }
746−
747796 win_data->enabled = true;
748797
749798 if (ctx->i80_if)
@@ -752,10 +801,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) · 2 unmodified lines
752801
753802 static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
754803 {
755− struct fimd_context *ctx = mgr->ctx;
804+ struct fimd_context *ctx = mgr_to_fimd(mgr);
756805 struct fimd_win_data *win_data;
757806 int win = zpos;
758− u32 val;
759807
760808 if (win == DEFAULT_ZPOS)
761809 win = ctx->default_win;
@@ -774,18 +822,12 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) · 12 unmodified lines
774822 /* protect windows */
775823 fimd_shadow_protect_win(ctx, win, true);
776824
777− /* wincon */
778− val = readl(ctx->regs + WINCON(win));
779− val &= ~WINCONx_ENWIN;
780− writel(val, ctx->regs + WINCON(win));
825+ fimd_enable_video_output(ctx, win, false);
781826
782− /* unprotect windows */
783− if (ctx->driver_data->has_shadowcon) {
784− val = readl(ctx->regs + SHADOWCON);
785− val &= ~SHADOWCON_CHx_ENABLE(win);
786− writel(val, ctx->regs + SHADOWCON);
787− }
827+ if (ctx->driver_data->has_shadowcon)
828+ fimd_enable_shadow_channel_path(ctx, win, false);
788829
830+ /* unprotect windows */
789831 fimd_shadow_protect_win(ctx, win, false);
790832
791833 win_data->enabled = false;
@@ -793,7 +835,7 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) · 1 unmodified line
793835
794836 static void fimd_window_suspend(struct exynos_drm_manager *mgr)
795837 {
796− struct fimd_context *ctx = mgr->ctx;
838+ struct fimd_context *ctx = mgr_to_fimd(mgr);
797839 struct fimd_win_data *win_data;
798840 int i;
799841
@@ -803,12 +845,11 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr) · 3 unmodified lines
803845 if (win_data->enabled)
804846 fimd_win_disable(mgr, i);
805847 }
806− fimd_wait_for_vblank(mgr);
807848 }
808849
809850 static void fimd_window_resume(struct exynos_drm_manager *mgr)
810851 {
811− struct fimd_context *ctx = mgr->ctx;
852+ struct fimd_context *ctx = mgr_to_fimd(mgr);
812853 struct fimd_win_data *win_data;
813854 int i;
814855
@@ -821,7 +862,7 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr) · 6 unmodified lines
821862
822863 static void fimd_apply(struct exynos_drm_manager *mgr)
823864 {
824− struct fimd_context *ctx = mgr->ctx;
865+ struct fimd_context *ctx = mgr_to_fimd(mgr);
825866 struct fimd_win_data *win_data;
826867 int i;
827868
@@ -838,7 +879,7 @@ static void fimd_apply(struct exynos_drm_manager *mgr) · 10 unmodified lines
838879
839880 static int fimd_poweron(struct exynos_drm_manager *mgr)
840881 {
841− struct fimd_context *ctx = mgr->ctx;
882+ struct fimd_context *ctx = mgr_to_fimd(mgr);
842883 int ret;
843884
844885 if (!ctx->suspended)
@@ -886,7 +927,7 @@ bus_clk_err: · 41 unmodified lines
886927
887928 static int fimd_poweroff(struct exynos_drm_manager *mgr)
888929 {
889− struct fimd_context *ctx = mgr->ctx;
930+ struct fimd_context *ctx = mgr_to_fimd(mgr);
890931
891932 if (ctx->suspended)
892933 return 0;
@@ -928,39 +969,41 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) · 35 unmodified lines
928969
929970 static void fimd_trigger(struct device *dev)
930971 {
931− struct exynos_drm_manager *mgr = get_fimd_manager(dev);
932− struct fimd_context *ctx = mgr->ctx;
972+ struct fimd_context *ctx = dev_get_drvdata(dev);
933973 struct fimd_driver_data *driver_data = ctx->driver_data;
934974 void *timing_base = ctx->regs + driver_data->timing_base;
935975 u32 reg;
936976
937− atomic_set(&ctx->triggering, 1);
977+ /*
978+ * Skips triggering if in triggering state, because multiple triggering
979+ * requests can cause panel reset.
980+ */
981+ if (atomic_read(&ctx->triggering))
982+ return;
938983
939− reg = readl(ctx->regs + VIDINTCON0);
940− reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |
941− VIDINTCON0_INT_SYSMAINCON);
942− writel(reg, ctx->regs + VIDINTCON0);
984+ /* Enters triggering mode */
985+ atomic_set(&ctx->triggering, 1);
943986
944987 reg = readl(timing_base + TRIGCON);
945988 reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
946989 writel(reg, timing_base + TRIGCON);
990+
991+ /*
992+ * Exits triggering mode if vblank is not enabled yet, because when the
993+ * VIDINTCON0 register is not set, it can not exit from triggering mode.
994+ */
995+ if (!test_bit(0, &ctx->irq_flags))
996+ atomic_set(&ctx->triggering, 0);
947997 }
948998
949999 static void fimd_te_handler(struct exynos_drm_manager *mgr)
9501000 {
951− struct fimd_context *ctx = mgr->ctx;
1001+ struct fimd_context *ctx = mgr_to_fimd(mgr);
9521002
9531003 /* Checks the crtc is detached already from encoder */
9541004 if (ctx->pipe < 0 || !ctx->drm_dev)
9551005 return;
9561006
957− /*
958− * Skips to trigger if in triggering state, because multiple triggering
959− * requests can cause panel reset.
960− */
961− if (atomic_read(&ctx->triggering))
962− return;
963−
9641007 /*
9651008 * If there is a page flip request, triggers and handles the page flip
9661009 * event so that current fb can be updated into panel GRAM.
@@ -972,10 +1015,10 @@ static void fimd_te_handler(struct exynos_drm_manager *mgr) · 5 unmodified lines
9721015 if (atomic_read(&ctx->wait_vsync_event)) {
9731016 atomic_set(&ctx->wait_vsync_event, 0);
9741017 wake_up(&ctx->wait_vsync_queue);
975−
976− if (!atomic_read(&ctx->triggering))
977− drm_handle_vblank(ctx->drm_dev, ctx->pipe);
9781018 }
1019+
1020+ if (test_bit(0, &ctx->irq_flags))
1021+ drm_handle_vblank(ctx->drm_dev, ctx->pipe);
9791022 }
9801023
9811024 static struct exynos_drm_manager_ops fimd_manager_ops = {
@@ -992,11 +1035,6 @@ static struct exynos_drm_manager_ops fimd_manager_ops = { · 10 unmodified lines
9921035 .te_handler = fimd_te_handler,
9931036 };
9941037
995−static struct exynos_drm_manager fimd_manager = {
996− .type = EXYNOS_DISPLAY_TYPE_LCD,
997− .ops = &fimd_manager_ops,
998−};
999−
10001038 static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
10011039 {
10021040 struct fimd_context *ctx = (struct fimd_context *)dev_id;
@@ -1013,16 +1051,10 @@ static irqreturn_t fimd_irq_handler(int irq, void *dev_id) · 10 unmodified lines
10131051 goto out;
10141052
10151053 if (ctx->i80_if) {
1016− /* unset I80 frame done interrupt */
1017− val = readl(ctx->regs + VIDINTCON0);
1018− val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
1019− writel(val, ctx->regs + VIDINTCON0);
1054+ exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
10201055
1021− /* exit triggering mode */
1056+ /* Exits triggering mode */
10221057 atomic_set(&ctx->triggering, 0);
1023−
1024− drm_handle_vblank(ctx->drm_dev, ctx->pipe);
1025− exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
10261058 } else {
10271059 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
10281060 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
@@ -1040,11 +1072,11 @@ out: · 11 unmodified lines
10401072
10411073 static int fimd_bind(struct device *dev, struct device *master, void *data)
10421074 {
1043− struct fimd_context *ctx = fimd_manager.ctx;
1075+ struct fimd_context *ctx = dev_get_drvdata(dev);
10441076 struct drm_device *drm_dev = data;
10451077
1046− fimd_mgr_initialize(&fimd_manager, drm_dev);
1047− exynos_drm_crtc_create(&fimd_manager);
1078+ fimd_mgr_initialize(&ctx->manager, drm_dev);
1079+ exynos_drm_crtc_create(&ctx->manager);
10481080 if (ctx->display)
10491081 exynos_drm_create_enc_conn(drm_dev, ctx->display);
10501082
@@ -1055,15 +1087,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) · 4 unmodified lines
10551087 static void fimd_unbind(struct device *dev, struct device *master,
10561088 void *data)
10571089 {
1058− struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1059− struct fimd_context *ctx = fimd_manager.ctx;
1090+ struct fimd_context *ctx = dev_get_drvdata(dev);
10601091
1061− fimd_dpms(mgr, DRM_MODE_DPMS_OFF);
1092+ fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF);
10621093
10631094 if (ctx->display)
1064− exynos_dpi_remove(dev);
1095+ exynos_dpi_remove(ctx->display);
10651096
1066− fimd_mgr_remove(mgr);
1097+ fimd_mgr_remove(&ctx->manager);
10671098 }
10681099
10691100 static const struct component_ops fimd_component_ops = {
@@ -1079,21 +1110,20 @@ static int fimd_probe(struct platform_device *pdev) · 9 unmodified lines
10791110 struct resource *res;
10801111 int ret = -EINVAL;
10811112
1082− ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1083− fimd_manager.type);
1084− if (ret)
1085− return ret;
1086−
1087− if (!dev->of_node) {
1088− ret = -ENODEV;
1089− goto err_del_component;
1090− }
1113+ if (!dev->of_node)
1114+ return -ENODEV;
10911115
10921116 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1093− if (!ctx) {
1094− ret = -ENOMEM;
1095− goto err_del_component;
1096− }
1117+ if (!ctx)
1118+ return -ENOMEM;
1119+
1120+ ctx->manager.type = EXYNOS_DISPLAY_TYPE_LCD;
1121+ ctx->manager.ops = &fimd_manager_ops;
1122+
1123+ ret = exynos_drm_component_add(dev, EXYNOS_DEVICE_TYPE_CRTC,
1124+ ctx->manager.type);
1125+ if (ret)
1126+ return ret;
10971127
10981128 ctx->dev = dev;
10991129 ctx->suspended = true;
@@ -1182,27 +1212,27 @@ static int fimd_probe(struct platform_device *pdev) · 82 unmodified lines
11821212 init_waitqueue_head(&ctx->wait_vsync_queue);
11831213 atomic_set(&ctx->wait_vsync_event, 0);
11841214
1185− platform_set_drvdata(pdev, &fimd_manager);
1186−
1187− fimd_manager.ctx = ctx;
1215+ platform_set_drvdata(pdev, ctx);
11881216
11891217 ctx->display = exynos_dpi_probe(dev);
1190− if (IS_ERR(ctx->display))
1191− return PTR_ERR(ctx->display);
1218+ if (IS_ERR(ctx->display)) {
1219+ ret = PTR_ERR(ctx->display);
1220+ goto err_del_component;
1221+ }
11921222
1193− pm_runtime_enable(&pdev->dev);
1223+ pm_runtime_enable(dev);
11941224
1195− ret = component_add(&pdev->dev, &fimd_component_ops);
1225+ ret = component_add(dev, &fimd_component_ops);
11961226 if (ret)
11971227 goto err_disable_pm_runtime;
11981228
11991229 return ret;
12001230
12011231 err_disable_pm_runtime:
1202− pm_runtime_disable(&pdev->dev);
1232+ pm_runtime_disable(dev);
12031233
12041234 err_del_component:
1205− exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1235+ exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
12061236 return ret;
12071237 }
12081238
drivers/gpu/drm/exynos/exynos_drm_iommu.h+0−1
@@ -40,7 +40,6 @@ static inline bool is_drm_iommu_supported(struct drm_device *drm_dev) · 39 unmodified lines
4040
4141 #else
4242
43−struct dma_iommu_mapping;
4443 static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
4544 {
4645 return 0;
drivers/gpu/drm/exynos/exynos_drm_ipp.c+3−0
@@ -426,18 +426,21 @@ int exynos_drm_ipp_set_property(struct drm_device *drm_dev, void *data, · 425 unmodified lines
426426 c_node->start_work = ipp_create_cmd_work();
427427 if (IS_ERR(c_node->start_work)) {
428428 DRM_ERROR("failed to create start work.\n");
429+ ret = PTR_ERR(c_node->start_work);
429430 goto err_remove_id;
430431 }
431432
432433 c_node->stop_work = ipp_create_cmd_work();
433434 if (IS_ERR(c_node->stop_work)) {
434435 DRM_ERROR("failed to create stop work.\n");
436+ ret = PTR_ERR(c_node->stop_work);
435437 goto err_free_start;
436438 }
437439
438440 c_node->event_work = ipp_create_event_work();
439441 if (IS_ERR(c_node->event_work)) {
440442 DRM_ERROR("failed to create event work.\n");
443+ ret = PTR_ERR(c_node->event_work);
441444 goto err_free_stop;
442445 }
443446
drivers/gpu/drm/exynos/exynos_drm_vidi.c+92−58
@@ -14,6 +14,7 @@ · 13 unmodified lines
1414
1515 #include <linux/kernel.h>
1616 #include <linux/platform_device.h>
17+#include <linux/component.h>
1718
1819 #include <drm/exynos_drm.h>
1920
@@ -28,7 +29,6 @@ · 8 unmodified lines
2829 /* vidi has totally three virtual windows. */
2930 #define WINDOWS_NR 3
3031
31−#define get_vidi_mgr(dev) platform_get_drvdata(to_platform_device(dev))
3232 #define ctx_from_connector(c) container_of(c, struct vidi_context, \
3333 connector)
3434
@@ -47,11 +47,13 @@ struct vidi_win_data { · 12 unmodified lines
4747 };
4848
4949 struct vidi_context {
50+ struct exynos_drm_manager manager;
51+ struct exynos_drm_display display;
52+ struct platform_device *pdev;
5053 struct drm_device *drm_dev;
5154 struct drm_crtc *crtc;
5255 struct drm_encoder *encoder;
5356 struct drm_connector connector;
54− struct exynos_drm_subdrv subdrv;
5557 struct vidi_win_data win_data[WINDOWS_NR];
5658 struct edid *raw_edid;
5759 unsigned int clkdiv;
@@ -66,6 +68,16 @@ struct vidi_context { · 8 unmodified lines
6668 int pipe;
6769 };
6870
71+static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
72+{
73+ return container_of(m, struct vidi_context, manager);
74+}
75+
76+static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
77+{
78+ return container_of(d, struct vidi_context, display);
79+}
80+
6981 static const char fake_edid_info[] = {
7082 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
7183 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,
@@ -93,7 +105,7 @@ static const char fake_edid_info[] = { · 21 unmodified lines
93105
94106 static void vidi_apply(struct exynos_drm_manager *mgr)
95107 {
96− struct vidi_context *ctx = mgr->ctx;
108+ struct vidi_context *ctx = manager_to_vidi(mgr);
97109 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
98110 struct vidi_win_data *win_data;
99111 int i;
@@ -110,7 +122,7 @@ static void vidi_apply(struct exynos_drm_manager *mgr) · 10 unmodified lines
110122
111123 static void vidi_commit(struct exynos_drm_manager *mgr)
112124 {
113− struct vidi_context *ctx = mgr->ctx;
125+ struct vidi_context *ctx = manager_to_vidi(mgr);
114126
115127 if (ctx->suspended)
116128 return;
@@ -118,7 +130,7 @@ static void vidi_commit(struct exynos_drm_manager *mgr) · 1 unmodified line
118130
119131 static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
120132 {
121− struct vidi_context *ctx = mgr->ctx;
133+ struct vidi_context *ctx = manager_to_vidi(mgr);
122134
123135 if (ctx->suspended)
124136 return -EPERM;
@@ -140,7 +152,7 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr) · 15 unmodified lines
140152
141153 static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
142154 {
143− struct vidi_context *ctx = mgr->ctx;
155+ struct vidi_context *ctx = manager_to_vidi(mgr);
144156
145157 if (ctx->suspended)
146158 return;
@@ -152,7 +164,7 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr) · 5 unmodified lines
152164 static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
153165 struct exynos_drm_overlay *overlay)
154166 {
155− struct vidi_context *ctx = mgr->ctx;
167+ struct vidi_context *ctx = manager_to_vidi(mgr);
156168 struct vidi_win_data *win_data;
157169 int win;
158170 unsigned long offset;
@@ -204,7 +216,7 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr, · 45 unmodified lines
204216
205217 static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
206218 {
207− struct vidi_context *ctx = mgr->ctx;
219+ struct vidi_context *ctx = manager_to_vidi(mgr);
208220 struct vidi_win_data *win_data;
209221 int win = zpos;
210222
@@ -229,7 +241,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) · 18 unmodified lines
229241
230242 static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
231243 {
232− struct vidi_context *ctx = mgr->ctx;
244+ struct vidi_context *ctx = manager_to_vidi(mgr);
233245 struct vidi_win_data *win_data;
234246 int win = zpos;
235247
@@ -247,7 +259,7 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) · 11 unmodified lines
247259
248260 static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
249261 {
250− struct vidi_context *ctx = mgr->ctx;
262+ struct vidi_context *ctx = manager_to_vidi(mgr);
251263
252264 DRM_DEBUG_KMS("%s\n", __FILE__);
253265
@@ -271,7 +283,7 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) · 17 unmodified lines
271283
272284 static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
273285 {
274− struct vidi_context *ctx = mgr->ctx;
286+ struct vidi_context *ctx = manager_to_vidi(mgr);
275287
276288 DRM_DEBUG_KMS("%d\n", mode);
277289
@@ -297,7 +309,7 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) · 19 unmodified lines
297309 static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
298310 struct drm_device *drm_dev)
299311 {
300− struct vidi_context *ctx = mgr->ctx;
312+ struct vidi_context *ctx = manager_to_vidi(mgr);
301313 struct exynos_drm_private *priv = drm_dev->dev_private;
302314
303315 mgr->drm_dev = ctx->drm_dev = drm_dev;
@@ -316,11 +328,6 @@ static struct exynos_drm_manager_ops vidi_manager_ops = { · 12 unmodified lines
316328 .win_disable = vidi_win_disable,
317329 };
318330
319−static struct exynos_drm_manager vidi_manager = {
320− .type = EXYNOS_DISPLAY_TYPE_VIDI,
321− .ops = &vidi_manager_ops,
322−};
323−
324331 static void vidi_fake_vblank_handler(struct work_struct *work)
325332 {
326333 struct vidi_context *ctx = container_of(work, struct vidi_context,
@@ -349,9 +356,8 @@ static void vidi_fake_vblank_handler(struct work_struct *work) · 22 unmodified lines
349356 static int vidi_show_connection(struct device *dev,
350357 struct device_attribute *attr, char *buf)
351358 {
359+ struct vidi_context *ctx = dev_get_drvdata(dev);
352360 int rc;
353− struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
354− struct vidi_context *ctx = mgr->ctx;
355361
356362 mutex_lock(&ctx->lock);
357363
@@ -366,8 +372,7 @@ static int vidi_store_connection(struct device *dev, · 8 unmodified lines
366372 struct device_attribute *attr,
367373 const char *buf, size_t len)
368374 {
369− struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
370− struct vidi_context *ctx = mgr->ctx;
375+ struct vidi_context *ctx = dev_get_drvdata(dev);
371376 int ret;
372377
373378 ret = kstrtoint(buf, 0, &ctx->connected);
@@ -420,7 +425,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, · 46 unmodified lines
420425 display = exynos_drm_get_display(encoder);
421426
422427 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
423− ctx = display->ctx;
428+ ctx = display_to_vidi(display);
424429 break;
425430 }
426431 }
@@ -530,7 +535,7 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = { · 103 unmodified lines
530535 static int vidi_create_connector(struct exynos_drm_display *display,
531536 struct drm_encoder *encoder)
532537 {
533− struct vidi_context *ctx = display->ctx;
538+ struct vidi_context *ctx = display_to_vidi(display);
534539 struct drm_connector *connector = &ctx->connector;
535540 int ret;
536541
@@ -556,27 +561,22 @@ static struct exynos_drm_display_ops vidi_display_ops = { · 19 unmodified lines
556561 .create_connector = vidi_create_connector,
557562 };
558563
559−static struct exynos_drm_display vidi_display = {
560− .type = EXYNOS_DISPLAY_TYPE_VIDI,
561− .ops = &vidi_display_ops,
562−};
563−
564−static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
564+static int vidi_bind(struct device *dev, struct device *master, void *data)
565565 {
566− struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
567− struct vidi_context *ctx = mgr->ctx;
566+ struct vidi_context *ctx = dev_get_drvdata(dev);
567+ struct drm_device *drm_dev = data;
568568 struct drm_crtc *crtc = ctx->crtc;
569569 int ret;
570570
571− vidi_mgr_initialize(mgr, drm_dev);
571+ vidi_mgr_initialize(&ctx->manager, drm_dev);
572572
573− ret = exynos_drm_crtc_create(&vidi_manager);
573+ ret = exynos_drm_crtc_create(&ctx->manager);
574574 if (ret) {
575575 DRM_ERROR("failed to create crtc.\n");
576576 return ret;
577577 }
578578
579− ret = exynos_drm_create_enc_conn(drm_dev, &vidi_display);
579+ ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
580580 if (ret) {
581581 crtc->funcs->destroy(crtc);
582582 DRM_ERROR("failed to create encoder and connector.\n");
@@ -586,9 +586,18 @@ static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev) · 3 unmodified lines
586586 return 0;
587587 }
588588
589+
590+static void vidi_unbind(struct device *dev, struct device *master, void *data)
591+{
592+}
593+
594+static const struct component_ops vidi_component_ops = {
595+ .bind = vidi_bind,
596+ .unbind = vidi_unbind,
597+};
598+
589599 static int vidi_probe(struct platform_device *pdev)
590600 {
591− struct exynos_drm_subdrv *subdrv;
592601 struct vidi_context *ctx;
593602 int ret;
594603
@@ -596,40 +605,54 @@ static int vidi_probe(struct platform_device *pdev) · 1 unmodified line
596605 if (!ctx)
597606 return -ENOMEM;
598607
608+ ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
609+ ctx->manager.ops = &vidi_manager_ops;
610+ ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
611+ ctx->display.ops = &vidi_display_ops;
599612 ctx->default_win = 0;
613+ ctx->pdev = pdev;
600614
601− INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
602−
603− vidi_manager.ctx = ctx;
604− vidi_display.ctx = ctx;
615+ ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
616+ ctx->manager.type);
617+ if (ret)
618+ return ret;
605619
606− mutex_init(&ctx->lock);
620+ ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
621+ ctx->display.type);
622+ if (ret)
623+ goto err_del_crtc_component;
607624
608− platform_set_drvdata(pdev, &vidi_manager);
625+ INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
609626
610− subdrv = &ctx->subdrv;
611− subdrv->dev = &pdev->dev;
612− subdrv->probe = vidi_subdrv_probe;
627+ mutex_init(&ctx->lock);
613628
614− ret = exynos_drm_subdrv_register(subdrv);
615− if (ret < 0) {
616− dev_err(&pdev->dev, "failed to register drm vidi device\n");
617− return ret;
618− }
629+ platform_set_drvdata(pdev, ctx);
619630
620631 ret = device_create_file(&pdev->dev, &dev_attr_connection);
621632 if (ret < 0) {
622− exynos_drm_subdrv_unregister(subdrv);
623− DRM_INFO("failed to create connection sysfs.\n");
633+ DRM_ERROR("failed to create connection sysfs.\n");
634+ goto err_del_conn_component;
624635 }
625636
626− return 0;
637+ ret = component_add(&pdev->dev, &vidi_component_ops);
638+ if (ret)
639+ goto err_remove_file;
640+
641+ return ret;
642+
643+err_remove_file:
644+ device_remove_file(&pdev->dev, &dev_attr_connection);
645+err_del_conn_component:
646+ exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
647+err_del_crtc_component:
648+ exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
649+
650+ return ret;
627651 }
628652
629653 static int vidi_remove(struct platform_device *pdev)
630654 {
631− struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);
632− struct vidi_context *ctx = mgr->ctx;
655+ struct vidi_context *ctx = platform_get_drvdata(pdev);
633656
634657 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
635658 kfree(ctx->raw_edid);
@@ -638,6 +661,10 @@ static int vidi_remove(struct platform_device *pdev) · 2 unmodified lines
638661 return -EINVAL;
639662 }
640663
664+ component_del(&pdev->dev, &vidi_component_ops);
665+ exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
666+ exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
667+
641668 return 0;
642669 }
643670
@@ -668,12 +695,19 @@ int exynos_drm_probe_vidi(void) · 24 unmodified lines
668695 return ret;
669696 }
670697
698+static int exynos_drm_remove_vidi_device(struct device *dev, void *data)
699+{
700+ platform_device_unregister(to_platform_device(dev));
701+
702+ return 0;
703+}
704+
671705 void exynos_drm_remove_vidi(void)
672706 {
673− struct vidi_context *ctx = vidi_manager.ctx;
674− struct exynos_drm_subdrv *subdrv = &ctx->subdrv;
675− struct platform_device *pdev = to_platform_device(subdrv->dev);
707+ int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
708+ exynos_drm_remove_vidi_device);
709+ /* silence compiler warning */
710+ (void)ret;
676711
677712 platform_driver_unregister(&vidi_driver);
678− platform_device_unregister(pdev);
679713 }
drivers/gpu/drm/exynos/exynos_hdmi.c+30−35
@@ -49,7 +49,6 @@ · 48 unmodified lines
4949 #include <linux/gpio.h>
5050 #include <media/s5p_hdmi.h>
5151
52−#define get_hdmi_display(dev) platform_get_drvdata(to_platform_device(dev))
5352 #define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)
5453
5554 #define HOTPLUG_DEBOUNCE_MS 1100
@@ -182,6 +181,7 @@ struct hdmi_conf_regs { · 126 unmodified lines
182181 };
183182
184183 struct hdmi_context {
184+ struct exynos_drm_display display;
185185 struct device *dev;
186186 struct drm_device *drm_dev;
187187 struct drm_connector connector;
@@ -213,6 +213,11 @@ struct hdmi_context { · 25 unmodified lines
213213 enum hdmi_type type;
214214 };
215215
216+static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
217+{
218+ return container_of(d, struct hdmi_context, display);
219+}
220+
216221 struct hdmiphy_config {
217222 int pixel_clock;
218223 u8 conf[32];
@@ -1123,7 +1128,7 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { · 904 unmodified lines
11231128 static int hdmi_create_connector(struct exynos_drm_display *display,
11241129 struct drm_encoder *encoder)
11251130 {
1126− struct hdmi_context *hdata = display->ctx;
1131+ struct hdmi_context *hdata = display_to_hdmi(display);
11271132 struct drm_connector *connector = &hdata->connector;
11281133 int ret;
11291134
@@ -2000,7 +2005,7 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata, · 870 unmodified lines
20002005 static void hdmi_mode_set(struct exynos_drm_display *display,
20012006 struct drm_display_mode *mode)
20022007 {
2003− struct hdmi_context *hdata = display->ctx;
2008+ struct hdmi_context *hdata = display_to_hdmi(display);
20042009 struct drm_display_mode *m = mode;
20052010
20062011 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",
@@ -2019,7 +2024,7 @@ static void hdmi_mode_set(struct exynos_drm_display *display, · 12 unmodified lines
20192024
20202025 static void hdmi_commit(struct exynos_drm_display *display)
20212026 {
2022− struct hdmi_context *hdata = display->ctx;
2027+ struct hdmi_context *hdata = display_to_hdmi(display);
20232028
20242029 mutex_lock(&hdata->hdmi_mutex);
20252030 if (!hdata->powered) {
@@ -2033,7 +2038,7 @@ static void hdmi_commit(struct exynos_drm_display *display) · 7 unmodified lines
20332038
20342039 static void hdmi_poweron(struct exynos_drm_display *display)
20352040 {
2036− struct hdmi_context *hdata = display->ctx;
2041+ struct hdmi_context *hdata = display_to_hdmi(display);
20372042 struct hdmi_resources *res = &hdata->res;
20382043
20392044 mutex_lock(&hdata->hdmi_mutex);
@@ -2064,7 +2069,7 @@ static void hdmi_poweron(struct exynos_drm_display *display) · 24 unmodified lines
20642069
20652070 static void hdmi_poweroff(struct exynos_drm_display *display)
20662071 {
2067− struct hdmi_context *hdata = display->ctx;
2072+ struct hdmi_context *hdata = display_to_hdmi(display);
20682073 struct hdmi_resources *res = &hdata->res;
20692074
20702075 mutex_lock(&hdata->hdmi_mutex);
@@ -2099,7 +2104,7 @@ out: · 28 unmodified lines
20992104
21002105 static void hdmi_dpms(struct exynos_drm_display *display, int mode)
21012106 {
2102− struct hdmi_context *hdata = display->ctx;
2107+ struct hdmi_context *hdata = display_to_hdmi(display);
21032108 struct drm_encoder *encoder = hdata->encoder;
21042109 struct drm_crtc *crtc = encoder->crtc;
21052110 struct drm_crtc_helper_funcs *funcs = NULL;
@@ -2143,11 +2148,6 @@ static struct exynos_drm_display_ops hdmi_display_ops = { · 37 unmodified lines
21432148 .commit = hdmi_commit,
21442149 };
21452150
2146−static struct exynos_drm_display hdmi_display = {
2147− .type = EXYNOS_DISPLAY_TYPE_HDMI,
2148− .ops = &hdmi_display_ops,
2149−};
2150−
21512151 static void hdmi_hotplug_work_func(struct work_struct *work)
21522152 {
21532153 struct hdmi_context *hdata;
@@ -2302,12 +2302,11 @@ MODULE_DEVICE_TABLE (of, hdmi_match_types); · 148 unmodified lines
23022302 static int hdmi_bind(struct device *dev, struct device *master, void *data)
23032303 {
23042304 struct drm_device *drm_dev = data;
2305− struct hdmi_context *hdata;
2305+ struct hdmi_context *hdata = dev_get_drvdata(dev);
23062306
2307− hdata = hdmi_display.ctx;
23082307 hdata->drm_dev = drm_dev;
23092308
2310− return exynos_drm_create_enc_conn(drm_dev, &hdmi_display);
2309+ return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
23112310 }
23122311
23132312 static void hdmi_unbind(struct device *dev, struct device *master, void *data)
@@ -2349,31 +2348,28 @@ static int hdmi_probe(struct platform_device *pdev) · 35 unmodified lines
23492348 struct resource *res;
23502349 int ret;
23512350
2352− ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2353− hdmi_display.type);
2354− if (ret)
2355− return ret;
2356−
2357− if (!dev->of_node) {
2358− ret = -ENODEV;
2359− goto err_del_component;
2360− }
2351+ if (!dev->of_node)
2352+ return -ENODEV;
23612353
23622354 pdata = drm_hdmi_dt_parse_pdata(dev);
2363− if (!pdata) {
2364− ret = -EINVAL;
2365− goto err_del_component;
2366− }
2355+ if (!pdata)
2356+ return -EINVAL;
23672357
23682358 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2369− if (!hdata) {
2370− ret = -ENOMEM;
2371− goto err_del_component;
2372− }
2359+ if (!hdata)
2360+ return -ENOMEM;
2361+
2362+ hdata->display.type = EXYNOS_DISPLAY_TYPE_HDMI;
2363+ hdata->display.ops = &hdmi_display_ops;
2364+
2365+ ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
2366+ hdata->display.type);
2367+ if (ret)
2368+ return ret;
23732369
23742370 mutex_init(&hdata->hdmi_mutex);
23752371
2376− platform_set_drvdata(pdev, &hdmi_display);
2372+ platform_set_drvdata(pdev, hdata);
23772373
23782374 match = of_match_node(hdmi_match_types, dev->of_node);
23792375 if (!match) {
@@ -2485,7 +2481,6 @@ out_get_phy_port: · 105 unmodified lines
24852481 }
24862482
24872483 pm_runtime_enable(dev);
2488− hdmi_display.ctx = hdata;
24892484
24902485 ret = component_add(&pdev->dev, &hdmi_component_ops);
24912486 if (ret)
@@ -2510,7 +2505,7 @@ err_del_component: · 18 unmodified lines
25102505
25112506 static int hdmi_remove(struct platform_device *pdev)
25122507 {
2513− struct hdmi_context *hdata = hdmi_display.ctx;
2508+ struct hdmi_context *hdata = platform_get_drvdata(pdev);
25142509
25152510 cancel_delayed_work_sync(&hdata->hotplug_work);
25162511
drivers/gpu/drm/exynos/exynos_mixer.c+66−60
@@ -40,8 +40,6 @@ · 39 unmodified lines
4040 #include "exynos_drm_iommu.h"
4141 #include "exynos_mixer.h"
4242
43−#define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev))
44−
4543 #define MIXER_WIN_NR 3
4644 #define MIXER_DEFAULT_WIN 0
4745
@@ -86,6 +84,7 @@ enum mixer_version_id { · 38 unmodified lines
8684 };
8785
8886 struct mixer_context {
87+ struct exynos_drm_manager manager;
8988 struct platform_device *pdev;
9089 struct device *dev;
9190 struct drm_device *drm_dev;
@@ -104,6 +103,11 @@ struct mixer_context { · 12 unmodified lines
104103 atomic_t wait_vsync_event;
105104 };
106105
106+static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr)
107+{
108+ return container_of(mgr, struct mixer_context, manager);
109+}
110+
107111 struct mixer_drv_data {
108112 enum mixer_version_id version;
109113 bool is_vp_enabled;
@@ -854,7 +858,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, · 744 unmodified lines
854858 struct drm_device *drm_dev)
855859 {
856860 int ret;
857− struct mixer_context *mixer_ctx = mgr->ctx;
861+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
858862 struct exynos_drm_private *priv;
859863 priv = drm_dev->dev_private;
860864
@@ -885,7 +889,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, · 24 unmodified lines
885889
886890 static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
887891 {
888− struct mixer_context *mixer_ctx = mgr->ctx;
892+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
889893
890894 if (is_drm_iommu_supported(mixer_ctx->drm_dev))
891895 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);
@@ -893,7 +897,7 @@ static void mixer_mgr_remove(struct exynos_drm_manager *mgr) · 1 unmodified line
893897
894898 static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
895899 {
896− struct mixer_context *mixer_ctx = mgr->ctx;
900+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
897901 struct mixer_resources *res = &mixer_ctx->mixer_res;
898902
899903 if (!mixer_ctx->powered) {
@@ -910,7 +914,7 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr) · 10 unmodified lines
910914
911915 static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
912916 {
913− struct mixer_context *mixer_ctx = mgr->ctx;
917+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
914918 struct mixer_resources *res = &mixer_ctx->mixer_res;
915919
916920 /* disable vsync interrupt */
@@ -920,7 +924,7 @@ static void mixer_disable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
920924 static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
921925 struct exynos_drm_overlay *overlay)
922926 {
923− struct mixer_context *mixer_ctx = mgr->ctx;
927+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
924928 struct hdmi_win_data *win_data;
925929 int win;
926930
@@ -971,7 +975,7 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr, · 44 unmodified lines
971975
972976 static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
973977 {
974− struct mixer_context *mixer_ctx = mgr->ctx;
978+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
975979 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
976980
977981 DRM_DEBUG_KMS("win: %d\n", win);
@@ -993,7 +997,7 @@ static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos) · 15 unmodified lines
993997
994998 static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
995999 {
996− struct mixer_context *mixer_ctx = mgr->ctx;
1000+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
9971001 struct mixer_resources *res = &mixer_ctx->mixer_res;
9981002 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
9991003 unsigned long flags;
@@ -1021,7 +1025,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) · 21 unmodified lines
10211025
10221026 static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
10231027 {
1024− struct mixer_context *mixer_ctx = mgr->ctx;
1028+ struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
10251029
10261030 mutex_lock(&mixer_ctx->mixer_mutex);
10271031 if (!mixer_ctx->powered) {
@@ -1048,7 +1052,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) · 20 unmodified lines
10481052
10491053 static void mixer_window_suspend(struct exynos_drm_manager *mgr)
10501054 {
1051− struct mixer_context *ctx = mgr->ctx;
1055+ struct mixer_context *ctx = mgr_to_mixer(mgr);
10521056 struct hdmi_win_data *win_data;
10531057 int i;
10541058
@@ -1062,7 +1066,7 @@ static void mixer_window_suspend(struct exynos_drm_manager *mgr) · 7 unmodified lines
10621066
10631067 static void mixer_window_resume(struct exynos_drm_manager *mgr)
10641068 {
1065− struct mixer_context *ctx = mgr->ctx;
1069+ struct mixer_context *ctx = mgr_to_mixer(mgr);
10661070 struct hdmi_win_data *win_data;
10671071 int i;
10681072
@@ -1077,7 +1081,7 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr) · 8 unmodified lines
10771081
10781082 static void mixer_poweron(struct exynos_drm_manager *mgr)
10791083 {
1080− struct mixer_context *ctx = mgr->ctx;
1084+ struct mixer_context *ctx = mgr_to_mixer(mgr);
10811085 struct mixer_resources *res = &ctx->mixer_res;
10821086
10831087 mutex_lock(&ctx->mixer_mutex);
@@ -1111,7 +1115,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) · 27 unmodified lines
11111115
11121116 static void mixer_poweroff(struct exynos_drm_manager *mgr)
11131117 {
1114− struct mixer_context *ctx = mgr->ctx;
1118+ struct mixer_context *ctx = mgr_to_mixer(mgr);
11151119 struct mixer_resources *res = &ctx->mixer_res;
11161120
11171121 mutex_lock(&ctx->mixer_mutex);
@@ -1187,11 +1191,6 @@ static struct exynos_drm_manager_ops mixer_manager_ops = { · 69 unmodified lines
11871191 .win_disable = mixer_win_disable,
11881192 };
11891193
1190−static struct exynos_drm_manager mixer_manager = {
1191− .type = EXYNOS_DISPLAY_TYPE_HDMI,
1192− .ops = &mixer_manager_ops,
1193−};
1194−
11951194 static struct mixer_drv_data exynos5420_mxr_drv_data = {
11961195 .version = MXR_VER_128_0_0_184,
11971196 .is_vp_enabled = 0,
@@ -1249,48 +1248,17 @@ MODULE_DEVICE_TABLE(of, mixer_match_types); · 51 unmodified lines
12491248
12501249 static int mixer_bind(struct device *dev, struct device *manager, void *data)
12511250 {
1252− struct platform_device *pdev = to_platform_device(dev);
1251+ struct mixer_context *ctx = dev_get_drvdata(dev);
12531252 struct drm_device *drm_dev = data;
1254− struct mixer_context *ctx;
1255− struct mixer_drv_data *drv;
12561253 int ret;
12571254
1258− dev_info(dev, "probe start\n");
1259−
1260− ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1261− if (!ctx) {
1262− DRM_ERROR("failed to alloc mixer context.\n");
1263− return -ENOMEM;
1264− }
1265−
1266− mutex_init(&ctx->mixer_mutex);
1267−
1268− if (dev->of_node) {
1269− const struct of_device_id *match;
1270− match = of_match_node(mixer_match_types, dev->of_node);
1271− drv = (struct mixer_drv_data *)match->data;
1272− } else {
1273− drv = (struct mixer_drv_data *)
1274− platform_get_device_id(pdev)->driver_data;
1275− }
1276−
1277− ctx->pdev = pdev;
1278− ctx->dev = dev;
1279− ctx->vp_enabled = drv->is_vp_enabled;
1280− ctx->has_sclk = drv->has_sclk;
1281− ctx->mxr_ver = drv->version;
1282− init_waitqueue_head(&ctx->wait_vsync_queue);
1283− atomic_set(&ctx->wait_vsync_event, 0);
1284−
1285− mixer_manager.ctx = ctx;
1286− ret = mixer_initialize(&mixer_manager, drm_dev);
1255+ ret = mixer_initialize(&ctx->manager, drm_dev);
12871256 if (ret)
12881257 return ret;
12891258
1290− platform_set_drvdata(pdev, &mixer_manager);
1291− ret = exynos_drm_crtc_create(&mixer_manager);
1259+ ret = exynos_drm_crtc_create(&ctx->manager);
12921260 if (ret) {
1293− mixer_mgr_remove(&mixer_manager);
1261+ mixer_mgr_remove(&ctx->manager);
12941262 return ret;
12951263 }
12961264
@@ -1301,11 +1269,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) · 4 unmodified lines
13011269
13021270 static void mixer_unbind(struct device *dev, struct device *master, void *data)
13031271 {
1304− struct exynos_drm_manager *mgr = dev_get_drvdata(dev);
1272+ struct mixer_context *ctx = dev_get_drvdata(dev);
13051273
1306− dev_info(dev, "remove successful\n");
1307−
1308− mixer_mgr_remove(mgr);
1274+ mixer_mgr_remove(&ctx->manager);
13091275
13101276 pm_runtime_disable(dev);
13111277 }
@@ -1317,22 +1283,62 @@ static const struct component_ops mixer_component_ops = { · 5 unmodified lines
13171283
13181284 static int mixer_probe(struct platform_device *pdev)
13191285 {
1286+ struct device *dev = &pdev->dev;
1287+ struct mixer_drv_data *drv;
1288+ struct mixer_context *ctx;
13201289 int ret;
13211290
1291+ ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
1292+ if (!ctx) {
1293+ DRM_ERROR("failed to alloc mixer context.\n");
1294+ return -ENOMEM;
1295+ }
1296+
1297+ mutex_init(&ctx->mixer_mutex);
1298+
1299+ ctx->manager.type = EXYNOS_DISPLAY_TYPE_HDMI;
1300+ ctx->manager.ops = &mixer_manager_ops;
1301+
1302+ if (dev->of_node) {
1303+ const struct of_device_id *match;
1304+
1305+ match = of_match_node(mixer_match_types, dev->of_node);
1306+ drv = (struct mixer_drv_data *)match->data;
1307+ } else {
1308+ drv = (struct mixer_drv_data *)
1309+ platform_get_device_id(pdev)->driver_data;
1310+ }
1311+
1312+ ctx->pdev = pdev;
1313+ ctx->dev = dev;
1314+ ctx->vp_enabled = drv->is_vp_enabled;
1315+ ctx->has_sclk = drv->has_sclk;
1316+ ctx->mxr_ver = drv->version;
1317+ init_waitqueue_head(&ctx->wait_vsync_queue);
1318+ atomic_set(&ctx->wait_vsync_event, 0);
1319+
1320+ platform_set_drvdata(pdev, ctx);
1321+
13221322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1323− mixer_manager.type);
1323+ ctx->manager.type);
13241324 if (ret)
13251325 return ret;
13261326
13271327 ret = component_add(&pdev->dev, &mixer_component_ops);
1328− if (ret)
1328+ if (ret) {
13291329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1330+ return ret;
1331+ }
1332+
1333+ pm_runtime_enable(dev);
13301334
13311335 return ret;
13321336 }
13331337
13341338 static int mixer_remove(struct platform_device *pdev)
13351339 {
1340+ pm_runtime_disable(&pdev->dev);
1341+
13361342 component_del(&pdev->dev, &mixer_component_ops);
13371343 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
13381344
drivers/gpu/drm/gma500/Makefile+1−0
@@ -39,6 +39,7 @@ gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \ · 38 unmodified lines
3939 gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \
4040 oaktrail_crtc.o \
4141 oaktrail_lvds.o \
42+ oaktrail_lvds_i2c.o \
4243 oaktrail_hdmi.o \
4344 oaktrail_hdmi_i2c.o
4445
drivers/gpu/drm/gma500/cdv_intel_dp.c+195−0
@@ -37,6 +37,201 @@ · 36 unmodified lines
3737 #include "gma_display.h"
3838 #include <drm/drm_dp_helper.h>
3939
40+/**
41+ * struct i2c_algo_dp_aux_data - driver interface structure for i2c over dp
42+ * aux algorithm
43+ * @running: set by the algo indicating whether an i2c is ongoing or whether
44+ * the i2c bus is quiescent
45+ * @address: i2c target address for the currently ongoing transfer
46+ * @aux_ch: driver callback to transfer a single byte of the i2c payload
47+ */
48+struct i2c_algo_dp_aux_data {
49+ bool running;
50+ u16 address;
51+ int (*aux_ch) (struct i2c_adapter *adapter,
52+ int mode, uint8_t write_byte,
53+ uint8_t *read_byte);
54+};
55+
56+/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
57+static int
58+i2c_algo_dp_aux_transaction(struct i2c_adapter *adapter, int mode,
59+ uint8_t write_byte, uint8_t *read_byte)
60+{
61+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
62+ int ret;
63+
64+ ret = (*algo_data->aux_ch)(adapter, mode,
65+ write_byte, read_byte);
66+ return ret;
67+}
68+
69+/*
70+ * I2C over AUX CH
71+ */
72+
73+/*
74+ * Send the address. If the I2C link is running, this 'restarts'
75+ * the connection with the new address, this is used for doing
76+ * a write followed by a read (as needed for DDC)
77+ */
78+static int
79+i2c_algo_dp_aux_address(struct i2c_adapter *adapter, u16 address, bool reading)
80+{
81+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
82+ int mode = MODE_I2C_START;
83+ int ret;
84+
85+ if (reading)
86+ mode |= MODE_I2C_READ;
87+ else
88+ mode |= MODE_I2C_WRITE;
89+ algo_data->address = address;
90+ algo_data->running = true;
91+ ret = i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
92+ return ret;
93+}
94+
95+/*
96+ * Stop the I2C transaction. This closes out the link, sending
97+ * a bare address packet with the MOT bit turned off
98+ */
99+static void
100+i2c_algo_dp_aux_stop(struct i2c_adapter *adapter, bool reading)
101+{
102+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
103+ int mode = MODE_I2C_STOP;
104+
105+ if (reading)
106+ mode |= MODE_I2C_READ;
107+ else
108+ mode |= MODE_I2C_WRITE;
109+ if (algo_data->running) {
110+ (void) i2c_algo_dp_aux_transaction(adapter, mode, 0, NULL);
111+ algo_data->running = false;
112+ }
113+}
114+
115+/*
116+ * Write a single byte to the current I2C address, the
117+ * the I2C link must be running or this returns -EIO
118+ */
119+static int
120+i2c_algo_dp_aux_put_byte(struct i2c_adapter *adapter, u8 byte)
121+{
122+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
123+ int ret;
124+
125+ if (!algo_data->running)
126+ return -EIO;
127+
128+ ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_WRITE, byte, NULL);
129+ return ret;
130+}
131+
132+/*
133+ * Read a single byte from the current I2C address, the
134+ * I2C link must be running or this returns -EIO
135+ */
136+static int
137+i2c_algo_dp_aux_get_byte(struct i2c_adapter *adapter, u8 *byte_ret)
138+{
139+ struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
140+ int ret;
141+
142+ if (!algo_data->running)
143+ return -EIO;
144+
145+ ret = i2c_algo_dp_aux_transaction(adapter, MODE_I2C_READ, 0, byte_ret);
146+ return ret;
147+}
148+
149+static int
150+i2c_algo_dp_aux_xfer(struct i2c_adapter *adapter,
151+ struct i2c_msg *msgs,
152+ int num)
153+{
154+ int ret = 0;
155+ bool reading = false;
156+ int m;
157+ int b;
158+
159+ for (m = 0; m < num; m++) {
160+ u16 len = msgs[m].len;
161+ u8 *buf = msgs[m].buf;
162+ reading = (msgs[m].flags & I2C_M_RD) != 0;
163+ ret = i2c_algo_dp_aux_address(adapter, msgs[m].addr, reading);
164+ if (ret < 0)
165+ break;
166+ if (reading) {
167+ for (b = 0; b < len; b++) {
168+ ret = i2c_algo_dp_aux_get_byte(adapter, &buf[b]);
169+ if (ret < 0)
170+ break;
171+ }
172+ } else {
173+ for (b = 0; b < len; b++) {
174+ ret = i2c_algo_dp_aux_put_byte(adapter, buf[b]);
175+ if (ret < 0)
176+ break;
177+ }
178+ }
179+ if (ret < 0)
180+ break;
181+ }
182+ if (ret >= 0)
183+ ret = num;
184+ i2c_algo_dp_aux_stop(adapter, reading);
185+ DRM_DEBUG_KMS("dp_aux_xfer return %d\n", ret);
186+ return ret;
187+}
188+
189+static u32
190+i2c_algo_dp_aux_functionality(struct i2c_adapter *adapter)
191+{
192+ return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL |
193+ I2C_FUNC_SMBUS_READ_BLOCK_DATA |
194+ I2C_FUNC_SMBUS_BLOCK_PROC_CALL |
195+ I2C_FUNC_10BIT_ADDR;
196+}
197+
198+static const struct i2c_algorithm i2c_dp_aux_algo = {
199+ .master_xfer = i2c_algo_dp_aux_xfer,
200+ .functionality = i2c_algo_dp_aux_functionality,

37 more lines aren’t shown here.

drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.c+31−44

This diff is large: its 181 lines aren’t shown here.

drivers/gpu/drm/gma500/mdfld_dsi_pkg_sender.h+0−12

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/gma500/oaktrail_lvds.c+19−12

This diff is large: its 59 lines aren’t shown here.

drivers/gpu/drm/gma500/oaktrail_lvds_i2c.c+170−0

This diff is large: its 171 lines aren’t shown here.

drivers/gpu/drm/gma500/psb_drv.c+20−0

This diff is large: its 34 lines aren’t shown here.

drivers/gpu/drm/gma500/psb_drv.h+3−0

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/gma500/psb_intel_display.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/gma500/psb_intel_drv.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/gma500/psb_intel_sdvo.c+0−49

This diff is large: its 58 lines aren’t shown here.

drivers/gpu/drm/i2c/Kconfig+6−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/i2c/Makefile+2−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i2c/adv7511.c+1010−0

This diff is large: its 1011 lines aren’t shown here.

drivers/gpu/drm/i2c/adv7511.h+289−0

This diff is large: its 290 lines aren’t shown here.

drivers/gpu/drm/i915/Makefile+10−3

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/i915/i915_cmd_parser.c+28−11

This diff is large: its 102 lines aren’t shown here.

drivers/gpu/drm/i915/i915_debugfs.c+203−67

This diff is large: its 519 lines aren’t shown here.

drivers/gpu/drm/i915/i915_dma.c+38−1032

This diff is large: its 1239 lines aren’t shown here.

drivers/gpu/drm/i915/i915_drv.c+149−210

This diff is large: its 605 lines aren’t shown here.

drivers/gpu/drm/i915/i915_drv.h+205−106

This diff is large: its 719 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem.c+336−309

This diff is large: its 1128 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_context.c+12−6

This diff is large: its 67 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_execbuffer.c+62−25

This diff is large: its 136 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_gtt.c+66−30

This diff is large: its 266 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_gtt.h+6−4

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_render_state.c+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_stolen.c+6−2

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gem_tiling.c+45−15

This diff is large: its 89 lines aren’t shown here.

drivers/gpu/drm/i915/i915_gpu_error.c+24−19

This diff is large: its 137 lines aren’t shown here.

drivers/gpu/drm/i915/i915_ioc32.c+0−2

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/i915/i915_irq.c+367−633

This diff is large: its 1848 lines aren’t shown here.

drivers/gpu/drm/i915/i915_reg.h+533−110

This diff is large: its 941 lines aren’t shown here.

drivers/gpu/drm/i915/i915_suspend.c+21−36

This diff is large: its 107 lines aren’t shown here.

drivers/gpu/drm/i915/i915_sysfs.c+19−3

This diff is large: its 54 lines aren’t shown here.

drivers/gpu/drm/i915/i915_trace.h+104−0

This diff is large: its 111 lines aren’t shown here.

drivers/gpu/drm/i915/i915_ums.c+14−0

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/i915/intel_audio.c+463−0

This diff is large: its 464 lines aren’t shown here.

drivers/gpu/drm/i915/intel_bios.h+5−5

This diff is large: its 42 lines aren’t shown here.

drivers/gpu/drm/i915/intel_crt.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/intel_ddi.c+658−61

This diff is large: its 961 lines aren’t shown here.

drivers/gpu/drm/i915/intel_display.c+1512−1373

This diff is large: its 4897 lines aren’t shown here.

drivers/gpu/drm/i915/intel_dp.c+455−530

This diff is large: its 1571 lines aren’t shown here.

drivers/gpu/drm/i915/intel_dp_mst.c+5−11

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/i915/intel_drv.h+145−67

This diff is large: its 419 lines aren’t shown here.

drivers/gpu/drm/i915/intel_dsi.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/i915/intel_fbdev.c+31−13

This diff is large: its 115 lines aren’t shown here.

drivers/gpu/drm/i915/intel_fifo_underrun.c+381−0

This diff is large: its 382 lines aren’t shown here.

drivers/gpu/drm/i915/intel_frontbuffer.c+279−0

This diff is large: its 280 lines aren’t shown here.

drivers/gpu/drm/i915/intel_hdmi.c+111−9

This diff is large: its 257 lines aren’t shown here.

drivers/gpu/drm/i915/intel_lrc.c+257−81

This diff is large: its 659 lines aren’t shown here.

drivers/gpu/drm/i915/intel_lrc.h+5−1

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/i915/intel_lvds.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/i915/intel_panel.c+86−50

This diff is large: its 376 lines aren’t shown here.

drivers/gpu/drm/i915/intel_pm.c+3371−3540

This diff is large: its 8078 lines aren’t shown here.

drivers/gpu/drm/i915/intel_psr.c+481−0

This diff is large: its 482 lines aren’t shown here.

drivers/gpu/drm/i915/intel_renderstate.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/i915/intel_renderstate_gen8.c+640−162

This diff is large: its 1035 lines aren’t shown here.

drivers/gpu/drm/i915/intel_renderstate_gen9.c+974−0

This diff is large: its 975 lines aren’t shown here.

drivers/gpu/drm/i915/intel_ringbuffer.c+188−231

This diff is large: its 626 lines aren’t shown here.

drivers/gpu/drm/i915/intel_ringbuffer.h+8−4

This diff is large: its 45 lines aren’t shown here.

drivers/gpu/drm/i915/intel_runtime_pm.c+1406−0

This diff is large: its 1407 lines aren’t shown here.

drivers/gpu/drm/i915/intel_sdvo.c+0−47

This diff is large: its 58 lines aren’t shown here.

drivers/gpu/drm/i915/intel_sprite.c+474−131

This diff is large: its 792 lines aren’t shown here.

drivers/gpu/drm/i915/intel_tv.c+4−5

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/i915/intel_uncore.c+393−102

This diff is large: its 704 lines aren’t shown here.

drivers/gpu/drm/imx/Kconfigrenamed from drivers/staging/imx-drm/Kconfig+0−0

File renamed without changes.

drivers/gpu/drm/imx/Makefilerenamed from drivers/staging/imx-drm/Makefile+0−0

File renamed without changes.

drivers/gpu/drm/imx/imx-drm-core.crenamed from drivers/staging/imx-drm/imx-drm-core.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/imx/imx-drm.hrenamed from drivers/staging/imx-drm/imx-drm.h+0−0

File renamed without changes.

drivers/gpu/drm/imx/imx-hdmi.crenamed from drivers/staging/imx-drm/imx-hdmi.c+0−0

File renamed without changes.

drivers/gpu/drm/imx/imx-hdmi.hrenamed from drivers/staging/imx-drm/imx-hdmi.h+0−0

File renamed without changes.

drivers/gpu/drm/imx/imx-ldb.crenamed from drivers/staging/imx-drm/imx-ldb.c+0−0

File renamed without changes.

drivers/gpu/drm/imx/imx-tve.crenamed from drivers/staging/imx-drm/imx-tve.c+0−0

File renamed without changes.

drivers/gpu/drm/imx/ipuv3-crtc.crenamed from drivers/staging/imx-drm/ipuv3-crtc.c+0−0

File renamed without changes.

drivers/gpu/drm/imx/ipuv3-plane.crenamed from drivers/staging/imx-drm/ipuv3-plane.c+0−0

File renamed without changes.

drivers/gpu/drm/imx/ipuv3-plane.hrenamed from drivers/staging/imx-drm/ipuv3-plane.h+0−0

File renamed without changes.

drivers/gpu/drm/imx/parallel-display.crenamed from drivers/staging/imx-drm/parallel-display.c+0−0

File renamed without changes.

drivers/gpu/drm/mgag200/mgag200_mode.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/msm/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/msm/Makefile+4−0

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a2xx.xml.h+13−13

This diff is large: its 72 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a3xx.xml.h+221−26

This diff is large: its 462 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a3xx_gpu.c+91−0

This diff is large: its 112 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a4xx.xml.h+2144−0

This diff is large: its 2145 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a4xx_gpu.c+604−0

This diff is large: its 605 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/a4xx_gpu.h+34−0

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_common.xml.h+13−4

This diff is large: its 45 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_device.c+13−0

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_gpu.c+18−13

This diff is large: its 86 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_gpu.h+126−0

This diff is large: its 160 lines aren’t shown here.

drivers/gpu/drm/msm/adreno/adreno_pm4.xml.h+39−36

This diff is large: its 135 lines aren’t shown here.

drivers/gpu/drm/msm/dsi/dsi.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/dsi/mmss_cc.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/dsi/sfpb.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi.c+81−63

This diff is large: its 284 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi.h+0−17

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi_bridge.c+1−2

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi_connector.c+4−3

This diff is large: its 28 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/hdmi_phy_8960.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/msm/hdmi/qfprom.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4.xml.h+4−4

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4_crtc.c+104−244

This diff is large: its 562 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.c+11−6

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4_kms.h+0−17

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4_lvds_connector.c+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp4/mdp4_plane.c+80−41

This diff is large: its 191 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5.xml.h+5−5

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.c+207−0

This diff is large: its 208 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_cfg.h+91−0

This diff is large: its 92 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_crtc.c+218−248

This diff is large: its 704 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.c+322−0

This diff is large: its 323 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_ctl.h+122−0

This diff is large: its 123 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_encoder.c+24−0

This diff is large: its 76 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_irq.c+90−3

This diff is large: its 113 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.c+105−168

This diff is large: its 390 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_kms.h+45−86

This diff is large: its 201 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_plane.c+205−123

This diff is large: its 490 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.c+203−38

This diff is large: its 305 lines aren’t shown here.

drivers/gpu/drm/msm/mdp/mdp5/mdp5_smp.h+14−9

This diff is large: its 42 lines aren’t shown here.

drivers/gpu/drm/msm/msm_atomic.c+163−0

This diff is large: its 164 lines aren’t shown here.

drivers/gpu/drm/msm/msm_drv.c+25−0

This diff is large: its 53 lines aren’t shown here.

drivers/gpu/drm/msm/msm_drv.h+23−12

This diff is large: its 100 lines aren’t shown here.

drivers/gpu/drm/msm/msm_fb.c+44−1

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/msm/msm_fbdev.c+0−3

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/msm/msm_gem.c+16−24

This diff is large: its 81 lines aren’t shown here.

drivers/gpu/drm/msm/msm_gem.h+13−0

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/msm/msm_gem_prime.c+13−0

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/nouveau/Makefile+18−0

This diff is large: its 85 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/core/handle.c+0−113

This diff is large: its 117 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/device/base.c+12−2

This diff is large: its 69 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/device/gm100.c+43−0

This diff is large: its 50 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/device/nve0.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/dport.c+6−3

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/gm107.c+8−8

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/gm204.c+114−0

This diff is large: its 115 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nv50.c+48−46

This diff is large: its 287 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nv50.h+34−29

This diff is large: its 123 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nv84.c+20−20

This diff is large: its 109 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nv94.c+15−15

This diff is large: its 75 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nva0.c+8−8

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nva3.c+8−8

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c+56−43

This diff is large: its 273 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nve0.c+15−15

This diff is large: its 75 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c+8−8

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/outp.c+4−1

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c+144−0

This diff is large: its 145 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c+42−6

This diff is large: its 98 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/core/device.h+8−1

This diff is large: its 37 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/core/handle.h+0−5

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/core/object.h+0−17

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/engine/disp.h+1−0

This diff is large: its 7 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h+31−0

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h+9−5

This diff is large: its 28 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h+13−0

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h+12−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h+18−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h+37−0

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h+22−1

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/devinit.h+1−0

This diff is large: its 7 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/i2c.h+3−0

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/pwr.h+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/include/subdev/volt.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/os.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c+129−0

This diff is large: its 130 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/base.c+15−354

This diff is large: its 393 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c+15−12

This diff is large: its 41 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/disp.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/dp.c+9−1

This diff is large: its 48 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c+36−9

This diff is large: its 71 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/image.c+78−0

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/init.c+49−7

This diff is large: its 99 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/npde.c+59−0

This diff is large: its 60 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c+69−0

This diff is large: its 70 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c+135−0

This diff is large: its 136 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/priv.h+25−0

This diff is large: its 26 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c+12−1

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c+2−1

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c+270−0

This diff is large: its 271 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c+111−0

This diff is large: its 112 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c+71−0

This diff is large: its 72 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c+108−0

This diff is large: its 109 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c+112−0

This diff is large: its 113 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c+69−0

This diff is large: its 70 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/bios/timing.c+38−4

This diff is large: its 49 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c+16−1

This diff is large: its 101 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/base.c+1−3

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c+2−1

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c+173−0

This diff is large: its 174 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c+10−0

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h+2−0

This diff is large: its 7 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c+1−0

This diff is large: its 6 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/base.c+15−22

This diff is large: its 53 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c+117−0

This diff is large: its 118 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/priv.h+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h+16−0

This diff is large: its 30 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c+697−116

This diff is large: its 1062 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/base.c+66−31

This diff is large: its 129 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c+221−0

This diff is large: its 222 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h+4−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c+2−11

This diff is large: its 27 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c+1−5

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c+86−0

This diff is large: its 87 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h+4−0

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc+111−0

This diff is large: its 141 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h+404−334

This diff is large: its 872 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h+500−363

This diff is large: its 1015 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h+481−347

This diff is large: its 969 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h+412−342

This diff is large: its 890 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h+5−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c+35−2

This diff is large: its 58 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/volt/base.c+38−29

This diff is large: its 88 lines aren’t shown here.

drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c+199−0

This diff is large: its 200 lines aren’t shown here.

drivers/gpu/drm/nouveau/dispnv04/crtc.c+3−2

This diff is large: its 26 lines aren’t shown here.

drivers/gpu/drm/nouveau/dispnv04/overlay.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_abi16.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_bios.c+15−11

This diff is large: its 42 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_bo.c+169−27

This diff is large: its 308 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_bo.h+4−1

This diff is large: its 26 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_chan.c+3−8

This diff is large: its 38 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_display.c+22−8

This diff is large: its 87 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_drm.c+127−121

This diff is large: its 288 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_fbcon.c+18−18

This diff is large: its 54 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_gem.c+15−0

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_platform.c+2−0

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_platform.h+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nouveau_prime.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nv17_fence.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nv50_display.c+64−70

This diff is large: its 293 lines aren’t shown here.

drivers/gpu/drm/nouveau/nv50_fence.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/nouveau/nv84_fence.c+4−4

This diff is large: its 23 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvif/class.h+3−0

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvif/client.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/nouveau/nvif/driver.h+1−0

This diff is large: its 7 lines aren’t shown here.

drivers/gpu/drm/omapdrm/omap_crtc.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/omapdrm/omap_gem.c+1−2

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/omapdrm/omap_plane.c+2−13

This diff is large: its 34 lines aren’t shown here.

drivers/gpu/drm/panel/Kconfig+13−0

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/panel/Makefile+1−0

This diff is large: its 5 lines aren’t shown here.

drivers/gpu/drm/panel/panel-ld9040.c+4−9

This diff is large: its 39 lines aren’t shown here.

drivers/gpu/drm/panel/panel-s6e8aa0.c+6−24

This diff is large: its 71 lines aren’t shown here.

drivers/gpu/drm/panel/panel-sharp-lq101r1sx01.c+464−0

This diff is large: its 465 lines aren’t shown here.

drivers/gpu/drm/panel/panel-simple.c+117−16

This diff is large: its 219 lines aren’t shown here.

drivers/gpu/drm/qxl/qxl_display.c+29−7

This diff is large: its 86 lines aren’t shown here.

drivers/gpu/drm/qxl/qxl_release.c+2−1

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/r128/r128_state.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/radeon/Makefile+3−1

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/radeon/atombios_crtc.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/radeon/ci_dpm.c+670−82

This diff is large: its 1093 lines aren’t shown here.

drivers/gpu/drm/radeon/ci_dpm.h+8−0

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/radeon/ci_smc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/radeon/cik.c+92−122

This diff is large: its 545 lines aren’t shown here.

drivers/gpu/drm/radeon/cik_reg.h+136−0

This diff is large: its 141 lines aren’t shown here.

drivers/gpu/drm/radeon/cik_sdma.c+17−25

This diff is large: its 108 lines aren’t shown here.

drivers/gpu/drm/radeon/cikd.h+90−3

This diff is large: its 152 lines aren’t shown here.

drivers/gpu/drm/radeon/evergreen_cs.c+7−7

This diff is large: its 56 lines aren’t shown here.

drivers/gpu/drm/radeon/evergreen_dma.c+7−11

This diff is large: its 52 lines aren’t shown here.

drivers/gpu/drm/radeon/ni.c+8−12

This diff is large: its 55 lines aren’t shown here.

drivers/gpu/drm/radeon/ni_dma.c+7−10

This diff is large: its 46 lines aren’t shown here.

drivers/gpu/drm/radeon/ppsmc.h+17−1

This diff is large: its 56 lines aren’t shown here.

drivers/gpu/drm/radeon/pptable.h+8−0

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/radeon/r100.c+5−5

This diff is large: its 45 lines aren’t shown here.

drivers/gpu/drm/radeon/r200.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/radeon/r300.c+3−3

This diff is large: its 27 lines aren’t shown here.

drivers/gpu/drm/radeon/r600.c+7−11

This diff is large: its 52 lines aren’t shown here.

drivers/gpu/drm/radeon/r600_cs.c+13−13

This diff is large: its 98 lines aren’t shown here.

drivers/gpu/drm/radeon/r600_dma.c+7−11

This diff is large: its 52 lines aren’t shown here.

drivers/gpu/drm/radeon/r600_dpm.c+9−0

This diff is large: its 23 lines aren’t shown here.

drivers/gpu/drm/radeon/r600_dpm.h+3−0

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon.h+98−64

This diff is large: its 336 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_asic.h+12−6

This diff is large: its 60 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_atombios.c+15−6

This diff is large: its 70 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_cs.c+49−72

This diff is large: its 321 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_cursor.c+167−101

This diff is large: its 290 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_device.c+32−0

This diff is large: its 46 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_display.c+2−1

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_drv.c+5−0

This diff is large: its 25 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_fb.c+31−1

This diff is large: its 42 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_fence.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_gem.c+87−5

This diff is large: its 151 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_ib.c+7−9

This diff is large: its 50 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_kfd.c+563−0

This diff is large: its 564 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_kfd.h+47−0

This diff is large: its 48 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_kms.c+7−2

This diff is large: its 37 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_legacy_crtc.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_mode.h+15−5

This diff is large: its 50 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_object.c+69−14

This diff is large: its 187 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_object.h+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_semaphore.c+4−150

This diff is large: its 180 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_sync.c+220−0

This diff is large: its 221 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_trace.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_ttm.c+25−2

This diff is large: its 35 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_uvd.c+7−7

This diff is large: its 50 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_vce.c+4−4

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/radeon/radeon_vm.c+149−87

This diff is large: its 517 lines aren’t shown here.

drivers/gpu/drm/radeon/rv770_dma.c+7−11

This diff is large: its 52 lines aren’t shown here.

drivers/gpu/drm/radeon/si.c+10−14

This diff is large: its 68 lines aren’t shown here.

drivers/gpu/drm/radeon/si_dma.c+15−22

This diff is large: its 89 lines aren’t shown here.

drivers/gpu/drm/radeon/si_dpm.c+365−16

This diff is large: its 434 lines aren’t shown here.

drivers/gpu/drm/radeon/si_dpm.h+5−0

This diff is large: its 19 lines aren’t shown here.

drivers/gpu/drm/radeon/si_smc.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/radeon/sid.h+39−1

This diff is large: its 61 lines aren’t shown here.

drivers/gpu/drm/radeon/sislands_smc.h+25−0

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/radeon/smu7_discrete.h+29−1

This diff is large: its 44 lines aren’t shown here.

drivers/gpu/drm/rcar-du/Kconfig+9−2

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/rcar-du/Makefile+2−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_crtc.c+2−1

This diff is large: its 17 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_crtc.h+9−1

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_drv.c+1−3

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_drv.h+0−2

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_encoder.c+32−13

This diff is large: its 96 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_encoder.h+17−6

This diff is large: its 47 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_hdmicon.c+121−0

This diff is large: its 122 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_hdmicon.h+31−0

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_hdmienc.c+151−0

This diff is large: its 152 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_hdmienc.h+35−0

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_kms.c+10−47

This diff is large: its 105 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_lvdscon.c+15−16

This diff is large: its 67 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_lvdscon.h+0−2

This diff is large: its 12 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_lvdsenc.h+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/rcar-du/rcar_du_vgacon.c+3−2

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/rockchip/Kconfig+17−0

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/rockchip/Makefile+8−0

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_drv.c+551−0

This diff is large: its 552 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_drv.h+68−0

This diff is large: its 69 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_fb.c+201−0

This diff is large: its 202 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_fb.h+28−0

This diff is large: its 29 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_fbdev.c+210−0

This diff is large: its 211 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_fbdev.h+21−0

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_gem.c+294−0

This diff is large: its 295 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_gem.h+54−0

This diff is large: its 55 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_vop.c+1455−0

This diff is large: its 1456 lines aren’t shown here.

drivers/gpu/drm/rockchip/rockchip_drm_vop.h+201−0

This diff is large: its 202 lines aren’t shown here.

drivers/gpu/drm/shmobile/shmob_drm_crtc.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/sti/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/sti/Makefile+3−1

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/sti/sti_compositor.c+12−8

This diff is large: its 73 lines aren’t shown here.

drivers/gpu/drm/sti/sti_compositor.h+0−2

This diff is large: its 16 lines aren’t shown here.

drivers/gpu/drm/sti/sti_cursor.c+242−0

This diff is large: its 243 lines aren’t shown here.

drivers/gpu/drm/sti/sti_cursor.h+12−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/sti/sti_drm_crtc.c+14−10

This diff is large: its 112 lines aren’t shown here.

drivers/gpu/drm/sti/sti_drm_drv.c+5−1

This diff is large: its 14 lines aren’t shown here.

drivers/gpu/drm/sti/sti_drm_plane.c+3−1

This diff is large: its 15 lines aren’t shown here.

drivers/gpu/drm/sti/sti_gdp.c+43−19

This diff is large: its 176 lines aren’t shown here.

drivers/gpu/drm/sti/sti_hdmi.c+46−38

This diff is large: its 163 lines aren’t shown here.

drivers/gpu/drm/sti/sti_hdmi.h+4−2

This diff is large: its 31 lines aren’t shown here.

drivers/gpu/drm/sti/sti_hqvdp.c+1073−0

This diff is large: its 1074 lines aren’t shown here.

drivers/gpu/drm/sti/sti_hqvdp.h+12−0

This diff is large: its 13 lines aren’t shown here.

drivers/gpu/drm/sti/sti_hqvdp_lut.h+373−0

This diff is large: its 374 lines aren’t shown here.

drivers/gpu/drm/sti/sti_layer.c+17−1

This diff is large: its 66 lines aren’t shown here.

drivers/gpu/drm/sti/sti_layer.h+10−2

This diff is large: its 57 lines aren’t shown here.

drivers/gpu/drm/sti/sti_mixer.c+17−0

This diff is large: its 53 lines aren’t shown here.

drivers/gpu/drm/sti/sti_mixer.h+3−0

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/sti/sti_tvout.c+59−45

This diff is large: its 287 lines aren’t shown here.

drivers/gpu/drm/sti/sti_vtg.c+28−3

This diff is large: its 64 lines aren’t shown here.

drivers/gpu/drm/tegra/Kconfig+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/tegra/dc.c+416−180

This diff is large: its 798 lines aren’t shown here.

drivers/gpu/drm/tegra/drm.c+42−4

This diff is large: its 96 lines aren’t shown here.

drivers/gpu/drm/tegra/drm.h+12−6

This diff is large: its 57 lines aren’t shown here.

drivers/gpu/drm/tegra/dsi.c+688−123

This diff is large: its 1122 lines aren’t shown here.

drivers/gpu/drm/tegra/dsi.h+13−1

This diff is large: its 40 lines aren’t shown here.

drivers/gpu/drm/tegra/fb.c+42−10

This diff is large: its 134 lines aren’t shown here.

drivers/gpu/drm/tegra/gem.c+287−79

This diff is large: its 513 lines aren’t shown here.

drivers/gpu/drm/tegra/gem.h+10−4

This diff is large: its 36 lines aren’t shown here.

drivers/gpu/drm/tegra/output.c+28−7

This diff is large: its 77 lines aren’t shown here.

drivers/gpu/drm/tilcdc/tilcdc_crtc.c+2−5

This diff is large: its 22 lines aren’t shown here.

drivers/gpu/drm/tilcdc/tilcdc_drv.c+1−2

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_bo_manager.c+5−3

This diff is large: its 28 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_execbuf_util.c+9−1

This diff is large: its 24 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_page_alloc.c+15−11

This diff is large: its 79 lines aren’t shown here.

drivers/gpu/drm/ttm/ttm_page_alloc_dma.c+15−10

This diff is large: its 77 lines aren’t shown here.

drivers/gpu/drm/udl/Makefile+1−1

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/udl/udl_dmabuf.c+276−0

This diff is large: its 277 lines aren’t shown here.

drivers/gpu/drm/udl/udl_drv.c+2−0

This diff is large: its 10 lines aren’t shown here.

drivers/gpu/drm/udl/udl_drv.h+8−0

This diff is large: its 32 lines aren’t shown here.

drivers/gpu/drm/udl/udl_gem.c+23−74

This diff is large: its 143 lines aren’t shown here.

drivers/gpu/drm/udl/udl_modeset.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_drv.c+7−4

This diff is large: its 25 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c+4−2

This diff is large: its 20 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_fence.c+8−31

This diff is large: its 78 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_kms.c+2−2

This diff is large: its 18 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_resource.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/gpu/drm/vmwgfx/vmwgfx_shader.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/host1x/cdma.c+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/host1x/cdma.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/host1x/hw/cdma_hw.c+5−5

This diff is large: its 29 lines aren’t shown here.

drivers/gpu/host1x/hw/channel_hw.c+8−4

This diff is large: its 27 lines aren’t shown here.

drivers/gpu/host1x/hw/debug_hw.c+2−2

This diff is large: its 11 lines aren’t shown here.

drivers/gpu/host1x/job.h+1−1

This diff is large: its 9 lines aren’t shown here.

drivers/gpu/host1x/mipi.c+107−41

This diff is large: its 267 lines aren’t shown here.

drivers/iommu/amd_iommu_v2.c+9−52

This diff is large: its 107 lines aren’t shown here.

drivers/soc/tegra/fuse/fuse-tegra.c+1−0

This diff is large: its 8 lines aren’t shown here.

drivers/staging/Kconfig+0−2

This diff is large: its 9 lines aren’t shown here.

drivers/staging/Makefile+0−1

This diff is large: its 8 lines aren’t shown here.

drivers/staging/imx-drm/TODO+0−17

This diff is large: its 18 lines aren’t shown here.

include/drm/drmP.h+21−6

This diff is large: its 73 lines aren’t shown here.

include/drm/drm_atomic.h+69−0

This diff is large: its 70 lines aren’t shown here.

include/drm/drm_atomic_helper.h+126−0

This diff is large: its 127 lines aren’t shown here.

include/drm/drm_crtc.h+289−38

This diff is large: its 675 lines aren’t shown here.

include/drm/drm_crtc_helper.h+13−0

This diff is large: its 34 lines aren’t shown here.

include/drm/drm_displayid.h+76−0

This diff is large: its 77 lines aren’t shown here.

include/drm/drm_dp_helper.h+4−22

This diff is large: its 54 lines aren’t shown here.

include/drm/drm_dp_mst_helper.h+5−3

This diff is large: its 36 lines aren’t shown here.

include/drm/drm_edid.h+109−0

This diff is large: its 134 lines aren’t shown here.

include/drm/drm_fb_helper.h+6−0

This diff is large: its 23 lines aren’t shown here.

include/drm/drm_flip_work.h+24−9

This diff is large: its 69 lines aren’t shown here.

include/drm/drm_gem.h+7−0

This diff is large: its 14 lines aren’t shown here.

include/drm/drm_gem_cma_helper.h+22−8

This diff is large: its 53 lines aren’t shown here.

include/drm/drm_mipi_dsi.h+88−6

This diff is large: its 139 lines aren’t shown here.

include/drm/drm_modeset_lock.h+4−1

This diff is large: its 23 lines aren’t shown here.

include/drm/drm_plane_helper.h+44−0

This diff is large: its 63 lines aren’t shown here.

include/drm/i915_pciids.h+17−0

This diff is large: its 22 lines aren’t shown here.

include/drm/ttm/ttm_execbuf_util.h+8−1

This diff is large: its 30 lines aren’t shown here.

include/linux/hdmi.h+18−3

This diff is large: its 28 lines aren’t shown here.

include/linux/mmu_notifier.h+83−5

This diff is large: its 137 lines aren’t shown here.

include/linux/platform_data/rcar-du.h+0−74

This diff is large: its 75 lines aren’t shown here.

include/trace/events/host1x.h+15−12

This diff is large: its 80 lines aren’t shown here.

include/uapi/drm/drm_mode.h+2−0

This diff is large: its 9 lines aren’t shown here.

include/uapi/drm/i915_drm.h+7−0

This diff is large: its 21 lines aren’t shown here.

include/uapi/linux/kfd_ioctl.h+154−0

This diff is large: its 155 lines aren’t shown here.

kernel/events/uprobes.c+1−1

This diff is large: its 9 lines aren’t shown here.

kernel/time/time.c+1−0

This diff is large: its 8 lines aren’t shown here.

mm/fremap.c+1−1

This diff is large: its 9 lines aren’t shown here.

mm/huge_memory.c+5−4

This diff is large: its 44 lines aren’t shown here.

mm/hugetlb.c+6−1

This diff is large: its 29 lines aren’t shown here.

mm/ksm.c+2−2

This diff is large: its 18 lines aren’t shown here.

mm/memory.c+2−1

This diff is large: its 17 lines aren’t shown here.

mm/migrate.c+2−1

This diff is large: its 17 lines aren’t shown here.

mm/mmu_notifier.c+25−0

This diff is large: its 39 lines aren’t shown here.

mm/rmap.c+1−1

This diff is large: its 9 lines aren’t shown here.