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
1197S: 80050-430 - Curitiba - Paraná1197S: 80050-430 - Curitiba - Paraná
1198S: Brazil1198S: Brazil
1199 1199
1200N: Oded Gabbay
1201E: oded.gabbay@gmail.com
1202D: AMD KFD maintainer
1203S: 12 Shraga Raphaeli
1204S: Petah-Tikva, 4906418
1205S: Israel
1206
1200N: Kumar Gala1207N: Kumar Gala
1201E: galak@kernel.crashing.org1208E: galak@kernel.crashing.org
1202D: Embedded PowerPC 6xx/7xx/74xx/82xx/83xx/85xx support1209D: 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
492 <sect2>492 <sect2>
493 <title>The Translation Table Manager (TTM)</title>493 <title>The Translation Table Manager (TTM)</title>
494 <para>494 <para>
495 TTM design background and information belongs here.495 TTM design background and information belongs here.
496 </para>496 </para>
497 <sect3>497 <sect3>
498 <title>TTM initialization</title>498 <title>TTM initialization</title>
499 <warning><para>This section is outdated.</para></warning>499 <warning><para>This section is outdated.</para></warning>
500 <para>500 <para>
501 Drivers wishing to support TTM must fill out a drm_bo_driver501 Drivers wishing to support TTM must fill out a drm_bo_driver
@@ -503,42 +503,42 @@ char *date;</synopsis> · 1 unmodified line
503 pointers for initializing the TTM, allocating and freeing memory,503 pointers for initializing the TTM, allocating and freeing memory,
504 waiting for command completion and fence synchronization, and memory504 waiting for command completion and fence synchronization, and memory
505 migration. See the radeon_ttm.c file for an example of usage.505 migration. See the radeon_ttm.c file for an example of usage.
506 </para>506 </para>
507 <para>507 <para>
508 The ttm_global_reference structure is made up of several fields:508 The ttm_global_reference structure is made up of several fields:
509 </para>509 </para>
510 <programlisting>510 <programlisting>
511 struct ttm_global_reference {511 struct ttm_global_reference {
512 enum ttm_global_types global_type;512 enum ttm_global_types global_type;
513 size_t size;513 size_t size;
514 void *object;514 void *object;
515 int (*init) (struct ttm_global_reference *);515 int (*init) (struct ttm_global_reference *);
516 void (*release) (struct ttm_global_reference *);516 void (*release) (struct ttm_global_reference *);
517 };517 };
518 </programlisting>518 </programlisting>
519 <para>519 <para>
520 There should be one global reference structure for your memory520 There should be one global reference structure for your memory
521 manager as a whole, and there will be others for each object521 manager as a whole, and there will be others for each object
522 created by the memory manager at runtime. Your global TTM should522 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 global523 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 and524 object should be sizeof(struct ttm_mem_global), and the init and
525 release hooks should point at your driver-specific init and525 release hooks should point at your driver-specific init and
526 release routines, which probably eventually call526 release routines, which probably eventually call
527 ttm_mem_global_init and ttm_mem_global_release, respectively.527 ttm_mem_global_init and ttm_mem_global_release, respectively.
528 </para>528 </para>
529 <para>529 <para>
530 Once your global TTM accounting structure is set up and initialized530 Once your global TTM accounting structure is set up and initialized
531 by calling ttm_global_item_ref() on it,531 by calling ttm_global_item_ref() on it,
532 you need to create a buffer object TTM to532 you need to create a buffer object TTM to
533 provide a pool for buffer object allocation by clients and the533 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,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,535 and its size should be sizeof(struct ttm_bo_global). Again,
536 driver-specific init and release functions may be provided,536 driver-specific init and release functions may be provided,
537 likely eventually calling ttm_bo_global_init() and537 likely eventually calling ttm_bo_global_init() and
538 ttm_bo_global_release(), respectively. Also, like the previous538 ttm_bo_global_release(), respectively. Also, like the previous
539 object, ttm_global_item_ref() is used to create an initial reference539 object, ttm_global_item_ref() is used to create an initial reference
540 count for the TTM, which will call your initialization function.540 count for the TTM, which will call your initialization function.
541 </para>541 </para>
542 </sect3>542 </sect3>
543 </sect2>543 </sect2>
544 <sect2 id="drm-gem">544 <sect2 id="drm-gem">
@@ -566,19 +566,19 @@ char *date;</synopsis> · 21 unmodified lines
566 using driver-specific ioctls.566 using driver-specific ioctls.
567 </para>567 </para>
568 <para>568 <para>
569 On a fundamental level, GEM involves several operations:569 On a fundamental level, GEM involves several operations:
570 <itemizedlist>570 <itemizedlist>
571 <listitem>Memory allocation and freeing</listitem>571 <listitem>Memory allocation and freeing</listitem>
572 <listitem>Command execution</listitem>572 <listitem>Command execution</listitem>
573 <listitem>Aperture management at command execution time</listitem>573 <listitem>Aperture management at command execution time</listitem>
574 </itemizedlist>574 </itemizedlist>
575 Buffer object allocation is relatively straightforward and largely575 Buffer object allocation is relatively straightforward and largely
576 provided by Linux's shmem layer, which provides memory to back each576 provided by Linux's shmem layer, which provides memory to back each
577 object.577 object.
578 </para>578 </para>
579 <para>579 <para>
580 Device-specific operations, such as command execution, pinning, buffer580 Device-specific operations, such as command execution, pinning, buffer
581 read &amp; write, mapping, and domain ownership transfers are left to581 read &amp; write, mapping, and domain ownership transfers are left to
582 driver-specific ioctls.582 driver-specific ioctls.
583 </para>583 </para>
584 <sect3>584 <sect3>
@@ -738,16 +738,16 @@ char *date;</synopsis> · 153 unmodified lines
738 respectively. The conversion is handled by the DRM core without any738 respectively. The conversion is handled by the DRM core without any
739 driver-specific support.739 driver-specific support.
740 </para>740 </para>
741 <para>741 <para>
742 GEM also supports buffer sharing with dma-buf file descriptors through742 GEM also supports buffer sharing with dma-buf file descriptors through
743 PRIME. GEM-based drivers must use the provided helpers functions to743 PRIME. GEM-based drivers must use the provided helpers functions to
744 implement the exporting and importing correctly. See <xref linkend="drm-prime-support" />.744 implement the exporting and importing correctly. See <xref linkend="drm-prime-support" />.
745 Since sharing file descriptors is inherently more secure than the745 Since sharing file descriptors is inherently more secure than the
746 easily guessable and global GEM names it is the preferred buffer746 easily guessable and global GEM names it is the preferred buffer
747 sharing mechanism. Sharing buffers through GEM names is only supported747 sharing mechanism. Sharing buffers through GEM names is only supported
748 for legacy userspace. Furthermore PRIME also allows cross-device748 for legacy userspace. Furthermore PRIME also allows cross-device
749 buffer sharing since it is based on dma-bufs.749 buffer sharing since it is based on dma-bufs.
750 </para>750 </para>
751 </sect3>751 </sect3>
752 <sect3 id="drm-gem-objects-mapping">752 <sect3 id="drm-gem-objects-mapping">
753 <title>GEM Objects Mapping</title>753 <title>GEM Objects Mapping</title>
@@ -852,7 +852,7 @@ char *date;</synopsis> · 98 unmodified lines
852 <sect3>852 <sect3>
853 <title>Command Execution</title>853 <title>Command Execution</title>
854 <para>854 <para>
855 Perhaps the most important GEM function for GPU devices is providing a855 Perhaps the most important GEM function for GPU devices is providing a
856 command execution interface to clients. Client programs construct856 command execution interface to clients. Client programs construct
857 command buffers containing references to previously allocated memory857 command buffers containing references to previously allocated memory
858 objects, and then submit them to GEM. At that point, GEM takes care to858 objects, and then submit them to GEM. At that point, GEM takes care to
@@ -874,95 +874,101 @@ char *date;</synopsis> · 15 unmodified lines
874 <title>GEM Function Reference</title>874 <title>GEM Function Reference</title>
875!Edrivers/gpu/drm/drm_gem.c875!Edrivers/gpu/drm/drm_gem.c
876 </sect3>876 </sect3>
877 </sect2>877 </sect2>
878 <sect2>878 <sect2>
879 <title>VMA Offset Manager</title>879 <title>VMA Offset Manager</title>
880!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager880!Pdrivers/gpu/drm/drm_vma_manager.c vma offset manager
881!Edrivers/gpu/drm/drm_vma_manager.c881!Edrivers/gpu/drm/drm_vma_manager.c
882!Iinclude/drm/drm_vma_manager.h882!Iinclude/drm/drm_vma_manager.h
883 </sect2>883 </sect2>
884 <sect2 id="drm-prime-support">884 <sect2 id="drm-prime-support">
885 <title>PRIME Buffer Sharing</title>885 <title>PRIME Buffer Sharing</title>
886 <para>886 <para>
887 PRIME is the cross device buffer sharing framework in drm, originally887 PRIME is the cross device buffer sharing framework in drm, originally
888 created for the OPTIMUS range of multi-gpu platforms. To userspace888 created for the OPTIMUS range of multi-gpu platforms. To userspace
889 PRIME buffers are dma-buf based file descriptors.889 PRIME buffers are dma-buf based file descriptors.
890 </para>890 </para>
891 <sect3>891 <sect3>
892 <title>Overview and Driver Interface</title>892 <title>Overview and Driver Interface</title>
893 <para>893 <para>
894 Similar to GEM global names, PRIME file descriptors are894 Similar to GEM global names, PRIME file descriptors are
895 also used to share buffer objects across processes. They offer895 also used to share buffer objects across processes. They offer
896 additional security: as file descriptors must be explicitly sent over896 additional security: as file descriptors must be explicitly sent over
897 UNIX domain sockets to be shared between applications, they can't be897 UNIX domain sockets to be shared between applications, they can't be
898 guessed like the globally unique GEM names.898 guessed like the globally unique GEM names.
899 </para>899 </para>
900 <para>900 <para>
901 Drivers that support the PRIME901 Drivers that support the PRIME
902 API must set the DRIVER_PRIME bit in the struct902 API must set the DRIVER_PRIME bit in the struct
903 <structname>drm_driver</structname>903 <structname>drm_driver</structname>
904 <structfield>driver_features</structfield> field, and implement the904 <structfield>driver_features</structfield> field, and implement the
905 <methodname>prime_handle_to_fd</methodname> and905 <methodname>prime_handle_to_fd</methodname> and
906 <methodname>prime_fd_to_handle</methodname> operations.906 <methodname>prime_fd_to_handle</methodname> operations.
907 </para>907 </para>
908 <para>908 <para>
909 <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,909 <synopsis>int (*prime_handle_to_fd)(struct drm_device *dev,
910 struct drm_file *file_priv, uint32_t handle,910 struct drm_file *file_priv, uint32_t handle,
911 uint32_t flags, int *prime_fd);911 uint32_t flags, int *prime_fd);
912int (*prime_fd_to_handle)(struct drm_device *dev,912int (*prime_fd_to_handle)(struct drm_device *dev,
913 struct drm_file *file_priv, int prime_fd,913 struct drm_file *file_priv, int prime_fd,
914 uint32_t *handle);</synopsis>914 uint32_t *handle);</synopsis>
915 Those two operations convert a handle to a PRIME file descriptor and915 Those two operations convert a handle to a PRIME file descriptor and
916 vice versa. Drivers must use the kernel dma-buf buffer sharing framework916 vice versa. Drivers must use the kernel dma-buf buffer sharing framework
917 to manage the PRIME file descriptors. Similar to the mode setting917 to manage the PRIME file descriptors. Similar to the mode setting
918 API PRIME is agnostic to the underlying buffer object manager, as918 API PRIME is agnostic to the underlying buffer object manager, as
919 long as handles are 32bit unsigned integers.919 long as handles are 32bit unsigned integers.
920 </para>920 </para>
921 <para>921 <para>
922 While non-GEM drivers must implement the operations themselves, GEM922 While non-GEM drivers must implement the operations themselves, GEM
923 drivers must use the <function>drm_gem_prime_handle_to_fd</function>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.924 and <function>drm_gem_prime_fd_to_handle</function> helper functions.
925 Those helpers rely on the driver925 Those helpers rely on the driver
926 <methodname>gem_prime_export</methodname> and926 <methodname>gem_prime_export</methodname> and
927 <methodname>gem_prime_import</methodname> operations to create a dma-buf927 <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 GEM928 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).929 object from a dma-buf instance (dma-buf importer role).
930 </para>930 </para>
931 <para>931 <para>
932 <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,932 <synopsis>struct dma_buf * (*gem_prime_export)(struct drm_device *dev,
933 struct drm_gem_object *obj,933 struct drm_gem_object *obj,
934 int flags);934 int flags);
935struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,935struct drm_gem_object * (*gem_prime_import)(struct drm_device *dev,
936 struct dma_buf *dma_buf);</synopsis>936 struct dma_buf *dma_buf);</synopsis>
937 These two operations are mandatory for GEM drivers that support937 These two operations are mandatory for GEM drivers that support
938 PRIME.938 PRIME.
939 </para>939 </para>
940 </sect3>
941 <sect3>
942 <title>PRIME Helper Functions</title>
943!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
944 </sect3>940 </sect3>
945 </sect2>941 <sect3>
946 <sect2>942 <title>PRIME Helper Functions</title>
947 <title>PRIME Function References</title>943!Pdrivers/gpu/drm/drm_prime.c PRIME Helpers
944 </sect3>
945 </sect2>
946 <sect2>
947 <title>PRIME Function References</title>
948!Edrivers/gpu/drm/drm_prime.c948!Edrivers/gpu/drm/drm_prime.c
949 </sect2>949 </sect2>
950 <sect2>950 <sect2>
951 <title>DRM MM Range Allocator</title>951 <title>DRM MM Range Allocator</title>
952 <sect3>952 <sect3>
953 <title>Overview</title>953 <title>Overview</title>
954!Pdrivers/gpu/drm/drm_mm.c Overview954!Pdrivers/gpu/drm/drm_mm.c Overview
955 </sect3>955 </sect3>
956 <sect3>956 <sect3>
957 <title>LRU Scan/Eviction Support</title>957 <title>LRU Scan/Eviction Support</title>
958!Pdrivers/gpu/drm/drm_mm.c lru scan roaster958!Pdrivers/gpu/drm/drm_mm.c lru scan roaster
959 </sect3>959 </sect3>
960 </sect2>960 </sect2>
961 <sect2>961 <sect2>
962 <title>DRM MM Range Allocator Function References</title>962 <title>DRM MM Range Allocator Function References</title>
963!Edrivers/gpu/drm/drm_mm.c963!Edrivers/gpu/drm/drm_mm.c
964!Iinclude/drm/drm_mm.h964!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>
966 </sect1>972 </sect1>
967 973
968 <!-- Internals: mode setting -->974 <!-- Internals: mode setting -->
@@ -994,6 +1000,10 @@ int max_width, max_height;</synopsis> · 25 unmodified lines
994 <title>Display Modes Function Reference</title>1000 <title>Display Modes Function Reference</title>
995!Iinclude/drm/drm_modes.h1001!Iinclude/drm/drm_modes.h
996!Edrivers/gpu/drm/drm_modes.c1002!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
997 </sect2>1007 </sect2>
998 <sect2>1008 <sect2>
999 <title>Frame Buffer Creation</title>1009 <title>Frame Buffer Creation</title>
@@ -1825,6 +1835,10 @@ void intel_crt_init(struct drm_device *dev) · 825 unmodified lines
1825 <sect2>1835 <sect2>
1826 <title>KMS API Functions</title>1836 <title>KMS API Functions</title>
1827!Edrivers/gpu/drm/drm_crtc.c1837!Edrivers/gpu/drm/drm_crtc.c
1838 </sect2>
1839 <sect2>
1840 <title>KMS Data Structures</title>
1841!Iinclude/drm/drm_crtc.h
1828 </sect2>1842 </sect2>
1829 <sect2>1843 <sect2>
1830 <title>KMS Locking</title>1844 <title>KMS Locking</title>
@@ -1933,10 +1947,16 @@ void intel_crt_init(struct drm_device *dev) · 102 unmodified lines
1933 and then retrieves a list of modes by calling the connector1947 and then retrieves a list of modes by calling the connector
1934 <methodname>get_modes</methodname> helper operation.1948 <methodname>get_modes</methodname> helper operation.
1935 </para>1949 </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>
1936 <para>1956 <para>
1937 The function filters out modes larger than1957 The function then filters out modes larger than
1938 <parameter>max_width</parameter> and <parameter>max_height</parameter>1958 <parameter>max_width</parameter> and <parameter>max_height</parameter>
1939 if specified. It then calls the optional connector1959 if specified. It finally calls the optional connector
1940 <methodname>mode_valid</methodname> helper operation for each mode in1960 <methodname>mode_valid</methodname> helper operation for each mode in
1941 the probed list to check whether the mode is valid for the connector.1961 the probed list to check whether the mode is valid for the connector.
1942 </para>1962 </para>
@@ -2076,11 +2096,19 @@ void intel_crt_init(struct drm_device *dev) · 133 unmodified lines
2076 <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis>2096 <synopsis>int (*get_modes)(struct drm_connector *connector);</synopsis>
2077 <para>2097 <para>
2078 Fill the connector's <structfield>probed_modes</structfield> list2098 Fill the connector's <structfield>probed_modes</structfield> list
2079 by parsing EDID data with <function>drm_add_edid_modes</function> or2099 by parsing EDID data with <function>drm_add_edid_modes</function>,
2080 calling <function>drm_mode_probed_add</function> directly for every2100 adding standard VESA DMT modes with <function>drm_add_modes_noedid</function>,
2101 or calling <function>drm_mode_probed_add</function> directly for every
2081 supported mode and return the number of modes it has detected. This2102 supported mode and return the number of modes it has detected. This
2082 operation is mandatory.2103 operation is mandatory.
2083 </para>2104 </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>
2084 <para>2112 <para>
2085 When adding modes manually the driver creates each mode with a call to2113 When adding modes manually the driver creates each mode with a call to
2086 <function>drm_mode_create</function> and must fill the following fields.2114 <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
2278 <function>drm_helper_probe_single_connector_modes</function>.2306 <function>drm_helper_probe_single_connector_modes</function>.
2279 </para>2307 </para>
2280 <para>2308 <para>
2281 When parsing EDID data, <function>drm_add_edid_modes</function> fill the2309 When parsing EDID data, <function>drm_add_edid_modes</function> fills the
2282 connector <structfield>display_info</structfield>2310 connector <structfield>display_info</structfield>
2283 <structfield>width_mm</structfield> and2311 <structfield>width_mm</structfield> and
2284 <structfield>height_mm</structfield> fields. When creating modes2312 <structfield>height_mm</structfield> fields. When creating modes
@@ -2315,9 +2343,27 @@ void intel_crt_init(struct drm_device *dev) · 30 unmodified lines
2315 </listitem>2343 </listitem>
2316 </itemizedlist>2344 </itemizedlist>
2317 </sect2>2345 </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>
2318 <sect2>2363 <sect2>
2319 <title>Modeset Helper Functions Reference</title>2364 <title>Modeset Helper Functions Reference</title>
2320!Edrivers/gpu/drm/drm_crtc_helper.c2365!Edrivers/gpu/drm/drm_crtc_helper.c
2366!Pdrivers/gpu/drm/drm_crtc_helper.c overview
2321 </sect2>2367 </sect2>
2322 <sect2>2368 <sect2>
2323 <title>Output Probing Helper Functions Reference</title>2369 <title>Output Probing Helper Functions Reference</title>
@@ -2341,6 +2387,12 @@ void intel_crt_init(struct drm_device *dev) · 17 unmodified lines
2341!Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper2387!Pdrivers/gpu/drm/drm_dp_mst_topology.c dp mst helper
2342!Iinclude/drm/drm_dp_mst_helper.h2388!Iinclude/drm/drm_dp_mst_helper.h
2343!Edrivers/gpu/drm/drm_dp_mst_topology.c2389!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
2344 </sect2>2396 </sect2>
2345 <sect2>2397 <sect2>
2346 <title>EDID Helper Functions Reference</title>2398 <title>EDID Helper Functions Reference</title>
@@ -2371,7 +2423,12 @@ void intel_crt_init(struct drm_device *dev) · 24 unmodified lines
2371 </sect2>2423 </sect2>
2372 <sect2>2424 <sect2>
2373 <title id="drm-kms-planehelpers">Plane Helper Reference</title>2425 <title id="drm-kms-planehelpers">Plane Helper Reference</title>
2374!Edrivers/gpu/drm/drm_plane_helper.c Plane Helpers2426!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
2375 </sect2>2432 </sect2>
2376 </sect1>2433 </sect1>
2377 2434
@@ -2507,8 +2564,8 @@ void intel_crt_init(struct drm_device *dev) · 129 unmodified lines
2507 <td valign="top" >Description/Restrictions</td>2564 <td valign="top" >Description/Restrictions</td>
2508 </tr>2565 </tr>
2509 <tr>2566 <tr>
2510 <td rowspan="21" valign="top" >DRM</td>2567 <td rowspan="25" valign="top" >DRM</td>
2511 <td rowspan="2" valign="top" >Generic</td>2568 <td rowspan="4" valign="top" >Generic</td>
2512 <td valign="top" >“EDID”</td>2569 <td valign="top" >“EDID”</td>
2513 <td valign="top" >BLOB | IMMUTABLE</td>2570 <td valign="top" >BLOB | IMMUTABLE</td>
2514 <td valign="top" >0</td>2571 <td valign="top" >0</td>
@@ -2523,6 +2580,20 @@ void intel_crt_init(struct drm_device *dev) · 8 unmodified lines
2523 <td valign="top" >Contains DPMS operation mode value.</td>2580 <td valign="top" >Contains DPMS operation mode value.</td>
2524 </tr>2581 </tr>
2525 <tr>2582 <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>
2526 <td rowspan="1" valign="top" >Plane</td>2597 <td rowspan="1" valign="top" >Plane</td>
2527 <td valign="top" >“type”</td>2598 <td valign="top" >“type”</td>
2528 <td valign="top" >ENUM | IMMUTABLE</td>2599 <td valign="top" >ENUM | IMMUTABLE</td>
@@ -2638,6 +2709,21 @@ void intel_crt_init(struct drm_device *dev) · 109 unmodified lines
2638 <td valign="top" >TBD</td>2709 <td valign="top" >TBD</td>
2639 </tr>2710 </tr>
2640 <tr>2711 <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>
2641 <td rowspan="3" valign="top" >Optional</td>2727 <td rowspan="3" valign="top" >Optional</td>
2642 <td valign="top" >“scaling mode”</td>2728 <td valign="top" >“scaling mode”</td>
2643 <td valign="top" >ENUM</td>2729 <td valign="top" >ENUM</td>
@@ -3787,6 +3873,26 @@ int num_ioctls;</synopsis> · 1143 unmodified lines
3787 blocks. This excludes a set of SoC platforms with an SGX rendering unit,3873 blocks. This excludes a set of SoC platforms with an SGX rendering unit,
3788 those have basic support through the gma500 drm driver.3874 those have basic support through the gma500 drm driver.
3789 </para>3875 </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>
3790 <sect1>3896 <sect1>
3791 <title>Display Hardware Handling</title>3897 <title>Display Hardware Handling</title>
3792 <para>3898 <para>
@@ -3803,6 +3909,18 @@ int num_ioctls;</synopsis> · 10 unmodified lines
3803 configuration change.3909 configuration change.
3804 </para>3910 </para>
3805 </sect2>3911 </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>
3806 <sect2>3924 <sect2>
3807 <title>Plane Configuration</title>3925 <title>Plane Configuration</title>
3808 <para>3926 <para>
@@ -3822,6 +3940,16 @@ int num_ioctls;</synopsis> · 13 unmodified lines
3822 probing, so those sections fully apply.3940 probing, so those sections fully apply.
3823 </para>3941 </para>
3824 </sect2>3942 </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>
3825 <sect2>3953 <sect2>
3826 <title>DPIO</title>3954 <title>DPIO</title>
3827!Pdrivers/gpu/drm/i915/i915_reg.h DPIO3955!Pdrivers/gpu/drm/i915/i915_reg.h DPIO
@@ -3931,6 +4059,28 @@ int num_ioctls;</synopsis> · 103 unmodified lines
3931!Idrivers/gpu/drm/i915/intel_lrc.c4059!Idrivers/gpu/drm/i915/intel_lrc.c
3932 </sect2>4060 </sect2>
3933 </sect1>4061 </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
3934 </chapter>4083 </chapter>
4084!Cdrivers/gpu/drm/i915/i915_irq.c
3935</part>4085</part>
3936</book>4086</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
191 - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection191 - nvidia,hpd-gpio: specifies a GPIO used for hotplug detection
192 - nvidia,edid: supplies a binary EDID blob192 - nvidia,edid: supplies a binary EDID blob
193 - nvidia,panel: phandle of a display panel193 - 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
194 196
195- sor: serial output resource197- sor: serial output resource
196 198
Documentation/devicetree/bindings/gpu/st,stih4xx.txt+27−2
@@ -68,7 +68,7 @@ STMicroelectronics stih4xx platforms · 67 unmodified lines
68 number of clocks may depend of the SoC type.68 number of clocks may depend of the SoC type.
69 - clock-names: names of the clocks listed in clocks property in the same69 - clock-names: names of the clocks listed in clocks property in the same
70 order.70 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
72 72
73sti-hda:73sti-hda:
74 Required properties:74 Required properties:
@@ -83,6 +83,22 @@ sti-hda: · 8 unmodified lines
83 - clock-names: names of the clocks listed in clocks property in the same83 - clock-names: names of the clocks listed in clocks property in the same
84 order.84 order.
85 85
86sti-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
86Example:102Example:
87 103
88/ {104/ {
@@ -173,7 +189,6 @@ Example: · 84 unmodified lines
173 interrupt-names = "irq";189 interrupt-names = "irq";
174 clock-names = "pix", "tmds", "phy", "audio";190 clock-names = "pix", "tmds", "phy", "audio";
175 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>;191 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>;
177 };192 };
178 193
179 sti-hda@fe85a000 {194 sti-hda@fe85a000 {
@@ -184,6 +199,16 @@ Example: · 4 unmodified lines
184 clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>;199 clocks = <&clockgen_c_vcc CLK_S_PIX_HD>, <&clockgen_c_vcc CLK_S_HDDAC>;
185 };200 };
186 };201 };
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 };
187 };212 };
188 ...213 ...
189};214};
Documentation/devicetree/bindings/panel/auo,b116xw03.txt+7−0
@@ -0,0 +1,7 @@
1AU Optronics Corporation 11.6" HD (1366x768) color TFT-LCD panel
2
3Required properties:
4- compatible: should be "auo,b116xw03"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/hannstar,hsd070pww1.txt+7−0
@@ -0,0 +1,7 @@
1HannStar Display Corp. HSD070PWW1 7.0" WXGA TFT LCD panel
2
3Required properties:
4- compatible: should be "hannstar,hsd070pww1"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/hit,tx23d38vm0caa.txt+7−0
@@ -0,0 +1,7 @@
1Hitachi Ltd. Corporation 9" WVGA (800x480) TFT LCD panel
2
3Required properties:
4- compatible: should be "hit,tx23d38vm0caa"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/innolux,g121i1-l01.txt+7−0
@@ -0,0 +1,7 @@
1Innolux Corporation 12.1" WXGA (1280x800) TFT LCD panel
2
3Required properties:
4- compatible: should be "innolux,g121i1-l01"
5
6This binding is compatible with the simple-panel binding, which is specified
7in simple-panel.txt in this directory.
Documentation/devicetree/bindings/panel/sharp,lq101r1sx01.txt+49−0
@@ -0,0 +1,49 @@
1Sharp Microelectronics 10.1" WQXGA TFT LCD panel
2
3This 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
7Each of the DSI channels controls a separate DSI peripheral. The peripheral
8driven by the first link (DSI-LINK1), left or even, is considered the primary
9peripheral and controls the device. The 'link2' property contains a phandle
10to the peripheral driven by the second link (DSI-LINK2, right or odd).
11
12Note that in video mode the DSI-LINK1 interface always provides the left/even
13pixels and DSI-LINK2 always provides the right/odd pixels. In command mode it
14is possible to program either link to drive the left/even or right/odd pixels
15but for the sake of consistency this binding assumes that the same assignment
16is chosen as for video mode.
17
18Required properties:
19- compatible: should be "sharp,lq101r1sx01"
20- reg: DSI virtual channel of the peripheral
21
22Required 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
27Optional properties (for DSI-LINK1 only):
28- backlight: phandle of the backlight device attached to the panel
29
30Example:
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
66google Google, Inc.66google Google, Inc.
67gumstix Gumstix, Inc.67gumstix Gumstix, Inc.
68gw Gateworks Corporation68gw Gateworks Corporation
69hannstar HannStar Display Corporation
69haoyu Haoyu Microelectronic Co. Ltd.70haoyu Haoyu Microelectronic Co. Ltd.
70hisilicon Hisilicon Limited.71hisilicon Hisilicon Limited.
72hit Hitachi Ltd.
71honeywell Honeywell73honeywell Honeywell
72hp Hewlett Packard74hp Hewlett Packard
73i2se I2SE GmbH75i2se I2SE GmbH
Documentation/devicetree/bindings/video/adi,adv7511.txt+88−0
@@ -0,0 +1,88 @@
1Analog Device ADV7511(W)/13 HDMI Encoders
2-----------------------------------------
3
4The ADV7511, ADV7511W and ADV7513 are HDMI audio and video transmitters
5compatible with HDMI 1.4 and DVI 1.0. They support color space conversion,
6S/PDIF, CEC and HDCP.
7
8Required properties:
9
10- compatible: Should be one of "adi,adv7511", "adi,adv7511w" or "adi,adv7513"
11- reg: I2C slave address
12
13The ADV7511 supports a large number of input data formats that differ by their
14color depth, color format, clock mode, bit justification and random
15arrangement of components on the data bus. The combination of the following
16properties describe the input and map directly to the video input tables of the
17ADV7511 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
27The 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
35Optional 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
46Required nodes:
47
48The ADV7511 has two video ports. Their connections are modelled using the OF
49graph 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
55Example
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
4 - compatible: value should be one of the following4 - compatible: value should be one of the following
5 "samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */5 "samsung,exynos3250-mipi-dsi" /* for Exynos3250/3472 SoCs */
6 "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */6 "samsung,exynos4210-mipi-dsi" /* for Exynos4 SoCs */
7 "samsung,exynos4415-mipi-dsi" /* for Exynos4415 SoC */
7 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */8 "samsung,exynos5410-mipi-dsi" /* for Exynos5410/5420/5440 SoCs */
8 - reg: physical base address and length of the registers set for the device9 - reg: physical base address and length of the registers set for the device
9 - interrupts: should contain DSI interrupt10 - interrupts: should contain DSI interrupt
Documentation/devicetree/bindings/video/rockchip-drm.txt+19−0
@@ -0,0 +1,19 @@
1Rockchip DRM master device
2================================
3
4The Rockchip DRM master device is a virtual device needed to list all
5vop devices or other display interface nodes that comprise the
6graphics subsystem.
7
8Required 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
14example:
15
16display-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 @@
1device-tree bindings for rockchip soc display controller (vop)
2
3VOP (Visual Output Processor) is the Display Controller for the Rockchip
4series of SoCs which transfers the image data from a video memory
5buffer to an external LCD interface.
6
7Required 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
35Example:
36SoC 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
11 "samsung,s5pv210-fimd"; /* for S5PV210 SoC */11 "samsung,s5pv210-fimd"; /* for S5PV210 SoC */
12 "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */12 "samsung,exynos3250-fimd"; /* for Exynos3250/3472 SoCs */
13 "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */13 "samsung,exynos4210-fimd"; /* for Exynos4 SoCs */
14 "samsung,exynos4415-fimd"; /* for Exynos4415 SoC */
14 "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */15 "samsung,exynos5250-fimd"; /* for Exynos5 SoCs */
15 16
16- reg: physical base address and length of the FIMD registers set.17- reg: physical base address and length of the FIMD registers set.
MAINTAINERS+17−0
@@ -618,6 +618,16 @@ S: Maintained · 617 unmodified lines
618F: drivers/iommu/amd_iommu*.[ch]618F: drivers/iommu/amd_iommu*.[ch]
619F: include/linux/amd-iommu.h619F: include/linux/amd-iommu.h
620 620
621AMD KFD
622M: Oded Gabbay <oded.gabbay@amd.com>
623L: dri-devel@lists.freedesktop.org
624T: git git://people.freedesktop.org/~gabbayo/linux.git
625S: Supported
626F: drivers/gpu/drm/amd/amdkfd/
627F: drivers/gpu/drm/radeon/radeon_kfd.c
628F: drivers/gpu/drm/radeon/radeon_kfd.h
629F: include/uapi/linux/kfd_ioctl.h
630
621AMD MICROCODE UPDATE SUPPORT631AMD MICROCODE UPDATE SUPPORT
622M: Andreas Herrmann <herrmann.der.user@googlemail.com>632M: Andreas Herrmann <herrmann.der.user@googlemail.com>
623L: amd64-microcode@amd64.org633L: amd64-microcode@amd64.org
@@ -3297,6 +3307,13 @@ F: drivers/gpu/drm/exynos/ · 2673 unmodified lines
3297F: include/drm/exynos*3307F: include/drm/exynos*
3298F: include/uapi/drm/exynos*3308F: include/uapi/drm/exynos*
3299 3309
3310DRM DRIVERS FOR FREESCALE IMX
3311M: Philipp Zabel <p.zabel@pengutronix.de>
3312L: dri-devel@lists.freedesktop.org
3313S: Maintained
3314F: drivers/gpu/drm/imx/
3315F: Documentation/devicetree/bindings/drm/imx/
3316
3300DRM DRIVERS FOR NVIDIA TEGRA3317DRM DRIVERS FOR NVIDIA TEGRA
3301M: Thierry Reding <thierry.reding@gmail.com>3318M: Thierry Reding <thierry.reding@gmail.com>
3302M: Terje Bergström <tbergstrom@nvidia.com>3319M: Terje Bergström <tbergstrom@nvidia.com>
arch/arm/mach-shmobile/board-lager.c+0−58
@@ -32,7 +32,6 @@ · 31 unmodified lines
32#include <linux/pinctrl/machine.h>32#include <linux/pinctrl/machine.h>
33#include <linux/platform_data/camera-rcar.h>33#include <linux/platform_data/camera-rcar.h>
34#include <linux/platform_data/gpio-rcar.h>34#include <linux/platform_data/gpio-rcar.h>
35#include <linux/platform_data/rcar-du.h>
36#include <linux/platform_data/usb-rcar-gen2-phy.h>35#include <linux/platform_data/usb-rcar-gen2-phy.h>
37#include <linux/platform_device.h>36#include <linux/platform_device.h>
38#include <linux/phy.h>37#include <linux/phy.h>
@@ -83,61 +82,6 @@ · 44 unmodified lines
83 *82 *
84 */83 */
85 84
86/* DU */
87static 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
112static 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
117static 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
126static 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
141/* LEDS */85/* LEDS */
142static struct gpio_led lager_leds[] = {86static struct gpio_led lager_leds[] = {
143 {87 {
@@ -800,8 +744,6 @@ static void __init lager_add_standard_devices(void) · 656 unmodified lines
800 744
801 platform_device_register_full(&ether_info);745 platform_device_register_full(&ether_info);
802 746
803 lager_add_du_device();
804
805 platform_device_register_resndata(NULL, "qspi", 0,747 platform_device_register_resndata(NULL, "qspi", 0,
806 qspi_resources,748 qspi_resources,
807 ARRAY_SIZE(qspi_resources),749 ARRAY_SIZE(qspi_resources),
arch/arm/mach-shmobile/board-marzen.c+0−58
@@ -27,7 +27,6 @@ · 26 unmodified lines
27#include <linux/pinctrl/machine.h>27#include <linux/pinctrl/machine.h>
28#include <linux/platform_data/camera-rcar.h>28#include <linux/platform_data/camera-rcar.h>
29#include <linux/platform_data/gpio-rcar.h>29#include <linux/platform_data/gpio-rcar.h>
30#include <linux/platform_data/rcar-du.h>
31#include <linux/platform_data/usb-rcar-phy.h>30#include <linux/platform_data/usb-rcar-phy.h>
32#include <linux/regulator/fixed.h>31#include <linux/regulator/fixed.h>
33#include <linux/regulator/machine.h>32#include <linux/regulator/machine.h>
@@ -171,62 +170,6 @@ static struct platform_device hspi_device = { · 137 unmodified lines
171 .num_resources = ARRAY_SIZE(hspi_resources),170 .num_resources = ARRAY_SIZE(hspi_resources),
172};171};
173 172
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 */
180static 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
205static const struct rcar_du_platform_data du_pdata __initconst = {
206 .encoders = du_encoders,
207 .num_encoders = ARRAY_SIZE(du_encoders),
208};
209
210static const struct resource du_resources[] __initconst = {
211 DEFINE_RES_MEM(0xfff80000, 0x40000),
212 DEFINE_RES_IRQ(gic_iid(0x3f)),
213};
214
215static 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
230/* LEDS */173/* LEDS */
231static struct gpio_led marzen_leds[] = {174static struct gpio_led marzen_leds[] = {
232 {175 {
@@ -385,7 +328,6 @@ static void __init marzen_init(void) · 152 unmodified lines
385 platform_device_register_full(&vin1_info);328 platform_device_register_full(&vin1_info);
386 platform_device_register_full(&vin3_info);329 platform_device_register_full(&vin3_info);
387 platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));330 platform_add_devices(marzen_devices, ARRAY_SIZE(marzen_devices));
388 marzen_add_du_device();
389}331}
390 332
391static const char *marzen_boards_compat_dt[] __initdata = {333static 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
455 u32 (*base)(int num, int slot, int func, size_t size);455 u32 (*base)(int num, int slot, int func, size_t size);
456};456};
457 457
458static 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
473typedef size_t (*stolen_size_fn)(int num, int slot, int func);
474
458static const struct intel_stolen_funcs i830_stolen_funcs __initconst = {475static const struct intel_stolen_funcs i830_stolen_funcs __initconst = {
459 .base = i830_stolen_base,476 .base = i830_stolen_base,
460 .size = i830_stolen_size,477 .size = i830_stolen_size,
@@ -490,6 +507,11 @@ static const struct intel_stolen_funcs gen8_stolen_funcs __initconst = { · 29 unmodified lines
490 .size = gen8_stolen_size,507 .size = gen8_stolen_size,
491};508};
492 509
510static const struct intel_stolen_funcs gen9_stolen_funcs __initconst = {
511 .base = intel_stolen_base,
512 .size = gen9_stolen_size,
513};
514
493static const struct intel_stolen_funcs chv_stolen_funcs __initconst = {515static const struct intel_stolen_funcs chv_stolen_funcs __initconst = {
494 .base = intel_stolen_base,516 .base = intel_stolen_base,
495 .size = chv_stolen_size,517 .size = chv_stolen_size,
@@ -523,6 +545,7 @@ static const struct pci_device_id intel_stolen_ids[] __initconst = { · 27 unmodified lines
523 INTEL_BDW_M_IDS(&gen8_stolen_funcs),545 INTEL_BDW_M_IDS(&gen8_stolen_funcs),
524 INTEL_BDW_D_IDS(&gen8_stolen_funcs),546 INTEL_BDW_D_IDS(&gen8_stolen_funcs),
525 INTEL_CHV_IDS(&chv_stolen_funcs),547 INTEL_CHV_IDS(&chv_stolen_funcs),
548 INTEL_SKL_IDS(&gen9_stolen_funcs),
526};549};
527 550
528static void __init intel_graphics_stolen(int num, int slot, int func)551static 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
153 __free_pages(page, 2);153 __free_pages(page, 2);
154 return NULL;154 return NULL;
155 }155 }
156 get_page(page);
157 atomic_inc(&agp_bridge->current_memory_agp);156 atomic_inc(&agp_bridge->current_memory_agp);
158 return page;157 return page;
159}158}
@@ -164,7 +163,6 @@ static void i8xx_destroy_pages(struct page *page) · 4 unmodified lines
164 return;163 return;
165 164
166 set_pages_wb(page, 4);165 set_pages_wb(page, 4);
167 put_page(page);
168 __free_pages(page, 2);166 __free_pages(page, 2);
169 atomic_dec(&agp_bridge->current_memory_agp);167 atomic_dec(&agp_bridge->current_memory_agp);
170}168}
@@ -300,7 +298,6 @@ static int intel_gtt_setup_scratch_page(void) · 129 unmodified lines
300 page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);298 page = alloc_page(GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
301 if (page == NULL)299 if (page == NULL)
302 return -ENOMEM;300 return -ENOMEM;
303 get_page(page);
304 set_pages_uc(page, 1);301 set_pages_uc(page, 1);
305 302
306 if (intel_private.needs_dmar) {303 if (intel_private.needs_dmar) {
@@ -560,7 +557,6 @@ static void intel_gtt_teardown_scratch_page(void) · 253 unmodified lines
560 set_pages_wb(intel_private.scratch_page, 1);557 set_pages_wb(intel_private.scratch_page, 1);
561 pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,558 pci_unmap_page(intel_private.pcidev, intel_private.scratch_page_dma,
562 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);559 PAGE_SIZE, PCI_DMA_BIDIRECTIONAL);
563 put_page(intel_private.scratch_page);
564 __free_page(intel_private.scratch_page);560 __free_page(intel_private.scratch_page);
565}561}
566 562
drivers/gpu/drm/Kconfig+6−0
@@ -167,6 +167,8 @@ config DRM_SAVAGE · 166 unmodified lines
167 167
168source "drivers/gpu/drm/exynos/Kconfig"168source "drivers/gpu/drm/exynos/Kconfig"
169 169
170source "drivers/gpu/drm/rockchip/Kconfig"
171
170source "drivers/gpu/drm/vmwgfx/Kconfig"172source "drivers/gpu/drm/vmwgfx/Kconfig"
171 173
172source "drivers/gpu/drm/gma500/Kconfig"174source "drivers/gpu/drm/gma500/Kconfig"
@@ -200,3 +202,7 @@ source "drivers/gpu/drm/tegra/Kconfig" · 27 unmodified lines
200source "drivers/gpu/drm/panel/Kconfig"202source "drivers/gpu/drm/panel/Kconfig"
201 203
202source "drivers/gpu/drm/sti/Kconfig"204source "drivers/gpu/drm/sti/Kconfig"
205
206source "drivers/gpu/drm/amd/amdkfd/Kconfig"
207
208source "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
14 drm_info.o drm_debugfs.o drm_encoder_slave.o \14 drm_info.o drm_debugfs.o drm_encoder_slave.o \
15 drm_trace_points.o drm_global.o drm_prime.o \15 drm_trace_points.o drm_global.o drm_prime.o \
16 drm_rect.o drm_vma_manager.o drm_flip_work.o \16 drm_rect.o drm_vma_manager.o drm_flip_work.o \
17 drm_modeset_lock.o17 drm_modeset_lock.o drm_atomic.o
18 18
19drm-$(CONFIG_COMPAT) += drm_ioc32.o19drm-$(CONFIG_COMPAT) += drm_ioc32.o
20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o20drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
@@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o · 2 unmodified lines
23drm-$(CONFIG_OF) += drm_of.o23drm-$(CONFIG_OF) += drm_of.o
24 24
25drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \25drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.o \
26 drm_plane_helper.o drm_dp_mst_topology.o26 drm_plane_helper.o drm_dp_mst_topology.o drm_atomic_helper.o
27drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o27drm_kms_helper-$(CONFIG_DRM_LOAD_EDID_FIRMWARE) += drm_edid_load.o
28drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o28drm_kms_helper-$(CONFIG_DRM_KMS_FB_HELPER) += drm_fb_helper.o
29drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o29drm_kms_helper-$(CONFIG_DRM_KMS_CMA_HELPER) += drm_fb_cma_helper.o
@@ -49,6 +49,7 @@ obj-$(CONFIG_DRM_VMWGFX)+= vmwgfx/ · 19 unmodified lines
49obj-$(CONFIG_DRM_VIA) +=via/49obj-$(CONFIG_DRM_VIA) +=via/
50obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/50obj-$(CONFIG_DRM_NOUVEAU) +=nouveau/
51obj-$(CONFIG_DRM_EXYNOS) +=exynos/51obj-$(CONFIG_DRM_EXYNOS) +=exynos/
52obj-$(CONFIG_DRM_ROCKCHIP) +=rockchip/
52obj-$(CONFIG_DRM_GMA500) += gma500/53obj-$(CONFIG_DRM_GMA500) += gma500/
53obj-$(CONFIG_DRM_UDL) += udl/54obj-$(CONFIG_DRM_UDL) += udl/
54obj-$(CONFIG_DRM_AST) += ast/55obj-$(CONFIG_DRM_AST) += ast/
@@ -62,6 +63,8 @@ obj-$(CONFIG_DRM_BOCHS) += bochs/ · 7 unmodified lines
62obj-$(CONFIG_DRM_MSM) += msm/63obj-$(CONFIG_DRM_MSM) += msm/
63obj-$(CONFIG_DRM_TEGRA) += tegra/64obj-$(CONFIG_DRM_TEGRA) += tegra/
64obj-$(CONFIG_DRM_STI) += sti/65obj-$(CONFIG_DRM_STI) += sti/
66obj-$(CONFIG_DRM_IMX) += imx/
65obj-y += i2c/67obj-y += i2c/
66obj-y += panel/68obj-y += panel/
67obj-y += bridge/69obj-y += bridge/
70obj-$(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
6The Direct Rendering Manager (drm) is a device-independent kernel-level
7device driver that provides support for the XFree86 Direct Rendering
8Infrastructure (DRI).
9
10The DRM supports the Direct Rendering Infrastructure (DRI) in four major
11ways:
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
28Documentation 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
33For 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
5config 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
5ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/amd/include/
6
7amdkfd-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
14obj-$(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
40static long kfd_ioctl(struct file *, unsigned int, unsigned long);
41static int kfd_open(struct inode *, struct file *);
42static int kfd_mmap(struct file *, struct vm_area_struct *);
43
44static const char kfd_dev_name[] = "kfd";
45
46static 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
54static int kfd_char_dev_major = -1;
55static struct class *kfd_class;
56struct device *kfd_device;
57
58int 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
81err_device_create:
82 class_destroy(kfd_class);
83err_class_create:
84 unregister_chrdev(kfd_char_dev_major, kfd_dev_name);
85err_register_chrdev:
86 return err;
87}
88
89void 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
96struct device *kfd_chardev(void)
97{
98 return kfd_device;
99}
100
101
102static 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
134static 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
149static 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
228static 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
295err_copy_args_out:
296 pqm_destroy_queue(&p->pqm, queue_id);
297err_create_queue:
298err_bind_process:
299 mutex_unlock(&p->mutex);
300 return err;
301}
302
303static 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
324static 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
374static 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
423out:
424 mutex_unlock(&p->mutex);
425
426 return err;
427}
428
429static 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
463static 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
523static 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
586static 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
47struct 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
92struct 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
125struct 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
151struct 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
180struct 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
211struct 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
240struct 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
264struct 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
277struct 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
32static 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
38struct 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. */
44static 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
69static 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
83struct 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
105static 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
156static 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
164bool 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
235dqm_start_error:
236 device_queue_manager_uninit(kfd->dqm);
237device_queue_manager_error:
238 amd_iommu_free_device(kfd->pdev);
239device_iommu_pasid_error:
240 kfd_interrupt_exit(kfd);
241kfd_interrupt_error:
242 kfd_topology_remove_device(kfd);
243kfd_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);
248out:
249 return kfd->init_complete;
250}
251
252void 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
264void 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
275int 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. */
297void 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
40static bool is_mem_initialized;
41
42static int init_memory(struct device_queue_manager *dqm);
43static int set_pasid_vmid_mapping(struct device_queue_manager *dqm,
44 unsigned int pasid, unsigned int vmid);
45
46static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
47 struct queue *q,
48 struct qcm_process_device *qpd);
49static int execute_queues_cpsch(struct device_queue_manager *dqm, bool lock);
50static int destroy_queues_cpsch(struct device_queue_manager *dqm, bool lock);
51
52
53static 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
59static 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
65static inline unsigned int get_pipes_num_cpsch(void)
66{
67 return PIPE_PER_ME_CP_SCHEDULING;
68}
69
70static inline unsigned int
71get_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
81static 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
90static uint32_t compute_sh_mem_bases_64bit(unsigned int top_address_nybble);
91static 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
124static 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
134static 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
158static 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
169static 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
211static 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
245static 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
251static 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
278static 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--;
314out:
315 mutex_unlock(&dqm->lock);
316 return retval;
317}
318
319static 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
346static 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
366static 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
392static 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;
417out:
418 mutex_unlock(&dqm->lock);
419 return retval;
420}
421
422static int
423set_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
434static 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
461static 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
475static 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
531static 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
548static 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
576static 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
592static int start_nocpsch(struct device_queue_manager *dqm)
593{
594 return 0;
595}
596
597static 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
606static 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
631static 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
650fail_init_pipelines:
651 mutex_destroy(&dqm->lock);
652 return retval;
653}
654
655static 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;
695fail_allocate_vidmem:
696fail_set_sched_resources:
697 pm_uninit(&dqm->packets);
698fail_packet_manager_init:
699 return retval;
700}
701
702static 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
722static 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
740static 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
757static 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
789out:
790 mutex_unlock(&dqm->lock);
791 return retval;
792}
793
794static 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
812static 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
838out:
839 if (lock)
840 mutex_unlock(&dqm->lock);
841 return retval;
842}
843
844static 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
876out:
877 if (lock)
878 mutex_unlock(&dqm->lock);
879 return retval;
880}
881
882static 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
913failed:
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
926static 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
994out:
995 mutex_unlock(&dqm->lock);
996 return false;
997}
998
999struct 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
1055void 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
40struct 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
89struct 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 */
35static DEFINE_MUTEX(doorbell_mutex);
36static 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. */
57static 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. */
65void 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
123int 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 */
170u32 __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
202void 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
215inline 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 */
227unsigned 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
241uint64_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
251phys_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
296int 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
49static void interrupt_wq(struct work_struct *);
50
51int 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
81void 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 */
108bool 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 */
136static 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
165static 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
37static 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;
164err_alloc_fence:
165err_init_mqd:
166 uninit_queue(kq->queue);
167err_init_queue:
168 kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->wptr_mem);
169err_wptr_allocate_vidmem:
170 kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->rptr_mem);
171err_rptr_allocate_vidmem:
172 kfd2kgd->free_mem(dev->kgd, (struct kgd_mem *) kq->pq);
173err_pq_allocate_vidmem:
174 pr_err("kfd: error init pq\n");
175 kfd_release_kernel_doorbell(dev, prop.doorbell_ptr);
176err_get_kernel_doorbell:
177 pr_err("kfd: error init doorbell");
178 return false;
179
180}
181
182static 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
202static 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
246static 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
268static 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
290static void rollback_packet(struct kernel_queue *kq)
291{
292 BUG_ON(!kq);
293 kq->pending_wptr = *kq->queue->properties.write_ptr;
294}
295
296struct 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
322void kernel_queue_uninit(struct kernel_queue *kq)
323{
324 BUG_ON(!kq);
325
326 kq->uninitialize(kq);
327 kfree(kq);
328}
329
330static __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
31struct 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
37const struct kfd2kgd_calls *kfd2kgd;
38static 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
48int sched_policy = KFD_SCHED_POLICY_HWS;
49module_param(sched_policy, int, 0444);
50MODULE_PARM_DESC(sched_policy,
51 "Kernel cmdline parameter that defines the amdkfd scheduling policy");
52
53int max_num_of_processes = KFD_MAX_NUM_OF_PROCESSES_DEFAULT;
54module_param(max_num_of_processes, int, 0444);
55MODULE_PARM_DESC(max_num_of_processes,
56 "Kernel cmdline parameter that defines the amdkfd maximum number of supported processes");
57
58int max_num_of_queues_per_process = KFD_MAX_NUM_OF_QUEUES_PER_PROCESS_DEFAULT;
59module_param(max_num_of_queues_per_process, int, 0444);
60MODULE_PARM_DESC(max_num_of_queues_per_process,
61 "Kernel cmdline parameter that defines the amdkfd maximum number of supported queues per process");
62
63bool 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}
83EXPORT_SYMBOL(kgd2kfd_init);
84
85void kgd2kfd_exit(void)
86{
87}
88
89static 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
134err_topology:
135 kfd_chardev_exit();
136err_ioctl:
137 kfd_pasid_exit();
138err_pasid:
139 return err;
140}
141
142static 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
151module_init(kfd_module_init);
152module_exit(kfd_module_exit);
153
154MODULE_AUTHOR(KFD_DRIVER_AUTHOR);
155MODULE_DESCRIPTION(KFD_DRIVER_DESC);
156MODULE_LICENSE("GPL and additional rights");
157MODULE_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
31inline void busy_wait(unsigned long ms)
32{
33 while (time_before(jiffies, ms))
34 cpu_relax();
35}
36
37static inline struct cik_mqd *get_mqd(void *mqd)
38{
39 return (struct cik_mqd *)mqd;
40}
41
42static 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
114static 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
121static 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
128static 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
173static 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
182static 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
198static 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
262static 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
304struct 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
63struct 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
32static 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
41static 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
53static 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
86static 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
119static 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
142static 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
182static 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
239static 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
320int 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
336void 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
344int 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
389int 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
425fail_create_runlist:
426 pm->priv_queue->rollback_packet(pm->priv_queue);
427fail_acquire_packet_buffer:
428 mutex_unlock(&pm->lock);
429fail_create_runlist_ib:
430 if (pm->allocated == true)
431 pm_release_ib(pm);
432 return retval;
433}
434
435int 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
471fail_acquire_packet_buffer:
472 mutex_unlock(&pm->lock);
473 return retval;
474}
475
476int 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
549err_acquire_packet_buffer:
550 mutex_unlock(&pm->lock);
551 return retval;
552}
553
554void 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
27static unsigned long *pasid_bitmap;
28static unsigned int pasid_limit;
29static DEFINE_MUTEX(pasid_mutex);
30
31int 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
44void kfd_pasid_exit(void)
45{
46 kfree(pasid_bitmap);
47}
48
49bool 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
70inline unsigned int kfd_get_pasid_limit(void)
71{
72 return pasid_limit;
73}
74
75unsigned 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
92void 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
29union 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
48enum 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
54struct 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
101struct 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
143struct 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
193enum 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
199enum 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
204enum 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
209enum 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
215struct 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
262enum 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
268enum 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
275enum 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
281struct 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
322enum 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
328enum 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
334enum 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
340struct 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
401enum {
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
28enum 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 */
56extern 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 */
65extern 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 */
73extern 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 */
96enum kfd_sched_policy {
97 KFD_SCHED_POLICY_HWS = 0,
98 KFD_SCHED_POLICY_HWS_NO_OVERSUBSCRIPTION,
99 KFD_SCHED_POLICY_NO_HWS
100};
101
102enum cache_policy {
103 cache_policy_coherent,
104 cache_policy_noncoherent
105};
106
107struct kfd_device_info {
108 unsigned int max_pasid_bits;
109 size_t ih_ring_entry_size;
110 uint16_t mqd_size_aligned;
111};
112
113struct 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 */
157void kgd2kfd_exit(void);
158struct kfd_dev *kgd2kfd_probe(struct kgd_dev *kgd, struct pci_dev *pdev);
159bool kgd2kfd_device_init(struct kfd_dev *kfd,
160 const struct kgd2kfd_shared_resources *gpu_resources);
161void kgd2kfd_device_exit(struct kfd_dev *kfd);
162
163extern const struct kfd2kgd_calls *kfd2kgd;
164
165struct kfd_mem_obj {
166 void *bo;
167 uint64_t gpu_addr;
168 uint32_t *cpu_ptr;
169};
170
171enum 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 */
178int kfd_chardev_init(void);
179void kfd_chardev_exit(void);
180struct 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 */
194enum 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
200enum 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 */
216enum 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
223enum 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 */
272struct 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
319struct 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 */
337enum 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
345struct 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
355struct 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
363struct 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. */
391struct 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 */
420struct 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
466void kfd_process_create_wq(void);
467void kfd_process_destroy_wq(void);
468struct kfd_process *kfd_create_process(const struct task_struct *);
469struct kfd_process *kfd_get_process(const struct task_struct *);
470
471struct kfd_process_device *kfd_bind_process_to_device(struct kfd_dev *dev,
472 struct kfd_process *p);
473void kfd_unbind_process_from_device(struct kfd_dev *dev, unsigned int pasid);
474struct 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 */
479struct kfd_process_device *kfd_get_first_process_device_data(struct kfd_process *p);
480struct kfd_process_device *kfd_get_next_process_device_data(struct kfd_process *p,
481 struct kfd_process_device *pdd);
482bool kfd_has_process_device_data(struct kfd_process *p);
483
484/* PASIDs */
485int kfd_pasid_init(void);
486void kfd_pasid_exit(void);
487bool kfd_set_pasid_limit(unsigned int new_limit);
488unsigned int kfd_get_pasid_limit(void);
489unsigned int kfd_pasid_alloc(void);
490void kfd_pasid_free(unsigned int pasid);
491
492/* Doorbells */
493void kfd_doorbell_init(struct kfd_dev *kfd);
494int kfd_doorbell_mmap(struct kfd_process *process, struct vm_area_struct *vma);
495u32 __iomem *kfd_get_kernel_doorbell(struct kfd_dev *kfd,
496 unsigned int *doorbell_off);
497void kfd_release_kernel_doorbell(struct kfd_dev *kfd, u32 __iomem *db_addr);
498u32 read_kernel_doorbell(u32 __iomem *db);
499void write_kernel_doorbell(u32 __iomem *db, u32 value);
500unsigned int kfd_queue_id_to_doorbell(struct kfd_dev *kfd,
501 struct kfd_process *process,
502 unsigned int queue_id);
503
504extern struct device *kfd_device;
505
506/* Topology */
507int kfd_topology_init(void);
508void kfd_topology_shutdown(void);
509int kfd_topology_add_device(struct kfd_dev *gpu);
510int kfd_topology_remove_device(struct kfd_dev *gpu);
511struct kfd_dev *kfd_device_by_id(uint32_t gpu_id);
512struct kfd_dev *kfd_device_by_pci_dev(const struct pci_dev *pdev);
513struct kfd_dev *kfd_topology_enum_kfd_devices(uint8_t idx);
514
515/* Interrupts */
516int kfd_interrupt_init(struct kfd_dev *dev);
517void kfd_interrupt_exit(struct kfd_dev *dev);
518void kgd2kfd_interrupt(struct kfd_dev *kfd, const void *ih_ring_entry);
519bool enqueue_ih_ring_entry(struct kfd_dev *kfd, const void *ih_ring_entry);
520
521/* Power Management */
522void kgd2kfd_suspend(struct kfd_dev *kfd);
523int kgd2kfd_resume(struct kfd_dev *kfd);
524
525/* amdkfd Apertures */
526int kfd_init_apertures(struct kfd_process *process);
527
528/* Queue Context Management */
529inline uint32_t lower_32(uint64_t x);
530inline uint32_t upper_32(uint64_t x);
531
532int init_queue(struct queue **q, struct queue_properties properties);
533void uninit_queue(struct queue *q);
534void print_queue_properties(struct queue_properties *q);
535void print_queue(struct queue *q);
536
537struct mqd_manager *mqd_manager_init(enum KFD_MQD_TYPE type,
538 struct kfd_dev *dev);
539struct device_queue_manager *device_queue_manager_init(struct kfd_dev *dev);
540void device_queue_manager_uninit(struct device_queue_manager *dqm);
541struct kernel_queue *kernel_queue_init(struct kfd_dev *dev,
542 enum kfd_queue_type type);
543void kernel_queue_uninit(struct kernel_queue *kq);
544
545/* Process Queue Manager */
546struct process_queue_node {
547 struct queue *q;
548 struct kernel_queue *kq;
549 struct list_head process_queue_list;
550};
551
552int pqm_init(struct process_queue_manager *pqm, struct kfd_process *p);
553void pqm_uninit(struct process_queue_manager *pqm);
554int 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);
561int pqm_destroy_queue(struct process_queue_manager *pqm, unsigned int qid);
562int 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
573struct 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
581int pm_init(struct packet_manager *pm, struct device_queue_manager *dqm);
582void pm_uninit(struct packet_manager *pm);
583int pm_send_set_resources(struct packet_manager *pm,
584 struct scheduling_resources *res);
585int pm_send_runlist(struct packet_manager *pm, struct list_head *dqm_queues);
586int pm_send_query_status(struct packet_manager *pm, uint64_t fence_address,
587 uint32_t fence_value);
588
589int 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
594void pm_release_ib(struct packet_manager *pm);
595
596uint64_t kfd_get_number_elems(struct kfd_dev *kfd);
597phys_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>
29struct 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 */
45static DEFINE_HASHTABLE(kfd_processes_table, KFD_PROCESS_TABLE_SIZE);
46static DEFINE_MUTEX(kfd_processes_mutex);
47
48DEFINE_STATIC_SRCU(kfd_processes_srcu);
49
50static struct workqueue_struct *kfd_process_wq;
51
52struct kfd_process_release_work {
53 struct work_struct kfd_work;
54 struct kfd_process *p;
55};
56
57static struct kfd_process *find_process(const struct task_struct *thread);
58static struct kfd_process *create_process(const struct task_struct *thread);
59
60void kfd_process_create_wq(void)
61{
62 if (!kfd_process_wq)
63 kfd_process_wq = create_workqueue("kfd_process_wq");
64}
65
66void 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
75struct 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
113struct 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
129static 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
141static 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
153static 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
186static 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
208static 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
242static const struct mmu_notifier_ops kfd_process_mmu_notifier_ops = {
243 .release = kfd_process_notifier_release,
244};
245
246static 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
290err_process_pqm_init:
291 hash_del_rcu(&process->kfd_processes);
292 synchronize_rcu();
293 mmu_notifier_unregister_no_release(&process->mmu_notifier, process->mm);
294err_mmu_notifier:
295 kfd_pasid_free(process->pasid);
296err_alloc_pasid:
297 kfree(process->queues);
298err_alloc_queues:
299 kfree(process);
300err_alloc_process:
301 return ERR_PTR(err);
302}
303
304struct 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 */
335struct 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
356void 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
392struct 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
399struct 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
407bool 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
30static 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
47static 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
73int 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
88void 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
113static 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
144err_init_queue:
145 return retval;
146}
147
148int 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
241err_create_queue:
242 kfree(pqn);
243err_allocate_pqn:
244 clear_bit(*qid, pqm->queue_slot_bitmap);
245 return retval;
246}
247
248int 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
305int 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
328static __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
27void 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
45void 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
66int 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
82void 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
35static struct list_head topology_device_list;
36static int topology_crat_parsed;
37static struct kfd_system_properties sys_props;
38
39static DECLARE_RWSEM(topology_lock);
40
41struct 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
59struct 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
77static 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
107static 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
122static 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 */
145static 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 */
173static 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 */
219static 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 */
268static 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
317static 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
364static 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
400static 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
413static 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
433static 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
497static 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
521static const struct sysfs_ops sysprops_ops = {
522 .show = sysprops_show,
523};
524
525static struct kobj_type sysprops_type = {
526 .sysfs_ops = &sysprops_ops,
527};
528
529static 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
556static const struct sysfs_ops iolink_ops = {
557 .show = iolink_show,
558};
559
560static struct kobj_type iolink_type = {
561 .sysfs_ops = &iolink_ops,
562};
563
564static 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
583static const struct sysfs_ops mem_ops = {
584 .show = mem_show,
585};
586
587static struct kobj_type mem_type = {
588 .sysfs_ops = &mem_ops,
589};
590
591static 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
622static const struct sysfs_ops cache_ops = {
623 .show = kfd_cache_show,
624};
625
626static struct kobj_type cache_type = {
627 .sysfs_ops = &cache_ops,
628};
629
630static 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
727static const struct sysfs_ops node_ops = {
728 .show = node_show,
729};
730
731static struct kobj_type node_type = {
732 .sysfs_ops = &node_ops,
733};
734
735static 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
742static 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
795static 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
913static 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
929static 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
937static 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
981static 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
1000int 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
1045err:
1046 pr_info("Finished initializing topology ret=%d\n", ret);
1047 return ret;
1048}
1049
1050void kfd_topology_shutdown(void)
1051{
1052 kfd_topology_release_sysfs();
1053 kfd_release_live_view();
1054}
1055
1056static 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
1071static 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
1094static 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
1111static 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
1119int 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
1172err:
1173 up_write(&topology_lock);
1174
1175 if (res == 0)
1176 kfd_notify_gpu_change(gpu_id, 1);
1177
1178 return res;
1179}
1180
1181int 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 */
1213struct 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
44struct 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
82struct 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
101struct 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
116struct 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
134struct 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
154struct 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
33struct pci_dev;
34
35#define KFD_INTERFACE_VERSION 1
36
37struct kfd_dev;
38struct kgd_dev;
39
40struct kgd_mem;
41
42enum kgd_memory_pool {
43 KGD_POOL_SYSTEM_CACHEABLE = 1,
44 KGD_POOL_SYSTEM_WRITECOMBINE = 2,
45 KGD_POOL_FRAMEBUFFER = 3,
46};
47
48struct 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 */
88struct 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 */
144struct 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
181bool 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
12#include <linux/platform_device.h>12#include <linux/platform_device.h>
13#include <drm/drmP.h>13#include <drm/drmP.h>
14#include <drm/drm_crtc_helper.h>14#include <drm/drm_crtc_helper.h>
15#include <drm/drm_plane_helper.h>
15#include "armada_crtc.h"16#include "armada_crtc.h"
16#include "armada_drm.h"17#include "armada_drm.h"
17#include "armada_fb.h"18#include "armada_fb.h"
drivers/gpu/drm/ast/ast_mode.c+1−0
@@ -31,6 +31,7 @@ · 30 unmodified lines
31#include <drm/drmP.h>31#include <drm/drmP.h>
32#include <drm/drm_crtc.h>32#include <drm/drm_crtc.h>
33#include <drm/drm_crtc_helper.h>33#include <drm/drm_crtc_helper.h>
34#include <drm/drm_plane_helper.h>
34#include "ast_drv.h"35#include "ast_drv.h"
35 36
36#include "ast_tables.h"37#include "ast_tables.h"
drivers/gpu/drm/bochs/bochs_fbdev.c+14−4
@@ -9,6 +9,17 @@ · 8 unmodified lines
9 9
10/* ---------------------------------------------------------------------- */10/* ---------------------------------------------------------------------- */
11 11
12static 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
12static struct fb_ops bochsfb_ops = {23static struct fb_ops bochsfb_ops = {
13 .owner = THIS_MODULE,24 .owner = THIS_MODULE,
14 .fb_check_var = drm_fb_helper_check_var,25 .fb_check_var = drm_fb_helper_check_var,
@@ -19,6 +30,7 @@ static struct fb_ops bochsfb_ops = { · 4 unmodified lines
19 .fb_pan_display = drm_fb_helper_pan_display,30 .fb_pan_display = drm_fb_helper_pan_display,
20 .fb_blank = drm_fb_helper_blank,31 .fb_blank = drm_fb_helper_blank,
21 .fb_setcmap = drm_fb_helper_setcmap,32 .fb_setcmap = drm_fb_helper_setcmap,
33 .fb_mmap = bochsfb_mmap,
22};34};
23 35
24static int bochsfb_create_object(struct bochs_device *bochs,36static int bochsfb_create_object(struct bochs_device *bochs,
@@ -123,11 +135,9 @@ static int bochsfb_create(struct drm_fb_helper *helper, · 98 unmodified lines
123 info->screen_base = bo->kmap.virtual;135 info->screen_base = bo->kmap.virtual;
124 info->screen_size = size;136 info->screen_size = size;
125 137
126#if 0138 drm_vma_offset_remove(&bo->bo.bdev->vma_manager, &bo->bo.vma_node);
127 /* FIXME: get this right for mmap(/dev/fb0) */139 info->fix.smem_start = 0;
128 info->fix.smem_start = bochs_bo_mmap_offset(bo);
129 info->fix.smem_len = size;140 info->fix.smem_len = size;
130#endif
131 141
132 ret = fb_alloc_cmap(&info->cmap, 256, 0);142 ret = fb_alloc_cmap(&info->cmap, 256, 0);
133 if (ret) {143 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
51{51{
52 struct bochs_device *bochs = dev->dev_private;52 struct bochs_device *bochs = dev->dev_private;
53 struct pci_dev *pdev = dev->pdev;53 struct pci_dev *pdev = dev->pdev;
54 unsigned long addr, size, mem, ioaddr, iosize;54 unsigned long addr, size, mem, ioaddr, iosize, qext_size;
55 u16 id;55 u16 id;
56 56
57 if (/* (ent->driver_data == BOCHS_QEMU_STDVGA) && */57 if (pdev->resource[2].flags & IORESOURCE_MEM) {
58 (pdev->resource[2].flags & IORESOURCE_MEM)) {
59 /* mmio bar with vga and bochs registers present */58 /* mmio bar with vga and bochs registers present */
60 if (pci_request_region(pdev, 2, "bochs-drm") != 0) {59 if (pci_request_region(pdev, 2, "bochs-drm") != 0) {
61 DRM_ERROR("Cannot request mmio region\n");60 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
116 size / 1024, addr,115 size / 1024, addr,
117 bochs->ioports ? "ioports" : "mmio",116 bochs->ioports ? "ioports" : "mmio",
118 ioaddr);117 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
135noext:
119 return 0;136 return 0;
120}137}
121 138
drivers/gpu/drm/bochs/bochs_kms.c+22−0
@@ -6,6 +6,7 @@ · 5 unmodified lines
6 */6 */
7 7
8#include "bochs.h"8#include "bochs.h"
9#include <drm/drm_plane_helper.h>
9 10
10static int defx = 1024;11static int defx = 1024;
11static int defy = 768;12static int defy = 768;
@@ -108,11 +109,32 @@ static void bochs_crtc_gamma_set(struct drm_crtc *crtc, u16 *red, u16 *green, · 96 unmodified lines
108{109{
109}110}
110 111
112static 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
111/* These provide the minimum set of functions required to handle a CRTC */132/* These provide the minimum set of functions required to handle a CRTC */
112static const struct drm_crtc_funcs bochs_crtc_funcs = {133static const struct drm_crtc_funcs bochs_crtc_funcs = {
113 .gamma_set = bochs_crtc_gamma_set,134 .gamma_set = bochs_crtc_gamma_set,
114 .set_config = drm_crtc_helper_set_config,135 .set_config = drm_crtc_helper_set_config,
115 .destroy = drm_crtc_cleanup,136 .destroy = drm_crtc_cleanup,
137 .page_flip = bochs_crtc_page_flip,
116};138};
117 139
118static const struct drm_crtc_helper_funcs bochs_helper_funcs = {140static 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
210 struct drm_mode_fb_cmd2 *mode_cmd,210 struct drm_mode_fb_cmd2 *mode_cmd,
211 struct drm_gem_object *obj);211 struct drm_gem_object *obj);
212 212
213bool cirrus_check_framebuffer(struct cirrus_device *cdev, int width, int height,
214 int bpp, int pitch);
215
213 /* cirrus_display.c */216 /* cirrus_display.c */
214int cirrus_modeset_init(struct cirrus_device *cdev);217int cirrus_modeset_init(struct cirrus_device *cdev);
215void cirrus_modeset_fini(struct cirrus_device *cdev);218void 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
139 struct drm_gem_object **gobj_p)139 struct drm_gem_object **gobj_p)
140{140{
141 struct drm_device *dev = afbdev->helper.dev;141 struct drm_device *dev = afbdev->helper.dev;
142 struct cirrus_device *cdev = dev->dev_private;
142 u32 bpp, depth;143 u32 bpp, depth;
143 u32 size;144 u32 size;
144 struct drm_gem_object *gobj;145 struct drm_gem_object *gobj;
@@ -146,8 +147,10 @@ static int cirrusfb_create_object(struct cirrus_fbdev *afbdev, · 1 unmodified line
146 int ret = 0;147 int ret = 0;
147 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);148 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
148 149
149 if (bpp > 24)150 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
151 bpp, mode_cmd->pitches[0]))
150 return -EINVAL;152 return -EINVAL;
153
151 size = mode_cmd->pitches[0] * mode_cmd->height;154 size = mode_cmd->pitches[0] * mode_cmd->height;
152 ret = cirrus_gem_create(dev, size, true, &gobj);155 ret = cirrus_gem_create(dev, size, true, &gobj);
153 if (ret)156 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
49 struct drm_file *filp,49 struct drm_file *filp,
50 struct drm_mode_fb_cmd2 *mode_cmd)50 struct drm_mode_fb_cmd2 *mode_cmd)
51{51{
52 struct cirrus_device *cdev = dev->dev_private;
52 struct drm_gem_object *obj;53 struct drm_gem_object *obj;
53 struct cirrus_framebuffer *cirrus_fb;54 struct cirrus_framebuffer *cirrus_fb;
54 int ret;55 int ret;
55 u32 bpp, depth;56 u32 bpp, depth;
56 57
57 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);58 drm_fb_get_bpp_depth(mode_cmd->pixel_format, &depth, &bpp);
58 /* cirrus can't handle > 24bpp framebuffers at all */59
59 if (bpp > 24)60 if (!cirrus_check_framebuffer(cdev, mode_cmd->width, mode_cmd->height,
61 bpp, mode_cmd->pitches[0]))
60 return ERR_PTR(-EINVAL);62 return ERR_PTR(-EINVAL);
61 63
62 obj = drm_gem_object_lookup(dev, filp, mode_cmd->handles[0]);64 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
96{98{
97 /* BAR 0 is VRAM */99 /* BAR 0 is VRAM */
98 cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);100 cdev->mc.vram_base = pci_resource_start(cdev->dev->pdev, 0);
99 /* We have 4MB of VRAM */101 cdev->mc.vram_size = pci_resource_len(cdev->dev->pdev, 0);
100 cdev->mc.vram_size = 4 * 1024 * 1024;
101 102
102 if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,103 if (!request_mem_region(cdev->mc.vram_base, cdev->mc.vram_size,
103 "cirrusdrmfb_vram")) {104 "cirrusdrmfb_vram")) {
@@ -179,17 +180,22 @@ int cirrus_driver_load(struct drm_device *dev, unsigned long flags) · 75 unmodified lines
179 }180 }
180 181
181 r = cirrus_mm_init(cdev);182 r = cirrus_mm_init(cdev);
182 if (r)183 if (r) {
183 dev_err(&dev->pdev->dev, "fatal err on mm init\n");184 dev_err(&dev->pdev->dev, "fatal err on mm init\n");
185 goto out;
186 }
184 187
185 r = cirrus_modeset_init(cdev);188 r = cirrus_modeset_init(cdev);
186 if (r)189 if (r) {
187 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);190 dev_err(&dev->pdev->dev, "Fatal error during modeset init: %d\n", r);
191 goto out;
192 }
188 193
189 dev->mode_config.funcs = (void *)&cirrus_mode_funcs;194 dev->mode_config.funcs = (void *)&cirrus_mode_funcs;
195
196 return 0;
190out:197out:
191 if (r)198 cirrus_driver_unload(dev);
192 cirrus_driver_unload(dev);
193 return r;199 return r;
194}200}
195 201
@@ -307,3 +313,21 @@ out_unlock: · 111 unmodified lines
307 return ret;313 return ret;
308 314
309}315}
316
317bool 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
16 */16 */
17#include <drm/drmP.h>17#include <drm/drmP.h>
18#include <drm/drm_crtc_helper.h>18#include <drm/drm_crtc_helper.h>
19#include <drm/drm_plane_helper.h>
19 20
20#include <video/cirrus.h>21#include <video/cirrus.h>
21 22
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
33static 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 */
50struct drm_atomic_state *
51drm_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;
93fail:
94 kfree_state(state);
95
96 return NULL;
97}
98EXPORT_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 */
114void 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}
154EXPORT_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 */
163void 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}
171EXPORT_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 */
188struct drm_crtc_state *
189drm_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}
217EXPORT_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 */
234struct drm_plane_state *
235drm_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}
272EXPORT_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 */
289struct drm_connector_state *
290drm_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}
343EXPORT_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 */
360int
361drm_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}
398EXPORT_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 */
410void
411drm_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}
426EXPORT_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 */
442int
443drm_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}
465EXPORT_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 */
484int
485drm_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}
515EXPORT_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 */
525int
526drm_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}
545EXPORT_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 */
555void drm_atomic_legacy_backoff(struct drm_atomic_state *state)
556{
557 int ret;
558
559retry:
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}
571EXPORT_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 */
584int 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}
595EXPORT_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 */
613int 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}
626EXPORT_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 */
644int 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}
657EXPORT_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 */
56static void
57drm_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
83static struct drm_crtc *
84get_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
102static int
103steal_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
151static int
152update_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
248static int
249mode_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
333static int
334drm_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 */
424int 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}
480EXPORT_SYMBOL(drm_atomic_helper_check);
481
482static void
483disable_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
553static void
554set_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
606static void
607crtc_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 */
666void 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}
673EXPORT_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 */
684void 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}
732EXPORT_SYMBOL(drm_atomic_helper_commit_post_planes);
733
734static 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
754static 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 */
792void
793drm_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}
842EXPORT_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 */
857int 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}
910EXPORT_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 */
962int 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
989fail:
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}
1009EXPORT_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 */
1024void 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}
1079EXPORT_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 */
1093void 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}
1115EXPORT_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 */
1142void 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}
1180EXPORT_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 */
1201int 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);
1218retry:
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;
1244fail:
1245 if (ret == -EDEADLK)
1246 goto backoff;
1247
1248 drm_atomic_state_free(state);
1249
1250 return ret;
1251backoff:
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}
1264EXPORT_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 */
1275int 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);
1297retry:
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;
1323fail:
1324 if (ret == -EDEADLK)
1325 goto backoff;
1326
1327 drm_atomic_state_free(state);
1328
1329 return ret;
1330backoff:
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}
1343EXPORT_SYMBOL(drm_atomic_helper_disable_plane);
1344
1345static 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 */
1435int 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);
1448retry:
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
1495commit:
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;
1506fail:
1507 if (ret == -EDEADLK)
1508 goto backoff;
1509
1510 drm_atomic_state_free(state);
1511
1512 return ret;
1513backoff:
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}
1526EXPORT_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 */
1539int
1540drm_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;
1554retry:
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;
1572fail:
1573 if (ret == -EDEADLK)
1574 goto backoff;
1575
1576 drm_atomic_state_free(state);
1577
1578 return ret;
1579backoff:
1580 drm_atomic_state_clear(state);
1581 drm_atomic_legacy_backoff(state);
1582
1583 goto retry;
1584}
1585EXPORT_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 */
1598int
1599drm_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;
1613retry:
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;
1631fail:
1632 if (ret == -EDEADLK)
1633 goto backoff;
1634
1635 drm_atomic_state_free(state);
1636
1637 return ret;
1638backoff:
1639 drm_atomic_state_clear(state);
1640 drm_atomic_legacy_backoff(state);
1641
1642 goto retry;
1643}
1644EXPORT_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 */
1657int
1658drm_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;
1672retry:
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;
1690fail:
1691 if (ret == -EDEADLK)
1692 goto backoff;
1693
1694 drm_atomic_state_free(state);
1695
1696 return ret;
1697backoff:
1698 drm_atomic_state_clear(state);
1699 drm_atomic_legacy_backoff(state);
1700
1701 goto retry;
1702}
1703EXPORT_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 */
1721int 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);
1740retry:
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;
1769fail:
1770 if (ret == -EDEADLK)
1771 goto backoff;
1772
1773 drm_atomic_state_free(state);
1774
1775 return ret;
1776backoff:
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}
1789EXPORT_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 */
1813void drm_atomic_helper_crtc_reset(struct drm_crtc *crtc)
1814{
1815 kfree(crtc->state);
1816 crtc->state = kzalloc(sizeof(*crtc->state), GFP_KERNEL);
1817}
1818EXPORT_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 */
1827struct drm_crtc_state *
1828drm_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}
1845EXPORT_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 */
1855void drm_atomic_helper_crtc_destroy_state(struct drm_crtc *crtc,
1856 struct drm_crtc_state *state)
1857{
1858 kfree(state);
1859}
1860EXPORT_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 */
1869void 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}
1877EXPORT_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 */
1886struct drm_plane_state *
1887drm_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}
1901EXPORT_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 */
1911void 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}
1919EXPORT_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 */
1929void drm_atomic_helper_connector_reset(struct drm_connector *connector)
1930{
1931 kfree(connector->state);
1932 connector->state = kzalloc(sizeof(*connector->state), GFP_KERNEL);
1933}
1934EXPORT_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 */
1943struct drm_connector_state *
1944drm_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}
1951EXPORT_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 */
1961void drm_atomic_helper_connector_destroy_state(struct drm_connector *connector,
1962 struct drm_connector_state *state)
1963{
1964 kfree(state);
1965}
1966EXPORT_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
683 drm_modeset_lock_init(&crtc->mutex);683 drm_modeset_lock_init(&crtc->mutex);
684 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);684 ret = drm_mode_object_get(dev, &crtc->base, DRM_MODE_OBJECT_CRTC);
685 if (ret)685 if (ret)
686 goto out;686 return ret;
687 687
688 crtc->base.properties = &crtc->properties;688 crtc->base.properties = &crtc->properties;
689 689
@@ -697,9 +697,7 @@ int drm_crtc_init_with_planes(struct drm_device *dev, struct drm_crtc *crtc, · 7 unmodified lines
697 if (cursor)697 if (cursor)
698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);698 cursor->possible_crtcs = 1 << drm_crtc_index(crtc);
699 699
700 out:700 return 0;
701
702 return ret;
703}701}
704EXPORT_SYMBOL(drm_crtc_init_with_planes);702EXPORT_SYMBOL(drm_crtc_init_with_planes);
705 703
@@ -723,6 +721,12 @@ void drm_crtc_cleanup(struct drm_crtc *crtc) · 17 unmodified lines
723 drm_mode_object_put(dev, &crtc->base);721 drm_mode_object_put(dev, &crtc->base);
724 list_del(&crtc->head);722 list_del(&crtc->head);
725 dev->mode_config.num_crtc--;723 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));
726}730}
727EXPORT_SYMBOL(drm_crtc_cleanup);731EXPORT_SYMBOL(drm_crtc_cleanup);
728 732
@@ -766,7 +770,6 @@ static void drm_mode_remove(struct drm_connector *connector, · 37 unmodified lines
766/**770/**
767 * drm_connector_get_cmdline_mode - reads the user's cmdline mode771 * drm_connector_get_cmdline_mode - reads the user's cmdline mode
768 * @connector: connector to quwery772 * @connector: connector to quwery
769 * @mode: returned mode
770 *773 *
771 * The kernel supports per-connector configration of its consoles through774 * The kernel supports per-connector configration of its consoles through
772 * use of the video= parameter. This function parses that option and775 * 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
870 873
871 drm_connector_get_cmdline_mode(connector);874 drm_connector_get_cmdline_mode(connector);
872 875
876 /* We should add connectors at the end to avoid upsetting the connector
877 * index too much. */
873 list_add_tail(&connector->head, &dev->mode_config.connector_list);878 list_add_tail(&connector->head, &dev->mode_config.connector_list);
874 dev->mode_config.num_connector++;879 dev->mode_config.num_connector++;
875 880
@@ -905,6 +910,11 @@ void drm_connector_cleanup(struct drm_connector *connector) · 29 unmodified lines
905 struct drm_device *dev = connector->dev;910 struct drm_device *dev = connector->dev;
906 struct drm_display_mode *mode, *t;911 struct drm_display_mode *mode, *t;
907 912
913 if (connector->tile_group) {
914 drm_mode_put_tile_group(dev, connector->tile_group);
915 connector->tile_group = NULL;
916 }
917
908 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)918 list_for_each_entry_safe(mode, t, &connector->probed_modes, head)
909 drm_mode_remove(connector, mode);919 drm_mode_remove(connector, mode);
910 920
@@ -919,6 +929,13 @@ void drm_connector_cleanup(struct drm_connector *connector) · 8 unmodified lines
919 connector->name = NULL;929 connector->name = NULL;
920 list_del(&connector->head);930 list_del(&connector->head);
921 dev->mode_config.num_connector--;931 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));
922}939}
923EXPORT_SYMBOL(drm_connector_cleanup);940EXPORT_SYMBOL(drm_connector_cleanup);
924 941
@@ -933,6 +950,9 @@ unsigned int drm_connector_index(struct drm_connector *connector) · 8 unmodified lines
933{950{
934 unsigned int index = 0;951 unsigned int index = 0;
935 struct drm_connector *tmp;952 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));
936 956
937 list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) {957 list_for_each_entry(tmp, &connector->dev->mode_config.connector_list, head) {
938 if (tmp == connector)958 if (tmp == connector)
@@ -1057,6 +1077,8 @@ void drm_bridge_cleanup(struct drm_bridge *bridge) · 118 unmodified lines
1057 list_del(&bridge->head);1077 list_del(&bridge->head);
1058 dev->mode_config.num_bridge--;1078 dev->mode_config.num_bridge--;
1059 drm_modeset_unlock_all(dev);1079 drm_modeset_unlock_all(dev);
1080
1081 memset(bridge, 0, sizeof(*bridge));
1060}1082}
1061EXPORT_SYMBOL(drm_bridge_cleanup);1083EXPORT_SYMBOL(drm_bridge_cleanup);
1062 1084
@@ -1123,10 +1145,11 @@ void drm_encoder_cleanup(struct drm_encoder *encoder) · 60 unmodified lines
1123 drm_modeset_lock_all(dev);1145 drm_modeset_lock_all(dev);
1124 drm_mode_object_put(dev, &encoder->base);1146 drm_mode_object_put(dev, &encoder->base);
1125 kfree(encoder->name);1147 kfree(encoder->name);
1126 encoder->name = NULL;
1127 list_del(&encoder->head);1148 list_del(&encoder->head);
1128 dev->mode_config.num_encoder--;1149 dev->mode_config.num_encoder--;
1129 drm_modeset_unlock_all(dev);1150 drm_modeset_unlock_all(dev);
1151
1152 memset(encoder, 0, sizeof(*encoder));
1130}1153}
1131EXPORT_SYMBOL(drm_encoder_cleanup);1154EXPORT_SYMBOL(drm_encoder_cleanup);
1132 1155
@@ -1153,11 +1176,11 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, · 20 unmodified lines
1153{1176{
1154 int ret;1177 int ret;
1155 1178
1156 drm_modeset_lock_all(dev);
1157
1158 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);1179 ret = drm_mode_object_get(dev, &plane->base, DRM_MODE_OBJECT_PLANE);
1159 if (ret)1180 if (ret)
1160 goto out;1181 return ret;
1182
1183 drm_modeset_lock_init(&plane->mutex);
1161 1184
1162 plane->base.properties = &plane->properties;1185 plane->base.properties = &plane->properties;
1163 plane->dev = dev;1186 plane->dev = dev;
@@ -1167,8 +1190,7 @@ int drm_universal_plane_init(struct drm_device *dev, struct drm_plane *plane, · 3 unmodified lines
1167 if (!plane->format_types) {1190 if (!plane->format_types) {
1168 DRM_DEBUG_KMS("out of memory when allocating plane\n");1191 DRM_DEBUG_KMS("out of memory when allocating plane\n");
1169 drm_mode_object_put(dev, &plane->base);1192 drm_mode_object_put(dev, &plane->base);
1170 ret = -ENOMEM;1193 return -ENOMEM;
1171 goto out;
1172 }1194 }
1173 1195
1174 memcpy(plane->format_types, formats, format_count * sizeof(uint32_t));1196 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
1185 dev->mode_config.plane_type_property,1207 dev->mode_config.plane_type_property,
1186 plane->type);1208 plane->type);
1187 1209
1188 out:1210 return 0;
1189 drm_modeset_unlock_all(dev);
1190
1191 return ret;
1192}1211}
1193EXPORT_SYMBOL(drm_universal_plane_init);1212EXPORT_SYMBOL(drm_universal_plane_init);
1194 1213
@@ -1246,6 +1265,12 @@ void drm_plane_cleanup(struct drm_plane *plane) · 51 unmodified lines
1246 if (plane->type == DRM_PLANE_TYPE_OVERLAY)1265 if (plane->type == DRM_PLANE_TYPE_OVERLAY)
1247 dev->mode_config.num_overlay_plane--;1266 dev->mode_config.num_overlay_plane--;
1248 drm_modeset_unlock_all(dev);1267 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));
1249}1274}
1250EXPORT_SYMBOL(drm_plane_cleanup);1275EXPORT_SYMBOL(drm_plane_cleanup);
1251 1276
@@ -1328,6 +1353,11 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) · 76 unmodified lines
1328 "PATH", 0);1353 "PATH", 0);
1329 dev->mode_config.path_property = dev_path;1354 dev->mode_config.path_property = dev_path;
1330 1355
1356 dev->mode_config.tile_property = drm_property_create(dev,
1357 DRM_MODE_PROP_BLOB |
1358 DRM_MODE_PROP_IMMUTABLE,
1359 "TILE", 0);
1360
1331 return 0;1361 return 0;
1332}1362}
1333 1363
@@ -1388,12 +1418,13 @@ EXPORT_SYMBOL(drm_mode_create_dvi_i_properties); · 54 unmodified lines
1388 * responsible for allocating a list of format names and passing them to1418 * responsible for allocating a list of format names and passing them to
1389 * this routine.1419 * this routine.
1390 */1420 */
1391int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes,1421int drm_mode_create_tv_properties(struct drm_device *dev,
1422 unsigned int num_modes,
1392 char *modes[])1423 char *modes[])
1393{1424{
1394 struct drm_property *tv_selector;1425 struct drm_property *tv_selector;
1395 struct drm_property *tv_subconnector;1426 struct drm_property *tv_subconnector;
1396 int i;1427 unsigned int i;
1397 1428
1398 if (dev->mode_config.tv_select_subconnector_property)1429 if (dev->mode_config.tv_select_subconnector_property)
1399 return 0;1430 return 0;
@@ -1491,7 +1522,7 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); · 91 unmodified lines
1491 * connectors.1522 * connectors.
1492 *1523 *
1493 * Returns:1524 * Returns:
1494 * Zero on success, errno on failure.1525 * Zero on success, negative errno on failure.
1495 */1526 */
1496int drm_mode_create_aspect_ratio_property(struct drm_device *dev)1527int drm_mode_create_aspect_ratio_property(struct drm_device *dev)
1497{1528{
@@ -1535,6 +1566,30 @@ int drm_mode_create_dirty_info_property(struct drm_device *dev) · 37 unmodified lines
1535}1566}
1536EXPORT_SYMBOL(drm_mode_create_dirty_info_property);1567EXPORT_SYMBOL(drm_mode_create_dirty_info_property);
1537 1568
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 */
1575int 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}
1591EXPORT_SYMBOL(drm_mode_create_suggested_offset_properties);
1592
1538static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)1593static int drm_mode_group_init(struct drm_device *dev, struct drm_mode_group *group)
1539{1594{
1540 uint32_t total_objects = 0;1595 uint32_t total_objects = 0;
@@ -1651,7 +1706,7 @@ static void drm_crtc_convert_to_umode(struct drm_mode_modeinfo *out, · 110 unmodified lines
1651 * the caller.1706 * the caller.
1652 *1707 *
1653 * Returns:1708 * Returns:
1654 * Zero on success, errno on failure.1709 * Zero on success, negative errno on failure.
1655 */1710 */
1656static int drm_crtc_convert_umode(struct drm_display_mode *out,1711static int drm_crtc_convert_umode(struct drm_display_mode *out,
1657 const struct drm_mode_modeinfo *in)1712 const struct drm_mode_modeinfo *in)
@@ -1694,7 +1749,7 @@ static int drm_crtc_convert_umode(struct drm_display_mode *out, · 36 unmodified lines
1694 * Called by the user via ioctl.1749 * Called by the user via ioctl.
1695 *1750 *
1696 * Returns:1751 * Returns:
1697 * Zero on success, errno on failure.1752 * Zero on success, negative errno on failure.
1698 */1753 */
1699int drm_mode_getresources(struct drm_device *dev, void *data,1754int drm_mode_getresources(struct drm_device *dev, void *data,
1700 struct drm_file *file_priv)1755 struct drm_file *file_priv)
@@ -1745,7 +1800,9 @@ int drm_mode_getresources(struct drm_device *dev, void *data, · 44 unmodified lines
1745 card_res->count_fbs = fb_count;1800 card_res->count_fbs = fb_count;
1746 mutex_unlock(&file_priv->fbs_lock);1801 mutex_unlock(&file_priv->fbs_lock);
1747 1802
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);
1749 if (!drm_is_primary_client(file_priv)) {1806 if (!drm_is_primary_client(file_priv)) {
1750 1807
1751 mode_group = NULL;1808 mode_group = NULL;
@@ -1865,7 +1922,7 @@ int drm_mode_getresources(struct drm_device *dev, void *data, · 113 unmodified lines
1865 card_res->count_connectors, card_res->count_encoders);1922 card_res->count_connectors, card_res->count_encoders);
1866 1923
1867out:1924out:
1868 drm_modeset_unlock_all(dev);1925 mutex_unlock(&dev->mode_config.mutex);
1869 return ret;1926 return ret;
1870}1927}
1871 1928
@@ -1880,26 +1937,22 @@ out: · 8 unmodified lines
1880 * Called by the user via ioctl.1937 * Called by the user via ioctl.
1881 *1938 *
1882 * Returns:1939 * Returns:
1883 * Zero on success, errno on failure.1940 * Zero on success, negative errno on failure.
1884 */1941 */
1885int drm_mode_getcrtc(struct drm_device *dev,1942int drm_mode_getcrtc(struct drm_device *dev,
1886 void *data, struct drm_file *file_priv)1943 void *data, struct drm_file *file_priv)
1887{1944{
1888 struct drm_mode_crtc *crtc_resp = data;1945 struct drm_mode_crtc *crtc_resp = data;
1889 struct drm_crtc *crtc;1946 struct drm_crtc *crtc;
1890 int ret = 0;
1891 1947
1892 if (!drm_core_check_feature(dev, DRIVER_MODESET))1948 if (!drm_core_check_feature(dev, DRIVER_MODESET))
1893 return -EINVAL;1949 return -EINVAL;
1894 1950
1895 drm_modeset_lock_all(dev);
1896
1897 crtc = drm_crtc_find(dev, crtc_resp->crtc_id);1951 crtc = drm_crtc_find(dev, crtc_resp->crtc_id);
1898 if (!crtc) {1952 if (!crtc)
1899 ret = -ENOENT;1953 return -ENOENT;
1900 goto out;
1901 }
1902 1954
1955 drm_modeset_lock_crtc(crtc, crtc->primary);
1903 crtc_resp->x = crtc->x;1956 crtc_resp->x = crtc->x;
1904 crtc_resp->y = crtc->y;1957 crtc_resp->y = crtc->y;
1905 crtc_resp->gamma_size = crtc->gamma_size;1958 crtc_resp->gamma_size = crtc->gamma_size;
@@ -1916,10 +1969,9 @@ int drm_mode_getcrtc(struct drm_device *dev, · 10 unmodified lines
1916 } else {1969 } else {
1917 crtc_resp->mode_valid = 0;1970 crtc_resp->mode_valid = 0;
1918 }1971 }
1972 drm_modeset_unlock_crtc(crtc);
1919 1973
1920out:1974 return 0;
1921 drm_modeset_unlock_all(dev);
1922 return ret;
1923}1975}
1924 1976
1925static bool drm_mode_expose_to_userspace(const struct drm_display_mode *mode,1977static 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
1935 return true;1987 return true;
1936}1988}
1937 1989
1990static 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
1938/**1999/**
1939 * drm_mode_getconnector - get connector configuration2000 * drm_mode_getconnector - get connector configuration
1940 * @dev: drm device for the ioctl2001 * @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
1946 * Called by the user via ioctl.2007 * Called by the user via ioctl.
1947 *2008 *
1948 * Returns:2009 * Returns:
1949 * Zero on success, errno on failure.2010 * Zero on success, negative errno on failure.
1950 */2011 */
1951int drm_mode_getconnector(struct drm_device *dev, void *data,2012int drm_mode_getconnector(struct drm_device *dev, void *data,
1952 struct drm_file *file_priv)2013 struct drm_file *file_priv)
1953{2014{
1954 struct drm_mode_get_connector *out_resp = data;2015 struct drm_mode_get_connector *out_resp = data;
1955 struct drm_connector *connector;2016 struct drm_connector *connector;
2017 struct drm_encoder *encoder;
1956 struct drm_display_mode *mode;2018 struct drm_display_mode *mode;
1957 int mode_count = 0;2019 int mode_count = 0;
1958 int props_count = 0;2020 int props_count = 0;
@@ -2008,8 +2070,10 @@ int drm_mode_getconnector(struct drm_device *dev, void *data, · 49 unmodified lines
2008 out_resp->subpixel = connector->display_info.subpixel_order;2070 out_resp->subpixel = connector->display_info.subpixel_order;
2009 out_resp->connection = connector->status;2071 out_resp->connection = connector->status;
2010 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);2072 drm_modeset_lock(&dev->mode_config.connection_mutex, NULL);
2011 if (connector->encoder)2073
2012 out_resp->encoder_id = connector->encoder->base.id;2074 encoder = drm_connector_get_encoder(connector);
2075 if (encoder)
2076 out_resp->encoder_id = encoder->base.id;
2013 else2077 else
2014 out_resp->encoder_id = 0;2078 out_resp->encoder_id = 0;
2015 drm_modeset_unlock(&dev->mode_config.connection_mutex);2079 drm_modeset_unlock(&dev->mode_config.connection_mutex);
@@ -2079,6 +2143,33 @@ out: · 63 unmodified lines
2079 return ret;2143 return ret;
2080}2144}
2081 2145
2146static 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
2082/**2173/**
2083 * drm_mode_getencoder - get encoder configuration2174 * drm_mode_getencoder - get encoder configuration
2084 * @dev: drm device for the ioctl2175 * @dev: drm device for the ioctl
@@ -2090,37 +2181,38 @@ out: · 5 unmodified lines
2090 * Called by the user via ioctl.2181 * Called by the user via ioctl.
2091 *2182 *
2092 * Returns:2183 * Returns:
2093 * Zero on success, errno on failure.2184 * Zero on success, negative errno on failure.
2094 */2185 */
2095int drm_mode_getencoder(struct drm_device *dev, void *data,2186int drm_mode_getencoder(struct drm_device *dev, void *data,
2096 struct drm_file *file_priv)2187 struct drm_file *file_priv)
2097{2188{
2098 struct drm_mode_get_encoder *enc_resp = data;2189 struct drm_mode_get_encoder *enc_resp = data;
2099 struct drm_encoder *encoder;2190 struct drm_encoder *encoder;
2100 int ret = 0;2191 struct drm_crtc *crtc;
2101 2192
2102 if (!drm_core_check_feature(dev, DRIVER_MODESET))2193 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2103 return -EINVAL;2194 return -EINVAL;
2104 2195
2105 drm_modeset_lock_all(dev);
2106 encoder = drm_encoder_find(dev, enc_resp->encoder_id);2196 encoder = drm_encoder_find(dev, enc_resp->encoder_id);
2107 if (!encoder) {2197 if (!encoder)
2108 ret = -ENOENT;2198 return -ENOENT;
2109 goto out;
2110 }
2111 2199
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)
2113 enc_resp->crtc_id = encoder->crtc->base.id;2205 enc_resp->crtc_id = encoder->crtc->base.id;
2114 else2206 else
2115 enc_resp->crtc_id = 0;2207 enc_resp->crtc_id = 0;
2208 drm_modeset_unlock(&dev->mode_config.connection_mutex);
2209
2116 enc_resp->encoder_type = encoder->encoder_type;2210 enc_resp->encoder_type = encoder->encoder_type;
2117 enc_resp->encoder_id = encoder->base.id;2211 enc_resp->encoder_id = encoder->base.id;
2118 enc_resp->possible_crtcs = encoder->possible_crtcs;2212 enc_resp->possible_crtcs = encoder->possible_crtcs;
2119 enc_resp->possible_clones = encoder->possible_clones;2213 enc_resp->possible_clones = encoder->possible_clones;
2120 2214
2121out:2215 return 0;
2122 drm_modeset_unlock_all(dev);
2123 return ret;
2124}2216}
2125 2217
2126/**2218/**
@@ -2134,7 +2226,7 @@ out: · 7 unmodified lines
2134 * Called by the user via ioctl.2226 * Called by the user via ioctl.
2135 *2227 *
2136 * Returns:2228 * Returns:
2137 * Zero on success, errno on failure.2229 * Zero on success, negative errno on failure.
2138 */2230 */
2139int drm_mode_getplane_res(struct drm_device *dev, void *data,2231int drm_mode_getplane_res(struct drm_device *dev, void *data,
2140 struct drm_file *file_priv)2232 struct drm_file *file_priv)
@@ -2143,13 +2235,12 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 2 unmodified lines
2143 struct drm_mode_config *config;2235 struct drm_mode_config *config;
2144 struct drm_plane *plane;2236 struct drm_plane *plane;
2145 uint32_t __user *plane_ptr;2237 uint32_t __user *plane_ptr;
2146 int copied = 0, ret = 0;2238 int copied = 0;
2147 unsigned num_planes;2239 unsigned num_planes;
2148 2240
2149 if (!drm_core_check_feature(dev, DRIVER_MODESET))2241 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2150 return -EINVAL;2242 return -EINVAL;
2151 2243
2152 drm_modeset_lock_all(dev);
2153 config = &dev->mode_config;2244 config = &dev->mode_config;
2154 2245
2155 if (file_priv->universal_planes)2246 if (file_priv->universal_planes)
@@ -2165,6 +2256,7 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 9 unmodified lines
2165 (plane_resp->count_planes >= num_planes)) {2256 (plane_resp->count_planes >= num_planes)) {
2166 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;2257 plane_ptr = (uint32_t __user *)(unsigned long)plane_resp->plane_id_ptr;
2167 2258
2259 /* Plane lists are invariant, no locking needed. */
2168 list_for_each_entry(plane, &config->plane_list, head) {2260 list_for_each_entry(plane, &config->plane_list, head) {
2169 /*2261 /*
2170 * Unless userspace set the 'universal planes'2262 * Unless userspace set the 'universal planes'
@@ -2174,18 +2266,14 @@ int drm_mode_getplane_res(struct drm_device *dev, void *data, · 3 unmodified lines
2174 !file_priv->universal_planes)2266 !file_priv->universal_planes)
2175 continue;2267 continue;
2176 2268
2177 if (put_user(plane->base.id, plane_ptr + copied)) {2269 if (put_user(plane->base.id, plane_ptr + copied))
2178 ret = -EFAULT;2270 return -EFAULT;
2179 goto out;
2180 }
2181 copied++;2271 copied++;
2182 }2272 }
2183 }2273 }
2184 plane_resp->count_planes = num_planes;2274 plane_resp->count_planes = num_planes;
2185 2275
2186out:2276 return 0;
2187 drm_modeset_unlock_all(dev);
2188 return ret;
2189}2277}
2190 2278
2191/**2279/**
@@ -2199,7 +2287,7 @@ out: · 7 unmodified lines
2199 * Called by the user via ioctl.2287 * Called by the user via ioctl.
2200 *2288 *
2201 * Returns:2289 * Returns:
2202 * Zero on success, errno on failure.2290 * Zero on success, negative errno on failure.
2203 */2291 */
2204int drm_mode_getplane(struct drm_device *dev, void *data,2292int drm_mode_getplane(struct drm_device *dev, void *data,
2205 struct drm_file *file_priv)2293 struct drm_file *file_priv)
@@ -2207,18 +2295,15 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 1 unmodified line
2207 struct drm_mode_get_plane *plane_resp = data;2295 struct drm_mode_get_plane *plane_resp = data;
2208 struct drm_plane *plane;2296 struct drm_plane *plane;
2209 uint32_t __user *format_ptr;2297 uint32_t __user *format_ptr;
2210 int ret = 0;
2211 2298
2212 if (!drm_core_check_feature(dev, DRIVER_MODESET))2299 if (!drm_core_check_feature(dev, DRIVER_MODESET))
2213 return -EINVAL;2300 return -EINVAL;
2214 2301
2215 drm_modeset_lock_all(dev);
2216 plane = drm_plane_find(dev, plane_resp->plane_id);2302 plane = drm_plane_find(dev, plane_resp->plane_id);
2217 if (!plane) {2303 if (!plane)
2218 ret = -ENOENT;2304 return -ENOENT;
2219 goto out;
2220 }
2221 2305
2306 drm_modeset_lock(&plane->mutex, NULL);
2222 if (plane->crtc)2307 if (plane->crtc)
2223 plane_resp->crtc_id = plane->crtc->base.id;2308 plane_resp->crtc_id = plane->crtc->base.id;
2224 else2309 else
@@ -2228,6 +2313,7 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 3 unmodified lines
2228 plane_resp->fb_id = plane->fb->base.id;2313 plane_resp->fb_id = plane->fb->base.id;
2229 else2314 else
2230 plane_resp->fb_id = 0;2315 plane_resp->fb_id = 0;
2316 drm_modeset_unlock(&plane->mutex);
2231 2317
2232 plane_resp->plane_id = plane->base.id;2318 plane_resp->plane_id = plane->base.id;
2233 plane_resp->possible_crtcs = plane->possible_crtcs;2319 plane_resp->possible_crtcs = plane->possible_crtcs;
@@ -2243,15 +2329,12 @@ int drm_mode_getplane(struct drm_device *dev, void *data, · 9 unmodified lines
2243 if (copy_to_user(format_ptr,2329 if (copy_to_user(format_ptr,
2244 plane->format_types,2330 plane->format_types,
2245 sizeof(uint32_t) * plane->format_count)) {2331 sizeof(uint32_t) * plane->format_count)) {
2246 ret = -EFAULT;2332 return -EFAULT;
2247 goto out;
2248 }2333 }
2249 }2334 }
2250 plane_resp->count_format_types = plane->format_count;2335 plane_resp->count_format_types = plane->format_count;
2251 2336
2252out:2337 return 0;
2253 drm_modeset_unlock_all(dev);
2254 return ret;
2255}2338}
2256 2339
2257/*2340/*
@@ -2274,7 +2357,7 @@ static int __setplane_internal(struct drm_plane *plane, · 16 unmodified lines
2274{2357{
2275 int ret = 0;2358 int ret = 0;
2276 unsigned int fb_width, fb_height;2359 unsigned int fb_width, fb_height;
2277 int i;2360 unsigned int i;
2278 2361
2279 /* No fb means shut it down */2362 /* No fb means shut it down */
2280 if (!fb) {2363 if (!fb) {
@@ -2378,13 +2461,12 @@ static int setplane_internal(struct drm_plane *plane, · 97 unmodified lines
2378 * valid crtc).2461 * valid crtc).
2379 *2462 *
2380 * Returns:2463 * Returns:
2381 * Zero on success, errno on failure.2464 * Zero on success, negative errno on failure.
2382 */2465 */
2383int drm_mode_setplane(struct drm_device *dev, void *data,2466int drm_mode_setplane(struct drm_device *dev, void *data,
2384 struct drm_file *file_priv)2467 struct drm_file *file_priv)
2385{2468{
2386 struct drm_mode_set_plane *plane_req = data;2469 struct drm_mode_set_plane *plane_req = data;
2387 struct drm_mode_object *obj;
2388 struct drm_plane *plane;2470 struct drm_plane *plane;
2389 struct drm_crtc *crtc = NULL;2471 struct drm_crtc *crtc = NULL;
2390 struct drm_framebuffer *fb = NULL;2472 struct drm_framebuffer *fb = NULL;
@@ -2407,14 +2489,12 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 16 unmodified lines
2407 * First, find the plane, crtc, and fb objects. If not available,2489 * First, find the plane, crtc, and fb objects. If not available,
2408 * we don't bother to call the driver.2490 * we don't bother to call the driver.
2409 */2491 */
2410 obj = drm_mode_object_find(dev, plane_req->plane_id,2492 plane = drm_plane_find(dev, plane_req->plane_id);
2411 DRM_MODE_OBJECT_PLANE);2493 if (!plane) {
2412 if (!obj) {
2413 DRM_DEBUG_KMS("Unknown plane ID %d\n",2494 DRM_DEBUG_KMS("Unknown plane ID %d\n",
2414 plane_req->plane_id);2495 plane_req->plane_id);
2415 return -ENOENT;2496 return -ENOENT;
2416 }2497 }
2417 plane = obj_to_plane(obj);
2418 2498
2419 if (plane_req->fb_id) {2499 if (plane_req->fb_id) {
2420 fb = drm_framebuffer_lookup(dev, plane_req->fb_id);2500 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
2424 return -ENOENT;2504 return -ENOENT;
2425 }2505 }
2426 2506
2427 obj = drm_mode_object_find(dev, plane_req->crtc_id,2507 crtc = drm_crtc_find(dev, plane_req->crtc_id);
2428 DRM_MODE_OBJECT_CRTC);2508 if (!crtc) {
2429 if (!obj) {
2430 DRM_DEBUG_KMS("Unknown crtc ID %d\n",2509 DRM_DEBUG_KMS("Unknown crtc ID %d\n",
2431 plane_req->crtc_id);2510 plane_req->crtc_id);
2432 return -ENOENT;2511 return -ENOENT;
2433 }2512 }
2434 crtc = obj_to_crtc(obj);
2435 }2513 }
2436 2514
2437 /*2515 /*
@@ -2453,7 +2531,7 @@ int drm_mode_setplane(struct drm_device *dev, void *data, · 15 unmodified lines
2453 * interface. The only thing it adds is correct refcounting dance.2531 * interface. The only thing it adds is correct refcounting dance.
2454 * 2532 *
2455 * Returns:2533 * Returns:
2456 * Zero on success, errno on failure.2534 * Zero on success, negative errno on failure.
2457 */2535 */
2458int drm_mode_set_config_internal(struct drm_mode_set *set)2536int drm_mode_set_config_internal(struct drm_mode_set *set)
2459{2537{
@@ -2546,7 +2624,7 @@ EXPORT_SYMBOL(drm_crtc_check_viewport); · 86 unmodified lines
2546 * Called by the user via ioctl.2624 * Called by the user via ioctl.
2547 *2625 *
2548 * Returns:2626 * Returns:
2549 * Zero on success, errno on failure.2627 * Zero on success, negative errno on failure.
2550 */2628 */
2551int drm_mode_setcrtc(struct drm_device *dev, void *data,2629int drm_mode_setcrtc(struct drm_device *dev, void *data,
2552 struct drm_file *file_priv)2630 struct drm_file *file_priv)
@@ -2709,7 +2787,7 @@ out: · 156 unmodified lines
2709 * userspace wants to make use of these capabilities.2787 * userspace wants to make use of these capabilities.
2710 *2788 *
2711 * Returns:2789 * Returns:
2712 * Zero on success, errno on failure.2790 * Zero on success, negative errno on failure.
2713 */2791 */
2714static int drm_mode_cursor_universal(struct drm_crtc *crtc,2792static int drm_mode_cursor_universal(struct drm_crtc *crtc,
2715 struct drm_mode_cursor2 *req,2793 struct drm_mode_cursor2 *req,
@@ -2810,7 +2888,7 @@ static int drm_mode_cursor_common(struct drm_device *dev, · 94 unmodified lines
2810 * If this crtc has a universal cursor plane, call that plane's update2888 * If this crtc has a universal cursor plane, call that plane's update
2811 * handler rather than using legacy cursor handlers.2889 * handler rather than using legacy cursor handlers.
2812 */2890 */
2813 drm_modeset_lock_crtc(crtc);2891 drm_modeset_lock_crtc(crtc, crtc->cursor);
2814 if (crtc->cursor) {2892 if (crtc->cursor) {
2815 ret = drm_mode_cursor_universal(crtc, req, file_priv);2893 ret = drm_mode_cursor_universal(crtc, req, file_priv);
2816 goto out;2894 goto out;
@@ -2857,7 +2935,7 @@ out: · 40 unmodified lines
2857 * Called by the user via ioctl.2935 * Called by the user via ioctl.
2858 *2936 *
2859 * Returns:2937 * Returns:
2860 * Zero on success, errno on failure.2938 * Zero on success, negative errno on failure.
2861 */2939 */
2862int drm_mode_cursor_ioctl(struct drm_device *dev,2940int drm_mode_cursor_ioctl(struct drm_device *dev,
2863 void *data, struct drm_file *file_priv)2941 void *data, struct drm_file *file_priv)
@@ -2884,7 +2962,7 @@ int drm_mode_cursor_ioctl(struct drm_device *dev, · 20 unmodified lines
2884 * Called by the user via ioctl.2962 * Called by the user via ioctl.
2885 *2963 *
2886 * Returns:2964 * Returns:
2887 * Zero on success, errno on failure.2965 * Zero on success, negative errno on failure.
2888 */2966 */
2889int drm_mode_cursor2_ioctl(struct drm_device *dev,2967int drm_mode_cursor2_ioctl(struct drm_device *dev,
2890 void *data, struct drm_file *file_priv)2968 void *data, struct drm_file *file_priv)
@@ -2943,23 +3021,21 @@ EXPORT_SYMBOL(drm_mode_legacy_fb_format); · 52 unmodified lines
2943 * @file_priv: drm file for the ioctl call3021 * @file_priv: drm file for the ioctl call
2944 *3022 *
2945 * Add a new FB to the specified CRTC, given a user request. This is the3023 * 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.
2947 *3025 *
2948 * Called by the user via ioctl.3026 * Called by the user via ioctl.
2949 *3027 *
2950 * Returns:3028 * Returns:
2951 * Zero on success, errno on failure.3029 * Zero on success, negative errno on failure.
2952 */3030 */
2953int drm_mode_addfb(struct drm_device *dev,3031int drm_mode_addfb(struct drm_device *dev,
2954 void *data, struct drm_file *file_priv)3032 void *data, struct drm_file *file_priv)
2955{3033{
2956 struct drm_mode_fb_cmd *or = data;3034 struct drm_mode_fb_cmd *or = data;
2957 struct drm_mode_fb_cmd2 r = {};3035 struct drm_mode_fb_cmd2 r = {};
2958 struct drm_mode_config *config = &dev->mode_config;3036 int ret;
2959 struct drm_framebuffer *fb;
2960 int ret = 0;
2961 3037
2962 /* Use new struct with format internally */3038 /* convert to new format and call new ioctl */
2963 r.fb_id = or->fb_id;3039 r.fb_id = or->fb_id;
2964 r.width = or->width;3040 r.width = or->width;
2965 r.height = or->height;3041 r.height = or->height;
@@ -2967,28 +3043,13 @@ int drm_mode_addfb(struct drm_device *dev, · 1 unmodified line
2967 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);3043 r.pixel_format = drm_mode_legacy_fb_format(or->bpp, or->depth);
2968 r.handles[0] = or->handle;3044 r.handles[0] = or->handle;
2969 3045
2970 if (!drm_core_check_feature(dev, DRIVER_MODESET))3046 ret = drm_mode_addfb2(dev, &r, file_priv);
2971 return -EINVAL;3047 if (ret)
2972 3048 return ret;
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;
2978 3049
2979 fb = dev->mode_config.funcs->fb_create(dev, file_priv, &r);3050 or->fb_id = r.fb_id;
2980 if (IS_ERR(fb)) {
2981 DRM_DEBUG_KMS("could not create framebuffer\n");
2982 return PTR_ERR(fb);
2983 }
2984 3051
2985 mutex_lock(&file_priv->fbs_lock);3052 return 0;
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;
2992}3053}
2993 3054
2994static int format_check(const struct drm_mode_fb_cmd2 *r)3055static 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
3080 num_planes = drm_format_num_planes(r->pixel_format);3141 num_planes = drm_format_num_planes(r->pixel_format);
3081 3142
3082 if (r->width == 0 || r->width % hsub) {3143 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);
3084 return -EINVAL;3145 return -EINVAL;
3085 }3146 }
3086 3147
@@ -3170,7 +3231,7 @@ static struct drm_framebuffer *add_framebuffer_internal(struct drm_device *dev, · 83 unmodified lines
3170 * Called by the user via ioctl.3231 * Called by the user via ioctl.
3171 *3232 *
3172 * Returns:3233 * Returns:
3173 * Zero on success, errno on failure.3234 * Zero on success, negative errno on failure.
3174 */3235 */
3175int drm_mode_addfb2(struct drm_device *dev,3236int drm_mode_addfb2(struct drm_device *dev,
3176 void *data, struct drm_file *file_priv)3237 void *data, struct drm_file *file_priv)
@@ -3198,7 +3259,7 @@ int drm_mode_addfb2(struct drm_device *dev, · 21 unmodified lines
3198 * Called by the user via ioctl.3259 * Called by the user via ioctl.
3199 *3260 *
3200 * Returns:3261 * Returns:
3201 * Zero on success, errno on failure.3262 * Zero on success, negative errno on failure.
3202 */3263 */
3203int drm_mode_rmfb(struct drm_device *dev,3264int drm_mode_rmfb(struct drm_device *dev,
3204 void *data, struct drm_file *file_priv)3265 void *data, struct drm_file *file_priv)
@@ -3252,7 +3313,7 @@ fail_lookup: · 47 unmodified lines
3252 * Called by the user via ioctl.3313 * Called by the user via ioctl.
3253 *3314 *
3254 * Returns:3315 * Returns:
3255 * Zero on success, errno on failure.3316 * Zero on success, negative errno on failure.
3256 */3317 */
3257int drm_mode_getfb(struct drm_device *dev,3318int drm_mode_getfb(struct drm_device *dev,
3258 void *data, struct drm_file *file_priv)3319 void *data, struct drm_file *file_priv)
@@ -3313,7 +3374,7 @@ int drm_mode_getfb(struct drm_device *dev, · 54 unmodified lines
3313 * Called by the user via ioctl.3374 * Called by the user via ioctl.
3314 *3375 *
3315 * Returns:3376 * Returns:
3316 * Zero on success, errno on failure.3377 * Zero on success, negative errno on failure.
3317 */3378 */
3318int drm_mode_dirtyfb_ioctl(struct drm_device *dev,3379int drm_mode_dirtyfb_ioctl(struct drm_device *dev,
3319 void *data, struct drm_file *file_priv)3380 void *data, struct drm_file *file_priv)
@@ -3393,7 +3454,7 @@ out_err1: · 73 unmodified lines
3393 * Called by the user via ioctl.3454 * Called by the user via ioctl.
3394 *3455 *
3395 * Returns:3456 * Returns:
3396 * Zero on success, errno on failure.3457 * Zero on success, negative errno on failure.
3397 */3458 */
3398void drm_fb_release(struct drm_file *priv)3459void drm_fb_release(struct drm_file *priv)
3399{3460{
@@ -3402,7 +3463,7 @@ void drm_fb_release(struct drm_file *priv) · 2 unmodified lines
3402 3463
3403 /*3464 /*
3404 * When the file gets released that means no one else can access the fb3465 * 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 to3466 * list any more, so no need to grab fpriv->fbs_lock. And we need to
3406 * avoid upsetting lockdep since the universal cursor code adds a3467 * avoid upsetting lockdep since the universal cursor code adds a
3407 * framebuffer while holding mutex locks.3468 * framebuffer while holding mutex locks.
3408 *3469 *
@@ -3435,6 +3496,10 @@ void drm_fb_release(struct drm_file *priv) · 26 unmodified lines
3435 * object with drm_object_attach_property. The returned property object must be3496 * object with drm_object_attach_property. The returned property object must be
3436 * freed with drm_property_destroy.3497 * freed with drm_property_destroy.
3437 *3498 *
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 *
3438 * Returns:3503 * Returns:
3439 * A pointer to the newly created property on success, NULL on failure.3504 * A pointer to the newly created property on success, NULL on failure.
3440 */3505 */
@@ -3462,7 +3527,7 @@ struct drm_property *drm_property_create(struct drm_device *dev, int flags, · 21 unmodified lines
3462 3527
3463 property->flags = flags;3528 property->flags = flags;
3464 property->num_values = num_values;3529 property->num_values = num_values;
3465 INIT_LIST_HEAD(&property->enum_blob_list);3530 INIT_LIST_HEAD(&property->enum_list);
3466 3531
3467 if (name) {3532 if (name) {
3468 strncpy(property->name, name, DRM_PROP_NAME_LEN);3533 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
3611 * object with drm_object_attach_property. The returned property object must be3676 * object with drm_object_attach_property. The returned property object must be
3612 * freed with drm_property_destroy.3677 * freed with drm_property_destroy.
3613 *3678 *
3614 * Userspace is allowed to set any interger value in the (min, max) range3679 * Userspace is allowed to set any integer value in the (min, max) range
3615 * inclusive.3680 * inclusive.
3616 *3681 *
3617 * Returns:3682 * Returns:
@@ -3684,8 +3749,8 @@ int drm_property_add_enum(struct drm_property *property, int index, · 66 unmodified lines
3684 (value > 63))3749 (value > 63))
3685 return -EINVAL;3750 return -EINVAL;
3686 3751
3687 if (!list_empty(&property->enum_blob_list)) {3752 if (!list_empty(&property->enum_list)) {
3688 list_for_each_entry(prop_enum, &property->enum_blob_list, head) {3753 list_for_each_entry(prop_enum, &property->enum_list, head) {
3689 if (prop_enum->value == value) {3754 if (prop_enum->value == value) {
3690 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);3755 strncpy(prop_enum->name, name, DRM_PROP_NAME_LEN);
3691 prop_enum->name[DRM_PROP_NAME_LEN-1] = '\0';3756 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
3703 prop_enum->value = value;3768 prop_enum->value = value;
3704 3769
3705 property->values[index] = value;3770 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);
3707 return 0;3772 return 0;
3708}3773}
3709EXPORT_SYMBOL(drm_property_add_enum);3774EXPORT_SYMBOL(drm_property_add_enum);
@@ -3720,7 +3785,7 @@ void drm_property_destroy(struct drm_device *dev, struct drm_property *property) · 10 unmodified lines
3720{3785{
3721 struct drm_property_enum *prop_enum, *pt;3786 struct drm_property_enum *prop_enum, *pt;
3722 3787
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) {
3724 list_del(&prop_enum->head);3789 list_del(&prop_enum->head);
3725 kfree(prop_enum);3790 kfree(prop_enum);
3726 }3791 }
@@ -3823,17 +3888,20 @@ int drm_object_property_get_value(struct drm_mode_object *obj, · 96 unmodified lines
3823EXPORT_SYMBOL(drm_object_property_get_value);3888EXPORT_SYMBOL(drm_object_property_get_value);
3824 3889
3825/**3890/**
3826 * drm_mode_getproperty_ioctl - get the current value of a connector's property3891 * drm_mode_getproperty_ioctl - get the property metadata
3827 * @dev: DRM device3892 * @dev: DRM device
3828 * @data: ioctl data3893 * @data: ioctl data
3829 * @file_priv: DRM file info3894 * @file_priv: DRM file info
3830 *3895 *
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
3832 *3900 *
3833 * Called by the user via ioctl.3901 * Called by the user via ioctl.
3834 *3902 *
3835 * Returns:3903 * Returns:
3836 * Zero on success, errno on failure.3904 * Zero on success, negative errno on failure.
3837 */3905 */
3838int drm_mode_getproperty_ioctl(struct drm_device *dev,3906int drm_mode_getproperty_ioctl(struct drm_device *dev,
3839 void *data, struct drm_file *file_priv)3907 void *data, struct drm_file *file_priv)
@@ -3841,16 +3909,12 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 1 unmodified line
3841 struct drm_mode_get_property *out_resp = data;3909 struct drm_mode_get_property *out_resp = data;
3842 struct drm_property *property;3910 struct drm_property *property;
3843 int enum_count = 0;3911 int enum_count = 0;
3844 int blob_count = 0;
3845 int value_count = 0;3912 int value_count = 0;
3846 int ret = 0, i;3913 int ret = 0, i;
3847 int copied;3914 int copied;
3848 struct drm_property_enum *prop_enum;3915 struct drm_property_enum *prop_enum;
3849 struct drm_mode_property_enum __user *enum_ptr;3916 struct drm_mode_property_enum __user *enum_ptr;
3850 struct drm_property_blob *prop_blob;
3851 uint32_t __user *blob_id_ptr;
3852 uint64_t __user *values_ptr;3917 uint64_t __user *values_ptr;
3853 uint32_t __user *blob_length_ptr;
3854 3918
3855 if (!drm_core_check_feature(dev, DRIVER_MODESET))3919 if (!drm_core_check_feature(dev, DRIVER_MODESET))
3856 return -EINVAL;3920 return -EINVAL;
@@ -3864,11 +3928,8 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 7 unmodified lines
3864 3928
3865 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||3929 if (drm_property_type_is(property, DRM_MODE_PROP_ENUM) ||
3866 drm_property_type_is(property, DRM_MODE_PROP_BITMASK)) {3930 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)
3868 enum_count++;3932 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++;
3872 }3933 }
3873 3934
3874 value_count = property->num_values;3935 value_count = property->num_values;
@@ -3893,7 +3954,7 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 18 unmodified lines
3893 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {3954 if ((out_resp->count_enum_blobs >= enum_count) && enum_count) {
3894 copied = 0;3955 copied = 0;
3895 enum_ptr = (struct drm_mode_property_enum __user *)(unsigned long)out_resp->enum_blob_ptr;3956 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) {
3897 3958
3898 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {3959 if (copy_to_user(&enum_ptr[copied].value, &prop_enum->value, sizeof(uint64_t))) {
3899 ret = -EFAULT;3960 ret = -EFAULT;
@@ -3911,35 +3972,24 @@ int drm_mode_getproperty_ioctl(struct drm_device *dev, · 11 unmodified lines
3911 out_resp->count_enum_blobs = enum_count;3972 out_resp->count_enum_blobs = enum_count;
3912 }3973 }
3913 3974
3914 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB)) {3975 /*
3915 if ((out_resp->count_enum_blobs >= blob_count) && blob_count) {3976 * NOTE: The idea seems to have been to use this to read all the blob
3916 copied = 0;3977 * property values. But nothing ever added them to the corresponding
3917 blob_id_ptr = (uint32_t __user *)(unsigned long)out_resp->enum_blob_ptr;3978 * list, userspace always used the special-purpose get_blob ioctl to
3918 blob_length_ptr = (uint32_t __user *)(unsigned long)out_resp->values_ptr;3979 * read the value for a blob property. It also doesn't make a lot of
3919 3980 * sense to return values here when everything else is just metadata for
3920 list_for_each_entry(prop_blob, &property->enum_blob_list, head) {3981 * the property itself.
3921 if (put_user(prop_blob->base.id, blob_id_ptr + copied)) {3982 */
3922 ret = -EFAULT;3983 if (drm_property_type_is(property, DRM_MODE_PROP_BLOB))
3923 goto done;3984 out_resp->count_enum_blobs = 0;
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 }
3936done:3985done:
3937 drm_modeset_unlock_all(dev);3986 drm_modeset_unlock_all(dev);
3938 return ret;3987 return ret;
3939}3988}
3940 3989
3941static struct drm_property_blob *drm_property_create_blob(struct drm_device *dev, int length,3990static struct drm_property_blob *
3942 void *data)3991drm_property_create_blob(struct drm_device *dev, size_t length,
3992 const void *data)
3943{3993{
3944 struct drm_property_blob *blob;3994 struct drm_property_blob *blob;
3945 int ret;3995 int ret;
@@ -3985,7 +4035,7 @@ static void drm_property_destroy_blob(struct drm_device *dev, · 39 unmodified lines
3985 * Called by the user via ioctl.4035 * Called by the user via ioctl.
3986 *4036 *
3987 * Returns:4037 * Returns:
3988 * Zero on success, errno on failure.4038 * Zero on success, negative errno on failure.
3989 */4039 */
3990int drm_mode_getblob_ioctl(struct drm_device *dev,4040int drm_mode_getblob_ioctl(struct drm_device *dev,
3991 void *data, struct drm_file *file_priv)4041 void *data, struct drm_file *file_priv)
@@ -4019,12 +4069,25 @@ done: · 27 unmodified lines
4019 return ret;4069 return ret;
4020}4070}
4021 4071
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 */
4022int drm_mode_connector_set_path_property(struct drm_connector *connector,4085int drm_mode_connector_set_path_property(struct drm_connector *connector,
4023 char *path)4086 const char *path)
4024{4087{
4025 struct drm_device *dev = connector->dev;4088 struct drm_device *dev = connector->dev;
4026 int ret, size;4089 size_t size = strlen(path) + 1;
4027 size = strlen(path) + 1;4090 int ret;
4028 4091
4029 connector->path_blob_ptr = drm_property_create_blob(connector->dev,4092 connector->path_blob_ptr = drm_property_create_blob(connector->dev,
4030 size, path);4093 size, path);
@@ -4038,6 +4101,52 @@ int drm_mode_connector_set_path_property(struct drm_connector *connector, · 7 unmodified lines
4038}4101}
4039EXPORT_SYMBOL(drm_mode_connector_set_path_property);4102EXPORT_SYMBOL(drm_mode_connector_set_path_property);
4040 4103
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 */
4115int 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}
4148EXPORT_SYMBOL(drm_mode_connector_set_tile_property);
4149
4041/**4150/**
4042 * drm_mode_connector_update_edid_property - update the edid property of a connector4151 * drm_mode_connector_update_edid_property - update the edid property of a connector
4043 * @connector: drm connector4152 * @connector: drm connector
@@ -4047,13 +4156,14 @@ EXPORT_SYMBOL(drm_mode_connector_set_path_property); · 3 unmodified lines
4047 * connector's edid property.4156 * connector's edid property.
4048 *4157 *
4049 * Returns:4158 * Returns:
4050 * Zero on success, errno on failure.4159 * Zero on success, negative errno on failure.
4051 */4160 */
4052int drm_mode_connector_update_edid_property(struct drm_connector *connector,4161int drm_mode_connector_update_edid_property(struct drm_connector *connector,
4053 struct edid *edid)4162 const struct edid *edid)
4054{4163{
4055 struct drm_device *dev = connector->dev;4164 struct drm_device *dev = connector->dev;
4056 int ret, size;4165 size_t size;
4166 int ret;
4057 4167
4058 /* ignore requests to set edid when overridden */4168 /* ignore requests to set edid when overridden */
4059 if (connector->override_edid)4169 if (connector->override_edid)
@@ -4143,7 +4253,7 @@ static bool drm_property_change_is_valid(struct drm_property *property, · 83 unmodified lines
4143 * Called by the user via ioctl.4253 * Called by the user via ioctl.
4144 *4254 *
4145 * Returns:4255 * Returns:
4146 * Zero on success, errno on failure.4256 * Zero on success, negative errno on failure.
4147 */4257 */
4148int drm_mode_connector_property_set_ioctl(struct drm_device *dev,4258int drm_mode_connector_property_set_ioctl(struct drm_device *dev,
4149 void *data, struct drm_file *file_priv)4259 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
4226EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);4336EXPORT_SYMBOL(drm_mode_plane_set_obj_prop);
4227 4337
4228/**4338/**
4229 * drm_mode_getproperty_ioctl - get the current value of a object's property4339 * drm_mode_obj_get_properties_ioctl - get the current value of a object's property
4230 * @dev: DRM device4340 * @dev: DRM device
4231 * @data: ioctl data4341 * @data: ioctl data
4232 * @file_priv: DRM file info4342 * @file_priv: DRM file info
@@ -4238,7 +4348,7 @@ EXPORT_SYMBOL(drm_mode_plane_set_obj_prop); · 5 unmodified lines
4238 * Called by the user via ioctl.4348 * Called by the user via ioctl.
4239 *4349 *
4240 * Returns:4350 * Returns:
4241 * Zero on success, errno on failure.4351 * Zero on success, negative errno on failure.
4242 */4352 */
4243int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,4353int drm_mode_obj_get_properties_ioctl(struct drm_device *dev, void *data,
4244 struct drm_file *file_priv)4354 struct drm_file *file_priv)
@@ -4310,7 +4420,7 @@ out: · 65 unmodified lines
4310 * Called by the user via ioctl.4420 * Called by the user via ioctl.
4311 *4421 *
4312 * Returns:4422 * Returns:
4313 * Zero on success, errno on failure.4423 * Zero on success, negative errno on failure.
4314 */4424 */
4315int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,4425int drm_mode_obj_set_property_ioctl(struct drm_device *dev, void *data,
4316 struct drm_file *file_priv)4426 struct drm_file *file_priv)
@@ -4382,7 +4492,7 @@ out: · 65 unmodified lines
4382 * possible_clones and possible_crtcs bitmasks.4492 * possible_clones and possible_crtcs bitmasks.
4383 *4493 *
4384 * Returns:4494 * Returns:
4385 * Zero on success, errno on failure.4495 * Zero on success, negative errno on failure.
4386 */4496 */
4387int drm_mode_connector_attach_encoder(struct drm_connector *connector,4497int drm_mode_connector_attach_encoder(struct drm_connector *connector,
4388 struct drm_encoder *encoder)4498 struct drm_encoder *encoder)
@@ -4409,7 +4519,7 @@ EXPORT_SYMBOL(drm_mode_connector_attach_encoder); · 20 unmodified lines
4409 * fixed gamma table size.4519 * fixed gamma table size.
4410 *4520 *
4411 * Returns:4521 * Returns:
4412 * Zero on success, errno on failure.4522 * Zero on success, negative errno on failure.
4413 */4523 */
4414int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,4524int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc,
4415 int gamma_size)4525 int gamma_size)
@@ -4438,7 +4548,7 @@ EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); · 22 unmodified lines
4438 * Called by the user via ioctl.4548 * Called by the user via ioctl.
4439 *4549 *
4440 * Returns:4550 * Returns:
4441 * Zero on success, errno on failure.4551 * Zero on success, negative errno on failure.
4442 */4552 */
4443int drm_mode_gamma_set_ioctl(struct drm_device *dev,4553int drm_mode_gamma_set_ioctl(struct drm_device *dev,
4444 void *data, struct drm_file *file_priv)4554 void *data, struct drm_file *file_priv)
@@ -4510,7 +4620,7 @@ out: · 65 unmodified lines
4510 * Called by the user via ioctl.4620 * Called by the user via ioctl.
4511 *4621 *
4512 * Returns:4622 * Returns:
4513 * Zero on success, errno on failure.4623 * Zero on success, negative errno on failure.
4514 */4624 */
4515int drm_mode_gamma_get_ioctl(struct drm_device *dev,4625int drm_mode_gamma_get_ioctl(struct drm_device *dev,
4516 void *data, struct drm_file *file_priv)4626 void *data, struct drm_file *file_priv)
@@ -4576,7 +4686,7 @@ out: · 59 unmodified lines
4576 * Called by the user via ioctl.4686 * Called by the user via ioctl.
4577 *4687 *
4578 * Returns:4688 * Returns:
4579 * Zero on success, errno on failure.4689 * Zero on success, negative errno on failure.
4580 */4690 */
4581int drm_mode_page_flip_ioctl(struct drm_device *dev,4691int drm_mode_page_flip_ioctl(struct drm_device *dev,
4582 void *data, struct drm_file *file_priv)4692 void *data, struct drm_file *file_priv)
@@ -4599,7 +4709,7 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, · 16 unmodified lines
4599 if (!crtc)4709 if (!crtc)
4600 return -ENOENT;4710 return -ENOENT;
4601 4711
4602 drm_modeset_lock_crtc(crtc);4712 drm_modeset_lock_crtc(crtc, crtc->primary);
4603 if (crtc->primary->fb == NULL) {4713 if (crtc->primary->fb == NULL) {
4604 /* The framebuffer is currently unbound, presumably4714 /* The framebuffer is currently unbound, presumably
4605 * due to a hotplug event, that userspace has not4715 * due to a hotplug event, that userspace has not
@@ -4742,7 +4852,7 @@ EXPORT_SYMBOL(drm_mode_config_reset); · 136 unmodified lines
4742 * Called by the user via ioctl.4852 * Called by the user via ioctl.
4743 *4853 *
4744 * Returns:4854 * Returns:
4745 * Zero on success, errno on failure.4855 * Zero on success, negative errno on failure.
4746 */4856 */
4747int drm_mode_create_dumb_ioctl(struct drm_device *dev,4857int drm_mode_create_dumb_ioctl(struct drm_device *dev,
4748 void *data, struct drm_file *file_priv)4858 void *data, struct drm_file *file_priv)
@@ -4769,6 +4879,16 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, · 20 unmodified lines
4769 if (PAGE_ALIGN(size) == 0)4879 if (PAGE_ALIGN(size) == 0)
4770 return -EINVAL;4880 return -EINVAL;
4771 4881
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
4772 return dev->driver->dumb_create(file_priv, dev, args);4892 return dev->driver->dumb_create(file_priv, dev, args);
4773}4893}
4774 4894
@@ -4784,7 +4904,7 @@ int drm_mode_create_dumb_ioctl(struct drm_device *dev, · 9 unmodified lines
4784 * Called by the user via ioctl.4904 * Called by the user via ioctl.
4785 *4905 *
4786 * Returns:4906 * Returns:
4787 * Zero on success, errno on failure.4907 * Zero on success, negative errno on failure.
4788 */4908 */
4789int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,4909int drm_mode_mmap_dumb_ioctl(struct drm_device *dev,
4790 void *data, struct drm_file *file_priv)4910 void *data, struct drm_file *file_priv)
@@ -4811,7 +4931,7 @@ int drm_mode_mmap_dumb_ioctl(struct drm_device *dev, · 20 unmodified lines
4811 * Called by the user via ioctl.4931 * Called by the user via ioctl.
4812 *4932 *
4813 * Returns:4933 * Returns:
4814 * Zero on success, errno on failure.4934 * Zero on success, negative errno on failure.
4815 */4935 */
4816int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,4936int drm_mode_destroy_dumb_ioctl(struct drm_device *dev,
4817 void *data, struct drm_file *file_priv)4937 void *data, struct drm_file *file_priv)
@@ -5097,6 +5217,7 @@ void drm_mode_config_init(struct drm_device *dev) · 279 unmodified lines
5097 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);5217 INIT_LIST_HEAD(&dev->mode_config.property_blob_list);
5098 INIT_LIST_HEAD(&dev->mode_config.plane_list);5218 INIT_LIST_HEAD(&dev->mode_config.plane_list);
5099 idr_init(&dev->mode_config.crtc_idr);5219 idr_init(&dev->mode_config.crtc_idr);
5220 idr_init(&dev->mode_config.tile_idr);
5100 5221
5101 drm_modeset_lock_all(dev);5222 drm_modeset_lock_all(dev);
5102 drm_mode_create_standard_connector_properties(dev);5223 drm_mode_create_standard_connector_properties(dev);
@@ -5184,6 +5305,7 @@ void drm_mode_config_cleanup(struct drm_device *dev) · 81 unmodified lines
5184 crtc->funcs->destroy(crtc);5305 crtc->funcs->destroy(crtc);
5185 }5306 }
5186 5307
5308 idr_destroy(&dev->mode_config.tile_idr);
5187 idr_destroy(&dev->mode_config.crtc_idr);5309 idr_destroy(&dev->mode_config.crtc_idr);
5188 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);5310 drm_modeset_lock_fini(&dev->mode_config.connection_mutex);
5189}5311}
@@ -5206,3 +5328,100 @@ struct drm_property *drm_mode_create_rotation_property(struct drm_device *dev, · 16 unmodified lines
5206 supported_rotations);5328 supported_rotations);
5207}5329}
5208EXPORT_SYMBOL(drm_mode_create_rotation_property);5330EXPORT_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 */
5340static 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 */
5357void 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 */
5373struct 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 */
5402struct 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
34#include <linux/moduleparam.h>34#include <linux/moduleparam.h>
35 35
36#include <drm/drmP.h>36#include <drm/drmP.h>
37#include <drm/drm_atomic.h>
37#include <drm/drm_crtc.h>38#include <drm/drm_crtc.h>
38#include <drm/drm_fourcc.h>39#include <drm/drm_fourcc.h>
39#include <drm/drm_crtc_helper.h>40#include <drm/drm_crtc_helper.h>
40#include <drm/drm_fb_helper.h>41#include <drm/drm_fb_helper.h>
42#include <drm/drm_plane_helper.h>
43#include <drm/drm_atomic_helper.h>
41#include <drm/drm_edid.h>44#include <drm/drm_edid.h>
42 45
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 */
43MODULE_AUTHOR("David Airlie, Jesse Barnes");66MODULE_AUTHOR("David Airlie, Jesse Barnes");
44MODULE_DESCRIPTION("DRM KMS helper");67MODULE_DESCRIPTION("DRM KMS helper");
45MODULE_LICENSE("GPL and additional rights");68MODULE_LICENSE("GPL and additional rights");
@@ -888,3 +911,112 @@ void drm_helper_resume_force_mode(struct drm_device *dev) · 842 unmodified lines
888 drm_modeset_unlock_all(dev);911 drm_modeset_unlock_all(dev);
889}912}
890EXPORT_SYMBOL(drm_helper_resume_force_mode);913EXPORT_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 */
932int 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}
978EXPORT_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 */
994int 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}
1022EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
drivers/gpu/drm/drm_dp_helper.c+6−195
@@ -39,198 +39,6 @@ · 38 unmodified lines
39 * blocks, ...39 * blocks, ...
40 */40 */
41 41
42/* Run a single AUX_CH I2C transaction, writing/reading data as necessary */
43static int
44i2c_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 */
64static int
65i2c_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 */
85static void
86i2c_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 */
105static int
106i2c_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 */
122static int
123i2c_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
135static int
136i2c_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
175static u32
176i2c_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
184static 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
189static void
190i2c_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
196static int
197i2c_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 */
221int
222i2c_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}
232EXPORT_SYMBOL(i2c_dp_aux_add_bus);
233
234/* Helpers for DP link training */42/* Helpers for DP link training */
235static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)43static u8 dp_link_status(const u8 link_status[DP_LINK_STATUS_SIZE], int r)
236{44{
@@ -378,10 +186,11 @@ static int drm_dp_dpcd_access(struct drm_dp_aux *aux, u8 request, · 141 unmodified lines
378 186
379 /*187 /*
380 * The specification doesn't give any recommendation on how often to188 * The specification doesn't give any recommendation on how often to
381 * retry native transactions, so retry 7 times like for I2C-over-AUX189 * retry native transactions. We used to retry 7 times like for
382 * transactions.190 * aux i2c transactions but real world devices this wasn't
191 * sufficient, bump to 32 which makes Dell 4k monitors happier.
383 */192 */
384 for (retry = 0; retry < 7; retry++) {193 for (retry = 0; retry < 32; retry++) {
385 194
386 mutex_lock(&aux->hw_mutex);195 mutex_lock(&aux->hw_mutex);
387 err = aux->transfer(aux, &msg);196 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
654 463
655 case DP_AUX_I2C_REPLY_NACK:464 case DP_AUX_I2C_REPLY_NACK:
656 DRM_DEBUG_KMS("I2C nack\n");465 DRM_DEBUG_KMS("I2C nack\n");
466 aux->i2c_nack_count++;
657 return -EREMOTEIO;467 return -EREMOTEIO;
658 468
659 case DP_AUX_I2C_REPLY_DEFER:469 case DP_AUX_I2C_REPLY_DEFER:
660 DRM_DEBUG_KMS("I2C defer\n");470 DRM_DEBUG_KMS("I2C defer\n");
471 aux->i2c_defer_count++;
661 usleep_range(400, 500);472 usleep_range(400, 500);
662 continue;473 continue;
663 474
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
839 839
840static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)840static void drm_dp_port_teardown_pdt(struct drm_dp_mst_port *port, int old_pdt)
841{841{
842 struct drm_dp_mst_branch *mstb;
843
842 switch (old_pdt) {844 switch (old_pdt) {
843 case DP_PEER_DEVICE_DP_LEGACY_CONV:845 case DP_PEER_DEVICE_DP_LEGACY_CONV:
844 case DP_PEER_DEVICE_SST_SINK:846 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
846 drm_dp_mst_unregister_i2c_bus(&port->aux);848 drm_dp_mst_unregister_i2c_bus(&port->aux);
847 break;849 break;
848 case DP_PEER_DEVICE_MST_BRANCHING:850 case DP_PEER_DEVICE_MST_BRANCHING:
849 drm_dp_put_mst_branch_device(port->mstb);851 mstb = port->mstb;
850 port->mstb = NULL;852 port->mstb = NULL;
853 drm_dp_put_mst_branch_device(mstb);
851 break;854 break;
852 }855 }
853}856}
@@ -858,6 +861,8 @@ static void drm_dp_destroy_port(struct kref *kref) · 4 unmodified lines
858 struct drm_dp_mst_topology_mgr *mgr = port->mgr;861 struct drm_dp_mst_topology_mgr *mgr = port->mgr;
859 if (!port->input) {862 if (!port->input) {
860 port->vcpi.num_slots = 0;863 port->vcpi.num_slots = 0;
864
865 kfree(port->cached_edid);
861 if (port->connector)866 if (port->connector)
862 (*port->mgr->cbs->destroy_connector)(mgr, port->connector);867 (*port->mgr->cbs->destroy_connector)(mgr, port->connector);
863 drm_dp_port_teardown_pdt(port, port->pdt);868 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
1011 1016
1012static void build_mst_prop_path(struct drm_dp_mst_port *port,1017static void build_mst_prop_path(struct drm_dp_mst_port *port,
1013 struct drm_dp_mst_branch *mstb,1018 struct drm_dp_mst_branch *mstb,
1014 char *proppath)1019 char *proppath,
1020 size_t proppath_size)
1015{1021{
1016 int i;1022 int i;
1017 char temp[8];1023 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);
1019 for (i = 0; i < (mstb->lct - 1); i++) {1025 for (i = 0; i < (mstb->lct - 1); i++) {
1020 int shift = (i % 2) ? 0 : 4;1026 int shift = (i % 2) ? 0 : 4;
1021 int port_num = mstb->rad[i / 2] >> shift;1027 int port_num = mstb->rad[i / 2] >> shift;
1022 snprintf(temp, 8, "-%d", port_num);1028 snprintf(temp, sizeof(temp), "-%d", port_num);
1023 strncat(proppath, temp, 255);1029 strlcat(proppath, temp, proppath_size);
1024 }1030 }
1025 snprintf(temp, 8, "-%d", port->port_num);1031 snprintf(temp, sizeof(temp), "-%d", port->port_num);
1026 strncat(proppath, temp, 255);1032 strlcat(proppath, temp, proppath_size);
1027}1033}
1028 1034
1029static void drm_dp_add_port(struct drm_dp_mst_branch *mstb,1035static 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
1094 1100
1095 if (created && !port->input) {1101 if (created && !port->input) {
1096 char proppath[255];1102 char proppath[255];
1097 build_mst_prop_path(port, mstb, proppath);1103 build_mst_prop_path(port, mstb, proppath, sizeof(proppath));
1098 port->connector = (*mstb->mgr->cbs->add_connector)(mstb->mgr, port, proppath);1104 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 }
1099 }1109 }
1100 1110
1101 /* put reference to this port */1111 /* 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
1798 return 0;1808 return 0;
1799}1809}
1800 1810
1801static int drm_dp_get_vc_payload_bw(int dp_link_bw, int dp_link_count)1811static bool drm_dp_get_vc_payload_bw(int dp_link_bw,
1812 int dp_link_count,
1813 int *out)
1802{1814{
1803 switch (dp_link_bw) {1815 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
1804 case DP_LINK_BW_1_62:1821 case DP_LINK_BW_1_62:
1805 return 3 * dp_link_count;1822 *out = 3 * dp_link_count;
1823 break;
1806 case DP_LINK_BW_2_7:1824 case DP_LINK_BW_2_7:
1807 return 5 * dp_link_count;1825 *out = 5 * dp_link_count;
1826 break;
1808 case DP_LINK_BW_5_4:1827 case DP_LINK_BW_5_4:
1809 return 10 * dp_link_count;1828 *out = 10 * dp_link_count;
1829 break;
1810 }1830 }
1811 BUG();1831 return true;
1812}1832}
1813 1833
1814/**1834/**
@@ -1840,7 +1860,13 @@ int drm_dp_mst_topology_mgr_set_mst(struct drm_dp_mst_topology_mgr *mgr, bool ms · 25 unmodified lines
1840 goto out_unlock;1860 goto out_unlock;
1841 }1861 }
1842 1862
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
1844 mgr->total_pbn = 2560;1870 mgr->total_pbn = 2560;
1845 mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);1871 mgr->total_slots = DIV_ROUND_UP(mgr->total_pbn, mgr->pbn_div);
1846 mgr->avail_slots = mgr->total_slots;1872 mgr->avail_slots = mgr->total_slots;
@@ -2150,7 +2176,8 @@ EXPORT_SYMBOL(drm_dp_mst_hpd_irq); · 303 unmodified lines
2150 * This returns the current connection state for a port. It validates the2176 * This returns the current connection state for a port. It validates the
2151 * port pointer still exists so the caller doesn't require a reference2177 * port pointer still exists so the caller doesn't require a reference
2152 */2178 */
2153enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr *mgr, struct drm_dp_mst_port *port)2179enum 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)
2154{2181{
2155 enum drm_connector_status status = connector_status_disconnected;2182 enum drm_connector_status status = connector_status_disconnected;
2156 2183
@@ -2169,6 +2196,10 @@ enum drm_connector_status drm_dp_mst_detect_port(struct drm_dp_mst_topology_mgr · 12 unmodified lines
2169 2196
2170 case DP_PEER_DEVICE_SST_SINK:2197 case DP_PEER_DEVICE_SST_SINK:
2171 status = connector_status_connected;2198 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 }
2172 break;2203 break;
2173 case DP_PEER_DEVICE_DP_LEGACY_CONV:2204 case DP_PEER_DEVICE_DP_LEGACY_CONV:
2174 if (port->ldps)2205 if (port->ldps)
@@ -2200,7 +2231,12 @@ struct edid *drm_dp_mst_get_edid(struct drm_connector *connector, struct drm_dp_ · 25 unmodified lines
2200 if (!port)2231 if (!port)
2201 return NULL;2232 return NULL;
2202 2233
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);
2204 drm_dp_put_port(port);2240 drm_dp_put_port(port);
2205 return edid;2241 return edid;
2206}2242}
drivers/gpu/drm/drm_drv.c+5−2
@@ -56,7 +56,7 @@ static struct idr drm_minors_idr; · 55 unmodified lines
56struct class *drm_class;56struct class *drm_class;
57static struct dentry *drm_debugfs_root;57static struct dentry *drm_debugfs_root;
58 58
59void drm_err(const char *func, const char *format, ...)59void drm_err(const char *format, ...)
60{60{
61 struct va_format vaf;61 struct va_format vaf;
62 va_list args;62 va_list args;
@@ -66,7 +66,8 @@ void drm_err(const char *func, const char *format, ...) · 3 unmodified lines
66 vaf.fmt = format;66 vaf.fmt = format;
67 vaf.va = &args;67 vaf.va = &args;
68 68
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);
70 71
71 va_end(args);72 va_end(args);
72}73}
@@ -534,6 +535,8 @@ static void drm_fs_inode_free(struct inode *inode) · 461 unmodified lines
534 * The initial ref-count of the object is 1. Use drm_dev_ref() and535 * The initial ref-count of the object is 1. Use drm_dev_ref() and
535 * drm_dev_unref() to take and drop further ref-counts.536 * drm_dev_unref() to take and drop further ref-counts.
536 *537 *
538 * Note that for purely virtual devices @parent can be NULL.
539 *
537 * RETURNS:540 * RETURNS:
538 * Pointer to new DRM device, or NULL if out of memory.541 * Pointer to new DRM device, or NULL if out of memory.
539 */542 */
drivers/gpu/drm/drm_edid.c+201−30
@@ -34,6 +34,7 @@ · 33 unmodified lines
34#include <linux/module.h>34#include <linux/module.h>
35#include <drm/drmP.h>35#include <drm/drmP.h>
36#include <drm/drm_edid.h>36#include <drm/drm_edid.h>
37#include <drm/drm_displayid.h>
37 38
38#define version_greater(edid, maj, min) \39#define version_greater(edid, maj, min) \
39 (((edid)->version > (maj)) || \40 (((edid)->version > (maj)) || \
@@ -1014,6 +1015,27 @@ module_param_named(edid_fixup, edid_fixup, int, 0400); · 974 unmodified lines
1014MODULE_PARM_DESC(edid_fixup,1015MODULE_PARM_DESC(edid_fixup,
1015 "Minimum number of valid EDID header bytes (0-8, default 6)");1016 "Minimum number of valid EDID header bytes (0-8, default 6)");
1016 1017
1018static void drm_get_displayid(struct drm_connector *connector,
1019 struct edid *edid);
1020
1021static 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
1031static 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
1017/**1039/**
1018 * drm_edid_block_valid - Sanity check the EDID block (base or extension)1040 * drm_edid_block_valid - Sanity check the EDID block (base or extension)
1019 * @raw_edid: pointer to raw EDID block1041 * @raw_edid: pointer to raw EDID block
@@ -1027,8 +1049,7 @@ MODULE_PARM_DESC(edid_fixup, · 7 unmodified lines
1027 */1049 */
1028bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)1050bool drm_edid_block_valid(u8 *raw_edid, int block, bool print_bad_edid)
1029{1051{
1030 int i;1052 u8 csum;
1031 u8 csum = 0;
1032 struct edid *edid = (struct edid *)raw_edid;1053 struct edid *edid = (struct edid *)raw_edid;
1033 1054
1034 if (WARN_ON(!raw_edid))1055 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
1048 }1069 }
1049 }1070 }
1050 1071
1051 for (i = 0; i < EDID_LENGTH; i++)1072 csum = drm_edid_block_checksum(raw_edid);
1052 csum += raw_edid[i];
1053 if (csum) {1073 if (csum) {
1054 if (print_bad_edid) {1074 if (print_bad_edid) {
1055 DRM_ERROR("EDID checksum is invalid, remainder is %d\n", csum);1075 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
1080 1100
1081bad:1101bad:
1082 if (print_bad_edid) {1102 if (print_bad_edid) {
1083 printk(KERN_ERR "Raw EDID:\n");1103 if (drm_edid_is_zero(raw_edid, EDID_LENGTH)) {
1084 print_hex_dump(KERN_ERR, " \t", DUMP_PREFIX_NONE, 16, 1,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,
1085 raw_edid, EDID_LENGTH, false);1108 raw_edid, EDID_LENGTH, false);
1109 }
1086 }1110 }
1087 return false;1111 return false;
1088}1112}
@@ -1115,7 +1139,7 @@ EXPORT_SYMBOL(drm_edid_is_valid); · 26 unmodified lines
1115#define DDC_SEGMENT_ADDR 0x301139#define DDC_SEGMENT_ADDR 0x30
1116/**1140/**
1117 * drm_do_probe_ddc_edid() - get EDID information via I2C1141 * drm_do_probe_ddc_edid() - get EDID information via I2C
1118 * @adapter: I2C device adaptor1142 * @data: I2C device adapter
1119 * @buf: EDID data buffer to be filled1143 * @buf: EDID data buffer to be filled
1120 * @block: 128 byte EDID block to start fetching from1144 * @block: 128 byte EDID block to start fetching from
1121 * @len: EDID data buffer length to fetch1145 * @len: EDID data buffer length to fetch
@@ -1125,9 +1149,9 @@ EXPORT_SYMBOL(drm_edid_is_valid); · 3 unmodified lines
1125 * Return: 0 on success or -1 on failure.1149 * Return: 0 on success or -1 on failure.
1126 */1150 */
1127static int1151static int
1128drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf,1152drm_do_probe_ddc_edid(void *data, u8 *buf, unsigned int block, size_t len)
1129 int block, int len)
1130{1153{
1154 struct i2c_adapter *adapter = data;
1131 unsigned char start = block * EDID_LENGTH;1155 unsigned char start = block * EDID_LENGTH;
1132 unsigned char segment = block >> 1;1156 unsigned char segment = block >> 1;
1133 unsigned char xfers = segment ? 3 : 2;1157 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
1176 return ret == xfers ? 0 : -1;1200 return ret == xfers ? 0 : -1;
1177}1201}
1178 1202
1179static bool drm_edid_is_zero(u8 *in_edid, int length)1203/**
1180{1204 * drm_do_get_edid - get EDID data using a custom EDID block read function
1181 if (memchr_inv(in_edid, 0, length))1205 * @connector: connector we're probing
1182 return false;1206 * @get_edid_block: EDID block read function
1183 1207 * @data: private data passed to the block read function
1184 return true;1208 *
1185}1209 * When the I2C adapter connected to the DDC bus is hidden behind a device that
1186 1210 * exposes a different interface to read EDID blocks this function can be used
1187static u8 *1211 * to get EDID data using a custom block read function.
1188drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter)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 */
1219struct 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)
1189{1223{
1190 int i, j = 0, valid_extensions = 0;1224 int i, j = 0, valid_extensions = 0;
1191 u8 *block, *new;1225 u8 *block, *new;
@@ -1196,7 +1230,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 4 unmodified lines
1196 1230
1197 /* base block fetch */1231 /* base block fetch */
1198 for (i = 0; i < 4; i++) {1232 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))
1200 goto out;1234 goto out;
1201 if (drm_edid_block_valid(block, 0, print_bad_edid))1235 if (drm_edid_block_valid(block, 0, print_bad_edid))
1202 break;1236 break;
@@ -1210,7 +1244,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 7 unmodified lines
1210 1244
1211 /* if there's no extensions, we're done */1245 /* if there's no extensions, we're done */
1212 if (block[0x7e] == 0)1246 if (block[0x7e] == 0)
1213 return block;1247 return (struct edid *)block;
1214 1248
1215 new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);1249 new = krealloc(block, (block[0x7e] + 1) * EDID_LENGTH, GFP_KERNEL);
1216 if (!new)1250 if (!new)
@@ -1219,7 +1253,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 2 unmodified lines
1219 1253
1220 for (j = 1; j <= block[0x7e]; j++) {1254 for (j = 1; j <= block[0x7e]; j++) {
1221 for (i = 0; i < 4; i++) {1255 for (i = 0; i < 4; i++) {
1222 if (drm_do_probe_ddc_edid(adapter,1256 if (get_edid_block(data,
1223 block + (valid_extensions + 1) * EDID_LENGTH,1257 block + (valid_extensions + 1) * EDID_LENGTH,
1224 j, EDID_LENGTH))1258 j, EDID_LENGTH))
1225 goto out;1259 goto out;
@@ -1247,7 +1281,7 @@ drm_do_get_edid(struct drm_connector *connector, struct i2c_adapter *adapter) · 21 unmodified lines
1247 block = new;1281 block = new;
1248 }1282 }
1249 1283
1250 return block;1284 return (struct edid *)block;
1251 1285
1252carp:1286carp:
1253 if (print_bad_edid) {1287 if (print_bad_edid) {
@@ -1260,6 +1294,7 @@ out: · 6 unmodified lines
1260 kfree(block);1294 kfree(block);
1261 return NULL;1295 return NULL;
1262}1296}
1297EXPORT_SYMBOL_GPL(drm_do_get_edid);
1263 1298
1264/**1299/**
1265 * drm_probe_ddc() - probe DDC presence1300 * drm_probe_ddc() - probe DDC presence
@@ -1289,11 +1324,14 @@ EXPORT_SYMBOL(drm_probe_ddc); · 23 unmodified lines
1289struct edid *drm_get_edid(struct drm_connector *connector,1324struct edid *drm_get_edid(struct drm_connector *connector,
1290 struct i2c_adapter *adapter)1325 struct i2c_adapter *adapter)
1291{1326{
1292 struct edid *edid = NULL;1327 struct edid *edid;
1293 1328
1294 if (drm_probe_ddc(adapter))1329 if (!drm_probe_ddc(adapter))
1295 edid = (struct edid *)drm_do_get_edid(connector, adapter);1330 return NULL;
1296 1331
1332 edid = drm_do_get_edid(connector, drm_do_probe_ddc_edid, adapter);
1333 if (edid)
1334 drm_get_displayid(connector, edid);
1297 return edid;1335 return edid;
1298}1336}
1299EXPORT_SYMBOL(drm_get_edid);1337EXPORT_SYMBOL(drm_get_edid);
@@ -2389,7 +2427,7 @@ add_detailed_modes(struct drm_connector *connector, struct edid *edid, · 1089 unmodified lines
2389/*2427/*
2390 * Search EDID for CEA extension block.2428 * Search EDID for CEA extension block.
2391 */2429 */
2392static u8 *drm_find_cea_extension(struct edid *edid)2430static u8 *drm_find_edid_extension(struct edid *edid, int ext_id)
2393{2431{
2394 u8 *edid_ext = NULL;2432 u8 *edid_ext = NULL;
2395 int i;2433 int i;
@@ -2401,7 +2439,7 @@ static u8 *drm_find_cea_extension(struct edid *edid) · 5 unmodified lines
2401 /* Find CEA extension */2439 /* Find CEA extension */
2402 for (i = 0; i < edid->extensions; i++) {2440 for (i = 0; i < edid->extensions; i++) {
2403 edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);2441 edid_ext = (u8 *)edid + EDID_LENGTH * (i + 1);
2404 if (edid_ext[0] == CEA_EXT)2442 if (edid_ext[0] == ext_id)
2405 break;2443 break;
2406 }2444 }
2407 2445
@@ -2411,6 +2449,16 @@ static u8 *drm_find_cea_extension(struct edid *edid) · 3 unmodified lines
2411 return edid_ext;2449 return edid_ext;
2412}2450}
2413 2451
2452static u8 *drm_find_cea_extension(struct edid *edid)
2453{
2454 return drm_find_edid_extension(edid, CEA_EXT);
2455}
2456
2457static u8 *drm_find_displayid_extension(struct edid *edid)
2458{
2459 return drm_find_edid_extension(edid, DISPLAYID_EXT);
2460}
2461
2414/*2462/*
2415 * Calculate the alternate clock for the CEA mode2463 * Calculate the alternate clock for the CEA mode
2416 * (60Hz vs. 59.94Hz etc.)2464 * (60Hz vs. 59.94Hz etc.)
@@ -3128,9 +3176,12 @@ void drm_edid_to_eld(struct drm_connector *connector, struct edid *edid) · 711 unmodified lines
3128 }3176 }
3129 }3177 }
3130 eld[5] |= sad_count << 4;3178 eld[5] |= sad_count << 4;
3131 eld[2] = (20 + mnl + sad_count * 3 + 3) / 4;
3132 3179
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);
3134}3185}
3135EXPORT_SYMBOL(drm_edid_to_eld);3186EXPORT_SYMBOL(drm_edid_to_eld);
3136 3187
@@ -3868,3 +3919,123 @@ drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, · 731 unmodified lines
3868 return 0;3919 return 0;
3869}3920}
3870EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);3921EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode);
3922
3923static 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
4017static 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;
4035out_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
254 name, connector_name);254 name, connector_name);
255 255
256out:256out:
257 if (fw)257 release_firmware(fw);
258 release_firmware(fw);
259 return edid;258 return edid;
260}259}
261 260
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
347{347{
348 struct drm_device *dev = fb_helper->dev;348 struct drm_device *dev = fb_helper->dev;
349 bool ret;349 bool ret;
350 bool do_delayed = false;
351
350 drm_modeset_lock_all(dev);352 drm_modeset_lock_all(dev);
351 ret = restore_fbdev_mode(fb_helper);353 ret = restore_fbdev_mode(fb_helper);
354
355 do_delayed = fb_helper->delayed_hotplug;
356 if (do_delayed)
357 fb_helper->delayed_hotplug = false;
352 drm_modeset_unlock_all(dev);358 drm_modeset_unlock_all(dev);
359
360 if (do_delayed)
361 drm_fb_helper_hotplug_event(fb_helper);
353 return ret;362 return ret;
354}363}
355EXPORT_SYMBOL(drm_fb_helper_restore_fbdev_mode_unlocked);364EXPORT_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
888 897
889 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);898 drm_fb_helper_restore_fbdev_mode_unlocked(fb_helper);
890 899
891 if (fb_helper->delayed_hotplug) {
892 fb_helper->delayed_hotplug = false;
893 drm_fb_helper_hotplug_event(fb_helper);
894 }
895 return 0;900 return 0;
896}901}
897EXPORT_SYMBOL(drm_fb_helper_set_par);902EXPORT_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
995 crtc_count = 0;1000 crtc_count = 0;
996 for (i = 0; i < fb_helper->crtc_count; i++) {1001 for (i = 0; i < fb_helper->crtc_count; i++) {
997 struct drm_display_mode *desired_mode;1002 struct drm_display_mode *desired_mode;
1003 int x, y;
998 desired_mode = fb_helper->crtc_info[i].desired_mode;1004 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;
1000 if (desired_mode) {1007 if (desired_mode) {
1001 if (gamma_size == 0)1008 if (gamma_size == 0)
1002 gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;1009 gamma_size = fb_helper->crtc_info[i].mode_set.crtc->gamma_size;
1003 if (desired_mode->hdisplay < sizes.fb_width)1010 if (desired_mode->hdisplay + x < sizes.fb_width)
1004 sizes.fb_width = desired_mode->hdisplay;1011 sizes.fb_width = desired_mode->hdisplay + x;
1005 if (desired_mode->vdisplay < sizes.fb_height)1012 if (desired_mode->vdisplay + y < sizes.fb_height)
1006 sizes.fb_height = desired_mode->vdisplay;1013 sizes.fb_height = desired_mode->vdisplay + y;
1007 if (desired_mode->hdisplay > sizes.surface_width)1014 if (desired_mode->hdisplay + x > sizes.surface_width)
1008 sizes.surface_width = desired_mode->hdisplay;1015 sizes.surface_width = desired_mode->hdisplay + x;
1009 if (desired_mode->vdisplay > sizes.surface_height)1016 if (desired_mode->vdisplay + y > sizes.surface_height)
1010 sizes.surface_height = desired_mode->vdisplay;1017 sizes.surface_height = desired_mode->vdisplay + y;
1011 crtc_count++;1018 crtc_count++;
1012 }1019 }
1013 }1020 }
@@ -1307,6 +1314,7 @@ static void drm_enable_connectors(struct drm_fb_helper *fb_helper, · 293 unmodified lines
1307 1314
1308static bool drm_target_cloned(struct drm_fb_helper *fb_helper,1315static bool drm_target_cloned(struct drm_fb_helper *fb_helper,
1309 struct drm_display_mode **modes,1316 struct drm_display_mode **modes,
1317 struct drm_fb_offset *offsets,
1310 bool *enabled, int width, int height)1318 bool *enabled, int width, int height)
1311{1319{
1312 int count, i, j;1320 int count, i, j;
@@ -1378,27 +1386,88 @@ static bool drm_target_cloned(struct drm_fb_helper *fb_helper, · 65 unmodified lines
1378 return false;1386 return false;
1379}1387}
1380 1388
1389static 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
1381static bool drm_target_preferred(struct drm_fb_helper *fb_helper,1421static bool drm_target_preferred(struct drm_fb_helper *fb_helper,
1382 struct drm_display_mode **modes,1422 struct drm_display_mode **modes,
1423 struct drm_fb_offset *offsets,
1383 bool *enabled, int width, int height)1424 bool *enabled, int width, int height)
1384{1425{
1385 struct drm_fb_helper_connector *fb_helper_conn;1426 struct drm_fb_helper_connector *fb_helper_conn;
1386 int i;1427 int i;
1387 1428 uint64_t conn_configured = 0, mask;
1429 int tile_pass = 0;
1430 mask = (1 << fb_helper->connector_count) - 1;
1431retry:
1388 for (i = 0; i < fb_helper->connector_count; i++) {1432 for (i = 0; i < fb_helper->connector_count; i++) {
1389 fb_helper_conn = fb_helper->connector_info[i];1433 fb_helper_conn = fb_helper->connector_info[i];
1390 1434
1391 if (enabled[i] == false)1435 if (conn_configured & (1 << i))
1392 continue;1436 continue;
1393 1437
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 }
1394 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",1463 DRM_DEBUG_KMS("looking for cmdline mode on connector %d\n",
1395 fb_helper_conn->connector->base.id);1464 fb_helper_conn->connector->base.id);
1396 1465
1397 /* got for command line mode first */1466 /* got for command line mode first */
1398 modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height);1467 modes[i] = drm_pick_cmdline_mode(fb_helper_conn, width, height);
1399 if (!modes[i]) {1468 if (!modes[i]) {
1400 DRM_DEBUG_KMS("looking for preferred mode on connector %d\n",1469 DRM_DEBUG_KMS("looking for preferred mode on connector %d %d\n",
1401 fb_helper_conn->connector->base.id);1470 fb_helper_conn->connector->base.id, fb_helper_conn->connector->tile_group ? fb_helper_conn->connector->tile_group->id : 0);
1402 modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height);1471 modes[i] = drm_has_preferred_mode(fb_helper_conn, width, height);
1403 }1472 }
1404 /* No preferred modes, pick one off the list */1473 /* 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
1408 }1477 }
1409 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :1478 DRM_DEBUG_KMS("found mode %s\n", modes[i] ? modes[i]->name :
1410 "none");1479 "none");
1480 conn_configured |= (1 << i);
1481 }
1482
1483 if ((conn_configured & mask) != mask) {
1484 tile_pass++;
1485 goto retry;
1411 }1486 }
1412 return true;1487 return true;
1413}1488}
@@ -1497,6 +1572,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 83 unmodified lines
1497 struct drm_device *dev = fb_helper->dev;1572 struct drm_device *dev = fb_helper->dev;
1498 struct drm_fb_helper_crtc **crtcs;1573 struct drm_fb_helper_crtc **crtcs;
1499 struct drm_display_mode **modes;1574 struct drm_display_mode **modes;
1575 struct drm_fb_offset *offsets;
1500 struct drm_mode_set *modeset;1576 struct drm_mode_set *modeset;
1501 bool *enabled;1577 bool *enabled;
1502 int width, height;1578 int width, height;
@@ -1511,9 +1587,11 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 8 unmodified lines
1511 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);1587 sizeof(struct drm_fb_helper_crtc *), GFP_KERNEL);
1512 modes = kcalloc(dev->mode_config.num_connector,1588 modes = kcalloc(dev->mode_config.num_connector,
1513 sizeof(struct drm_display_mode *), GFP_KERNEL);1589 sizeof(struct drm_display_mode *), GFP_KERNEL);
1590 offsets = kcalloc(dev->mode_config.num_connector,
1591 sizeof(struct drm_fb_offset), GFP_KERNEL);
1514 enabled = kcalloc(dev->mode_config.num_connector,1592 enabled = kcalloc(dev->mode_config.num_connector,
1515 sizeof(bool), GFP_KERNEL);1593 sizeof(bool), GFP_KERNEL);
1516 if (!crtcs || !modes || !enabled) {1594 if (!crtcs || !modes || !enabled || !offsets) {
1517 DRM_ERROR("Memory allocation failed\n");1595 DRM_ERROR("Memory allocation failed\n");
1518 goto out;1596 goto out;
1519 }1597 }
@@ -1523,14 +1601,16 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 3 unmodified lines
1523 1601
1524 if (!(fb_helper->funcs->initial_config &&1602 if (!(fb_helper->funcs->initial_config &&
1525 fb_helper->funcs->initial_config(fb_helper, crtcs, modes,1603 fb_helper->funcs->initial_config(fb_helper, crtcs, modes,
1604 offsets,
1526 enabled, width, height))) {1605 enabled, width, height))) {
1527 memset(modes, 0, dev->mode_config.num_connector*sizeof(modes[0]));1606 memset(modes, 0, dev->mode_config.num_connector*sizeof(modes[0]));
1528 memset(crtcs, 0, dev->mode_config.num_connector*sizeof(crtcs[0]));1607 memset(crtcs, 0, dev->mode_config.num_connector*sizeof(crtcs[0]));
1608 memset(offsets, 0, dev->mode_config.num_connector*sizeof(offsets[0]));
1529 1609
1530 if (!drm_target_cloned(fb_helper,1610 if (!drm_target_cloned(fb_helper, modes, offsets,
1531 modes, enabled, width, height) &&1611 enabled, width, height) &&
1532 !drm_target_preferred(fb_helper,1612 !drm_target_preferred(fb_helper, modes, offsets,
1533 modes, enabled, width, height))1613 enabled, width, height))
1534 DRM_ERROR("Unable to find initial modes\n");1614 DRM_ERROR("Unable to find initial modes\n");
1535 1615
1536 DRM_DEBUG_KMS("picking CRTCs for %dx%d config\n",1616 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
1550 for (i = 0; i < fb_helper->connector_count; i++) {1630 for (i = 0; i < fb_helper->connector_count; i++) {
1551 struct drm_display_mode *mode = modes[i];1631 struct drm_display_mode *mode = modes[i];
1552 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];1632 struct drm_fb_helper_crtc *fb_crtc = crtcs[i];
1633 struct drm_fb_offset *offset = &offsets[i];
1553 modeset = &fb_crtc->mode_set;1634 modeset = &fb_crtc->mode_set;
1554 1635
1555 if (mode && fb_crtc) {1636 if (mode && fb_crtc) {
1556 DRM_DEBUG_KMS("desired mode %s set on crtc %d\n",1637 DRM_DEBUG_KMS("desired mode %s set on crtc %d (%d,%d)\n",
1557 mode->name, fb_crtc->mode_set.crtc->base.id);1638 mode->name, fb_crtc->mode_set.crtc->base.id, offset->x, offset->y);
1558 fb_crtc->desired_mode = mode;1639 fb_crtc->desired_mode = mode;
1640 fb_crtc->x = offset->x;
1641 fb_crtc->y = offset->y;
1559 if (modeset->mode)1642 if (modeset->mode)
1560 drm_mode_destroy(dev, modeset->mode);1643 drm_mode_destroy(dev, modeset->mode);
1561 modeset->mode = drm_mode_duplicate(dev,1644 modeset->mode = drm_mode_duplicate(dev,
1562 fb_crtc->desired_mode);1645 fb_crtc->desired_mode);
1563 modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;1646 modeset->connectors[modeset->num_connectors++] = fb_helper->connector_info[i]->connector;
1564 modeset->fb = fb_helper->fb;1647 modeset->fb = fb_helper->fb;
1648 modeset->x = offset->x;
1649 modeset->y = offset->y;
1565 }1650 }
1566 }1651 }
1567 1652
@@ -1570,7 +1655,6 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 2 unmodified lines
1570 modeset = &fb_helper->crtc_info[i].mode_set;1655 modeset = &fb_helper->crtc_info[i].mode_set;
1571 if (modeset->num_connectors == 0) {1656 if (modeset->num_connectors == 0) {
1572 BUG_ON(modeset->fb);1657 BUG_ON(modeset->fb);
1573 BUG_ON(modeset->num_connectors);
1574 if (modeset->mode)1658 if (modeset->mode)
1575 drm_mode_destroy(dev, modeset->mode);1659 drm_mode_destroy(dev, modeset->mode);
1576 modeset->mode = NULL;1660 modeset->mode = NULL;
@@ -1579,6 +1663,7 @@ static void drm_setup_crtcs(struct drm_fb_helper *fb_helper) · 2 unmodified lines
1579out:1663out:
1580 kfree(crtcs);1664 kfree(crtcs);
1581 kfree(modes);1665 kfree(modes);
1666 kfree(offsets);
1582 kfree(enabled);1667 kfree(enabled);
1583}1668}
1584 1669
drivers/gpu/drm/drm_flip_work.c+74−31
@@ -24,6 +24,44 @@ · 23 unmodified lines
24#include "drmP.h"24#include "drmP.h"
25#include "drm_flip_work.h"25#include "drm_flip_work.h"
26 26
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 */
34struct 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}
44EXPORT_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 */
54void 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}
63EXPORT_SYMBOL(drm_flip_work_queue_task);
64
27/**65/**
28 * drm_flip_work_queue - queue work66 * drm_flip_work_queue - queue work
29 * @work: the flip-work67 * @work: the flip-work
@@ -34,10 +72,14 @@ · 4 unmodified lines
34 */72 */
35void drm_flip_work_queue(struct drm_flip_work *work, void *val)73void drm_flip_work_queue(struct drm_flip_work *work, void *val)
36{74{
37 if (kfifo_put(&work->fifo, val)) {75 struct drm_flip_task *task;
38 atomic_inc(&work->pending);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);
39 } else {81 } else {
40 DRM_ERROR("%s fifo full!\n", work->name);82 DRM_ERROR("%s could not allocate task!\n", work->name);
41 work->func(work, val);83 work->func(work, val);
42 }84 }
43}85}
@@ -56,9 +98,12 @@ EXPORT_SYMBOL(drm_flip_work_queue); · 12 unmodified lines
56void drm_flip_work_commit(struct drm_flip_work *work,98void drm_flip_work_commit(struct drm_flip_work *work,
57 struct workqueue_struct *wq)99 struct workqueue_struct *wq)
58{100{
59 uint32_t pending = atomic_read(&work->pending);101 unsigned long flags;
60 atomic_add(pending, &work->count);102
61 atomic_sub(pending, &work->pending);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);
62 queue_work(wq, &work->worker);107 queue_work(wq, &work->worker);
63}108}
64EXPORT_SYMBOL(drm_flip_work_commit);109EXPORT_SYMBOL(drm_flip_work_commit);
@@ -66,47 +111,46 @@ EXPORT_SYMBOL(drm_flip_work_commit); · 1 unmodified line
66static void flip_worker(struct work_struct *w)111static void flip_worker(struct work_struct *w)
67{112{
68 struct drm_flip_work *work = container_of(w, struct drm_flip_work, worker);113 struct drm_flip_work *work = container_of(w, struct drm_flip_work, worker);
69 uint32_t count = atomic_read(&work->count);114 struct list_head tasks;
70 void *val = NULL;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);
71 125
72 atomic_sub(count, &work->count);126 if (list_empty(&tasks))
127 break;
73 128
74 while(count--)129 list_for_each_entry_safe(task, tmp, &tasks, node) {
75 if (!WARN_ON(!kfifo_get(&work->fifo, &val)))130 work->func(work, task->data);
76 work->func(work, val);131 kfree(task);
132 }
133 }
77}134}
78 135
79/**136/**
80 * drm_flip_work_init - initialize flip-work137 * drm_flip_work_init - initialize flip-work
81 * @work: the flip-work to initialize138 * @work: the flip-work to initialize
82 * @size: the max queue depth
83 * @name: debug name139 * @name: debug name
84 * @func: the callback work function140 * @func: the callback work function
85 *141 *
86 * Initializes/allocates resources for the flip-work142 * Initializes/allocates resources for the flip-work
87 *
88 * RETURNS:
89 * Zero on success, error code on failure.
90 */143 */
91int drm_flip_work_init(struct drm_flip_work *work, int size,144void drm_flip_work_init(struct drm_flip_work *work,
92 const char *name, drm_flip_func_t func)145 const char *name, drm_flip_func_t func)
93{146{
94 int ret;
95
96 work->name = name;147 work->name = name;
97 atomic_set(&work->count, 0);148 INIT_LIST_HEAD(&work->queued);
98 atomic_set(&work->pending, 0);149 INIT_LIST_HEAD(&work->commited);
150 spin_lock_init(&work->lock);
99 work->func = func;151 work->func = func;
100 152
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
107 INIT_WORK(&work->worker, flip_worker);153 INIT_WORK(&work->worker, flip_worker);
108
109 return 0;
110}154}
111EXPORT_SYMBOL(drm_flip_work_init);155EXPORT_SYMBOL(drm_flip_work_init);
112 156
@@ -118,7 +162,6 @@ EXPORT_SYMBOL(drm_flip_work_init); · 5 unmodified lines
118 */162 */
119void drm_flip_work_cleanup(struct drm_flip_work *work)163void drm_flip_work_cleanup(struct drm_flip_work *work)
120{164{
121 WARN_ON(!kfifo_is_empty(&work->fifo));165 WARN_ON(!list_empty(&work->queued) || !list_empty(&work->commited));
122 kfifo_free(&work->fifo);
123}166}
124EXPORT_SYMBOL(drm_flip_work_cleanup);167EXPORT_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
515 size_t total;515 size_t total;
516 ssize_t ret;516 ssize_t ret;
517 517
518 ret = wait_event_interruptible(file_priv->event_wait,518 if ((filp->f_flags & O_NONBLOCK) == 0) {
519 !list_empty(&file_priv->event_list));519 ret = wait_event_interruptible(file_priv->event_wait,
520 if (ret < 0)520 !list_empty(&file_priv->event_list));
521 return ret;521 if (ret < 0)
522 return ret;
523 }
522 524
523 total = 0;525 total = 0;
524 while (drm_dequeue_event(file_priv, total, count, &e)) {526 while (drm_dequeue_event(file_priv, total, count, &e)) {
525 if (copy_to_user(buffer + total,527 if (copy_to_user(buffer + total,
526 e->event, e->event->length)) {528 e->event, e->event->length)) {
527 total = -EFAULT;529 total = -EFAULT;
530 e->destroy(e);
528 break;531 break;
529 }532 }
530 533
@@ -532,7 +535,7 @@ ssize_t drm_read(struct file *filp, char __user *buffer, · 1 unmodified line
532 e->destroy(e);535 e->destroy(e);
533 }536 }
534 537
535 return total;538 return total ?: -EAGAIN;
536}539}
537EXPORT_SYMBOL(drm_read);540EXPORT_SYMBOL(drm_read);
538 541
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
188}188}
189 189
190/**190/**
191 * drm_gem_object_free - release resources bound to userspace handles191 * drm_gem_object_handle_free - release resources bound to userspace handles
192 * @obj: GEM object to clean up.192 * @obj: GEM object to clean up.
193 *193 *
194 * Called after the last handle to the object has been closed194 * Called after the last handle to the object has been closed
@@ -309,7 +309,7 @@ EXPORT_SYMBOL(drm_gem_dumb_destroy); · 114 unmodified lines
309 * drm_gem_handle_create_tail - internal functions to create a handle309 * drm_gem_handle_create_tail - internal functions to create a handle
310 * @file_priv: drm file-private structure to register the handle for310 * @file_priv: drm file-private structure to register the handle for
311 * @obj: object to register311 * @obj: object to register
312 * @handlep: pionter to return the created handle to the caller312 * @handlep: pointer to return the created handle to the caller
313 * 313 *
314 * This expects the dev->object_name_lock to be held already and will drop it314 * This expects the dev->object_name_lock to be held already and will drop it
315 * before returning. Used to avoid races in establishing new handles when315 * 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
362}362}
363 363
364/**364/**
365 * gem_handle_create - create a gem handle for an object365 * drm_gem_handle_create - create a gem handle for an object
366 * @file_priv: drm file-private structure to register the handle for366 * @file_priv: drm file-private structure to register the handle for
367 * @obj: object to register367 * @obj: object to register
368 * @handlep: pionter to return the created handle to the caller368 * @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
371 * to the object, which includes a regular reference count. Callers371 * to the object, which includes a regular reference count. Callers
372 * will likely want to dereference the object afterwards.372 * will likely want to dereference the object afterwards.
373 */373 */
374int374int drm_gem_handle_create(struct drm_file *file_priv,
375drm_gem_handle_create(struct drm_file *file_priv,375 struct drm_gem_object *obj,
376 struct drm_gem_object *obj,376 u32 *handlep)
377 u32 *handlep)
378{377{
379 mutex_lock(&obj->dev->object_name_lock);378 mutex_lock(&obj->dev->object_name_lock);
380 379
drivers/gpu/drm/drm_gem_cma_helper.c+215−44
@@ -29,18 +29,31 @@ · 28 unmodified lines
29#include <drm/drm_gem_cma_helper.h>29#include <drm/drm_gem_cma_helper.h>
30#include <drm/drm_vma_manager.h>30#include <drm/drm_vma_manager.h>
31 31
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/**
33 * __drm_gem_cma_create - Create a GEM CMA object without allocating memory44 * __drm_gem_cma_create - Create a GEM CMA object without allocating memory
34 * @drm: The drm device45 * @drm: DRM device
35 * @size: The GEM object size46 * @size: size of the object to allocate
36 *47 *
37 * This function creates and initializes a GEM CMA object of the given size, but48 * This function creates and initializes a GEM CMA object of the given size,
38 * doesn't allocate any memory to back the object.49 * but doesn't allocate any memory to back the object.
39 *50 *
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.
41 */54 */
42static struct drm_gem_cma_object *55static 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)
44{57{
45 struct drm_gem_cma_object *cma_obj;58 struct drm_gem_cma_object *cma_obj;
46 struct drm_gem_object *gem_obj;59 struct drm_gem_object *gem_obj;
@@ -69,14 +82,21 @@ error: · 22 unmodified lines
69 return ERR_PTR(ret);82 return ERR_PTR(ret);
70}83}
71 84
72/*85/**
73 * drm_gem_cma_create - allocate an object with the given size86 * 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.
74 *93 *
75 * returns a struct drm_gem_cma_object* on success or ERR_PTR values94 * Returns:
76 * on failure.95 * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
96 * error code on failure.
77 */97 */
78struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,98struct drm_gem_cma_object *drm_gem_cma_create(struct drm_device *drm,
79 unsigned int size)99 size_t size)
80{100{
81 struct drm_gem_cma_object *cma_obj;101 struct drm_gem_cma_object *cma_obj;
82 int ret;102 int ret;
@@ -104,17 +124,26 @@ error: · 21 unmodified lines
104}124}
105EXPORT_SYMBOL_GPL(drm_gem_cma_create);125EXPORT_SYMBOL_GPL(drm_gem_cma_create);
106 126
107/*127/**
108 * drm_gem_cma_create_with_handle - allocate an object with the given128 * drm_gem_cma_create_with_handle - allocate an object with the given size and
109 * size and create a gem handle on it129 * 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.
110 *138 *
111 * returns a struct drm_gem_cma_object* on success or ERR_PTR values139 * Returns:
112 * on failure.140 * A struct drm_gem_cma_object * on success or an ERR_PTR()-encoded negative
141 * error code on failure.
113 */142 */
114static struct drm_gem_cma_object *drm_gem_cma_create_with_handle(143static struct drm_gem_cma_object *
115 struct drm_file *file_priv,144drm_gem_cma_create_with_handle(struct drm_file *file_priv,
116 struct drm_device *drm, unsigned int size,145 struct drm_device *drm, size_t size,
117 unsigned int *handle)146 uint32_t *handle)
118{147{
119 struct drm_gem_cma_object *cma_obj;148 struct drm_gem_cma_object *cma_obj;
120 struct drm_gem_object *gem_obj;149 struct drm_gem_object *gem_obj;
@@ -145,16 +174,19 @@ err_handle_create: · 24 unmodified lines
145 return ERR_PTR(ret);174 return ERR_PTR(ret);
146}175}
147 176
148/*177/**
149 * drm_gem_cma_free_object - (struct drm_driver)->gem_free_object callback178 * drm_gem_cma_free_object - free resources associated with a CMA GEM object
150 * function179 * @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.
151 */185 */
152void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)186void drm_gem_cma_free_object(struct drm_gem_object *gem_obj)
153{187{
154 struct drm_gem_cma_object *cma_obj;188 struct drm_gem_cma_object *cma_obj;
155 189
156 drm_gem_free_mmap_offset(gem_obj);
157
158 cma_obj = to_drm_gem_cma_obj(gem_obj);190 cma_obj = to_drm_gem_cma_obj(gem_obj);
159 191
160 if (cma_obj->vaddr) {192 if (cma_obj->vaddr) {
@@ -170,18 +202,26 @@ void drm_gem_cma_free_object(struct drm_gem_object *gem_obj) · 9 unmodified lines
170}202}
171EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);203EXPORT_SYMBOL_GPL(drm_gem_cma_free_object);
172 204
173/*205/**
174 * drm_gem_cma_dumb_create - (struct drm_driver)->dumb_create callback206 * drm_gem_cma_dumb_create_internal - create a dumb buffer object
175 * function207 * @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.
176 *215 *
177 * This aligns the pitch and size arguments to the minimum required. wrap216 * Returns:
178 * this into your own function if you need bigger alignment.217 * 0 on success or a negative error code on failure.
179 */218 */
180int drm_gem_cma_dumb_create(struct drm_file *file_priv,219int drm_gem_cma_dumb_create_internal(struct drm_file *file_priv,
181 struct drm_device *dev, struct drm_mode_create_dumb *args)220 struct drm_device *drm,
221 struct drm_mode_create_dumb *args)
182{222{
223 unsigned int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
183 struct drm_gem_cma_object *cma_obj;224 struct drm_gem_cma_object *cma_obj;
184 int min_pitch = DIV_ROUND_UP(args->width * args->bpp, 8);
185 225
186 if (args->pitch < min_pitch)226 if (args->pitch < min_pitch)
187 args->pitch = min_pitch;227 args->pitch = min_pitch;
@@ -189,18 +229,63 @@ int drm_gem_cma_dumb_create(struct drm_file *file_priv, · 1 unmodified line
189 if (args->size < args->pitch * args->height)229 if (args->size < args->pitch * args->height)
190 args->size = args->pitch * args->height;230 args->size = args->pitch * args->height;
191 231
192 cma_obj = drm_gem_cma_create_with_handle(file_priv, dev,232 cma_obj = drm_gem_cma_create_with_handle(file_priv, drm, args->size,
193 args->size, &args->handle);233 &args->handle);
234 return PTR_ERR_OR_ZERO(cma_obj);
235}
236EXPORT_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 */
256int 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);
194 return PTR_ERR_OR_ZERO(cma_obj);267 return PTR_ERR_OR_ZERO(cma_obj);
195}268}
196EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);269EXPORT_SYMBOL_GPL(drm_gem_cma_dumb_create);
197 270
198/*271/**
199 * drm_gem_cma_dumb_map_offset - (struct drm_driver)->dumb_map_offset callback272 * drm_gem_cma_dumb_map_offset - return the fake mmap offset for a CMA GEM
200 * function273 * 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.
201 */285 */
202int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv,286int 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)
204{289{
205 struct drm_gem_object *gem_obj;290 struct drm_gem_object *gem_obj;
206 291
@@ -208,7 +293,7 @@ int drm_gem_cma_dumb_map_offset(struct drm_file *file_priv, · 1 unmodified line
208 293
209 gem_obj = drm_gem_object_lookup(drm, file_priv, handle);294 gem_obj = drm_gem_object_lookup(drm, file_priv, handle);
210 if (!gem_obj) {295 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");
212 mutex_unlock(&drm->struct_mutex);297 mutex_unlock(&drm->struct_mutex);
213 return -EINVAL;298 return -EINVAL;
214 }299 }
@@ -251,8 +336,20 @@ static int drm_gem_cma_mmap_obj(struct drm_gem_cma_object *cma_obj, · 36 unmodified lines
251 return ret;336 return ret;
252}337}
253 338
254/*339/**
255 * drm_gem_cma_mmap - (struct file_operation)->mmap callback function340 * 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.
256 */353 */
257int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)354int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma)
258{355{
@@ -272,7 +369,16 @@ int drm_gem_cma_mmap(struct file *filp, struct vm_area_struct *vma) · 13 unmodified lines
272EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);369EXPORT_SYMBOL_GPL(drm_gem_cma_mmap);
273 370
274#ifdef CONFIG_DEBUG_FS371#ifdef CONFIG_DEBUG_FS
275void 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 */
380void drm_gem_cma_describe(struct drm_gem_cma_object *cma_obj,
381 struct seq_file *m)
276{382{
277 struct drm_gem_object *obj = &cma_obj->base;383 struct drm_gem_object *obj = &cma_obj->base;
278 struct drm_device *dev = obj->dev;384 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
291EXPORT_SYMBOL_GPL(drm_gem_cma_describe);397EXPORT_SYMBOL_GPL(drm_gem_cma_describe);
292#endif398#endif
293 399
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 */
295struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj)412struct sg_table *drm_gem_cma_prime_get_sg_table(struct drm_gem_object *obj)
296{413{
297 struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);414 struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);
@@ -315,6 +432,23 @@ out: · 17 unmodified lines
315}432}
316EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table);433EXPORT_SYMBOL_GPL(drm_gem_cma_prime_get_sg_table);
317 434
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 */
318struct drm_gem_object *452struct drm_gem_object *
319drm_gem_cma_prime_import_sg_table(struct drm_device *dev,453drm_gem_cma_prime_import_sg_table(struct drm_device *dev,
320 struct dma_buf_attachment *attach,454 struct dma_buf_attachment *attach,
@@ -339,6 +473,18 @@ drm_gem_cma_prime_import_sg_table(struct drm_device *dev, · 18 unmodified lines
339}473}
340EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);474EXPORT_SYMBOL_GPL(drm_gem_cma_prime_import_sg_table);
341 475
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 */
342int drm_gem_cma_prime_mmap(struct drm_gem_object *obj,488int drm_gem_cma_prime_mmap(struct drm_gem_object *obj,
343 struct vm_area_struct *vma)489 struct vm_area_struct *vma)
344{490{
@@ -357,6 +503,20 @@ int drm_gem_cma_prime_mmap(struct drm_gem_object *obj, · 12 unmodified lines
357}503}
358EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);504EXPORT_SYMBOL_GPL(drm_gem_cma_prime_mmap);
359 505
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 */
360void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj)520void *drm_gem_cma_prime_vmap(struct drm_gem_object *obj)
361{521{
362 struct drm_gem_cma_object *cma_obj = to_drm_gem_cma_obj(obj);522 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
365}525}
366EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap);526EXPORT_SYMBOL_GPL(drm_gem_cma_prime_vmap);
367 527
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 */
368void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr)539void drm_gem_cma_prime_vunmap(struct drm_gem_object *obj, void *vaddr)
369{540{
370 /* Nothing to do */541 /* 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
166 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);166 spin_lock_irqsave(&dev->vblank_time_lock, irqflags);
167 167
168 /*168 /*
169 * If the vblank interrupt was already disbled update the count169 * If the vblank interrupt was already disabled update the count
170 * and timestamp to maintain the appearance that the counter170 * and timestamp to maintain the appearance that the counter
171 * has been ticking all along until this time. This makes the171 * has been ticking all along until this time. This makes the
172 * count account for the entire time between drm_vblank_on() and172 * 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
1029{1029{
1030 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];1030 struct drm_vblank_crtc *vblank = &dev->vblank[crtc];
1031 1031
1032 BUG_ON(atomic_read(&vblank->refcount) == 0);1032 if (WARN_ON(atomic_read(&vblank->refcount) == 0))
1033 return;
1033 1034
1034 if (WARN_ON(crtc >= dev->num_crtcs))1035 if (WARN_ON(crtc >= dev->num_crtcs))
1035 return;1036 return;
@@ -1190,7 +1191,7 @@ EXPORT_SYMBOL(drm_crtc_vblank_off); · 154 unmodified lines
1190 *1191 *
1191 * This functions restores the vblank interrupt state captured with1192 * This functions restores the vblank interrupt state captured with
1192 * drm_vblank_off() again. Note that calls to drm_vblank_on() and1193 * 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 called1194 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
1194 * in driver load code to reflect the current hardware state of the crtc.1195 * in driver load code to reflect the current hardware state of the crtc.
1195 *1196 *
1196 * This is the legacy version of drm_crtc_vblank_on().1197 * This is the legacy version of drm_crtc_vblank_on().
@@ -1237,7 +1238,7 @@ EXPORT_SYMBOL(drm_vblank_on); · 40 unmodified lines
1237 *1238 *
1238 * This functions restores the vblank interrupt state captured with1239 * This functions restores the vblank interrupt state captured with
1239 * drm_vblank_off() again. Note that calls to drm_vblank_on() and1240 * 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 called1241 * drm_vblank_off() can be unbalanced and so can also be unconditionally called
1241 * in driver load code to reflect the current hardware state of the crtc.1242 * in driver load code to reflect the current hardware state of the crtc.
1242 *1243 *
1243 * This is the native kms version of drm_vblank_on().1244 * 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
35 35
36#include <video/mipi_display.h>36#include <video/mipi_display.h>
37 37
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
38static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)48static int mipi_dsi_device_match(struct device *dev, struct device_driver *drv)
39{49{
40 return of_driver_match_device(dev, drv);50 return of_driver_match_device(dev, drv);
@@ -57,6 +67,29 @@ static struct bus_type mipi_dsi_bus_type = { · 16 unmodified lines
57 .pm = &mipi_dsi_device_pm_ops,67 .pm = &mipi_dsi_device_pm_ops,
58};68};
59 69
70static 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 */
83struct 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}
91EXPORT_SYMBOL(of_find_mipi_dsi_device_by_node);
92
60static void mipi_dsi_dev_release(struct device *dev)93static void mipi_dsi_dev_release(struct device *dev)
61{94{
62 struct mipi_dsi_device *dsi = to_mipi_dsi_device(dev);95 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
198}231}
199EXPORT_SYMBOL(mipi_dsi_detach);232EXPORT_SYMBOL(mipi_dsi_detach);
200 233
234static 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
201/**248/**
202 * mipi_dsi_dcs_write - send DCS write command249 * mipi_dsi_packet_format_is_short - check if a packet is of the short format
203 * @dsi: DSI device250 * @type: MIPI DSI data type of the packet
204 * @data: pointer to the command followed by parameters251 *
205 * @len: length of @data252 * Return: true if the packet for the given data type is a short packet, false
253 * otherwise.
206 */254 */
207ssize_t mipi_dsi_dcs_write(struct mipi_dsi_device *dsi, const void *data,255bool mipi_dsi_packet_format_is_short(u8 type)
208 size_t len)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}
282EXPORT_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 */
291bool 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}
313EXPORT_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 */
323int 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}
366EXPORT_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 */
377int 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}
390EXPORT_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 */
404ssize_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}
433EXPORT_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 */
449ssize_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}
479EXPORT_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 */
493ssize_t mipi_dsi_dcs_write_buffer(struct mipi_dsi_device *dsi,
494 const void *data, size_t len)
209{495{
210 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
211 struct mipi_dsi_msg msg = {496 struct mipi_dsi_msg msg = {
212 .channel = dsi->channel,497 .channel = dsi->channel,
213 .tx_buf = data,498 .tx_buf = data,
214 .tx_len = len499 .tx_len = len
215 };500 };
216 501
217 if (!ops || !ops->transfer)
218 return -ENOSYS;
219
220 switch (len) {502 switch (len) {
221 case 0:503 case 0:
222 return -EINVAL;504 return -EINVAL;
505
223 case 1:506 case 1:
224 msg.type = MIPI_DSI_DCS_SHORT_WRITE;507 msg.type = MIPI_DSI_DCS_SHORT_WRITE;
225 break;508 break;
509
226 case 2:510 case 2:
227 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;511 msg.type = MIPI_DSI_DCS_SHORT_WRITE_PARAM;
228 break;512 break;
513
229 default:514 default:
230 msg.type = MIPI_DSI_DCS_LONG_WRITE;515 msg.type = MIPI_DSI_DCS_LONG_WRITE;
231 break;516 break;
232 }517 }
233 518
234 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)519 return mipi_dsi_device_transfer(dsi, &msg);
235 msg.flags = MIPI_DSI_MSG_USE_LPM;520}
521EXPORT_SYMBOL(mipi_dsi_dcs_write_buffer);
236 522
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 */
536ssize_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;
238}564}
239EXPORT_SYMBOL(mipi_dsi_dcs_write);565EXPORT_SYMBOL(mipi_dsi_dcs_write);
240 566
241/**567/**
242 * mipi_dsi_dcs_read - send DCS read request command568 * mipi_dsi_dcs_read() - send DCS read request command
243 * @dsi: DSI device569 * @dsi: DSI peripheral device
244 * @cmd: DCS read command570 * @cmd: DCS command
245 * @data: pointer to read buffer571 * @data: buffer in which to receive data
246 * @len: length of @data572 * @len: size of receive buffer
247 *573 *
248 * Function returns number of read bytes or error code.574 * Return: The number of bytes read or a negative error code on failure.
249 */575 */
250ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,576ssize_t mipi_dsi_dcs_read(struct mipi_dsi_device *dsi, u8 cmd, void *data,
251 size_t len)577 size_t len)
252{578{
253 const struct mipi_dsi_host_ops *ops = dsi->host->ops;
254 struct mipi_dsi_msg msg = {579 struct mipi_dsi_msg msg = {
255 .channel = dsi->channel,580 .channel = dsi->channel,
256 .type = MIPI_DSI_DCS_READ,581 .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
260 .rx_len = len585 .rx_len = len
261 };586 };
262 587
263 if (!ops || !ops->transfer)588 return mipi_dsi_device_transfer(dsi, &msg);
264 return -ENOSYS;589}
590EXPORT_SYMBOL(mipi_dsi_dcs_read);
265 591
266 if (dsi->mode_flags & MIPI_DSI_MODE_LPM)592/**
267 msg.flags = MIPI_DSI_MSG_USE_LPM;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 */
598int 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;
268 605
269 return ops->transfer(dsi->host, &msg);606 return 0;
270}607}
271EXPORT_SYMBOL(mipi_dsi_dcs_read);608EXPORT_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 */
616int 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}
626EXPORT_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 */
636int 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}
651EXPORT_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 */
661int 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}
676EXPORT_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 */
685int 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}
695EXPORT_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 */
704int 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}
714EXPORT_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 */
723int 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}
733EXPORT_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 */
742int 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}
752EXPORT_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 */
763int 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}
776EXPORT_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 */
787int 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}
800EXPORT_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 */
809int 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}
819EXPORT_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 */
829int 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}
842EXPORT_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 */
852int 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}
863EXPORT_SYMBOL(mipi_dsi_dcs_set_pixel_format);
272 864
273static int mipi_dsi_drv_probe(struct device *dev)865static int mipi_dsi_drv_probe(struct device *dev)
274{866{
@@ -295,12 +887,18 @@ static void mipi_dsi_drv_shutdown(struct device *dev) · 20 unmodified lines
295}887}
296 888
297/**889/**
298 * mipi_dsi_driver_register - register a driver for DSI devices890 * mipi_dsi_driver_register_full() - register a driver for DSI devices
299 * @drv: DSI driver structure891 * @drv: DSI driver structure
892 * @owner: owner module
893 *
894 * Return: 0 on success or a negative error code on failure.
300 */895 */
301int mipi_dsi_driver_register(struct mipi_dsi_driver *drv)896int mipi_dsi_driver_register_full(struct mipi_dsi_driver *drv,
897 struct module *owner)
302{898{
303 drv->driver.bus = &mipi_dsi_bus_type;899 drv->driver.bus = &mipi_dsi_bus_type;
900 drv->driver.owner = owner;
901
304 if (drv->probe)902 if (drv->probe)
305 drv->driver.probe = mipi_dsi_drv_probe;903 drv->driver.probe = mipi_dsi_drv_probe;
306 if (drv->remove)904 if (drv->remove)
@@ -310,11 +908,13 @@ int mipi_dsi_driver_register(struct mipi_dsi_driver *drv) · 3 unmodified lines
310 908
311 return driver_register(&drv->driver);909 return driver_register(&drv->driver);
312}910}
313EXPORT_SYMBOL(mipi_dsi_driver_register);911EXPORT_SYMBOL(mipi_dsi_driver_register_full);
314 912
315/**913/**
316 * mipi_dsi_driver_unregister - unregister a driver for DSI devices914 * mipi_dsi_driver_unregister() - unregister a driver for DSI devices
317 * @drv: DSI driver structure915 * @drv: DSI driver structure
916 *
917 * Return: 0 on success or a negative error code on failure.
318 */918 */
319void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)919void mipi_dsi_driver_unregister(struct mipi_dsi_driver *drv)
320{920{
drivers/gpu/drm/drm_modes.c+1−1
@@ -914,7 +914,7 @@ EXPORT_SYMBOL(drm_mode_equal_no_clocks_no_stereo); · 913 unmodified lines
914 *914 *
915 * This function is a helper which can be used to validate modes against size915 * This function is a helper which can be used to validate modes against size
916 * limitations of the DRM device/connector. If a mode is too big its status916 * 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 list917 * member is updated with the appropriate validation failure code. The list
918 * itself is not changed.918 * itself is not changed.
919 */919 */
920void drm_mode_validate_size(struct drm_device *dev,920void 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
157EXPORT_SYMBOL(drm_modeset_unlock_all);157EXPORT_SYMBOL(drm_modeset_unlock_all);
158 158
159/**159/**
160 * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx160 * drm_modeset_lock_crtc - lock crtc with hidden acquire ctx for a plane update
161 * @crtc: drm crtc161 * @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.
162 *168 *
163 * This function locks the given crtc using a hidden acquire context. This is169 * Note that @plane can be NULL, e.g. when the cursor support hasn't yet been
164 * necessary so that drivers internally using the atomic interfaces can grab170 * converted to universal planes yet.
165 * further locks with the lock acquire context.
166 */171 */
167void drm_modeset_lock_crtc(struct drm_crtc *crtc)172void drm_modeset_lock_crtc(struct drm_crtc *crtc,
173 struct drm_plane *plane)
168{174{
169 struct drm_modeset_acquire_ctx *ctx;175 struct drm_modeset_acquire_ctx *ctx;
170 int ret;176 int ret;
@@ -180,6 +186,18 @@ retry: · 9 unmodified lines
180 if (ret)186 if (ret)
181 goto fail;187 goto fail;
182 188
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
183 WARN_ON(crtc->acquire_ctx);201 WARN_ON(crtc->acquire_ctx);
184 202
185 /* now we hold the locks, so now that it is safe, stash the203 /* 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
437}455}
438EXPORT_SYMBOL(drm_modeset_unlock);456EXPORT_SYMBOL(drm_modeset_unlock);
439 457
440/* Temporary.. until we have sufficiently fine grained locking, there458/* In some legacy codepaths it's convenient to just grab all the crtc and plane
441 * are a couple scenarios where it is convenient to grab all crtc locks.459 * related locks. */
442 * It is planned to remove this:
443 */
444int drm_modeset_lock_all_crtcs(struct drm_device *dev,460int drm_modeset_lock_all_crtcs(struct drm_device *dev,
445 struct drm_modeset_acquire_ctx *ctx)461 struct drm_modeset_acquire_ctx *ctx)
446{462{
447 struct drm_mode_config *config = &dev->mode_config;463 struct drm_mode_config *config = &dev->mode_config;
448 struct drm_crtc *crtc;464 struct drm_crtc *crtc;
465 struct drm_plane *plane;
449 int ret = 0;466 int ret = 0;
450 467
451 list_for_each_entry(crtc, &config->crtc_list, head) {468 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
454 return ret;471 return ret;
455 }472 }
456 473
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
457 return 0;480 return 0;
458}481}
459EXPORT_SYMBOL(drm_modeset_lock_all_crtcs);482EXPORT_SYMBOL(drm_modeset_lock_all_crtcs);
drivers/gpu/drm/drm_plane_helper.c+202−1
@@ -27,10 +27,38 @@ · 26 unmodified lines
27#include <drm/drmP.h>27#include <drm/drmP.h>
28#include <drm/drm_plane_helper.h>28#include <drm/drm_plane_helper.h>
29#include <drm/drm_rect.h>29#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>
31 33
32#define SUBPIXEL_MASK 0xffff34#define SUBPIXEL_MASK 0xffff
33 35
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
34/*62/*
35 * This is the minimal list of formats that seem to be safe for modeset use63 * This is the minimal list of formats that seem to be safe for modeset use
36 * with all current DRM drivers. Most hardware can actually support more64 * 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
127 return -ERANGE;155 return -ERANGE;
128 }156 }
129 157
158 if (!fb) {
159 *visible = false;
160 return 0;
161 }
162
130 *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);163 *visible = drm_rect_clip_scaled(src, dest, clip, hscale, vscale);
131 if (!*visible)164 if (!*visible)
132 /*165 /*
@@ -369,3 +402,171 @@ int drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc, · 236 unmodified lines
369 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs);402 return drm_crtc_init_with_planes(dev, crtc, primary, NULL, funcs);
370}403}
371EXPORT_SYMBOL(drm_crtc_init);404EXPORT_SYMBOL(drm_crtc_init);
405
406int 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);
469out:
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 */
503int 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}
534EXPORT_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 */
549int 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}
572EXPORT_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
328 */328 */
329 329
330/**330/**
331 * drm_gem_prime_export - helper library implemention of the export callback331 * drm_gem_prime_export - helper library implementation of the export callback
332 * @dev: drm_device to export from332 * @dev: drm_device to export from
333 * @obj: GEM object to export333 * @obj: GEM object to export
334 * @flags: flags like DRM_CLOEXEC334 * @flags: flags like DRM_CLOEXEC
@@ -483,7 +483,7 @@ out_unlock: · 148 unmodified lines
483EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);483EXPORT_SYMBOL(drm_gem_prime_handle_to_fd);
484 484
485/**485/**
486 * drm_gem_prime_import - helper library implemention of the import callback486 * drm_gem_prime_import - helper library implementation of the import callback
487 * @dev: drm_device to import into487 * @dev: drm_device to import into
488 * @dma_buf: dma-buf object to import488 * @dma_buf: dma-buf object to import
489 *489 *
@@ -669,7 +669,7 @@ int drm_prime_fd_to_handle_ioctl(struct drm_device *dev, void *data, · 179 unmodified lines
669 * the driver is responsible for mapping the pages into the669 * the driver is responsible for mapping the pages into the
670 * importers address space for use with dma_buf itself.670 * importers address space for use with dma_buf itself.
671 */671 */
672struct sg_table *drm_prime_pages_to_sg(struct page **pages, int nr_pages)672struct sg_table *drm_prime_pages_to_sg(struct page **pages, unsigned int nr_pages)
673{673{
674 struct sg_table *sg = NULL;674 struct sg_table *sg = NULL;
675 int ret;675 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
118 mode->status = MODE_UNVERIFIED;118 mode->status = MODE_UNVERIFIED;
119 119
120 if (connector->force) {120 if (connector->force) {
121 if (connector->force == DRM_FORCE_ON)121 if (connector->force == DRM_FORCE_ON ||
122 connector->force == DRM_FORCE_ON_DIGITAL)
122 connector->status = connector_status_connected;123 connector->status = connector_status_connected;
123 else124 else
124 connector->status = connector_status_disconnected;125 connector->status = connector_status_disconnected;
drivers/gpu/drm/exynos/exynos_dp_core.c+45−87
@@ -30,12 +30,17 @@ · 29 unmodified lines
30#include <drm/drm_panel.h>30#include <drm/drm_panel.h>
31#include <drm/bridge/ptn3460.h>31#include <drm/bridge/ptn3460.h>
32 32
33#include "exynos_drm_drv.h"
34#include "exynos_dp_core.h"33#include "exynos_dp_core.h"
35 34
36#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \35#define ctx_from_connector(c) container_of(c, struct exynos_dp_device, \
37 connector)36 connector)
38 37
38static inline struct exynos_dp_device *
39display_to_dp(struct exynos_drm_display *d)
40{
41 return container_of(d, struct exynos_dp_device, display);
42}
43
39struct bridge_init {44struct bridge_init {
40 struct i2c_client *client;45 struct i2c_client *client;
41 struct device_node *node;46 struct device_node *node;
@@ -882,7 +887,7 @@ static void exynos_dp_hotplug(struct work_struct *work) · 840 unmodified lines
882 887
883static void exynos_dp_commit(struct exynos_drm_display *display)888static void exynos_dp_commit(struct exynos_drm_display *display)
884{889{
885 struct exynos_dp_device *dp = display->ctx;890 struct exynos_dp_device *dp = display_to_dp(display);
886 int ret;891 int ret;
887 892
888 /* Keep the panel disabled while we configure video */893 /* 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
1020static int exynos_dp_create_connector(struct exynos_drm_display *display,1025static int exynos_dp_create_connector(struct exynos_drm_display *display,
1021 struct drm_encoder *encoder)1026 struct drm_encoder *encoder)
1022{1027{
1023 struct exynos_dp_device *dp = display->ctx;1028 struct exynos_dp_device *dp = display_to_dp(display);
1024 struct drm_connector *connector = &dp->connector;1029 struct drm_connector *connector = &dp->connector;
1025 int ret;1030 int ret;
1026 1031
@@ -1052,33 +1057,19 @@ static int exynos_dp_create_connector(struct exynos_drm_display *display, · 25 unmodified lines
1052 1057
1053static void exynos_dp_phy_init(struct exynos_dp_device *dp)1058static void exynos_dp_phy_init(struct exynos_dp_device *dp)
1054{1059{
1055 if (dp->phy) {1060 if (dp->phy)
1056 phy_power_on(dp->phy);1061 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 }
1064}1062}
1065 1063
1066static void exynos_dp_phy_exit(struct exynos_dp_device *dp)1064static void exynos_dp_phy_exit(struct exynos_dp_device *dp)
1067{1065{
1068 if (dp->phy) {1066 if (dp->phy)
1069 phy_power_off(dp->phy);1067 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 }
1077}1068}
1078 1069
1079static void exynos_dp_poweron(struct exynos_drm_display *display)1070static void exynos_dp_poweron(struct exynos_drm_display *display)
1080{1071{
1081 struct exynos_dp_device *dp = display->ctx;1072 struct exynos_dp_device *dp = display_to_dp(display);
1082 1073
1083 if (dp->dpms_mode == DRM_MODE_DPMS_ON)1074 if (dp->dpms_mode == DRM_MODE_DPMS_ON)
1084 return;1075 return;
@@ -1099,7 +1090,7 @@ static void exynos_dp_poweron(struct exynos_drm_display *display) · 14 unmodified lines
1099 1090
1100static void exynos_dp_poweroff(struct exynos_drm_display *display)1091static void exynos_dp_poweroff(struct exynos_drm_display *display)
1101{1092{
1102 struct exynos_dp_device *dp = display->ctx;1093 struct exynos_dp_device *dp = display_to_dp(display);
1103 1094
1104 if (dp->dpms_mode != DRM_MODE_DPMS_ON)1095 if (dp->dpms_mode != DRM_MODE_DPMS_ON)
1105 return;1096 return;
@@ -1124,7 +1115,7 @@ static void exynos_dp_poweroff(struct exynos_drm_display *display) · 18 unmodified lines
1124 1115
1125static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)1116static void exynos_dp_dpms(struct exynos_drm_display *display, int mode)
1126{1117{
1127 struct exynos_dp_device *dp = display->ctx;1118 struct exynos_dp_device *dp = display_to_dp(display);
1128 1119
1129 switch (mode) {1120 switch (mode) {
1130 case DRM_MODE_DPMS_ON:1121 case DRM_MODE_DPMS_ON:
@@ -1147,11 +1138,6 @@ static struct exynos_drm_display_ops exynos_dp_display_ops = { · 16 unmodified lines
1147 .commit = exynos_dp_commit,1138 .commit = exynos_dp_commit,
1148};1139};
1149 1140
1150static struct exynos_drm_display exynos_dp_display = {
1151 .type = EXYNOS_DISPLAY_TYPE_LCD,
1152 .ops = &exynos_dp_display_ops,
1153};
1154
1155static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)1141static struct video_info *exynos_dp_dt_parse_pdata(struct device *dev)
1156{1142{
1157 struct device_node *dp_node = dev->of_node;1143 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
1210 return dp_video_config;1196 return dp_video_config;
1211}1197}
1212 1198
1213static 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
1245err:
1246 of_node_put(dp_phy_node);
1247
1248 return ret;
1249}
1250
1251static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)1199static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp)
1252{1200{
1253 int ret;1201 int ret;
@@ -1263,10 +1211,10 @@ static int exynos_dp_dt_parse_panel(struct exynos_dp_device *dp) · 9 unmodified lines
1263 1211
1264static int exynos_dp_bind(struct device *dev, struct device *master, void *data)1212static int exynos_dp_bind(struct device *dev, struct device *master, void *data)
1265{1213{
1214 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1266 struct platform_device *pdev = to_platform_device(dev);1215 struct platform_device *pdev = to_platform_device(dev);
1267 struct drm_device *drm_dev = data;1216 struct drm_device *drm_dev = data;
1268 struct resource *res;1217 struct resource *res;
1269 struct exynos_dp_device *dp = exynos_dp_display.ctx;
1270 unsigned int irq_flags;1218 unsigned int irq_flags;
1271 int ret = 0;1219 int ret = 0;
1272 1220
@@ -1277,9 +1225,21 @@ static int exynos_dp_bind(struct device *dev, struct device *master, void *data) · 4 unmodified lines
1277 if (IS_ERR(dp->video_info))1225 if (IS_ERR(dp->video_info))
1278 return PTR_ERR(dp->video_info);1226 return PTR_ERR(dp->video_info);
1279 1227
1280 ret = exynos_dp_dt_parse_phydata(dp);1228 dp->phy = devm_phy_get(dp->dev, "dp");
1281 if (ret)1229 if (IS_ERR(dp->phy)) {
1282 return ret;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 }
1283 1243
1284 if (!dp->panel) {1244 if (!dp->panel) {
1285 ret = exynos_dp_dt_parse_panel(dp);1245 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
1346 1306
1347 dp->drm_dev = drm_dev;1307 dp->drm_dev = drm_dev;
1348 1308
1349 platform_set_drvdata(pdev, &exynos_dp_display);1309 return exynos_drm_create_enc_conn(drm_dev, &dp->display);
1350
1351 return exynos_drm_create_enc_conn(drm_dev, &exynos_dp_display);
1352}1310}
1353 1311
1354static void exynos_dp_unbind(struct device *dev, struct device *master,1312static void exynos_dp_unbind(struct device *dev, struct device *master,
1355 void *data)1313 void *data)
1356{1314{
1357 struct exynos_drm_display *display = dev_get_drvdata(dev);1315 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1358 1316
1359 exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);1317 exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
1360}1318}
1361 1319
1362static const struct component_ops exynos_dp_ops = {1320static const struct component_ops exynos_dp_ops = {
@@ -1371,16 +1329,20 @@ static int exynos_dp_probe(struct platform_device *pdev) · 8 unmodified lines
1371 struct exynos_dp_device *dp;1329 struct exynos_dp_device *dp;
1372 int ret;1330 int ret;
1373 1331
1374 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,
1375 exynos_dp_display.type);
1376 if (ret)
1377 return ret;
1378
1379 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),1332 dp = devm_kzalloc(&pdev->dev, sizeof(struct exynos_dp_device),
1380 GFP_KERNEL);1333 GFP_KERNEL);
1381 if (!dp)1334 if (!dp)
1382 return -ENOMEM;1335 return -ENOMEM;
1383 1336
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
1384 panel_node = of_parse_phandle(dev->of_node, "panel", 0);1346 panel_node = of_parse_phandle(dev->of_node, "panel", 0);
1385 if (panel_node) {1347 if (panel_node) {
1386 dp->panel = of_drm_find_panel(panel_node);1348 dp->panel = of_drm_find_panel(panel_node);
@@ -1389,8 +1351,6 @@ static int exynos_dp_probe(struct platform_device *pdev) · 2 unmodified lines
1389 return -EPROBE_DEFER;1351 return -EPROBE_DEFER;
1390 }1352 }
1391 1353
1392 exynos_dp_display.ctx = dp;
1393
1394 ret = component_add(&pdev->dev, &exynos_dp_ops);1354 ret = component_add(&pdev->dev, &exynos_dp_ops);
1395 if (ret)1355 if (ret)
1396 exynos_drm_component_del(&pdev->dev,1356 exynos_drm_component_del(&pdev->dev,
@@ -1410,19 +1370,17 @@ static int exynos_dp_remove(struct platform_device *pdev) · 13 unmodified lines
1410#ifdef CONFIG_PM_SLEEP1370#ifdef CONFIG_PM_SLEEP
1411static int exynos_dp_suspend(struct device *dev)1371static int exynos_dp_suspend(struct device *dev)
1412{1372{
1413 struct platform_device *pdev = to_platform_device(dev);1373 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1414 struct exynos_drm_display *display = platform_get_drvdata(pdev);
1415 1374
1416 exynos_dp_dpms(display, DRM_MODE_DPMS_OFF);1375 exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_OFF);
1417 return 0;1376 return 0;
1418}1377}
1419 1378
1420static int exynos_dp_resume(struct device *dev)1379static int exynos_dp_resume(struct device *dev)
1421{1380{
1422 struct platform_device *pdev = to_platform_device(dev);1381 struct exynos_dp_device *dp = dev_get_drvdata(dev);
1423 struct exynos_drm_display *display = platform_get_drvdata(pdev);
1424 1382
1425 exynos_dp_dpms(display, DRM_MODE_DPMS_ON);1383 exynos_dp_dpms(&dp->display, DRM_MODE_DPMS_ON);
1426 return 0;1384 return 0;
1427}1385}
1428#endif1386#endif
drivers/gpu/drm/exynos/exynos_dp_core.h+3−2
@@ -17,6 +17,8 @@ · 16 unmodified lines
17#include <drm/drm_dp_helper.h>17#include <drm/drm_dp_helper.h>
18#include <drm/exynos_drm.h>18#include <drm/exynos_drm.h>
19 19
20#include "exynos_drm_drv.h"
21
20#define DP_TIMEOUT_LOOP_COUNT 10022#define DP_TIMEOUT_LOOP_COUNT 100
21#define MAX_CR_LOOP 523#define MAX_CR_LOOP 5
22#define MAX_EQ_LOOP 524#define MAX_EQ_LOOP 5
@@ -145,6 +147,7 @@ struct link_train { · 122 unmodified lines
145};147};
146 148
147struct exynos_dp_device {149struct exynos_dp_device {
150 struct exynos_drm_display display;
148 struct device *dev;151 struct device *dev;
149 struct drm_device *drm_dev;152 struct drm_device *drm_dev;
150 struct drm_connector connector;153 struct drm_connector connector;
@@ -153,8 +156,6 @@ struct exynos_dp_device { · 2 unmodified lines
153 struct clk *clock;156 struct clk *clock;
154 unsigned int irq;157 unsigned int irq;
155 void __iomem *reg_base;158 void __iomem *reg_base;
156 void __iomem *phy_addr;
157 unsigned int enable_mask;
158 159
159 struct video_info *video_info;160 struct video_info *video_info;
160 struct link_train link_train;161 struct link_train link_train;
drivers/gpu/drm/exynos/exynos_drm_crtc.h+1−4
@@ -15,10 +15,7 @@ · 14 unmodified lines
15#ifndef _EXYNOS_DRM_CRTC_H_15#ifndef _EXYNOS_DRM_CRTC_H_
16#define _EXYNOS_DRM_CRTC_H_16#define _EXYNOS_DRM_CRTC_H_
17 17
18struct drm_device;18#include "exynos_drm_drv.h"
19struct drm_crtc;
20struct exynos_drm_manager;
21struct exynos_drm_overlay;
22 19
23int exynos_drm_crtc_create(struct exynos_drm_manager *manager);20int exynos_drm_crtc_create(struct exynos_drm_manager *manager);
24int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);21int 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
22#include "exynos_drm_drv.h"22#include "exynos_drm_drv.h"
23 23
24struct exynos_dpi {24struct exynos_dpi {
25 struct exynos_drm_display display;
25 struct device *dev;26 struct device *dev;
26 struct device_node *panel_node;27 struct device_node *panel_node;
27 28
@@ -35,6 +36,11 @@ struct exynos_dpi { · 7 unmodified lines
35 36
36#define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)37#define connector_to_dpi(c) container_of(c, struct exynos_dpi, connector)
37 38
39static inline struct exynos_dpi *display_to_dpi(struct exynos_drm_display *d)
40{
41 return container_of(d, struct exynos_dpi, display);
42}
43
38static enum drm_connector_status44static enum drm_connector_status
39exynos_dpi_detect(struct drm_connector *connector, bool force)45exynos_dpi_detect(struct drm_connector *connector, bool force)
40{46{
@@ -100,7 +106,7 @@ static struct drm_connector_helper_funcs exynos_dpi_connector_helper_funcs = { · 59 unmodified lines
100static int exynos_dpi_create_connector(struct exynos_drm_display *display,106static int exynos_dpi_create_connector(struct exynos_drm_display *display,
101 struct drm_encoder *encoder)107 struct drm_encoder *encoder)
102{108{
103 struct exynos_dpi *ctx = display->ctx;109 struct exynos_dpi *ctx = display_to_dpi(display);
104 struct drm_connector *connector = &ctx->connector;110 struct drm_connector *connector = &ctx->connector;
105 int ret;111 int ret;
106 112
@@ -141,7 +147,7 @@ static void exynos_dpi_poweroff(struct exynos_dpi *ctx) · 34 unmodified lines
141 147
142static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)148static void exynos_dpi_dpms(struct exynos_drm_display *display, int mode)
143{149{
144 struct exynos_dpi *ctx = display->ctx;150 struct exynos_dpi *ctx = display_to_dpi(display);
145 151
146 switch (mode) {152 switch (mode) {
147 case DRM_MODE_DPMS_ON:153 case DRM_MODE_DPMS_ON:
@@ -165,11 +171,6 @@ static struct exynos_drm_display_ops exynos_dpi_display_ops = { · 17 unmodified lines
165 .dpms = exynos_dpi_dpms171 .dpms = exynos_dpi_dpms
166};172};
167 173
168static struct exynos_drm_display exynos_dpi_display = {
169 .type = EXYNOS_DISPLAY_TYPE_LCD,
170 .ops = &exynos_dpi_display_ops,
171};
172
173/* of_* functions will be removed after merge of of_graph patches */174/* of_* functions will be removed after merge of of_graph patches */
174static struct device_node *175static struct device_node *
175of_get_child_by_name_reg(struct device_node *parent, const char *name, u32 reg)176of_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
299 struct exynos_dpi *ctx;300 struct exynos_dpi *ctx;
300 int ret;301 int ret;
301 302
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
308 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);303 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
309 if (!ctx)304 if (!ctx)
310 goto err_del_component;305 return ERR_PTR(-ENOMEM);
311 306
307 ctx->display.type = EXYNOS_DISPLAY_TYPE_LCD;
308 ctx->display.ops = &exynos_dpi_display_ops;
312 ctx->dev = dev;309 ctx->dev = dev;
313 exynos_dpi_display.ctx = ctx;
314 ctx->dpms_mode = DRM_MODE_DPMS_OFF;310 ctx->dpms_mode = DRM_MODE_DPMS_OFF;
315 311
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
316 ret = exynos_dpi_parse_dt(ctx);318 ret = exynos_dpi_parse_dt(ctx);
317 if (ret < 0) {319 if (ret < 0) {
318 devm_kfree(dev, ctx);320 devm_kfree(dev, ctx);
@@ -328,7 +330,7 @@ struct exynos_drm_display *exynos_dpi_probe(struct device *dev) · 9 unmodified lines
328 }330 }
329 }331 }
330 332
331 return &exynos_dpi_display;333 return &ctx->display;
332 334
333err_del_component:335err_del_component:
334 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);336 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
@@ -336,16 +338,16 @@ err_del_component: · 1 unmodified line
336 return NULL;338 return NULL;
337}339}
338 340
339int exynos_dpi_remove(struct device *dev)341int exynos_dpi_remove(struct exynos_drm_display *display)
340{342{
341 struct exynos_dpi *ctx = exynos_dpi_display.ctx;343 struct exynos_dpi *ctx = display_to_dpi(display);
342 344
343 exynos_dpi_dpms(&exynos_dpi_display, DRM_MODE_DPMS_OFF);345 exynos_dpi_dpms(&ctx->display, DRM_MODE_DPMS_OFF);
344 346
345 if (ctx->panel)347 if (ctx->panel)
346 drm_panel_detach(ctx->panel);348 drm_panel_detach(ctx->panel);
347 349
348 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);350 exynos_drm_component_del(ctx->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
349 351
350 return 0;352 return 0;
351}353}
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
203 }203 }
204 drm_modeset_unlock_all(dev);204 drm_modeset_unlock_all(dev);
205 205
206 drm_helper_resume_force_mode(dev);
207
208 return 0;206 return 0;
209}207}
210 208
@@ -475,8 +473,6 @@ void exynos_drm_component_del(struct device *dev, · 264 unmodified lines
475 list_del(&cdev->list);473 list_del(&cdev->list);
476 kfree(cdev);474 kfree(cdev);
477 }475 }
478
479 break;
480 }476 }
481 477
482 mutex_unlock(&drm_component_lock);478 mutex_unlock(&drm_component_lock);
@@ -556,182 +552,68 @@ static const struct component_master_ops exynos_drm_ops = { · 73 unmodified lines
556 .unbind = exynos_drm_unbind,552 .unbind = exynos_drm_unbind,
557};553};
558 554
559static int exynos_drm_platform_probe(struct platform_device *pdev)555static struct platform_driver *const exynos_drm_kms_drivers[] = {
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
567#ifdef CONFIG_DRM_EXYNOS_FIMD556#ifdef CONFIG_DRM_EXYNOS_FIMD
568 ret = platform_driver_register(&fimd_driver);557 &fimd_driver,
569 if (ret < 0)
570 return ret;
571#endif558#endif
572
573#ifdef CONFIG_DRM_EXYNOS_DP559#ifdef CONFIG_DRM_EXYNOS_DP
574 ret = platform_driver_register(&dp_driver);560 &dp_driver,
575 if (ret < 0)
576 goto err_unregister_fimd_drv;
577#endif561#endif
578
579#ifdef CONFIG_DRM_EXYNOS_DSI562#ifdef CONFIG_DRM_EXYNOS_DSI
580 ret = platform_driver_register(&dsi_driver);563 &dsi_driver,
581 if (ret < 0)
582 goto err_unregister_dp_drv;
583#endif564#endif
584
585#ifdef CONFIG_DRM_EXYNOS_HDMI565#ifdef CONFIG_DRM_EXYNOS_HDMI
586 ret = platform_driver_register(&mixer_driver);566 &mixer_driver,
587 if (ret < 0)567 &hdmi_driver,
588 goto err_unregister_dsi_drv;
589 ret = platform_driver_register(&hdmi_driver);
590 if (ret < 0)
591 goto err_unregister_mixer_drv;
592#endif568#endif
569};
593 570
594 match = exynos_drm_match_add(&pdev->dev);571static struct platform_driver *const exynos_drm_non_kms_drivers[] = {
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
605#ifdef CONFIG_DRM_EXYNOS_G2D572#ifdef CONFIG_DRM_EXYNOS_G2D
606 ret = platform_driver_register(&g2d_driver);573 &g2d_driver,
607 if (ret < 0)
608 goto err_del_component_master;
609#endif574#endif
610
611#ifdef CONFIG_DRM_EXYNOS_FIMC575#ifdef CONFIG_DRM_EXYNOS_FIMC
612 ret = platform_driver_register(&fimc_driver);576 &fimc_driver,
613 if (ret < 0)
614 goto err_unregister_g2d_drv;
615#endif577#endif
616
617#ifdef CONFIG_DRM_EXYNOS_ROTATOR578#ifdef CONFIG_DRM_EXYNOS_ROTATOR
618 ret = platform_driver_register(&rotator_driver);579 &rotator_driver,
619 if (ret < 0)
620 goto err_unregister_fimc_drv;
621#endif580#endif
622
623#ifdef CONFIG_DRM_EXYNOS_GSC581#ifdef CONFIG_DRM_EXYNOS_GSC
624 ret = platform_driver_register(&gsc_driver);582 &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;
637#endif583#endif
638
639 return ret;
640
641#ifdef CONFIG_DRM_EXYNOS_IPP584#ifdef CONFIG_DRM_EXYNOS_IPP
642err_unregister_ipp_drv:585 &ipp_driver,
643 platform_driver_unregister(&ipp_driver);
644err_unregister_gsc_drv:
645#endif
646
647#ifdef CONFIG_DRM_EXYNOS_GSC
648 platform_driver_unregister(&gsc_driver);
649err_unregister_rotator_drv:
650#endif586#endif
587};
651 588
652#ifdef CONFIG_DRM_EXYNOS_ROTATOR589static int exynos_drm_platform_probe(struct platform_device *pdev)
653 platform_driver_unregister(&rotator_driver);590{
654err_unregister_fimc_drv:591 struct component_match *match;
655#endif
656
657#ifdef CONFIG_DRM_EXYNOS_FIMC
658 platform_driver_unregister(&fimc_driver);
659err_unregister_g2d_drv:
660#endif
661
662#ifdef CONFIG_DRM_EXYNOS_G2D
663 platform_driver_unregister(&g2d_driver);
664err_del_component_master:
665#endif
666 component_master_del(&pdev->dev, &exynos_drm_ops);
667
668err_unregister_hdmi_drv:
669#ifdef CONFIG_DRM_EXYNOS_HDMI
670 platform_driver_unregister(&hdmi_driver);
671err_unregister_mixer_drv:
672 platform_driver_unregister(&mixer_driver);
673err_unregister_dsi_drv:
674#endif
675 592
676#ifdef CONFIG_DRM_EXYNOS_DSI593 pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
677 platform_driver_unregister(&dsi_driver);594 exynos_drm_driver.num_ioctls = ARRAY_SIZE(exynos_ioctls);
678err_unregister_dp_drv:
679#endif
680 595
681#ifdef CONFIG_DRM_EXYNOS_DP596 match = exynos_drm_match_add(&pdev->dev);
682 platform_driver_unregister(&dp_driver);597 if (IS_ERR(match)) {
683err_unregister_fimd_drv:598 return PTR_ERR(match);
684#endif599 }
685 600
686#ifdef CONFIG_DRM_EXYNOS_FIMD601 return component_master_add_with_match(&pdev->dev, &exynos_drm_ops,
687 platform_driver_unregister(&fimd_driver);602 match);
688#endif
689 return ret;
690}603}
691 604
692static int exynos_drm_platform_remove(struct platform_device *pdev)605static int exynos_drm_platform_remove(struct platform_device *pdev)
693{606{
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
731 component_master_del(&pdev->dev, &exynos_drm_ops);607 component_master_del(&pdev->dev, &exynos_drm_ops);
732 return 0;608 return 0;
733}609}
734 610
611static const char * const strings[] = {
612 "samsung,exynos3",
613 "samsung,exynos4",
614 "samsung,exynos5",
615};
616
735static struct platform_driver exynos_drm_platform_driver = {617static struct platform_driver exynos_drm_platform_driver = {
736 .probe = exynos_drm_platform_probe,618 .probe = exynos_drm_platform_probe,
737 .remove = exynos_drm_platform_remove,619 .remove = exynos_drm_platform_remove,
@@ -743,7 +625,25 @@ static struct platform_driver exynos_drm_platform_driver = { · 5 unmodified lines
743 625
744static int exynos_drm_init(void)626static int exynos_drm_init(void)
745{627{
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;
747 647
748 /*648 /*
749 * Register device object only in case of Exynos SoC.649 * Register device object only in case of Exynos SoC.
@@ -762,24 +662,50 @@ static int exynos_drm_init(void) · 12 unmodified lines
762 if (IS_ERR(exynos_drm_pdev))662 if (IS_ERR(exynos_drm_pdev))
763 return PTR_ERR(exynos_drm_pdev);663 return PTR_ERR(exynos_drm_pdev);
764 664
765#ifdef CONFIG_DRM_EXYNOS_VIDI
766 ret = exynos_drm_probe_vidi();665 ret = exynos_drm_probe_vidi();
767 if (ret < 0)666 if (ret < 0)
768 goto err_unregister_pd;667 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;
769#endif685#endif
770 686
771 ret = platform_driver_register(&exynos_drm_platform_driver);687 ret = platform_driver_register(&exynos_drm_platform_driver);
772 if (ret)688 if (ret)
773 goto err_remove_vidi;689 goto err_unregister_resources;
774 690
775 return 0;691 return 0;
776 692
777err_remove_vidi:693err_unregister_resources:
778#ifdef CONFIG_DRM_EXYNOS_VIDI694#ifdef CONFIG_DRM_EXYNOS_IPP
695 exynos_platform_device_ipp_unregister();
696#endif
697
698err_unregister_non_kms_drivers:
699 while (--j >= 0)
700 platform_driver_unregister(exynos_drm_non_kms_drivers[j]);
701
702err_unregister_kms_drivers:
703 while (--i >= 0)
704 platform_driver_unregister(exynos_drm_kms_drivers[i]);
705
779 exynos_drm_remove_vidi();706 exynos_drm_remove_vidi();
780 707
781err_unregister_pd:708err_unregister_pd:
782#endif
783 platform_device_unregister(exynos_drm_pdev);709 platform_device_unregister(exynos_drm_pdev);
784 710
785 return ret;711 return ret;
@@ -787,10 +713,22 @@ err_unregister_pd: · 1 unmodified line
787 713
788static void exynos_drm_exit(void)714static void exynos_drm_exit(void)
789{715{
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
790 platform_driver_unregister(&exynos_drm_platform_driver);728 platform_driver_unregister(&exynos_drm_platform_driver);
791#ifdef CONFIG_DRM_EXYNOS_VIDI729
792 exynos_drm_remove_vidi();730 exynos_drm_remove_vidi();
793#endif731
794 platform_device_unregister(exynos_drm_pdev);732 platform_device_unregister(exynos_drm_pdev);
795}733}
796 734
drivers/gpu/drm/exynos/exynos_drm_drv.h+26−57
@@ -15,6 +15,7 @@ · 14 unmodified lines
15#ifndef _EXYNOS_DRM_DRV_H_15#ifndef _EXYNOS_DRM_DRV_H_
16#define _EXYNOS_DRM_DRV_H_16#define _EXYNOS_DRM_DRV_H_
17 17
18#include <drm/drmP.h>
18#include <linux/module.h>19#include <linux/module.h>
19 20
20#define MAX_CRTC 321#define MAX_CRTC 3
@@ -22,24 +23,6 @@ · 1 unmodified line
22#define MAX_FB_BUFFER 423#define MAX_FB_BUFFER 4
23#define DEFAULT_ZPOS -124#define DEFAULT_ZPOS -1
24 25
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
39struct drm_device;
40struct exynos_drm_overlay;
41struct drm_connector;
42
43/* This enumerates device type. */26/* This enumerates device type. */
44enum exynos_drm_device_type {27enum exynos_drm_device_type {
45 EXYNOS_DEVICE_TYPE_NONE,28 EXYNOS_DEVICE_TYPE_NONE,
@@ -83,10 +66,10 @@ enum exynos_drm_output_type { · 37 unmodified lines
83 * @dma_addr: array of bus(accessed by dma) address to the memory region66 * @dma_addr: array of bus(accessed by dma) address to the memory region
84 * allocated for a overlay.67 * allocated for a overlay.
85 * @zpos: order of overlay layer(z position).68 * @zpos: order of overlay layer(z position).
86 * @default_win: a window to be enabled.
87 * @color_key: color key on or off.
88 * @index_color: if using color key feature then this value would be used69 * @index_color: if using color key feature then this value would be used
89 * as index color.70 * as index color.
71 * @default_win: a window to be enabled.
72 * @color_key: color key on or off.
90 * @local_path: in case of lcd type, local path mode on or off.73 * @local_path: in case of lcd type, local path mode on or off.
91 * @transparency: transparency on or off.74 * @transparency: transparency on or off.
92 * @activated: activated or not.75 * @activated: activated or not.
@@ -114,19 +97,20 @@ struct exynos_drm_overlay { · 21 unmodified lines
114 uint32_t pixel_format;97 uint32_t pixel_format;
115 dma_addr_t dma_addr[MAX_FB_BUFFER];98 dma_addr_t dma_addr[MAX_FB_BUFFER];
116 int zpos;99 int zpos;
117
118 bool default_win;
119 bool color_key;
120 unsigned int index_color;100 unsigned int index_color;
121 bool local_path;101
122 bool transparency;102 bool default_win:1;
123 bool activated;103 bool color_key:1;
104 bool local_path:1;
105 bool transparency:1;
106 bool activated:1;
124};107};
125 108
126/*109/*
127 * Exynos DRM Display Structure.110 * Exynos DRM Display Structure.
128 * - this structure is common to analog tv, digital tv and lcd panel.111 * - this structure is common to analog tv, digital tv and lcd panel.
129 *112 *
113 * @create_connector: initialize and register a new connector
130 * @remove: cleans up the display for removal114 * @remove: cleans up the display for removal
131 * @mode_fixup: fix mode data comparing to hw specific display mode.115 * @mode_fixup: fix mode data comparing to hw specific display mode.
132 * @mode_set: convert drm_display_mode to hw specific display mode and116 * @mode_set: convert drm_display_mode to hw specific display mode and
@@ -168,7 +152,6 @@ struct exynos_drm_display { · 35 unmodified lines
168 struct drm_encoder *encoder;152 struct drm_encoder *encoder;
169 struct drm_connector *connector;153 struct drm_connector *connector;
170 struct exynos_drm_display_ops *ops;154 struct exynos_drm_display_ops *ops;
171 void *ctx;
172};155};
173 156
174/*157/*
@@ -227,7 +210,6 @@ struct exynos_drm_manager { · 52 unmodified lines
227 struct drm_crtc *crtc;210 struct drm_crtc *crtc;
228 int pipe;211 int pipe;
229 struct exynos_drm_manager_ops *ops;212 struct exynos_drm_manager_ops *ops;
230 void *ctx;
231};213};
232 214
233struct exynos_drm_g2d_private {215struct exynos_drm_g2d_private {
@@ -279,8 +261,6 @@ struct exynos_drm_private { · 45 unmodified lines
279 * @dev: pointer to device object for subdrv device driver.261 * @dev: pointer to device object for subdrv device driver.
280 * @drm_dev: pointer to drm_device and this pointer would be set262 * @drm_dev: pointer to drm_device and this pointer would be set
281 * when sub driver calls exynos_drm_subdrv_register().263 * 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.
284 * @probe: this callback would be called by exynos drm driver after264 * @probe: this callback would be called by exynos drm driver after
285 * subdrv is registered to it.265 * subdrv is registered to it.
286 * @remove: this callback is used to release resources created266 * @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
312int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);292int exynos_drm_subdrv_open(struct drm_device *dev, struct drm_file *file);
313void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);293void exynos_drm_subdrv_close(struct drm_device *dev, struct drm_file *file);
314 294
315/*295#ifdef CONFIG_DRM_EXYNOS_IPP
316 * this function registers exynos drm hdmi platform device. It ensures only one
317 * instance of the device is created.
318 */
319int exynos_platform_device_hdmi_register(void);
320
321/*
322 * this function unregisters exynos drm hdmi platform device if it exists.
323 */
324void exynos_platform_device_hdmi_unregister(void);
325
326/*
327 * this function registers exynos drm ipp platform device.
328 */
329int exynos_platform_device_ipp_register(void);296int exynos_platform_device_ipp_register(void);
330
331/*
332 * this function unregisters exynos drm ipp platform device if it exists.
333 */
334void exynos_platform_device_ipp_unregister(void);297void exynos_platform_device_ipp_unregister(void);
298#else
299static inline int exynos_platform_device_ipp_register(void) { return 0; }
300static inline void exynos_platform_device_ipp_unregister(void) {}
301#endif
302
335 303
336#ifdef CONFIG_DRM_EXYNOS_DPI304#ifdef CONFIG_DRM_EXYNOS_DPI
337struct exynos_drm_display * exynos_dpi_probe(struct device *dev);305struct exynos_drm_display * exynos_dpi_probe(struct device *dev);
338int exynos_dpi_remove(struct device *dev);306int exynos_dpi_remove(struct exynos_drm_display *display);
339#else307#else
340static inline struct exynos_drm_display *308static inline struct exynos_drm_display *
341exynos_dpi_probe(struct device *dev) { return NULL; }309exynos_dpi_probe(struct device *dev) { return NULL; }
342static inline int exynos_dpi_remove(struct device *dev) { return 0; }310static inline int exynos_dpi_remove(struct exynos_drm_display *display)
311{
312 return 0;
313}
343#endif314#endif
344 315
345/*316#ifdef CONFIG_DRM_EXYNOS_VIDI
346 * this function registers exynos drm vidi platform device/driver.
347 */
348int exynos_drm_probe_vidi(void);317int exynos_drm_probe_vidi(void);
349
350/*
351 * this function unregister exynos drm vidi platform device/driver.
352 */
353void exynos_drm_remove_vidi(void);318void exynos_drm_remove_vidi(void);
319#else
320static inline int exynos_drm_probe_vidi(void) { return 0; }
321static inline void exynos_drm_remove_vidi(void) {}
322#endif
354 323
355/* This function creates a encoder and a connector, and initializes them. */324/* This function creates a encoder and a connector, and initializes them. */
356int exynos_drm_create_enc_conn(struct drm_device *dev,325int 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
268};268};
269 269
270struct exynos_dsi {270struct exynos_dsi {
271 struct exynos_drm_display display;
271 struct mipi_dsi_host dsi_host;272 struct mipi_dsi_host dsi_host;
272 struct drm_connector connector;273 struct drm_connector connector;
273 struct drm_encoder *encoder;
274 struct device_node *panel_node;274 struct device_node *panel_node;
275 struct drm_panel *panel;275 struct drm_panel *panel;
276 struct device *dev;276 struct device *dev;
@@ -304,6 +304,11 @@ struct exynos_dsi { · 27 unmodified lines
304#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)304#define host_to_dsi(host) container_of(host, struct exynos_dsi, dsi_host)
305#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)305#define connector_to_dsi(c) container_of(c, struct exynos_dsi, connector)
306 306
307static inline struct exynos_dsi *display_to_dsi(struct exynos_drm_display *d)
308{
309 return container_of(d, struct exynos_dsi, display);
310}
311
307static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {312static struct exynos_dsi_driver_data exynos3_dsi_driver_data = {
308 .plltmr_reg = 0x50,313 .plltmr_reg = 0x50,
309 .has_freqband = 1,314 .has_freqband = 1,
@@ -316,6 +321,11 @@ static struct exynos_dsi_driver_data exynos4_dsi_driver_data = { · 6 unmodified lines
316 .has_clklane_stop = 1,321 .has_clklane_stop = 1,
317};322};
318 323
324static struct exynos_dsi_driver_data exynos4415_dsi_driver_data = {
325 .plltmr_reg = 0x58,
326 .has_clklane_stop = 1,
327};
328
319static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {329static struct exynos_dsi_driver_data exynos5_dsi_driver_data = {
320 .plltmr_reg = 0x58,330 .plltmr_reg = 0x58,
321};331};
@@ -325,6 +335,8 @@ static struct of_device_id exynos_dsi_of_match[] = { · 3 unmodified lines
325 .data = &exynos3_dsi_driver_data },335 .data = &exynos3_dsi_driver_data },
326 { .compatible = "samsung,exynos4210-mipi-dsi",336 { .compatible = "samsung,exynos4210-mipi-dsi",
327 .data = &exynos4_dsi_driver_data },337 .data = &exynos4_dsi_driver_data },
338 { .compatible = "samsung,exynos4415-mipi-dsi",
339 .data = &exynos4415_dsi_driver_data },
328 { .compatible = "samsung,exynos5410-mipi-dsi",340 { .compatible = "samsung,exynos5410-mipi-dsi",
329 .data = &exynos5_dsi_driver_data },341 .data = &exynos5_dsi_driver_data },
330 { }342 { }
@@ -1104,7 +1116,7 @@ static irqreturn_t exynos_dsi_irq(int irq, void *dev_id) · 773 unmodified lines
1104static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)1116static irqreturn_t exynos_dsi_te_irq_handler(int irq, void *dev_id)
1105{1117{
1106 struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;1118 struct exynos_dsi *dsi = (struct exynos_dsi *)dev_id;
1107 struct drm_encoder *encoder = dsi->encoder;1119 struct drm_encoder *encoder = dsi->display.encoder;
1108 1120
1109 if (dsi->state & DSIM_STATE_ENABLED)1121 if (dsi->state & DSIM_STATE_ENABLED)
1110 exynos_drm_crtc_te_handler(encoder->crtc);1122 exynos_drm_crtc_te_handler(encoder->crtc);
@@ -1143,6 +1155,7 @@ static int exynos_dsi_init(struct exynos_dsi *dsi) · 32 unmodified lines
1143static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)1155static int exynos_dsi_register_te_irq(struct exynos_dsi *dsi)
1144{1156{
1145 int ret;1157 int ret;
1158 int te_gpio_irq;
1146 1159
1147 dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);1160 dsi->te_gpio = of_get_named_gpio(dsi->panel_node, "te-gpios", 0);
1148 if (!gpio_is_valid(dsi->te_gpio)) {1161 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
1157 goto out;1170 goto out;
1158 }1171 }
1159 1172
1160 /*1173 te_gpio_irq = gpio_to_irq(dsi->te_gpio);
1161 * This TE GPIO IRQ should not be set to IRQ_NOAUTOEN, because panel1174
1162 * calls drm_panel_init() first then calls mipi_dsi_attach() in probe().1175 irq_set_status_flags(te_gpio_irq, IRQ_NOAUTOEN);
1163 * It means that te_gpio is invalid when exynos_dsi_enable_irq() is1176 ret = request_threaded_irq(te_gpio_irq, exynos_dsi_te_irq_handler, NULL,
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,
1168 IRQF_TRIGGER_RISING, "TE", dsi);1177 IRQF_TRIGGER_RISING, "TE", dsi);
1169 if (ret) {1178 if (ret) {
1170 dev_err(dsi->dev, "request interrupt failed with %d\n", ret);1179 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
1195 dsi->mode_flags = device->mode_flags;1204 dsi->mode_flags = device->mode_flags;
1196 dsi->panel_node = device->dev.of_node;1205 dsi->panel_node = device->dev.of_node;
1197 1206
1198 if (dsi->connector.dev)
1199 drm_helper_hpd_irq_event(dsi->connector.dev);
1200
1201 /*1207 /*
1202 * This is a temporary solution and should be made by more generic way.1208 * This is a temporary solution and should be made by more generic way.
1203 *1209 *
@@ -1211,6 +1217,9 @@ static int exynos_dsi_host_attach(struct mipi_dsi_host *host, · 7 unmodified lines
1211 return ret;1217 return ret;
1212 }1218 }
1213 1219
1220 if (dsi->connector.dev)
1221 drm_helper_hpd_irq_event(dsi->connector.dev);
1222
1214 return 0;1223 return 0;
1215}1224}
1216 1225
@@ -1236,7 +1245,7 @@ static bool exynos_dsi_is_short_dsi_type(u8 type) · 19 unmodified lines
1236}1245}
1237 1246
1238static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,1247static ssize_t exynos_dsi_host_transfer(struct mipi_dsi_host *host,
1239 struct mipi_dsi_msg *msg)1248 const struct mipi_dsi_msg *msg)
1240{1249{
1241 struct exynos_dsi *dsi = host_to_dsi(host);1250 struct exynos_dsi *dsi = host_to_dsi(host);
1242 struct exynos_dsi_transfer xfer;1251 struct exynos_dsi_transfer xfer;
@@ -1369,16 +1378,17 @@ static int exynos_dsi_enable(struct exynos_dsi *dsi) · 126 unmodified lines
1369 exynos_dsi_set_display_mode(dsi);1378 exynos_dsi_set_display_mode(dsi);
1370 exynos_dsi_set_display_enable(dsi, true);1379 exynos_dsi_set_display_enable(dsi, true);
1371 1380
1381 dsi->state |= DSIM_STATE_ENABLED;
1382
1372 ret = drm_panel_enable(dsi->panel);1383 ret = drm_panel_enable(dsi->panel);
1373 if (ret < 0) {1384 if (ret < 0) {
1385 dsi->state &= ~DSIM_STATE_ENABLED;
1374 exynos_dsi_set_display_enable(dsi, false);1386 exynos_dsi_set_display_enable(dsi, false);
1375 drm_panel_unprepare(dsi->panel);1387 drm_panel_unprepare(dsi->panel);
1376 exynos_dsi_poweroff(dsi);1388 exynos_dsi_poweroff(dsi);
1377 return ret;1389 return ret;
1378 }1390 }
1379 1391
1380 dsi->state |= DSIM_STATE_ENABLED;
1381
1382 return 0;1392 return 0;
1383}1393}
1384 1394
@@ -1397,7 +1407,7 @@ static void exynos_dsi_disable(struct exynos_dsi *dsi) · 12 unmodified lines
1397 1407
1398static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)1408static void exynos_dsi_dpms(struct exynos_drm_display *display, int mode)
1399{1409{
1400 struct exynos_dsi *dsi = display->ctx;1410 struct exynos_dsi *dsi = display_to_dsi(display);
1401 1411
1402 if (dsi->panel) {1412 if (dsi->panel) {
1403 switch (mode) {1413 switch (mode) {
@@ -1474,7 +1484,7 @@ exynos_dsi_best_encoder(struct drm_connector *connector) · 70 unmodified lines
1474{1484{
1475 struct exynos_dsi *dsi = connector_to_dsi(connector);1485 struct exynos_dsi *dsi = connector_to_dsi(connector);
1476 1486
1477 return dsi->encoder;1487 return dsi->display.encoder;
1478}1488}
1479 1489
1480static struct drm_connector_helper_funcs exynos_dsi_connector_helper_funcs = {1490static 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
1486static int exynos_dsi_create_connector(struct exynos_drm_display *display,1496static int exynos_dsi_create_connector(struct exynos_drm_display *display,
1487 struct drm_encoder *encoder)1497 struct drm_encoder *encoder)
1488{1498{
1489 struct exynos_dsi *dsi = display->ctx;1499 struct exynos_dsi *dsi = display_to_dsi(display);
1490 struct drm_connector *connector = &dsi->connector;1500 struct drm_connector *connector = &dsi->connector;
1491 int ret;1501 int ret;
1492 1502
1493 dsi->encoder = encoder;
1494
1495 connector->polled = DRM_CONNECTOR_POLL_HPD;1503 connector->polled = DRM_CONNECTOR_POLL_HPD;
1496 1504
1497 ret = drm_connector_init(encoder->dev, connector,1505 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
1512static void exynos_dsi_mode_set(struct exynos_drm_display *display,1520static void exynos_dsi_mode_set(struct exynos_drm_display *display,
1513 struct drm_display_mode *mode)1521 struct drm_display_mode *mode)
1514{1522{
1515 struct exynos_dsi *dsi = display->ctx;1523 struct exynos_dsi *dsi = display_to_dsi(display);
1516 struct videomode *vm = &dsi->vm;1524 struct videomode *vm = &dsi->vm;
1517 1525
1518 vm->hactive = mode->hdisplay;1526 vm->hactive = mode->hdisplay;
@@ -1531,10 +1539,6 @@ static struct exynos_drm_display_ops exynos_dsi_display_ops = { · 12 unmodified lines
1531 .dpms = exynos_dsi_dpms1539 .dpms = exynos_dsi_dpms
1532};1540};
1533 1541
1534static struct exynos_drm_display exynos_dsi_display = {
1535 .type = EXYNOS_DISPLAY_TYPE_LCD,
1536 .ops = &exynos_dsi_display_ops,
1537};
1538MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);1542MODULE_DEVICE_TABLE(of, exynos_dsi_of_match);
1539 1543
1540/* of_* functions will be removed after merge of of_graph patches */1544/* of_* functions will be removed after merge of of_graph patches */
@@ -1640,28 +1644,28 @@ end: · 99 unmodified lines
1640static int exynos_dsi_bind(struct device *dev, struct device *master,1644static int exynos_dsi_bind(struct device *dev, struct device *master,
1641 void *data)1645 void *data)
1642{1646{
1647 struct exynos_drm_display *display = dev_get_drvdata(dev);
1648 struct exynos_dsi *dsi = display_to_dsi(display);
1643 struct drm_device *drm_dev = data;1649 struct drm_device *drm_dev = data;
1644 struct exynos_dsi *dsi;
1645 int ret;1650 int ret;
1646 1651
1647 ret = exynos_drm_create_enc_conn(drm_dev, &exynos_dsi_display);1652 ret = exynos_drm_create_enc_conn(drm_dev, display);
1648 if (ret) {1653 if (ret) {
1649 DRM_ERROR("Encoder create [%d] failed with %d\n",1654 DRM_ERROR("Encoder create [%d] failed with %d\n",
1650 exynos_dsi_display.type, ret);1655 display->type, ret);
1651 return ret;1656 return ret;
1652 }1657 }
1653 1658
1654 dsi = exynos_dsi_display.ctx;
1655
1656 return mipi_dsi_host_register(&dsi->dsi_host);1659 return mipi_dsi_host_register(&dsi->dsi_host);
1657}1660}
1658 1661
1659static void exynos_dsi_unbind(struct device *dev, struct device *master,1662static void exynos_dsi_unbind(struct device *dev, struct device *master,
1660 void *data)1663 void *data)
1661{1664{
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);
1663 1667
1664 exynos_dsi_dpms(&exynos_dsi_display, DRM_MODE_DPMS_OFF);1668 exynos_dsi_dpms(display, DRM_MODE_DPMS_OFF);
1665 1669
1666 mipi_dsi_host_unregister(&dsi->dsi_host);1670 mipi_dsi_host_unregister(&dsi->dsi_host);
1667}1671}
@@ -1673,22 +1677,23 @@ static const struct component_ops exynos_dsi_component_ops = { · 5 unmodified lines
1673 1677
1674static int exynos_dsi_probe(struct platform_device *pdev)1678static int exynos_dsi_probe(struct platform_device *pdev)
1675{1679{
1680 struct device *dev = &pdev->dev;
1676 struct resource *res;1681 struct resource *res;
1677 struct exynos_dsi *dsi;1682 struct exynos_dsi *dsi;
1678 int ret;1683 int ret;
1679 1684
1680 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,1685 dsi = devm_kzalloc(dev, sizeof(*dsi), GFP_KERNEL);
1681 exynos_dsi_display.type);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);
1682 if (ret)1694 if (ret)
1683 return ret;1695 return ret;
1684 1696
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
1692 /* To be checked as invalid one */1697 /* To be checked as invalid one */
1693 dsi->te_gpio = -ENOENT;1698 dsi->te_gpio = -ENOENT;
1694 1699
@@ -1697,9 +1702,9 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 2 unmodified lines
1697 INIT_LIST_HEAD(&dsi->transfer_list);1702 INIT_LIST_HEAD(&dsi->transfer_list);
1698 1703
1699 dsi->dsi_host.ops = &exynos_dsi_ops;1704 dsi->dsi_host.ops = &exynos_dsi_ops;
1700 dsi->dsi_host.dev = &pdev->dev;1705 dsi->dsi_host.dev = dev;
1701 1706
1702 dsi->dev = &pdev->dev;1707 dsi->dev = dev;
1703 dsi->driver_data = exynos_dsi_get_driver_data(pdev);1708 dsi->driver_data = exynos_dsi_get_driver_data(pdev);
1704 1709
1705 ret = exynos_dsi_parse_dt(dsi);1710 ret = exynos_dsi_parse_dt(dsi);
@@ -1708,70 +1713,68 @@ static int exynos_dsi_probe(struct platform_device *pdev) · 2 unmodified lines
1708 1713
1709 dsi->supplies[0].supply = "vddcore";1714 dsi->supplies[0].supply = "vddcore";
1710 dsi->supplies[1].supply = "vddio";1715 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),
1712 dsi->supplies);1717 dsi->supplies);
1713 if (ret) {1718 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);
1715 return -EPROBE_DEFER;1720 return -EPROBE_DEFER;
1716 }1721 }
1717 1722
1718 dsi->pll_clk = devm_clk_get(&pdev->dev, "pll_clk");1723 dsi->pll_clk = devm_clk_get(dev, "pll_clk");
1719 if (IS_ERR(dsi->pll_clk)) {1724 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");
1721 ret = PTR_ERR(dsi->pll_clk);1726 ret = PTR_ERR(dsi->pll_clk);
1722 goto err_del_component;1727 goto err_del_component;
1723 }1728 }
1724 1729
1725 dsi->bus_clk = devm_clk_get(&pdev->dev, "bus_clk");1730 dsi->bus_clk = devm_clk_get(dev, "bus_clk");
1726 if (IS_ERR(dsi->bus_clk)) {1731 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");
1728 ret = PTR_ERR(dsi->bus_clk);1733 ret = PTR_ERR(dsi->bus_clk);
1729 goto err_del_component;1734 goto err_del_component;
1730 }1735 }
1731 1736
1732 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);1737 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);
1734 if (IS_ERR(dsi->reg_base)) {1739 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");
1736 ret = PTR_ERR(dsi->reg_base);1741 ret = PTR_ERR(dsi->reg_base);
1737 goto err_del_component;1742 goto err_del_component;
1738 }1743 }
1739 1744
1740 dsi->phy = devm_phy_get(&pdev->dev, "dsim");1745 dsi->phy = devm_phy_get(dev, "dsim");
1741 if (IS_ERR(dsi->phy)) {1746 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");
1743 ret = PTR_ERR(dsi->phy);1748 ret = PTR_ERR(dsi->phy);
1744 goto err_del_component;1749 goto err_del_component;
1745 }1750 }
1746 1751
1747 dsi->irq = platform_get_irq(pdev, 0);1752 dsi->irq = platform_get_irq(pdev, 0);
1748 if (dsi->irq < 0) {1753 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");
1750 ret = dsi->irq;1755 ret = dsi->irq;
1751 goto err_del_component;1756 goto err_del_component;
1752 }1757 }
1753 1758
1754 irq_set_status_flags(dsi->irq, IRQ_NOAUTOEN);1759 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,
1756 exynos_dsi_irq, IRQF_ONESHOT,1761 exynos_dsi_irq, IRQF_ONESHOT,
1757 dev_name(&pdev->dev), dsi);1762 dev_name(dev), dsi);
1758 if (ret) {1763 if (ret) {
1759 dev_err(&pdev->dev, "failed to request dsi irq\n");1764 dev_err(dev, "failed to request dsi irq\n");
1760 goto err_del_component;1765 goto err_del_component;
1761 }1766 }
1762 1767
1763 exynos_dsi_display.ctx = dsi;1768 platform_set_drvdata(pdev, &dsi->display);
1764
1765 platform_set_drvdata(pdev, &exynos_dsi_display);
1766 1769
1767 ret = component_add(&pdev->dev, &exynos_dsi_component_ops);1770 ret = component_add(dev, &exynos_dsi_component_ops);
1768 if (ret)1771 if (ret)
1769 goto err_del_component;1772 goto err_del_component;
1770 1773
1771 return ret;1774 return ret;
1772 1775
1773err_del_component:1776err_del_component:
1774 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);1777 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
1775 return ret;1778 return ret;
1776}1779}
1777 1780
drivers/gpu/drm/exynos/exynos_drm_encoder.h+0−2
@@ -14,8 +14,6 @@ · 13 unmodified lines
14#ifndef _EXYNOS_DRM_ENCODER_H_14#ifndef _EXYNOS_DRM_ENCODER_H_
15#define _EXYNOS_DRM_ENCODER_H_15#define _EXYNOS_DRM_ENCODER_H_
16 16
17struct exynos_drm_manager;
18
19void exynos_drm_encoder_setup(struct drm_device *dev);17void exynos_drm_encoder_setup(struct drm_device *dev);
20struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,18struct drm_encoder *exynos_drm_encoder_create(struct drm_device *dev,
21 struct exynos_drm_display *mgr,19 struct exynos_drm_display *mgr,
drivers/gpu/drm/exynos/exynos_drm_fimd.c+148−118
@@ -84,8 +84,6 @@ · 83 unmodified lines
84/* FIMD has totally five hardware windows. */84/* FIMD has totally five hardware windows. */
85#define WINDOWS_NR 585#define WINDOWS_NR 5
86 86
87#define get_fimd_manager(mgr) platform_get_drvdata(to_platform_device(dev))
88
89struct fimd_driver_data {87struct fimd_driver_data {
90 unsigned int timing_base;88 unsigned int timing_base;
91 unsigned int lcdblk_offset;89 unsigned int lcdblk_offset;
@@ -96,6 +94,7 @@ struct fimd_driver_data { · 4 unmodified lines
96 unsigned int has_clksel:1;94 unsigned int has_clksel:1;
97 unsigned int has_limited_fmt:1;95 unsigned int has_limited_fmt:1;
98 unsigned int has_vidoutcon:1;96 unsigned int has_vidoutcon:1;
97 unsigned int has_vtsel:1;
99};98};
100 99
101static struct fimd_driver_data s3c64xx_fimd_driver_data = {100static struct fimd_driver_data s3c64xx_fimd_driver_data = {
@@ -118,6 +117,17 @@ static struct fimd_driver_data exynos4_fimd_driver_data = { · 16 unmodified lines
118 .lcdblk_vt_shift = 10,117 .lcdblk_vt_shift = 10,
119 .lcdblk_bypass_shift = 1,118 .lcdblk_bypass_shift = 1,
120 .has_shadowcon = 1,119 .has_shadowcon = 1,
120 .has_vtsel = 1,
121};
122
123static 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,
121};131};
122 132
123static struct fimd_driver_data exynos5_fimd_driver_data = {133static struct fimd_driver_data exynos5_fimd_driver_data = {
@@ -127,6 +137,7 @@ static struct fimd_driver_data exynos5_fimd_driver_data = { · 3 unmodified lines
127 .lcdblk_bypass_shift = 15,137 .lcdblk_bypass_shift = 15,
128 .has_shadowcon = 1,138 .has_shadowcon = 1,
129 .has_vidoutcon = 1,139 .has_vidoutcon = 1,
140 .has_vtsel = 1,
130};141};
131 142
132struct fimd_win_data {143struct fimd_win_data {
@@ -146,6 +157,7 @@ struct fimd_win_data { · 13 unmodified lines
146};157};
147 158
148struct fimd_context {159struct fimd_context {
160 struct exynos_drm_manager manager;
149 struct device *dev;161 struct device *dev;
150 struct drm_device *drm_dev;162 struct drm_device *drm_dev;
151 struct clk *bus_clk;163 struct clk *bus_clk;
@@ -173,6 +185,11 @@ struct fimd_context { · 21 unmodified lines
173 struct exynos_drm_display *display;185 struct exynos_drm_display *display;
174};186};
175 187
188static inline struct fimd_context *mgr_to_fimd(struct exynos_drm_manager *mgr)
189{
190 return container_of(mgr, struct fimd_context, manager);
191}
192
176static const struct of_device_id fimd_driver_dt_match[] = {193static const struct of_device_id fimd_driver_dt_match[] = {
177 { .compatible = "samsung,s3c6400-fimd",194 { .compatible = "samsung,s3c6400-fimd",
178 .data = &s3c64xx_fimd_driver_data },195 .data = &s3c64xx_fimd_driver_data },
@@ -180,6 +197,8 @@ static const struct of_device_id fimd_driver_dt_match[] = { · 1 unmodified line
180 .data = &exynos3_fimd_driver_data },197 .data = &exynos3_fimd_driver_data },
181 { .compatible = "samsung,exynos4210-fimd",198 { .compatible = "samsung,exynos4210-fimd",
182 .data = &exynos4_fimd_driver_data },199 .data = &exynos4_fimd_driver_data },
200 { .compatible = "samsung,exynos4415-fimd",
201 .data = &exynos4415_fimd_driver_data },
183 { .compatible = "samsung,exynos5250-fimd",202 { .compatible = "samsung,exynos5250-fimd",
184 .data = &exynos5_fimd_driver_data },203 .data = &exynos5_fimd_driver_data },
185 {},204 {},
@@ -197,7 +216,7 @@ static inline struct fimd_driver_data *drm_fimd_get_driver_data( · 11 unmodified lines
197 216
198static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)217static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr)
199{218{
200 struct fimd_context *ctx = mgr->ctx;219 struct fimd_context *ctx = mgr_to_fimd(mgr);
201 220
202 if (ctx->suspended)221 if (ctx->suspended)
203 return;222 return;
@@ -214,9 +233,35 @@ static void fimd_wait_for_vblank(struct exynos_drm_manager *mgr) · 10 unmodified lines
214 DRM_DEBUG_KMS("vblank wait timed out.\n");233 DRM_DEBUG_KMS("vblank wait timed out.\n");
215}234}
216 235
236static 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
249static 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
217static void fimd_clear_channel(struct exynos_drm_manager *mgr)262static void fimd_clear_channel(struct exynos_drm_manager *mgr)
218{263{
219 struct fimd_context *ctx = mgr->ctx;264 struct fimd_context *ctx = mgr_to_fimd(mgr);
220 int win, ch_enabled = 0;265 int win, ch_enabled = 0;
221 266
222 DRM_DEBUG_KMS("%s\n", __FILE__);267 DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -226,16 +271,12 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) · 3 unmodified lines
226 u32 val = readl(ctx->regs + WINCON(win));271 u32 val = readl(ctx->regs + WINCON(win));
227 272
228 if (val & WINCONx_ENWIN) {273 if (val & WINCONx_ENWIN) {
229 /* wincon */274 fimd_enable_video_output(ctx, win, false);
230 val &= ~WINCONx_ENWIN;275
231 writel(val, ctx->regs + WINCON(win));276 if (ctx->driver_data->has_shadowcon)
232 277 fimd_enable_shadow_channel_path(ctx, win,
233 /* unprotect windows */278 false);
234 if (ctx->driver_data->has_shadowcon) {279
235 val = readl(ctx->regs + SHADOWCON);
236 val &= ~SHADOWCON_CHx_ENABLE(win);
237 writel(val, ctx->regs + SHADOWCON);
238 }
239 ch_enabled = 1;280 ch_enabled = 1;
240 }281 }
241 }282 }
@@ -253,7 +294,7 @@ static void fimd_clear_channel(struct exynos_drm_manager *mgr) · 11 unmodified lines
253static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,294static int fimd_mgr_initialize(struct exynos_drm_manager *mgr,
254 struct drm_device *drm_dev)295 struct drm_device *drm_dev)
255{296{
256 struct fimd_context *ctx = mgr->ctx;297 struct fimd_context *ctx = mgr_to_fimd(mgr);
257 struct exynos_drm_private *priv;298 struct exynos_drm_private *priv;
258 priv = drm_dev->dev_private;299 priv = drm_dev->dev_private;
259 300
@@ -275,7 +316,7 @@ static int fimd_mgr_initialize(struct exynos_drm_manager *mgr, · 15 unmodified lines
275 316
276static void fimd_mgr_remove(struct exynos_drm_manager *mgr)317static void fimd_mgr_remove(struct exynos_drm_manager *mgr)
277{318{
278 struct fimd_context *ctx = mgr->ctx;319 struct fimd_context *ctx = mgr_to_fimd(mgr);
279 320
280 /* detach this sub driver from iommu mapping if supported. */321 /* detach this sub driver from iommu mapping if supported. */
281 if (is_drm_iommu_supported(ctx->drm_dev))322 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
315static void fimd_mode_set(struct exynos_drm_manager *mgr,356static void fimd_mode_set(struct exynos_drm_manager *mgr,
316 const struct drm_display_mode *in_mode)357 const struct drm_display_mode *in_mode)
317{358{
318 struct fimd_context *ctx = mgr->ctx;359 struct fimd_context *ctx = mgr_to_fimd(mgr);
319 360
320 drm_mode_copy(&ctx->mode, in_mode);361 drm_mode_copy(&ctx->mode, in_mode);
321}362}
322 363
323static void fimd_commit(struct exynos_drm_manager *mgr)364static void fimd_commit(struct exynos_drm_manager *mgr)
324{365{
325 struct fimd_context *ctx = mgr->ctx;366 struct fimd_context *ctx = mgr_to_fimd(mgr);
326 struct drm_display_mode *mode = &ctx->mode;367 struct drm_display_mode *mode = &ctx->mode;
327 struct fimd_driver_data *driver_data = ctx->driver_data;368 struct fimd_driver_data *driver_data = ctx->driver_data;
328 void *timing_base = ctx->regs + driver_data->timing_base;369 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
343 writel(0, timing_base + I80IFCONFBx(0));384 writel(0, timing_base + I80IFCONFBx(0));
344 385
345 /* set video type selection to I80 interface */386 /* 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,
347 driver_data->lcdblk_offset,389 driver_data->lcdblk_offset,
348 0x3 << driver_data->lcdblk_vt_shift,390 0x3 << driver_data->lcdblk_vt_shift,
349 0x1 << driver_data->lcdblk_vt_shift)) {391 0x1 << driver_data->lcdblk_vt_shift)) {
@@ -421,7 +463,7 @@ static void fimd_commit(struct exynos_drm_manager *mgr) · 71 unmodified lines
421 463
422static int fimd_enable_vblank(struct exynos_drm_manager *mgr)464static int fimd_enable_vblank(struct exynos_drm_manager *mgr)
423{465{
424 struct fimd_context *ctx = mgr->ctx;466 struct fimd_context *ctx = mgr_to_fimd(mgr);
425 u32 val;467 u32 val;
426 468
427 if (ctx->suspended)469 if (ctx->suspended)
@@ -431,12 +473,19 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
431 val = readl(ctx->regs + VIDINTCON0);473 val = readl(ctx->regs + VIDINTCON0);
432 474
433 val |= VIDINTCON0_INT_ENABLE;475 val |= VIDINTCON0_INT_ENABLE;
434 val |= VIDINTCON0_INT_FRAME;
435 476
436 val &= ~VIDINTCON0_FRAMESEL0_MASK;477 if (ctx->i80_if) {
437 val |= VIDINTCON0_FRAMESEL0_VSYNC;478 val |= VIDINTCON0_INT_I80IFDONE;
438 val &= ~VIDINTCON0_FRAMESEL1_MASK;479 val |= VIDINTCON0_INT_SYSMAINCON;
439 val |= VIDINTCON0_FRAMESEL1_NONE;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 }
440 489
441 writel(val, ctx->regs + VIDINTCON0);490 writel(val, ctx->regs + VIDINTCON0);
442 }491 }
@@ -446,7 +495,7 @@ static int fimd_enable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
446 495
447static void fimd_disable_vblank(struct exynos_drm_manager *mgr)496static void fimd_disable_vblank(struct exynos_drm_manager *mgr)
448{497{
449 struct fimd_context *ctx = mgr->ctx;498 struct fimd_context *ctx = mgr_to_fimd(mgr);
450 u32 val;499 u32 val;
451 500
452 if (ctx->suspended)501 if (ctx->suspended)
@@ -455,9 +504,15 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) · 2 unmodified lines
455 if (test_and_clear_bit(0, &ctx->irq_flags)) {504 if (test_and_clear_bit(0, &ctx->irq_flags)) {
456 val = readl(ctx->regs + VIDINTCON0);505 val = readl(ctx->regs + VIDINTCON0);
457 506
458 val &= ~VIDINTCON0_INT_FRAME;
459 val &= ~VIDINTCON0_INT_ENABLE;507 val &= ~VIDINTCON0_INT_ENABLE;
460 508
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
461 writel(val, ctx->regs + VIDINTCON0);516 writel(val, ctx->regs + VIDINTCON0);
462 }517 }
463}518}
@@ -465,7 +520,7 @@ static void fimd_disable_vblank(struct exynos_drm_manager *mgr) · 1 unmodified line
465static void fimd_win_mode_set(struct exynos_drm_manager *mgr,520static void fimd_win_mode_set(struct exynos_drm_manager *mgr,
466 struct exynos_drm_overlay *overlay)521 struct exynos_drm_overlay *overlay)
467{522{
468 struct fimd_context *ctx = mgr->ctx;523 struct fimd_context *ctx = mgr_to_fimd(mgr);
469 struct fimd_win_data *win_data;524 struct fimd_win_data *win_data;
470 int win;525 int win;
471 unsigned long offset;526 unsigned long offset;
@@ -623,7 +678,7 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, · 151 unmodified lines
623 678
624static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)679static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos)
625{680{
626 struct fimd_context *ctx = mgr->ctx;681 struct fimd_context *ctx = mgr_to_fimd(mgr);
627 struct fimd_win_data *win_data;682 struct fimd_win_data *win_data;
628 int win = zpos;683 int win = zpos;
629 unsigned long val, alpha, size;684 unsigned long val, alpha, size;
@@ -730,20 +785,14 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) · 100 unmodified lines
730 if (win != 0)785 if (win != 0)
731 fimd_win_set_colkey(ctx, win);786 fimd_win_set_colkey(ctx, win);
732 787
733 /* wincon */788 fimd_enable_video_output(ctx, win, true);
734 val = readl(ctx->regs + WINCON(win));789
735 val |= WINCONx_ENWIN;790 if (ctx->driver_data->has_shadowcon)
736 writel(val, ctx->regs + WINCON(win));791 fimd_enable_shadow_channel_path(ctx, win, true);
737 792
738 /* Enable DMA channel and unprotect windows */793 /* Enable DMA channel and unprotect windows */
739 fimd_shadow_protect_win(ctx, win, false);794 fimd_shadow_protect_win(ctx, win, false);
740 795
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
747 win_data->enabled = true;796 win_data->enabled = true;
748 797
749 if (ctx->i80_if)798 if (ctx->i80_if)
@@ -752,10 +801,9 @@ static void fimd_win_commit(struct exynos_drm_manager *mgr, int zpos) · 2 unmodified lines
752 801
753static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)802static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos)
754{803{
755 struct fimd_context *ctx = mgr->ctx;804 struct fimd_context *ctx = mgr_to_fimd(mgr);
756 struct fimd_win_data *win_data;805 struct fimd_win_data *win_data;
757 int win = zpos;806 int win = zpos;
758 u32 val;
759 807
760 if (win == DEFAULT_ZPOS)808 if (win == DEFAULT_ZPOS)
761 win = ctx->default_win;809 win = ctx->default_win;
@@ -774,18 +822,12 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) · 12 unmodified lines
774 /* protect windows */822 /* protect windows */
775 fimd_shadow_protect_win(ctx, win, true);823 fimd_shadow_protect_win(ctx, win, true);
776 824
777 /* wincon */825 fimd_enable_video_output(ctx, win, false);
778 val = readl(ctx->regs + WINCON(win));
779 val &= ~WINCONx_ENWIN;
780 writel(val, ctx->regs + WINCON(win));
781 826
782 /* unprotect windows */827 if (ctx->driver_data->has_shadowcon)
783 if (ctx->driver_data->has_shadowcon) {828 fimd_enable_shadow_channel_path(ctx, win, false);
784 val = readl(ctx->regs + SHADOWCON);
785 val &= ~SHADOWCON_CHx_ENABLE(win);
786 writel(val, ctx->regs + SHADOWCON);
787 }
788 829
830 /* unprotect windows */
789 fimd_shadow_protect_win(ctx, win, false);831 fimd_shadow_protect_win(ctx, win, false);
790 832
791 win_data->enabled = false;833 win_data->enabled = false;
@@ -793,7 +835,7 @@ static void fimd_win_disable(struct exynos_drm_manager *mgr, int zpos) · 1 unmodified line
793 835
794static void fimd_window_suspend(struct exynos_drm_manager *mgr)836static void fimd_window_suspend(struct exynos_drm_manager *mgr)
795{837{
796 struct fimd_context *ctx = mgr->ctx;838 struct fimd_context *ctx = mgr_to_fimd(mgr);
797 struct fimd_win_data *win_data;839 struct fimd_win_data *win_data;
798 int i;840 int i;
799 841
@@ -803,12 +845,11 @@ static void fimd_window_suspend(struct exynos_drm_manager *mgr) · 3 unmodified lines
803 if (win_data->enabled)845 if (win_data->enabled)
804 fimd_win_disable(mgr, i);846 fimd_win_disable(mgr, i);
805 }847 }
806 fimd_wait_for_vblank(mgr);
807}848}
808 849
809static void fimd_window_resume(struct exynos_drm_manager *mgr)850static void fimd_window_resume(struct exynos_drm_manager *mgr)
810{851{
811 struct fimd_context *ctx = mgr->ctx;852 struct fimd_context *ctx = mgr_to_fimd(mgr);
812 struct fimd_win_data *win_data;853 struct fimd_win_data *win_data;
813 int i;854 int i;
814 855
@@ -821,7 +862,7 @@ static void fimd_window_resume(struct exynos_drm_manager *mgr) · 6 unmodified lines
821 862
822static void fimd_apply(struct exynos_drm_manager *mgr)863static void fimd_apply(struct exynos_drm_manager *mgr)
823{864{
824 struct fimd_context *ctx = mgr->ctx;865 struct fimd_context *ctx = mgr_to_fimd(mgr);
825 struct fimd_win_data *win_data;866 struct fimd_win_data *win_data;
826 int i;867 int i;
827 868
@@ -838,7 +879,7 @@ static void fimd_apply(struct exynos_drm_manager *mgr) · 10 unmodified lines
838 879
839static int fimd_poweron(struct exynos_drm_manager *mgr)880static int fimd_poweron(struct exynos_drm_manager *mgr)
840{881{
841 struct fimd_context *ctx = mgr->ctx;882 struct fimd_context *ctx = mgr_to_fimd(mgr);
842 int ret;883 int ret;
843 884
844 if (!ctx->suspended)885 if (!ctx->suspended)
@@ -886,7 +927,7 @@ bus_clk_err: · 41 unmodified lines
886 927
887static int fimd_poweroff(struct exynos_drm_manager *mgr)928static int fimd_poweroff(struct exynos_drm_manager *mgr)
888{929{
889 struct fimd_context *ctx = mgr->ctx;930 struct fimd_context *ctx = mgr_to_fimd(mgr);
890 931
891 if (ctx->suspended)932 if (ctx->suspended)
892 return 0;933 return 0;
@@ -928,39 +969,41 @@ static void fimd_dpms(struct exynos_drm_manager *mgr, int mode) · 35 unmodified lines
928 969
929static void fimd_trigger(struct device *dev)970static void fimd_trigger(struct device *dev)
930{971{
931 struct exynos_drm_manager *mgr = get_fimd_manager(dev);972 struct fimd_context *ctx = dev_get_drvdata(dev);
932 struct fimd_context *ctx = mgr->ctx;
933 struct fimd_driver_data *driver_data = ctx->driver_data;973 struct fimd_driver_data *driver_data = ctx->driver_data;
934 void *timing_base = ctx->regs + driver_data->timing_base;974 void *timing_base = ctx->regs + driver_data->timing_base;
935 u32 reg;975 u32 reg;
936 976
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;
938 983
939 reg = readl(ctx->regs + VIDINTCON0);984 /* Enters triggering mode */
940 reg |= (VIDINTCON0_INT_ENABLE | VIDINTCON0_INT_I80IFDONE |985 atomic_set(&ctx->triggering, 1);
941 VIDINTCON0_INT_SYSMAINCON);
942 writel(reg, ctx->regs + VIDINTCON0);
943 986
944 reg = readl(timing_base + TRIGCON);987 reg = readl(timing_base + TRIGCON);
945 reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);988 reg |= (TRGMODE_I80_RGB_ENABLE_I80 | SWTRGCMD_I80_RGB_ENABLE);
946 writel(reg, timing_base + TRIGCON);989 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);
947}997}
948 998
949static void fimd_te_handler(struct exynos_drm_manager *mgr)999static void fimd_te_handler(struct exynos_drm_manager *mgr)
950{1000{
951 struct fimd_context *ctx = mgr->ctx;1001 struct fimd_context *ctx = mgr_to_fimd(mgr);
952 1002
953 /* Checks the crtc is detached already from encoder */1003 /* Checks the crtc is detached already from encoder */
954 if (ctx->pipe < 0 || !ctx->drm_dev)1004 if (ctx->pipe < 0 || !ctx->drm_dev)
955 return;1005 return;
956 1006
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
964 /*1007 /*
965 * If there is a page flip request, triggers and handles the page flip1008 * If there is a page flip request, triggers and handles the page flip
966 * event so that current fb can be updated into panel GRAM.1009 * 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
972 if (atomic_read(&ctx->wait_vsync_event)) {1015 if (atomic_read(&ctx->wait_vsync_event)) {
973 atomic_set(&ctx->wait_vsync_event, 0);1016 atomic_set(&ctx->wait_vsync_event, 0);
974 wake_up(&ctx->wait_vsync_queue);1017 wake_up(&ctx->wait_vsync_queue);
975
976 if (!atomic_read(&ctx->triggering))
977 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
978 }1018 }
1019
1020 if (test_bit(0, &ctx->irq_flags))
1021 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
979}1022}
980 1023
981static struct exynos_drm_manager_ops fimd_manager_ops = {1024static struct exynos_drm_manager_ops fimd_manager_ops = {
@@ -992,11 +1035,6 @@ static struct exynos_drm_manager_ops fimd_manager_ops = { · 10 unmodified lines
992 .te_handler = fimd_te_handler,1035 .te_handler = fimd_te_handler,
993};1036};
994 1037
995static struct exynos_drm_manager fimd_manager = {
996 .type = EXYNOS_DISPLAY_TYPE_LCD,
997 .ops = &fimd_manager_ops,
998};
999
1000static irqreturn_t fimd_irq_handler(int irq, void *dev_id)1038static irqreturn_t fimd_irq_handler(int irq, void *dev_id)
1001{1039{
1002 struct fimd_context *ctx = (struct fimd_context *)dev_id;1040 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
1013 goto out;1051 goto out;
1014 1052
1015 if (ctx->i80_if) {1053 if (ctx->i80_if) {
1016 /* unset I80 frame done interrupt */1054 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
1017 val = readl(ctx->regs + VIDINTCON0);
1018 val &= ~(VIDINTCON0_INT_I80IFDONE | VIDINTCON0_INT_SYSMAINCON);
1019 writel(val, ctx->regs + VIDINTCON0);
1020 1055
1021 /* exit triggering mode */1056 /* Exits triggering mode */
1022 atomic_set(&ctx->triggering, 0);1057 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);
1026 } else {1058 } else {
1027 drm_handle_vblank(ctx->drm_dev, ctx->pipe);1059 drm_handle_vblank(ctx->drm_dev, ctx->pipe);
1028 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);1060 exynos_drm_crtc_finish_pageflip(ctx->drm_dev, ctx->pipe);
@@ -1040,11 +1072,11 @@ out: · 11 unmodified lines
1040 1072
1041static int fimd_bind(struct device *dev, struct device *master, void *data)1073static int fimd_bind(struct device *dev, struct device *master, void *data)
1042{1074{
1043 struct fimd_context *ctx = fimd_manager.ctx;1075 struct fimd_context *ctx = dev_get_drvdata(dev);
1044 struct drm_device *drm_dev = data;1076 struct drm_device *drm_dev = data;
1045 1077
1046 fimd_mgr_initialize(&fimd_manager, drm_dev);1078 fimd_mgr_initialize(&ctx->manager, drm_dev);
1047 exynos_drm_crtc_create(&fimd_manager);1079 exynos_drm_crtc_create(&ctx->manager);
1048 if (ctx->display)1080 if (ctx->display)
1049 exynos_drm_create_enc_conn(drm_dev, ctx->display);1081 exynos_drm_create_enc_conn(drm_dev, ctx->display);
1050 1082
@@ -1055,15 +1087,14 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) · 4 unmodified lines
1055static void fimd_unbind(struct device *dev, struct device *master,1087static void fimd_unbind(struct device *dev, struct device *master,
1056 void *data)1088 void *data)
1057{1089{
1058 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);1090 struct fimd_context *ctx = dev_get_drvdata(dev);
1059 struct fimd_context *ctx = fimd_manager.ctx;
1060 1091
1061 fimd_dpms(mgr, DRM_MODE_DPMS_OFF);1092 fimd_dpms(&ctx->manager, DRM_MODE_DPMS_OFF);
1062 1093
1063 if (ctx->display)1094 if (ctx->display)
1064 exynos_dpi_remove(dev);1095 exynos_dpi_remove(ctx->display);
1065 1096
1066 fimd_mgr_remove(mgr);1097 fimd_mgr_remove(&ctx->manager);
1067}1098}
1068 1099
1069static const struct component_ops fimd_component_ops = {1100static const struct component_ops fimd_component_ops = {
@@ -1079,21 +1110,20 @@ static int fimd_probe(struct platform_device *pdev) · 9 unmodified lines
1079 struct resource *res;1110 struct resource *res;
1080 int ret = -EINVAL;1111 int ret = -EINVAL;
1081 1112
1082 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,1113 if (!dev->of_node)
1083 fimd_manager.type);1114 return -ENODEV;
1084 if (ret)
1085 return ret;
1086
1087 if (!dev->of_node) {
1088 ret = -ENODEV;
1089 goto err_del_component;
1090 }
1091 1115
1092 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);1116 ctx = devm_kzalloc(dev, sizeof(*ctx), GFP_KERNEL);
1093 if (!ctx) {1117 if (!ctx)
1094 ret = -ENOMEM;1118 return -ENOMEM;
1095 goto err_del_component;1119
1096 }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;
1097 1127
1098 ctx->dev = dev;1128 ctx->dev = dev;
1099 ctx->suspended = true;1129 ctx->suspended = true;
@@ -1182,27 +1212,27 @@ static int fimd_probe(struct platform_device *pdev) · 82 unmodified lines
1182 init_waitqueue_head(&ctx->wait_vsync_queue);1212 init_waitqueue_head(&ctx->wait_vsync_queue);
1183 atomic_set(&ctx->wait_vsync_event, 0);1213 atomic_set(&ctx->wait_vsync_event, 0);
1184 1214
1185 platform_set_drvdata(pdev, &fimd_manager);1215 platform_set_drvdata(pdev, ctx);
1186
1187 fimd_manager.ctx = ctx;
1188 1216
1189 ctx->display = exynos_dpi_probe(dev);1217 ctx->display = exynos_dpi_probe(dev);
1190 if (IS_ERR(ctx->display))1218 if (IS_ERR(ctx->display)) {
1191 return PTR_ERR(ctx->display);1219 ret = PTR_ERR(ctx->display);
1220 goto err_del_component;
1221 }
1192 1222
1193 pm_runtime_enable(&pdev->dev);1223 pm_runtime_enable(dev);
1194 1224
1195 ret = component_add(&pdev->dev, &fimd_component_ops);1225 ret = component_add(dev, &fimd_component_ops);
1196 if (ret)1226 if (ret)
1197 goto err_disable_pm_runtime;1227 goto err_disable_pm_runtime;
1198 1228
1199 return ret;1229 return ret;
1200 1230
1201err_disable_pm_runtime:1231err_disable_pm_runtime:
1202 pm_runtime_disable(&pdev->dev);1232 pm_runtime_disable(dev);
1203 1233
1204err_del_component:1234err_del_component:
1205 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);1235 exynos_drm_component_del(dev, EXYNOS_DEVICE_TYPE_CRTC);
1206 return ret;1236 return ret;
1207}1237}
1208 1238
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
40 40
41#else41#else
42 42
43struct dma_iommu_mapping;
44static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)43static inline int drm_create_iommu_mapping(struct drm_device *drm_dev)
45{44{
46 return 0;45 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
426 c_node->start_work = ipp_create_cmd_work();426 c_node->start_work = ipp_create_cmd_work();
427 if (IS_ERR(c_node->start_work)) {427 if (IS_ERR(c_node->start_work)) {
428 DRM_ERROR("failed to create start work.\n");428 DRM_ERROR("failed to create start work.\n");
429 ret = PTR_ERR(c_node->start_work);
429 goto err_remove_id;430 goto err_remove_id;
430 }431 }
431 432
432 c_node->stop_work = ipp_create_cmd_work();433 c_node->stop_work = ipp_create_cmd_work();
433 if (IS_ERR(c_node->stop_work)) {434 if (IS_ERR(c_node->stop_work)) {
434 DRM_ERROR("failed to create stop work.\n");435 DRM_ERROR("failed to create stop work.\n");
436 ret = PTR_ERR(c_node->stop_work);
435 goto err_free_start;437 goto err_free_start;
436 }438 }
437 439
438 c_node->event_work = ipp_create_event_work();440 c_node->event_work = ipp_create_event_work();
439 if (IS_ERR(c_node->event_work)) {441 if (IS_ERR(c_node->event_work)) {
440 DRM_ERROR("failed to create event work.\n");442 DRM_ERROR("failed to create event work.\n");
443 ret = PTR_ERR(c_node->event_work);
441 goto err_free_stop;444 goto err_free_stop;
442 }445 }
443 446
drivers/gpu/drm/exynos/exynos_drm_vidi.c+92−58
@@ -14,6 +14,7 @@ · 13 unmodified lines
14 14
15#include <linux/kernel.h>15#include <linux/kernel.h>
16#include <linux/platform_device.h>16#include <linux/platform_device.h>
17#include <linux/component.h>
17 18
18#include <drm/exynos_drm.h>19#include <drm/exynos_drm.h>
19 20
@@ -28,7 +29,6 @@ · 8 unmodified lines
28/* vidi has totally three virtual windows. */29/* vidi has totally three virtual windows. */
29#define WINDOWS_NR 330#define WINDOWS_NR 3
30 31
31#define get_vidi_mgr(dev) platform_get_drvdata(to_platform_device(dev))
32#define ctx_from_connector(c) container_of(c, struct vidi_context, \32#define ctx_from_connector(c) container_of(c, struct vidi_context, \
33 connector)33 connector)
34 34
@@ -47,11 +47,13 @@ struct vidi_win_data { · 12 unmodified lines
47};47};
48 48
49struct vidi_context {49struct vidi_context {
50 struct exynos_drm_manager manager;
51 struct exynos_drm_display display;
52 struct platform_device *pdev;
50 struct drm_device *drm_dev;53 struct drm_device *drm_dev;
51 struct drm_crtc *crtc;54 struct drm_crtc *crtc;
52 struct drm_encoder *encoder;55 struct drm_encoder *encoder;
53 struct drm_connector connector;56 struct drm_connector connector;
54 struct exynos_drm_subdrv subdrv;
55 struct vidi_win_data win_data[WINDOWS_NR];57 struct vidi_win_data win_data[WINDOWS_NR];
56 struct edid *raw_edid;58 struct edid *raw_edid;
57 unsigned int clkdiv;59 unsigned int clkdiv;
@@ -66,6 +68,16 @@ struct vidi_context { · 8 unmodified lines
66 int pipe;68 int pipe;
67};69};
68 70
71static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
72{
73 return container_of(m, struct vidi_context, manager);
74}
75
76static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
77{
78 return container_of(d, struct vidi_context, display);
79}
80
69static const char fake_edid_info[] = {81static const char fake_edid_info[] = {
70 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,82 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x4c, 0x2d, 0x05, 0x05,
71 0x00, 0x00, 0x00, 0x00, 0x30, 0x12, 0x01, 0x03, 0x80, 0x10, 0x09, 0x78,83 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
93 105
94static void vidi_apply(struct exynos_drm_manager *mgr)106static void vidi_apply(struct exynos_drm_manager *mgr)
95{107{
96 struct vidi_context *ctx = mgr->ctx;108 struct vidi_context *ctx = manager_to_vidi(mgr);
97 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;109 struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
98 struct vidi_win_data *win_data;110 struct vidi_win_data *win_data;
99 int i;111 int i;
@@ -110,7 +122,7 @@ static void vidi_apply(struct exynos_drm_manager *mgr) · 10 unmodified lines
110 122
111static void vidi_commit(struct exynos_drm_manager *mgr)123static void vidi_commit(struct exynos_drm_manager *mgr)
112{124{
113 struct vidi_context *ctx = mgr->ctx;125 struct vidi_context *ctx = manager_to_vidi(mgr);
114 126
115 if (ctx->suspended)127 if (ctx->suspended)
116 return;128 return;
@@ -118,7 +130,7 @@ static void vidi_commit(struct exynos_drm_manager *mgr) · 1 unmodified line
118 130
119static int vidi_enable_vblank(struct exynos_drm_manager *mgr)131static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
120{132{
121 struct vidi_context *ctx = mgr->ctx;133 struct vidi_context *ctx = manager_to_vidi(mgr);
122 134
123 if (ctx->suspended)135 if (ctx->suspended)
124 return -EPERM;136 return -EPERM;
@@ -140,7 +152,7 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr) · 15 unmodified lines
140 152
141static void vidi_disable_vblank(struct exynos_drm_manager *mgr)153static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
142{154{
143 struct vidi_context *ctx = mgr->ctx;155 struct vidi_context *ctx = manager_to_vidi(mgr);
144 156
145 if (ctx->suspended)157 if (ctx->suspended)
146 return;158 return;
@@ -152,7 +164,7 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr) · 5 unmodified lines
152static void vidi_win_mode_set(struct exynos_drm_manager *mgr,164static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
153 struct exynos_drm_overlay *overlay)165 struct exynos_drm_overlay *overlay)
154{166{
155 struct vidi_context *ctx = mgr->ctx;167 struct vidi_context *ctx = manager_to_vidi(mgr);
156 struct vidi_win_data *win_data;168 struct vidi_win_data *win_data;
157 int win;169 int win;
158 unsigned long offset;170 unsigned long offset;
@@ -204,7 +216,7 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr, · 45 unmodified lines
204 216
205static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)217static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
206{218{
207 struct vidi_context *ctx = mgr->ctx;219 struct vidi_context *ctx = manager_to_vidi(mgr);
208 struct vidi_win_data *win_data;220 struct vidi_win_data *win_data;
209 int win = zpos;221 int win = zpos;
210 222
@@ -229,7 +241,7 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos) · 18 unmodified lines
229 241
230static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)242static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
231{243{
232 struct vidi_context *ctx = mgr->ctx;244 struct vidi_context *ctx = manager_to_vidi(mgr);
233 struct vidi_win_data *win_data;245 struct vidi_win_data *win_data;
234 int win = zpos;246 int win = zpos;
235 247
@@ -247,7 +259,7 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos) · 11 unmodified lines
247 259
248static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)260static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
249{261{
250 struct vidi_context *ctx = mgr->ctx;262 struct vidi_context *ctx = manager_to_vidi(mgr);
251 263
252 DRM_DEBUG_KMS("%s\n", __FILE__);264 DRM_DEBUG_KMS("%s\n", __FILE__);
253 265
@@ -271,7 +283,7 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable) · 17 unmodified lines
271 283
272static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)284static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
273{285{
274 struct vidi_context *ctx = mgr->ctx;286 struct vidi_context *ctx = manager_to_vidi(mgr);
275 287
276 DRM_DEBUG_KMS("%d\n", mode);288 DRM_DEBUG_KMS("%d\n", mode);
277 289
@@ -297,7 +309,7 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode) · 19 unmodified lines
297static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,309static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
298 struct drm_device *drm_dev)310 struct drm_device *drm_dev)
299{311{
300 struct vidi_context *ctx = mgr->ctx;312 struct vidi_context *ctx = manager_to_vidi(mgr);
301 struct exynos_drm_private *priv = drm_dev->dev_private;313 struct exynos_drm_private *priv = drm_dev->dev_private;
302 314
303 mgr->drm_dev = ctx->drm_dev = drm_dev;315 mgr->drm_dev = ctx->drm_dev = drm_dev;
@@ -316,11 +328,6 @@ static struct exynos_drm_manager_ops vidi_manager_ops = { · 12 unmodified lines
316 .win_disable = vidi_win_disable,328 .win_disable = vidi_win_disable,
317};329};
318 330
319static struct exynos_drm_manager vidi_manager = {
320 .type = EXYNOS_DISPLAY_TYPE_VIDI,
321 .ops = &vidi_manager_ops,
322};
323
324static void vidi_fake_vblank_handler(struct work_struct *work)331static void vidi_fake_vblank_handler(struct work_struct *work)
325{332{
326 struct vidi_context *ctx = container_of(work, struct vidi_context,333 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
349static int vidi_show_connection(struct device *dev,356static int vidi_show_connection(struct device *dev,
350 struct device_attribute *attr, char *buf)357 struct device_attribute *attr, char *buf)
351{358{
359 struct vidi_context *ctx = dev_get_drvdata(dev);
352 int rc;360 int rc;
353 struct exynos_drm_manager *mgr = get_vidi_mgr(dev);
354 struct vidi_context *ctx = mgr->ctx;
355 361
356 mutex_lock(&ctx->lock);362 mutex_lock(&ctx->lock);
357 363
@@ -366,8 +372,7 @@ static int vidi_store_connection(struct device *dev, · 8 unmodified lines
366 struct device_attribute *attr,372 struct device_attribute *attr,
367 const char *buf, size_t len)373 const char *buf, size_t len)
368{374{
369 struct exynos_drm_manager *mgr = get_vidi_mgr(dev);375 struct vidi_context *ctx = dev_get_drvdata(dev);
370 struct vidi_context *ctx = mgr->ctx;
371 int ret;376 int ret;
372 377
373 ret = kstrtoint(buf, 0, &ctx->connected);378 ret = kstrtoint(buf, 0, &ctx->connected);
@@ -420,7 +425,7 @@ int vidi_connection_ioctl(struct drm_device *drm_dev, void *data, · 46 unmodified lines
420 display = exynos_drm_get_display(encoder);425 display = exynos_drm_get_display(encoder);
421 426
422 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {427 if (display->type == EXYNOS_DISPLAY_TYPE_VIDI) {
423 ctx = display->ctx;428 ctx = display_to_vidi(display);
424 break;429 break;
425 }430 }
426 }431 }
@@ -530,7 +535,7 @@ static struct drm_connector_helper_funcs vidi_connector_helper_funcs = { · 103 unmodified lines
530static int vidi_create_connector(struct exynos_drm_display *display,535static int vidi_create_connector(struct exynos_drm_display *display,
531 struct drm_encoder *encoder)536 struct drm_encoder *encoder)
532{537{
533 struct vidi_context *ctx = display->ctx;538 struct vidi_context *ctx = display_to_vidi(display);
534 struct drm_connector *connector = &ctx->connector;539 struct drm_connector *connector = &ctx->connector;
535 int ret;540 int ret;
536 541
@@ -556,27 +561,22 @@ static struct exynos_drm_display_ops vidi_display_ops = { · 19 unmodified lines
556 .create_connector = vidi_create_connector,561 .create_connector = vidi_create_connector,
557};562};
558 563
559static struct exynos_drm_display vidi_display = {564static int vidi_bind(struct device *dev, struct device *master, void *data)
560 .type = EXYNOS_DISPLAY_TYPE_VIDI,
561 .ops = &vidi_display_ops,
562};
563
564static int vidi_subdrv_probe(struct drm_device *drm_dev, struct device *dev)
565{565{
566 struct exynos_drm_manager *mgr = get_vidi_mgr(dev);566 struct vidi_context *ctx = dev_get_drvdata(dev);
567 struct vidi_context *ctx = mgr->ctx;567 struct drm_device *drm_dev = data;
568 struct drm_crtc *crtc = ctx->crtc;568 struct drm_crtc *crtc = ctx->crtc;
569 int ret;569 int ret;
570 570
571 vidi_mgr_initialize(mgr, drm_dev);571 vidi_mgr_initialize(&ctx->manager, drm_dev);
572 572
573 ret = exynos_drm_crtc_create(&vidi_manager);573 ret = exynos_drm_crtc_create(&ctx->manager);
574 if (ret) {574 if (ret) {
575 DRM_ERROR("failed to create crtc.\n");575 DRM_ERROR("failed to create crtc.\n");
576 return ret;576 return ret;
577 }577 }
578 578
579 ret = exynos_drm_create_enc_conn(drm_dev, &vidi_display);579 ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
580 if (ret) {580 if (ret) {
581 crtc->funcs->destroy(crtc);581 crtc->funcs->destroy(crtc);
582 DRM_ERROR("failed to create encoder and connector.\n");582 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
586 return 0;586 return 0;
587}587}
588 588
589
590static void vidi_unbind(struct device *dev, struct device *master, void *data)
591{
592}
593
594static const struct component_ops vidi_component_ops = {
595 .bind = vidi_bind,
596 .unbind = vidi_unbind,
597};
598
589static int vidi_probe(struct platform_device *pdev)599static int vidi_probe(struct platform_device *pdev)
590{600{
591 struct exynos_drm_subdrv *subdrv;
592 struct vidi_context *ctx;601 struct vidi_context *ctx;
593 int ret;602 int ret;
594 603
@@ -596,40 +605,54 @@ static int vidi_probe(struct platform_device *pdev) · 1 unmodified line
596 if (!ctx)605 if (!ctx)
597 return -ENOMEM;606 return -ENOMEM;
598 607
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;
599 ctx->default_win = 0;612 ctx->default_win = 0;
613 ctx->pdev = pdev;
600 614
601 INIT_WORK(&ctx->work, vidi_fake_vblank_handler);615 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
602 616 ctx->manager.type);
603 vidi_manager.ctx = ctx;617 if (ret)
604 vidi_display.ctx = ctx;618 return ret;
605 619
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;
607 624
608 platform_set_drvdata(pdev, &vidi_manager);625 INIT_WORK(&ctx->work, vidi_fake_vblank_handler);
609 626
610 subdrv = &ctx->subdrv;627 mutex_init(&ctx->lock);
611 subdrv->dev = &pdev->dev;
612 subdrv->probe = vidi_subdrv_probe;
613 628
614 ret = exynos_drm_subdrv_register(subdrv);629 platform_set_drvdata(pdev, ctx);
615 if (ret < 0) {
616 dev_err(&pdev->dev, "failed to register drm vidi device\n");
617 return ret;
618 }
619 630
620 ret = device_create_file(&pdev->dev, &dev_attr_connection);631 ret = device_create_file(&pdev->dev, &dev_attr_connection);
621 if (ret < 0) {632 if (ret < 0) {
622 exynos_drm_subdrv_unregister(subdrv);633 DRM_ERROR("failed to create connection sysfs.\n");
623 DRM_INFO("failed to create connection sysfs.\n");634 goto err_del_conn_component;
624 }635 }
625 636
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
643err_remove_file:
644 device_remove_file(&pdev->dev, &dev_attr_connection);
645err_del_conn_component:
646 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR);
647err_del_crtc_component:
648 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
649
650 return ret;
627}651}
628 652
629static int vidi_remove(struct platform_device *pdev)653static int vidi_remove(struct platform_device *pdev)
630{654{
631 struct exynos_drm_manager *mgr = platform_get_drvdata(pdev);655 struct vidi_context *ctx = platform_get_drvdata(pdev);
632 struct vidi_context *ctx = mgr->ctx;
633 656
634 if (ctx->raw_edid != (struct edid *)fake_edid_info) {657 if (ctx->raw_edid != (struct edid *)fake_edid_info) {
635 kfree(ctx->raw_edid);658 kfree(ctx->raw_edid);
@@ -638,6 +661,10 @@ static int vidi_remove(struct platform_device *pdev) · 2 unmodified lines
638 return -EINVAL;661 return -EINVAL;
639 }662 }
640 663
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
641 return 0;668 return 0;
642}669}
643 670
@@ -668,12 +695,19 @@ int exynos_drm_probe_vidi(void) · 24 unmodified lines
668 return ret;695 return ret;
669}696}
670 697
698static 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
671void exynos_drm_remove_vidi(void)705void exynos_drm_remove_vidi(void)
672{706{
673 struct vidi_context *ctx = vidi_manager.ctx;707 int ret = driver_for_each_device(&vidi_driver.driver, NULL, NULL,
674 struct exynos_drm_subdrv *subdrv = &ctx->subdrv;708 exynos_drm_remove_vidi_device);
675 struct platform_device *pdev = to_platform_device(subdrv->dev);709 /* silence compiler warning */
710 (void)ret;
676 711
677 platform_driver_unregister(&vidi_driver);712 platform_driver_unregister(&vidi_driver);
678 platform_device_unregister(pdev);
679}713}
drivers/gpu/drm/exynos/exynos_hdmi.c+30−35
@@ -49,7 +49,6 @@ · 48 unmodified lines
49#include <linux/gpio.h>49#include <linux/gpio.h>
50#include <media/s5p_hdmi.h>50#include <media/s5p_hdmi.h>
51 51
52#define get_hdmi_display(dev) platform_get_drvdata(to_platform_device(dev))
53#define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)52#define ctx_from_connector(c) container_of(c, struct hdmi_context, connector)
54 53
55#define HOTPLUG_DEBOUNCE_MS 110054#define HOTPLUG_DEBOUNCE_MS 1100
@@ -182,6 +181,7 @@ struct hdmi_conf_regs { · 126 unmodified lines
182};181};
183 182
184struct hdmi_context {183struct hdmi_context {
184 struct exynos_drm_display display;
185 struct device *dev;185 struct device *dev;
186 struct drm_device *drm_dev;186 struct drm_device *drm_dev;
187 struct drm_connector connector;187 struct drm_connector connector;
@@ -213,6 +213,11 @@ struct hdmi_context { · 25 unmodified lines
213 enum hdmi_type type;213 enum hdmi_type type;
214};214};
215 215
216static inline struct hdmi_context *display_to_hdmi(struct exynos_drm_display *d)
217{
218 return container_of(d, struct hdmi_context, display);
219}
220
216struct hdmiphy_config {221struct hdmiphy_config {
217 int pixel_clock;222 int pixel_clock;
218 u8 conf[32];223 u8 conf[32];
@@ -1123,7 +1128,7 @@ static struct drm_connector_helper_funcs hdmi_connector_helper_funcs = { · 904 unmodified lines
1123static int hdmi_create_connector(struct exynos_drm_display *display,1128static int hdmi_create_connector(struct exynos_drm_display *display,
1124 struct drm_encoder *encoder)1129 struct drm_encoder *encoder)
1125{1130{
1126 struct hdmi_context *hdata = display->ctx;1131 struct hdmi_context *hdata = display_to_hdmi(display);
1127 struct drm_connector *connector = &hdata->connector;1132 struct drm_connector *connector = &hdata->connector;
1128 int ret;1133 int ret;
1129 1134
@@ -2000,7 +2005,7 @@ static void hdmi_v14_mode_set(struct hdmi_context *hdata, · 870 unmodified lines
2000static void hdmi_mode_set(struct exynos_drm_display *display,2005static void hdmi_mode_set(struct exynos_drm_display *display,
2001 struct drm_display_mode *mode)2006 struct drm_display_mode *mode)
2002{2007{
2003 struct hdmi_context *hdata = display->ctx;2008 struct hdmi_context *hdata = display_to_hdmi(display);
2004 struct drm_display_mode *m = mode;2009 struct drm_display_mode *m = mode;
2005 2010
2006 DRM_DEBUG_KMS("xres=%d, yres=%d, refresh=%d, intl=%s\n",2011 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
2019 2024
2020static void hdmi_commit(struct exynos_drm_display *display)2025static void hdmi_commit(struct exynos_drm_display *display)
2021{2026{
2022 struct hdmi_context *hdata = display->ctx;2027 struct hdmi_context *hdata = display_to_hdmi(display);
2023 2028
2024 mutex_lock(&hdata->hdmi_mutex);2029 mutex_lock(&hdata->hdmi_mutex);
2025 if (!hdata->powered) {2030 if (!hdata->powered) {
@@ -2033,7 +2038,7 @@ static void hdmi_commit(struct exynos_drm_display *display) · 7 unmodified lines
2033 2038
2034static void hdmi_poweron(struct exynos_drm_display *display)2039static void hdmi_poweron(struct exynos_drm_display *display)
2035{2040{
2036 struct hdmi_context *hdata = display->ctx;2041 struct hdmi_context *hdata = display_to_hdmi(display);
2037 struct hdmi_resources *res = &hdata->res;2042 struct hdmi_resources *res = &hdata->res;
2038 2043
2039 mutex_lock(&hdata->hdmi_mutex);2044 mutex_lock(&hdata->hdmi_mutex);
@@ -2064,7 +2069,7 @@ static void hdmi_poweron(struct exynos_drm_display *display) · 24 unmodified lines
2064 2069
2065static void hdmi_poweroff(struct exynos_drm_display *display)2070static void hdmi_poweroff(struct exynos_drm_display *display)
2066{2071{
2067 struct hdmi_context *hdata = display->ctx;2072 struct hdmi_context *hdata = display_to_hdmi(display);
2068 struct hdmi_resources *res = &hdata->res;2073 struct hdmi_resources *res = &hdata->res;
2069 2074
2070 mutex_lock(&hdata->hdmi_mutex);2075 mutex_lock(&hdata->hdmi_mutex);
@@ -2099,7 +2104,7 @@ out: · 28 unmodified lines
2099 2104
2100static void hdmi_dpms(struct exynos_drm_display *display, int mode)2105static void hdmi_dpms(struct exynos_drm_display *display, int mode)
2101{2106{
2102 struct hdmi_context *hdata = display->ctx;2107 struct hdmi_context *hdata = display_to_hdmi(display);
2103 struct drm_encoder *encoder = hdata->encoder;2108 struct drm_encoder *encoder = hdata->encoder;
2104 struct drm_crtc *crtc = encoder->crtc;2109 struct drm_crtc *crtc = encoder->crtc;
2105 struct drm_crtc_helper_funcs *funcs = NULL;2110 struct drm_crtc_helper_funcs *funcs = NULL;
@@ -2143,11 +2148,6 @@ static struct exynos_drm_display_ops hdmi_display_ops = { · 37 unmodified lines
2143 .commit = hdmi_commit,2148 .commit = hdmi_commit,
2144};2149};
2145 2150
2146static struct exynos_drm_display hdmi_display = {
2147 .type = EXYNOS_DISPLAY_TYPE_HDMI,
2148 .ops = &hdmi_display_ops,
2149};
2150
2151static void hdmi_hotplug_work_func(struct work_struct *work)2151static void hdmi_hotplug_work_func(struct work_struct *work)
2152{2152{
2153 struct hdmi_context *hdata;2153 struct hdmi_context *hdata;
@@ -2302,12 +2302,11 @@ MODULE_DEVICE_TABLE (of, hdmi_match_types); · 148 unmodified lines
2302static int hdmi_bind(struct device *dev, struct device *master, void *data)2302static int hdmi_bind(struct device *dev, struct device *master, void *data)
2303{2303{
2304 struct drm_device *drm_dev = data;2304 struct drm_device *drm_dev = data;
2305 struct hdmi_context *hdata;2305 struct hdmi_context *hdata = dev_get_drvdata(dev);
2306 2306
2307 hdata = hdmi_display.ctx;
2308 hdata->drm_dev = drm_dev;2307 hdata->drm_dev = drm_dev;
2309 2308
2310 return exynos_drm_create_enc_conn(drm_dev, &hdmi_display);2309 return exynos_drm_create_enc_conn(drm_dev, &hdata->display);
2311}2310}
2312 2311
2313static void hdmi_unbind(struct device *dev, struct device *master, void *data)2312static 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
2349 struct resource *res;2348 struct resource *res;
2350 int ret;2349 int ret;
2351 2350
2352 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CONNECTOR,2351 if (!dev->of_node)
2353 hdmi_display.type);2352 return -ENODEV;
2354 if (ret)
2355 return ret;
2356
2357 if (!dev->of_node) {
2358 ret = -ENODEV;
2359 goto err_del_component;
2360 }
2361 2353
2362 pdata = drm_hdmi_dt_parse_pdata(dev);2354 pdata = drm_hdmi_dt_parse_pdata(dev);
2363 if (!pdata) {2355 if (!pdata)
2364 ret = -EINVAL;2356 return -EINVAL;
2365 goto err_del_component;
2366 }
2367 2357
2368 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);2358 hdata = devm_kzalloc(dev, sizeof(struct hdmi_context), GFP_KERNEL);
2369 if (!hdata) {2359 if (!hdata)
2370 ret = -ENOMEM;2360 return -ENOMEM;
2371 goto err_del_component;2361
2372 }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;
2373 2369
2374 mutex_init(&hdata->hdmi_mutex);2370 mutex_init(&hdata->hdmi_mutex);
2375 2371
2376 platform_set_drvdata(pdev, &hdmi_display);2372 platform_set_drvdata(pdev, hdata);
2377 2373
2378 match = of_match_node(hdmi_match_types, dev->of_node);2374 match = of_match_node(hdmi_match_types, dev->of_node);
2379 if (!match) {2375 if (!match) {
@@ -2485,7 +2481,6 @@ out_get_phy_port: · 105 unmodified lines
2485 }2481 }
2486 2482
2487 pm_runtime_enable(dev);2483 pm_runtime_enable(dev);
2488 hdmi_display.ctx = hdata;
2489 2484
2490 ret = component_add(&pdev->dev, &hdmi_component_ops);2485 ret = component_add(&pdev->dev, &hdmi_component_ops);
2491 if (ret)2486 if (ret)
@@ -2510,7 +2505,7 @@ err_del_component: · 18 unmodified lines
2510 2505
2511static int hdmi_remove(struct platform_device *pdev)2506static int hdmi_remove(struct platform_device *pdev)
2512{2507{
2513 struct hdmi_context *hdata = hdmi_display.ctx;2508 struct hdmi_context *hdata = platform_get_drvdata(pdev);
2514 2509
2515 cancel_delayed_work_sync(&hdata->hotplug_work);2510 cancel_delayed_work_sync(&hdata->hotplug_work);
2516 2511
drivers/gpu/drm/exynos/exynos_mixer.c+66−60
@@ -40,8 +40,6 @@ · 39 unmodified lines
40#include "exynos_drm_iommu.h"40#include "exynos_drm_iommu.h"
41#include "exynos_mixer.h"41#include "exynos_mixer.h"
42 42
43#define get_mixer_manager(dev) platform_get_drvdata(to_platform_device(dev))
44
45#define MIXER_WIN_NR 343#define MIXER_WIN_NR 3
46#define MIXER_DEFAULT_WIN 044#define MIXER_DEFAULT_WIN 0
47 45
@@ -86,6 +84,7 @@ enum mixer_version_id { · 38 unmodified lines
86};84};
87 85
88struct mixer_context {86struct mixer_context {
87 struct exynos_drm_manager manager;
89 struct platform_device *pdev;88 struct platform_device *pdev;
90 struct device *dev;89 struct device *dev;
91 struct drm_device *drm_dev;90 struct drm_device *drm_dev;
@@ -104,6 +103,11 @@ struct mixer_context { · 12 unmodified lines
104 atomic_t wait_vsync_event;103 atomic_t wait_vsync_event;
105};104};
106 105
106static inline struct mixer_context *mgr_to_mixer(struct exynos_drm_manager *mgr)
107{
108 return container_of(mgr, struct mixer_context, manager);
109}
110
107struct mixer_drv_data {111struct mixer_drv_data {
108 enum mixer_version_id version;112 enum mixer_version_id version;
109 bool is_vp_enabled;113 bool is_vp_enabled;
@@ -854,7 +858,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, · 744 unmodified lines
854 struct drm_device *drm_dev)858 struct drm_device *drm_dev)
855{859{
856 int ret;860 int ret;
857 struct mixer_context *mixer_ctx = mgr->ctx;861 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
858 struct exynos_drm_private *priv;862 struct exynos_drm_private *priv;
859 priv = drm_dev->dev_private;863 priv = drm_dev->dev_private;
860 864
@@ -885,7 +889,7 @@ static int mixer_initialize(struct exynos_drm_manager *mgr, · 24 unmodified lines
885 889
886static void mixer_mgr_remove(struct exynos_drm_manager *mgr)890static void mixer_mgr_remove(struct exynos_drm_manager *mgr)
887{891{
888 struct mixer_context *mixer_ctx = mgr->ctx;892 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
889 893
890 if (is_drm_iommu_supported(mixer_ctx->drm_dev))894 if (is_drm_iommu_supported(mixer_ctx->drm_dev))
891 drm_iommu_detach_device(mixer_ctx->drm_dev, mixer_ctx->dev);895 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
893 897
894static int mixer_enable_vblank(struct exynos_drm_manager *mgr)898static int mixer_enable_vblank(struct exynos_drm_manager *mgr)
895{899{
896 struct mixer_context *mixer_ctx = mgr->ctx;900 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
897 struct mixer_resources *res = &mixer_ctx->mixer_res;901 struct mixer_resources *res = &mixer_ctx->mixer_res;
898 902
899 if (!mixer_ctx->powered) {903 if (!mixer_ctx->powered) {
@@ -910,7 +914,7 @@ static int mixer_enable_vblank(struct exynos_drm_manager *mgr) · 10 unmodified lines
910 914
911static void mixer_disable_vblank(struct exynos_drm_manager *mgr)915static void mixer_disable_vblank(struct exynos_drm_manager *mgr)
912{916{
913 struct mixer_context *mixer_ctx = mgr->ctx;917 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
914 struct mixer_resources *res = &mixer_ctx->mixer_res;918 struct mixer_resources *res = &mixer_ctx->mixer_res;
915 919
916 /* disable vsync interrupt */920 /* disable vsync interrupt */
@@ -920,7 +924,7 @@ static void mixer_disable_vblank(struct exynos_drm_manager *mgr) · 3 unmodified lines
920static void mixer_win_mode_set(struct exynos_drm_manager *mgr,924static void mixer_win_mode_set(struct exynos_drm_manager *mgr,
921 struct exynos_drm_overlay *overlay)925 struct exynos_drm_overlay *overlay)
922{926{
923 struct mixer_context *mixer_ctx = mgr->ctx;927 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
924 struct hdmi_win_data *win_data;928 struct hdmi_win_data *win_data;
925 int win;929 int win;
926 930
@@ -971,7 +975,7 @@ static void mixer_win_mode_set(struct exynos_drm_manager *mgr, · 44 unmodified lines
971 975
972static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)976static void mixer_win_commit(struct exynos_drm_manager *mgr, int zpos)
973{977{
974 struct mixer_context *mixer_ctx = mgr->ctx;978 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
975 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;979 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
976 980
977 DRM_DEBUG_KMS("win: %d\n", win);981 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
993 997
994static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)998static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos)
995{999{
996 struct mixer_context *mixer_ctx = mgr->ctx;1000 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
997 struct mixer_resources *res = &mixer_ctx->mixer_res;1001 struct mixer_resources *res = &mixer_ctx->mixer_res;
998 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;1002 int win = zpos == DEFAULT_ZPOS ? MIXER_DEFAULT_WIN : zpos;
999 unsigned long flags;1003 unsigned long flags;
@@ -1021,7 +1025,7 @@ static void mixer_win_disable(struct exynos_drm_manager *mgr, int zpos) · 21 unmodified lines
1021 1025
1022static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)1026static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr)
1023{1027{
1024 struct mixer_context *mixer_ctx = mgr->ctx;1028 struct mixer_context *mixer_ctx = mgr_to_mixer(mgr);
1025 1029
1026 mutex_lock(&mixer_ctx->mixer_mutex);1030 mutex_lock(&mixer_ctx->mixer_mutex);
1027 if (!mixer_ctx->powered) {1031 if (!mixer_ctx->powered) {
@@ -1048,7 +1052,7 @@ static void mixer_wait_for_vblank(struct exynos_drm_manager *mgr) · 20 unmodified lines
1048 1052
1049static void mixer_window_suspend(struct exynos_drm_manager *mgr)1053static void mixer_window_suspend(struct exynos_drm_manager *mgr)
1050{1054{
1051 struct mixer_context *ctx = mgr->ctx;1055 struct mixer_context *ctx = mgr_to_mixer(mgr);
1052 struct hdmi_win_data *win_data;1056 struct hdmi_win_data *win_data;
1053 int i;1057 int i;
1054 1058
@@ -1062,7 +1066,7 @@ static void mixer_window_suspend(struct exynos_drm_manager *mgr) · 7 unmodified lines
1062 1066
1063static void mixer_window_resume(struct exynos_drm_manager *mgr)1067static void mixer_window_resume(struct exynos_drm_manager *mgr)
1064{1068{
1065 struct mixer_context *ctx = mgr->ctx;1069 struct mixer_context *ctx = mgr_to_mixer(mgr);
1066 struct hdmi_win_data *win_data;1070 struct hdmi_win_data *win_data;
1067 int i;1071 int i;
1068 1072
@@ -1077,7 +1081,7 @@ static void mixer_window_resume(struct exynos_drm_manager *mgr) · 8 unmodified lines
1077 1081
1078static void mixer_poweron(struct exynos_drm_manager *mgr)1082static void mixer_poweron(struct exynos_drm_manager *mgr)
1079{1083{
1080 struct mixer_context *ctx = mgr->ctx;1084 struct mixer_context *ctx = mgr_to_mixer(mgr);
1081 struct mixer_resources *res = &ctx->mixer_res;1085 struct mixer_resources *res = &ctx->mixer_res;
1082 1086
1083 mutex_lock(&ctx->mixer_mutex);1087 mutex_lock(&ctx->mixer_mutex);
@@ -1111,7 +1115,7 @@ static void mixer_poweron(struct exynos_drm_manager *mgr) · 27 unmodified lines
1111 1115
1112static void mixer_poweroff(struct exynos_drm_manager *mgr)1116static void mixer_poweroff(struct exynos_drm_manager *mgr)
1113{1117{
1114 struct mixer_context *ctx = mgr->ctx;1118 struct mixer_context *ctx = mgr_to_mixer(mgr);
1115 struct mixer_resources *res = &ctx->mixer_res;1119 struct mixer_resources *res = &ctx->mixer_res;
1116 1120
1117 mutex_lock(&ctx->mixer_mutex);1121 mutex_lock(&ctx->mixer_mutex);
@@ -1187,11 +1191,6 @@ static struct exynos_drm_manager_ops mixer_manager_ops = { · 69 unmodified lines
1187 .win_disable = mixer_win_disable,1191 .win_disable = mixer_win_disable,
1188};1192};
1189 1193
1190static struct exynos_drm_manager mixer_manager = {
1191 .type = EXYNOS_DISPLAY_TYPE_HDMI,
1192 .ops = &mixer_manager_ops,
1193};
1194
1195static struct mixer_drv_data exynos5420_mxr_drv_data = {1194static struct mixer_drv_data exynos5420_mxr_drv_data = {
1196 .version = MXR_VER_128_0_0_184,1195 .version = MXR_VER_128_0_0_184,
1197 .is_vp_enabled = 0,1196 .is_vp_enabled = 0,
@@ -1249,48 +1248,17 @@ MODULE_DEVICE_TABLE(of, mixer_match_types); · 51 unmodified lines
1249 1248
1250static int mixer_bind(struct device *dev, struct device *manager, void *data)1249static int mixer_bind(struct device *dev, struct device *manager, void *data)
1251{1250{
1252 struct platform_device *pdev = to_platform_device(dev);1251 struct mixer_context *ctx = dev_get_drvdata(dev);
1253 struct drm_device *drm_dev = data;1252 struct drm_device *drm_dev = data;
1254 struct mixer_context *ctx;
1255 struct mixer_drv_data *drv;
1256 int ret;1253 int ret;
1257 1254
1258 dev_info(dev, "probe start\n");1255 ret = mixer_initialize(&ctx->manager, drm_dev);
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);
1287 if (ret)1256 if (ret)
1288 return ret;1257 return ret;
1289 1258
1290 platform_set_drvdata(pdev, &mixer_manager);1259 ret = exynos_drm_crtc_create(&ctx->manager);
1291 ret = exynos_drm_crtc_create(&mixer_manager);
1292 if (ret) {1260 if (ret) {
1293 mixer_mgr_remove(&mixer_manager);1261 mixer_mgr_remove(&ctx->manager);
1294 return ret;1262 return ret;
1295 }1263 }
1296 1264
@@ -1301,11 +1269,9 @@ static int mixer_bind(struct device *dev, struct device *manager, void *data) · 4 unmodified lines
1301 1269
1302static void mixer_unbind(struct device *dev, struct device *master, void *data)1270static void mixer_unbind(struct device *dev, struct device *master, void *data)
1303{1271{
1304 struct exynos_drm_manager *mgr = dev_get_drvdata(dev);1272 struct mixer_context *ctx = dev_get_drvdata(dev);
1305 1273
1306 dev_info(dev, "remove successful\n");1274 mixer_mgr_remove(&ctx->manager);
1307
1308 mixer_mgr_remove(mgr);
1309 1275
1310 pm_runtime_disable(dev);1276 pm_runtime_disable(dev);
1311}1277}
@@ -1317,22 +1283,62 @@ static const struct component_ops mixer_component_ops = { · 5 unmodified lines
1317 1283
1318static int mixer_probe(struct platform_device *pdev)1284static int mixer_probe(struct platform_device *pdev)
1319{1285{
1286 struct device *dev = &pdev->dev;
1287 struct mixer_drv_data *drv;
1288 struct mixer_context *ctx;
1320 int ret;1289 int ret;
1321 1290
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
1322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,1322 ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
1323 mixer_manager.type);1323 ctx->manager.type);
1324 if (ret)1324 if (ret)
1325 return ret;1325 return ret;
1326 1326
1327 ret = component_add(&pdev->dev, &mixer_component_ops);1327 ret = component_add(&pdev->dev, &mixer_component_ops);
1328 if (ret)1328 if (ret) {
1329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);1329 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1330 return ret;
1331 }
1332
1333 pm_runtime_enable(dev);
1330 1334
1331 return ret;1335 return ret;
1332}1336}
1333 1337
1334static int mixer_remove(struct platform_device *pdev)1338static int mixer_remove(struct platform_device *pdev)
1335{1339{
1340 pm_runtime_disable(&pdev->dev);
1341
1336 component_del(&pdev->dev, &mixer_component_ops);1342 component_del(&pdev->dev, &mixer_component_ops);
1337 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);1343 exynos_drm_component_del(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC);
1338 1344
drivers/gpu/drm/gma500/Makefile+1−0
@@ -39,6 +39,7 @@ gma500_gfx-$(CONFIG_DRM_GMA3600) += cdv_device.o \ · 38 unmodified lines
39gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \39gma500_gfx-$(CONFIG_DRM_GMA600) += oaktrail_device.o \
40 oaktrail_crtc.o \40 oaktrail_crtc.o \
41 oaktrail_lvds.o \41 oaktrail_lvds.o \
42 oaktrail_lvds_i2c.o \
42 oaktrail_hdmi.o \43 oaktrail_hdmi.o \
43 oaktrail_hdmi_i2c.o44 oaktrail_hdmi_i2c.o
44 45
drivers/gpu/drm/gma500/cdv_intel_dp.c+195−0
@@ -37,6 +37,201 @@ · 36 unmodified lines
37#include "gma_display.h"37#include "gma_display.h"
38#include <drm/drm_dp_helper.h>38#include <drm/drm_dp_helper.h>
39 39
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 */
48struct 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 */
57static int
58i2c_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 */
78static int
79i2c_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 */
99static void
100i2c_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 */
119static int
120i2c_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 */
136static int
137i2c_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
149static int
150i2c_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
189static u32
190i2c_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
198static 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.